Skip to content

Commit

Permalink
Merge pull request #14 from sacconazzo:feat/v2
Browse files Browse the repository at this point in the history
Feat/v2
  • Loading branch information
sacconazzo authored Sep 14, 2024
2 parents ddc1f12 + 6382246 commit ab73224
Show file tree
Hide file tree
Showing 23 changed files with 178 additions and 49 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Directus utilities CLI

Utilities scripts for Directus projects:
Utilities scripts for Directus 11 (or latest) projects:

- Automatic migrations (reading from your db and creating a migration for deployment)
- roles
- permissions
- translations
- settings
- files table
- **policies** (with permission rules)
- **roles** (with associated policy relationship attributes - policy migration needed first)
- **translations** (transations table)
- **settings**
- **files table**
- Batch updates (set common values on Directus tables)

## Prerequisites
Expand Down Expand Up @@ -61,6 +61,10 @@ Guide for list of commands:
npx directus-x --help
```

Example to create a migration for a **specific policy** `AAA` -> _uuid key_

npx directus-x migrate --policy AAA

Example to create a migration for the **public role** and **related permissions**

```
Expand Down
2 changes: 1 addition & 1 deletion directus-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
client: 'mysql',
connection: {
user: 'root',
password: 'password',
password: 'secret',
database: 'directus',
host: 'localhost',
port: 3306,
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "directus-x",
"version": "1.5.5",
"version": "2.0.0",
"repository": "https://github.com/sacconazzo/directus-utils.git",
"bin": "scripts/index.js",
"main": "scripts/index.js",
Expand All @@ -26,6 +26,7 @@
"knex": "^2.5.1"
},
"devDependencies": {
"mysql": "^2.18.1"
"mysql": "^2.18.1",
"prettier": "^3.3.3"
}
}
26 changes: 18 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ const program = new Command()
const { migrate } = require('./migrate')
const { batch } = require('./batch')

program.name('string-util').description('Directus utilities').version('1.2.0')
program.name('string-util').description('Directus utilities').version('2.0.0')

program
.command('migrate')
.description('Create migration for a specific entity (upsert mode)')
.option('-r, --role <uuid>|public', 'migrate a role (with all related permissions)')
.option('-p, --policy <uuid>', 'migrate a policy (including permissions)')
.option('-r, --role <uuid>|public', 'migrate a role (including associated policy relationship attributes)')
.option('-t, --translations', 'migrate translation keys')
.option('-f, --files', 'migrate files table')
.option('-s, --settings', 'migrate settings')
Expand Down
53 changes: 53 additions & 0 deletions scripts/migrate/policy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const fs = require('fs')
const root = require('find-root')()
const Knex = require('knex')
const { getMigrationKey } = require('./index')

const { db: dbConfig, options, migrationPath } = require('../config')

module.exports = async policy => {
let knex
try {
knex = Knex(dbConfig)

const [policyContent] = await knex('directus_policies').select().where({ id: policy })
if (!policyContent) throw new Error('Policy not valid')

const tamplateContent = fs.readFileSync(
`${root}/scripts/migrate/templates/policy-update${options.module ? '-es' : ''}.js`,
'utf8',
)

const migrationContent = tamplateContent.replaceAll('$$$$', policy).replace('%%%%', JSON.stringify(policyContent))

const migrationName = `${getMigrationKey()}-policy-update.js`
fs.writeFileSync(`${migrationPath}/${migrationName}`, migrationContent)

console.log(`Migration created for policy ${policy}: ${migrationName}`)

const permissionContent = await knex('directus_permissions').select().where({ policy })
permissionContent.forEach(p => {
p.permissions = JSON.parse(p.permissions)
p.validation = JSON.parse(p.validation)
p.presets = JSON.parse(p.presets)
})

const tamplatePContent = fs.readFileSync(
`${root}/scripts/migrate/templates/permissions-update${options.module ? '-es' : ''}.js`,
'utf8',
)

const migrationPContent = tamplatePContent
.replace('$$$$', policy)
.replace('%%%%', JSON.stringify(permissionContent))

const migrationPName = `${getMigrationKey()}-permissions-update.js`
fs.writeFileSync(`${migrationPath}/${migrationPName}`, migrationPContent)

console.log(`Migration created for permissions: ${migrationPName}`)
} catch (err) {
console.error(err.message || err.code || err)
} finally {
knex && knex.client.pool.destroy()
}
}
23 changes: 9 additions & 14 deletions scripts/migrate/role.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = async role => {
role = null
} else {
const [roleContent] = await knex('directus_roles').select().where({ id: role })
if (!roleContent) throw new Error('Ruolo non valido')
if (!roleContent) throw new Error('Role not valid')

const tamplateContent = fs.readFileSync(
`${root}/scripts/migrate/templates/role-update${options.module ? '-es' : ''}.js`,
Expand All @@ -26,27 +26,22 @@ module.exports = async role => {
const migrationName = `${getMigrationKey()}-role-update.js`
fs.writeFileSync(`${migrationPath}/${migrationName}`, migrationContent)

console.log(`Creata migration per ruolo ${role}: ${migrationName}`)
console.log(`Migration created for role ${role}: ${migrationName}`)
}

const permissionContent = await knex('directus_permissions').select().where({ role })
permissionContent.forEach(p => {
if (typeof p.permissions !== 'object') p.permissions = JSON.parse(p.permissions)
if (typeof p.validation !== 'object') p.validation = JSON.parse(p.validation)
if (typeof p.presets !== 'object') p.presets = JSON.parse(p.presets)
})
const accessContent = await knex('directus_access').select().where({ role })

const tamplatePContent = fs.readFileSync(
`${root}/scripts/migrate/templates/permissions-update${options.module ? '-es' : ''}.js`,
const tamplateAContent = fs.readFileSync(
`${root}/scripts/migrate/templates/access-update${options.module ? '-es' : ''}.js`,
'utf8',
)

const migrationPContent = tamplatePContent.replace('$$$$', role).replace('%%%%', JSON.stringify(permissionContent))
const migrationAContent = tamplateAContent.replace('$$$$', role).replace('%%%%', JSON.stringify(accessContent))

const migrationPName = `${getMigrationKey()}-permissions-update.js`
fs.writeFileSync(`${migrationPath}/${migrationPName}`, migrationPContent)
const migrationAName = `${getMigrationKey()}-access-update.js`
fs.writeFileSync(`${migrationPath}/${migrationAName}`, migrationAContent)

console.log(`Creata migration per permissions: ${migrationPName}`)
console.log(`Migration created for permissions: ${migrationAName}`)
} catch (err) {
console.error(err.message || err.code || err)
} finally {
Expand Down
20 changes: 20 additions & 0 deletions scripts/migrate/templates/access-update-es.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import uuid from 'uuid'

const access = JSON.parse('%%%%')
access.forEach(p => {
p.id = uuid.v4()
})

module.exports = {
async up(knex) {
const role = '$$$$'
await knex('directus_access')
.delete()
.where('role', role !== 'null' ? role : null)
return access.length ? knex('directus_access').insert(access) : true
},

async down(knex) {
return true
},
}
18 changes: 18 additions & 0 deletions scripts/migrate/templates/access-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const uuid = require('uuid')

const access = JSON.parse('%%%%')
access.forEach(p => {
p.id = uuid.v4()
})

module.exports = {
up: async knex => {
const role = '$$$$'
await knex('directus_access')
.delete()
.where('role', role !== 'null' ? role : null)
return access.length ? knex('directus_access').insert(access) : true
},

down: async knex => true,
}
2 changes: 1 addition & 1 deletion scripts/migrate/templates/files-update-es.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default {
}
},

down(knex) {
async down(knex) {
return true
},
}
2 changes: 1 addition & 1 deletion scripts/migrate/templates/files-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ module.exports = {
}
},

down: knex => true,
down: async knex => true,
}
6 changes: 3 additions & 3 deletions scripts/migrate/templates/permissions-update-es.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ permissions.forEach(p => {

export default {
async up(knex) {
const role = '$$$$'
const policy = '$$$$'
await knex('directus_permissions')
.delete()
.where('role', role !== 'null' ? role : null)
.where('policy', policy !== 'null' ? policy : null)
return permissions.length ? knex('directus_permissions').insert(permissions) : true
},

down(knex) {
async down(knex) {
return true
},
}
6 changes: 3 additions & 3 deletions scripts/migrate/templates/permissions-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ permissions.forEach(p => {

module.exports = {
up: async knex => {
const role = '$$$$'
const policy = '$$$$'
await knex('directus_permissions')
.delete()
.where('role', role !== 'null' ? role : null)
.where('policy', policy !== 'null' ? policy : null)
return permissions.length ? knex('directus_permissions').insert(permissions) : true
},

down: knex => true,
down: async knex => true,
}
14 changes: 14 additions & 0 deletions scripts/migrate/templates/policy-update-es.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const policies = JSON.parse('%%%%')

export default {
async up(knex) {
const [setPolicy] = await knex('directus_policies').select().where('id', '$$$$')
return setPolicy
? knex('directus_policies').update(policies).where('id', '$$$$')
: knex('directus_policies').insert(policies)
},

async down(knex) {
return true
},
}
12 changes: 12 additions & 0 deletions scripts/migrate/templates/policy-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const policies = JSON.parse('%%%%')

module.exports = {
up: async knex => {
const [setPolicy] = await knex('directus_policies').select().where('id', '$$$$')
return setPolicy
? knex('directus_policies').update(policies).where('id', '$$$$')
: knex('directus_policies').insert(policies)
},

down: async knex => true,
}
2 changes: 1 addition & 1 deletion scripts/migrate/templates/role-update-es.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
return setRole ? knex('directus_roles').update(role).where('id', '$$$$') : knex('directus_roles').insert(role)
},

down(knex) {
async down(knex) {
return true
},
}
2 changes: 1 addition & 1 deletion scripts/migrate/templates/role-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ module.exports = {
return setRole ? knex('directus_roles').update(role).where('id', '$$$$') : knex('directus_roles').insert(role)
},

down: knex => true,
down: async knex => true,
}
Loading

0 comments on commit ab73224

Please sign in to comment.