directus-template-cli 0.5.0-beta.2 → 0.5.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +176 -15
  2. package/dist/commands/apply.d.ts +41 -18
  3. package/dist/commands/apply.js +113 -122
  4. package/dist/commands/extract.d.ts +29 -1
  5. package/dist/commands/extract.js +76 -51
  6. package/dist/flags/common.d.ts +7 -0
  7. package/dist/flags/common.js +41 -0
  8. package/dist/lib/constants.d.ts +3 -0
  9. package/dist/lib/constants.js +6 -0
  10. package/dist/lib/extract/extract-access.js +5 -3
  11. package/dist/lib/extract/extract-assets.d.ts +0 -414
  12. package/dist/lib/extract/extract-assets.js +29 -25
  13. package/dist/lib/extract/extract-collections.js +5 -4
  14. package/dist/lib/extract/extract-content.d.ts +0 -2
  15. package/dist/lib/extract/extract-content.js +16 -15
  16. package/dist/lib/extract/extract-dashboards.js +8 -6
  17. package/dist/lib/extract/extract-extensions.js +5 -3
  18. package/dist/lib/extract/extract-fields.js +5 -4
  19. package/dist/lib/extract/extract-files.js +5 -3
  20. package/dist/lib/extract/extract-flows.js +8 -6
  21. package/dist/lib/extract/extract-folders.js +5 -3
  22. package/dist/lib/extract/extract-permissions.js +5 -3
  23. package/dist/lib/extract/extract-policies.js +5 -3
  24. package/dist/lib/extract/extract-presets.js +5 -3
  25. package/dist/lib/extract/extract-relations.js +5 -3
  26. package/dist/lib/extract/extract-roles.js +5 -3
  27. package/dist/lib/extract/extract-schema.js +6 -8
  28. package/dist/lib/extract/extract-settings.js +5 -3
  29. package/dist/lib/extract/extract-translations.js +6 -6
  30. package/dist/lib/extract/extract-users.js +6 -6
  31. package/dist/lib/load/apply-flags.d.ts +22 -0
  32. package/dist/lib/load/apply-flags.js +67 -0
  33. package/dist/lib/load/index.js +9 -5
  34. package/dist/lib/load/load-access.js +47 -41
  35. package/dist/lib/load/load-collections.js +61 -17
  36. package/dist/lib/load/load-dashboards.js +30 -30
  37. package/dist/lib/load/load-data.js +47 -11
  38. package/dist/lib/load/load-extensions.js +49 -43
  39. package/dist/lib/load/load-files.js +44 -51
  40. package/dist/lib/load/load-flows.d.ts +1 -1
  41. package/dist/lib/load/load-flows.js +44 -38
  42. package/dist/lib/load/load-folders.js +34 -35
  43. package/dist/lib/load/load-permissions.js +15 -17
  44. package/dist/lib/load/load-policies.js +23 -21
  45. package/dist/lib/load/load-presets.js +27 -26
  46. package/dist/lib/load/load-relations.js +19 -18
  47. package/dist/lib/load/load-roles.js +45 -45
  48. package/dist/lib/load/load-settings.js +39 -2
  49. package/dist/lib/load/load-translations.js +24 -24
  50. package/dist/lib/load/load-users.js +44 -34
  51. package/dist/lib/load/update-required-fields.d.ts +1 -0
  52. package/dist/lib/load/update-required-fields.js +24 -0
  53. package/dist/lib/sdk.d.ts +20 -2
  54. package/dist/lib/sdk.js +124 -9
  55. package/dist/lib/utils/auth.d.ts +26 -0
  56. package/dist/lib/utils/auth.js +48 -4
  57. package/dist/lib/utils/catch-error.d.ts +15 -2
  58. package/dist/lib/utils/catch-error.js +31 -25
  59. package/dist/lib/utils/get-template.d.ts +1 -0
  60. package/dist/lib/utils/get-template.js +42 -1
  61. package/dist/lib/utils/read-file.js +2 -1
  62. package/dist/lib/utils/read-templates.js +4 -2
  63. package/oclif.manifest.json +74 -28
  64. package/package.json +2 -2
  65. package/dist/lib/interfaces.d.ts +0 -8
  66. package/dist/lib/interfaces.js +0 -2
@@ -4,61 +4,67 @@ exports.loadOperations = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const sdk_1 = require("@directus/sdk");
6
6
  const core_1 = require("@oclif/core");
7
+ const constants_1 = require("../constants");
7
8
  const sdk_2 = require("../sdk");
8
9
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
9
10
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
10
11
  async function loadFlows(dir) {
11
12
  const flows = (0, read_file_1.default)('flows', dir);
12
- core_1.ux.action.start(`Loading ${flows.length} flows`);
13
- // Fetch existing flows
14
- const existingFlows = await sdk_2.api.client.request((0, sdk_1.readFlows)({
15
- limit: -1,
16
- }));
17
- const existingFlowIds = new Set(existingFlows.map(flow => flow.id));
18
- const cleanedUpFlows = flows.map(flow => {
19
- const cleanFlow = { ...flow };
20
- delete cleanFlow.operations;
21
- return cleanFlow;
22
- });
23
- for (const flow of cleanedUpFlows) {
13
+ const allOperations = (0, read_file_1.default)('operations', dir);
14
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${flows.length} flows`));
15
+ if (flows && flows.length > 0) {
24
16
  try {
25
- if (existingFlowIds.has(flow.id)) {
26
- core_1.ux.log(`Skipping existing flow: ${flow.name}`);
27
- continue;
17
+ // Fetch existing flows
18
+ const existingFlows = await sdk_2.api.client.request((0, sdk_1.readFlows)({
19
+ limit: -1,
20
+ }));
21
+ const existingFlowIds = new Set(existingFlows.map(flow => flow.id));
22
+ const newFlows = flows.filter(flow => !existingFlowIds.has(flow.id));
23
+ const results = await Promise.allSettled(newFlows.map(flow => sdk_2.api.client.request((0, sdk_1.createFlow)(flow))));
24
+ const createdFlowIds = new Set();
25
+ for (const [index, result] of results.entries()) {
26
+ if (result.status === 'fulfilled') {
27
+ createdFlowIds.add(newFlows[index].id);
28
+ }
29
+ else {
30
+ (0, catch_error_1.default)(result.reason);
31
+ }
28
32
  }
29
- await sdk_2.api.client.request((0, sdk_1.createFlow)(flow));
30
- existingFlowIds.add(flow.id);
33
+ // Filter operations for newly created flows
34
+ const newOperations = allOperations.filter(operation => createdFlowIds.has(operation.flow));
35
+ await loadOperations(newOperations);
31
36
  }
32
37
  catch (error) {
33
38
  (0, catch_error_1.default)(error);
34
39
  }
40
+ finally {
41
+ core_1.ux.action.stop();
42
+ }
35
43
  }
36
- await loadOperations(dir);
37
- core_1.ux.action.stop();
38
- core_1.ux.log('Loaded Flows');
39
44
  }
40
45
  exports.default = loadFlows;
41
- async function loadOperations(dir) {
42
- const operations = (0, read_file_1.default)('operations', dir);
43
- core_1.ux.log(`Loading ${operations.length} operations`);
44
- const opsIds = operations.map(i => {
45
- const del = { ...i };
46
- delete del.resolve;
47
- delete del.reject;
48
- return del;
49
- });
50
- await sdk_2.api.client.request((0, sdk_1.createOperations)(opsIds));
51
- for (const operation of operations) {
52
- const pl = {
46
+ async function loadOperations(operations) {
47
+ core_1.ux.action.status = `Loading ${operations.length} operations`;
48
+ try {
49
+ const opsIds = operations.map(operation => {
50
+ const opCopy = { ...operation };
51
+ delete opCopy.reject;
52
+ delete opCopy.resolve;
53
+ return opCopy;
54
+ });
55
+ await sdk_2.api.client.request((0, sdk_1.createOperations)(opsIds));
56
+ const results = await Promise.allSettled(operations.map(operation => sdk_2.api.client.request((0, sdk_1.updateOperation)(operation.id, {
53
57
  reject: operation.reject,
54
58
  resolve: operation.resolve,
55
- };
56
- try {
57
- await sdk_2.api.client.request((0, sdk_1.updateOperation)(operation.id, pl));
58
- }
59
- catch (error) {
60
- (0, catch_error_1.default)(error);
59
+ }))));
60
+ for (const [index, result] of results.entries()) {
61
+ if (result.status === 'rejected') {
62
+ (0, catch_error_1.default)(result.reason);
63
+ }
61
64
  }
62
65
  }
66
+ catch (error) {
67
+ (0, catch_error_1.default)(error);
68
+ }
63
69
  }
64
70
  exports.loadOperations = loadOperations;
@@ -3,50 +3,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
9
10
  async function loadFolders(dir) {
10
11
  const folders = (0, read_file_1.default)('folders', dir);
11
- core_1.ux.action.start(`Loading ${folders.length} folders`);
12
- try {
13
- // Fetch existing folders
14
- const existingFolders = await sdk_2.api.client.request((0, sdk_1.readFolders)({
15
- limit: -1,
16
- }));
17
- const existingFolderIds = new Set(existingFolders.map(folder => folder.id));
18
- const foldersToAdd = folders.filter(folder => {
19
- if (existingFolderIds.has(folder.id)) {
20
- core_1.ux.log(`Skipping existing folder: ${folder.name}`);
21
- return false;
22
- }
23
- return true;
24
- });
25
- if (foldersToAdd.length > 0) {
26
- const folderSkeleton = foldersToAdd.map(folder => ({ id: folder.id, name: folder.name }));
27
- // Create the folders
28
- await sdk_2.api.client.request((0, sdk_1.createFolders)(folderSkeleton));
29
- core_1.ux.log(`Created ${foldersToAdd.length} new folders`);
30
- // Update the folders with relationships concurrently
31
- await Promise.all(foldersToAdd.map(async (folder) => {
32
- const { id, ...rest } = folder;
33
- try {
34
- await sdk_2.api.client.request((0, sdk_1.updateFolder)(id, rest));
35
- core_1.ux.log(`Updated relationships for folder: ${folder.name}`);
36
- }
37
- catch (error) {
38
- (0, catch_error_1.default)(error);
39
- }
12
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${folders.length} folders`));
13
+ if (folders && folders.length > 0) {
14
+ try {
15
+ // Fetch existing folders
16
+ const existingFolders = await sdk_2.api.client.request((0, sdk_1.readFolders)({
17
+ limit: -1,
40
18
  }));
19
+ const existingFolderIds = new Set(existingFolders.map(folder => folder.id));
20
+ const foldersToAdd = folders.filter(folder => {
21
+ if (existingFolderIds.has(folder.id)) {
22
+ return false;
23
+ }
24
+ return true;
25
+ });
26
+ if (foldersToAdd.length > 0) {
27
+ const folderSkeleton = foldersToAdd.map(folder => ({ id: folder.id, name: folder.name }));
28
+ // Create the folders
29
+ await sdk_2.api.client.request((0, sdk_1.createFolders)(folderSkeleton));
30
+ // Update the folders with relationships concurrently
31
+ await Promise.all(foldersToAdd.map(async (folder) => {
32
+ const { id, ...rest } = folder;
33
+ try {
34
+ await sdk_2.api.client.request((0, sdk_1.updateFolder)(id, rest));
35
+ }
36
+ catch (error) {
37
+ (0, catch_error_1.default)(error);
38
+ }
39
+ }));
40
+ }
41
+ else {
42
+ // ux.info('-- No new folders to create')
43
+ }
41
44
  }
42
- else {
43
- core_1.ux.log('No new folders to create');
45
+ catch (error) {
46
+ (0, catch_error_1.default)(error);
44
47
  }
45
48
  }
46
- catch (error) {
47
- (0, catch_error_1.default)(error);
48
- }
49
49
  core_1.ux.action.stop();
50
- core_1.ux.log('Loaded folders');
51
50
  }
52
51
  exports.default = loadFolders;
@@ -3,31 +3,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
9
10
  async function loadPermissions(dir) {
10
11
  const permissions = (0, read_file_1.default)('permissions', dir);
11
- core_1.ux.action.start(`Loading ${permissions.length} permissions`);
12
- try {
13
- const existingPermissions = await sdk_2.api.client.request((0, sdk_1.readPermissions)({
14
- limit: -1,
15
- }));
16
- const existingPermissionKeys = new Set(existingPermissions.map(p => `${p.collection}:${p.action}:${p.policy}`));
17
- // Filter out duplicates
18
- const newPermissions = permissions.filter(newPerm => !existingPermissionKeys.has(`${newPerm.collection}:${newPerm.action}:${newPerm.policy}`));
19
- if (newPermissions.length > 0) {
20
- await sdk_2.api.client.request((0, sdk_1.createPermissions)(newPermissions));
21
- core_1.ux.log(`Created ${newPermissions.length} new permissions`);
12
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${permissions.length} permissions`));
13
+ if (permissions && permissions.length > 0) {
14
+ try {
15
+ const existingPermissions = await sdk_2.api.client.request((0, sdk_1.readPermissions)({
16
+ limit: -1,
17
+ }));
18
+ const existingPermissionKeys = new Set(existingPermissions.map(p => `${p.collection}:${p.action}:${p.policy}`));
19
+ // Filter out duplicates
20
+ const newPermissions = permissions.filter(newPerm => !existingPermissionKeys.has(`${newPerm.collection}:${newPerm.action}:${newPerm.policy}`));
21
+ if (newPermissions.length > 0) {
22
+ await sdk_2.api.client.request((0, sdk_1.createPermissions)(newPermissions));
23
+ }
22
24
  }
23
- else {
24
- core_1.ux.log('No new permissions to create');
25
+ catch (error) {
26
+ (0, catch_error_1.default)(error);
25
27
  }
26
28
  }
27
- catch (error) {
28
- (0, catch_error_1.default)(error);
29
- }
30
29
  core_1.ux.action.stop();
31
- core_1.ux.log('Loaded permissions');
32
30
  }
33
31
  exports.default = loadPermissions;
@@ -3,35 +3,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
9
10
  async function loadPolicies(dir) {
10
11
  const policies = (0, read_file_1.default)('policies', dir);
11
- core_1.ux.action.start(`Loading ${policies.length} policies`);
12
- // Fetch existing policies
13
- const existingPolicies = await sdk_2.api.client.request((0, sdk_1.readPolicies)({
14
- limit: -1,
15
- }));
16
- const existingPolicyIds = new Set(existingPolicies.map(policy => policy.id));
17
- const PUBLIC_POLICY_ID = 'abf8a154-5b1c-4a46-ac9c-7300570f4f17';
18
- const policiesWithoutPublic = policies.filter(policy => policy.id !== PUBLIC_POLICY_ID);
19
- for await (const policy of policiesWithoutPublic) {
20
- try {
21
- if (existingPolicyIds.has(policy.id)) {
22
- core_1.ux.log(`Skipping existing policy: ${policy.name}`);
23
- continue;
12
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${policies.length} policies`));
13
+ if (policies && policies.length > 0) {
14
+ // Fetch existing policies
15
+ const existingPolicies = await sdk_2.api.client.request((0, sdk_1.readPolicies)({
16
+ limit: -1,
17
+ }));
18
+ const existingPolicyIds = new Set(existingPolicies.map(policy => policy.id));
19
+ const PUBLIC_POLICY_ID = 'abf8a154-5b1c-4a46-ac9c-7300570f4f17';
20
+ const policiesWithoutPublic = policies.filter(policy => policy.id !== PUBLIC_POLICY_ID);
21
+ for await (const policy of policiesWithoutPublic) {
22
+ try {
23
+ if (existingPolicyIds.has(policy.id)) {
24
+ core_1.ux.action.status = `Skipping existing policy: ${policy.name}`;
25
+ continue;
26
+ }
27
+ // Create new policy
28
+ await sdk_2.api.client.request((0, sdk_1.createPolicy)(policy));
29
+ // Add the new policy ID to our set of existing policies
30
+ existingPolicyIds.add(policy.id);
31
+ }
32
+ catch (error) {
33
+ (0, catch_error_1.default)(error);
24
34
  }
25
- // Create new policy
26
- await sdk_2.api.client.request((0, sdk_1.createPolicy)(policy));
27
- // Add the new policy ID to our set of existing policies
28
- existingPolicyIds.add(policy.id);
29
- }
30
- catch (error) {
31
- (0, catch_error_1.default)(error);
32
35
  }
33
36
  }
34
37
  core_1.ux.action.stop();
35
- core_1.ux.log('Loaded policies');
36
38
  }
37
39
  exports.default = loadPolicies;
@@ -3,40 +3,41 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
9
10
  async function loadPresets(dir) {
10
11
  const presets = (0, read_file_1.default)('presets', dir);
11
- core_1.ux.action.start(`Loading ${presets.length} presets`);
12
- // Fetch existing presets
13
- const existingPresets = await sdk_2.api.client.request((0, sdk_1.readPresets)({
14
- limit: -1,
15
- }));
16
- const existingPresetIds = new Set(existingPresets.map(preset => preset.id));
17
- const presetsToAdd = presets.filter(preset => {
18
- if (existingPresetIds.has(preset.id)) {
19
- return false;
12
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${presets.length} presets`));
13
+ if (presets && presets.length > 0) {
14
+ // Fetch existing presets
15
+ const existingPresets = await sdk_2.api.client.request((0, sdk_1.readPresets)({
16
+ limit: -1,
17
+ }));
18
+ const existingPresetIds = new Set(existingPresets.map(preset => preset.id));
19
+ const presetsToAdd = presets.filter(preset => {
20
+ if (existingPresetIds.has(preset.id)) {
21
+ return false;
22
+ }
23
+ return true;
24
+ }).map(preset => {
25
+ const cleanPreset = { ...preset };
26
+ cleanPreset.user = null;
27
+ return cleanPreset;
28
+ });
29
+ if (presetsToAdd.length > 0) {
30
+ try {
31
+ await sdk_2.api.client.request((0, sdk_1.createPresets)(presetsToAdd));
32
+ }
33
+ catch (error) {
34
+ (0, catch_error_1.default)(error);
35
+ }
20
36
  }
21
- return true;
22
- }).map(preset => {
23
- const cleanPreset = { ...preset };
24
- cleanPreset.user = null;
25
- return cleanPreset;
26
- });
27
- if (presetsToAdd.length > 0) {
28
- try {
29
- await sdk_2.api.client.request((0, sdk_1.createPresets)(presetsToAdd));
30
- core_1.ux.log(`Created ${presetsToAdd.length} new presets`);
37
+ else {
38
+ // ux.info('-- No new presets to create')
31
39
  }
32
- catch (error) {
33
- (0, catch_error_1.default)(error);
34
- }
35
- }
36
- else {
37
- core_1.ux.log('No new presets to create');
38
40
  }
39
41
  core_1.ux.action.stop();
40
- core_1.ux.log('Loaded presets');
41
42
  }
42
43
  exports.default = loadPresets;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
@@ -11,25 +12,25 @@ const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
11
12
  */
12
13
  async function loadRelations(dir) {
13
14
  const relations = (0, read_file_1.default)('relations', dir);
14
- core_1.ux.action.start(`Loading ${relations.length} relations`);
15
- // Fetch existing relations
16
- const existingRelations = await sdk_2.api.client.request((0, sdk_1.readRelations)());
17
- const existingRelationKeys = new Set(existingRelations.map(relation => `${relation.collection}:${relation.field}:${relation.related_collection}`));
18
- const relationsToAdd = relations.filter(relation => {
19
- const key = `${relation.collection}:${relation.field}:${relation.related_collection}`;
20
- if (existingRelationKeys.has(key)) {
21
- core_1.ux.log(`Skipping existing relation: ${key}`);
22
- return false;
23
- }
24
- return true;
25
- }).map(relation => {
26
- const cleanRelation = { ...relation };
27
- delete cleanRelation.meta.id;
28
- return cleanRelation;
29
- });
30
- await addRelations(relationsToAdd);
15
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${relations.length} relations`));
16
+ if (relations && relations.length > 0) {
17
+ // Fetch existing relations
18
+ const existingRelations = await sdk_2.api.client.request((0, sdk_1.readRelations)());
19
+ const existingRelationKeys = new Set(existingRelations.map(relation => `${relation.collection}:${relation.field}:${relation.related_collection}`));
20
+ const relationsToAdd = relations.filter(relation => {
21
+ const key = `${relation.collection}:${relation.field}:${relation.related_collection}`;
22
+ if (existingRelationKeys.has(key)) {
23
+ return false;
24
+ }
25
+ return true;
26
+ }).map(relation => {
27
+ const cleanRelation = { ...relation };
28
+ delete cleanRelation.meta.id;
29
+ return cleanRelation;
30
+ });
31
+ await addRelations(relationsToAdd);
32
+ }
31
33
  core_1.ux.action.stop();
32
- core_1.ux.log('Loaded relations');
33
34
  }
34
35
  exports.default = loadRelations;
35
36
  async function addRelations(relations) {
@@ -3,62 +3,62 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
5
  const core_1 = require("@oclif/core");
6
+ const constants_1 = require("../constants");
6
7
  const sdk_2 = require("../sdk");
7
8
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
9
  const get_role_ids_1 = tslib_1.__importDefault(require("../utils/get-role-ids"));
9
10
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
10
11
  async function loadRoles(dir) {
11
12
  const roles = (0, read_file_1.default)('roles', dir);
12
- core_1.ux.action.start(`Loading ${roles.length} roles`);
13
- const { legacyAdminRoleId, newAdminRoleId } = await (0, get_role_ids_1.default)(dir);
14
- // Fetch existing roles
15
- const existingRoles = await sdk_2.api.client.request((0, sdk_1.readRoles)({
16
- limit: -1,
17
- }));
18
- const existingRoleIds = new Set(existingRoles.map(role => role.id));
19
- const existingRoleNames = new Set(existingRoles.map(role => role.name.toLowerCase()));
20
- const cleanedUpRoles = roles
21
- .filter(role => role.name !== 'Administrator') // Don't load legacy admin role
22
- .filter(role => !existingRoleNames.has(role.name.toLowerCase())) // Filter out roles with existing names
23
- .map(role => {
24
- const r = { ...role };
25
- delete r.users; // Alias field. User roles will be applied when the users are loaded.
26
- delete r.parent; // We need to load all roles first
27
- return r;
28
- });
29
- for await (const role of cleanedUpRoles) {
30
- try {
31
- if (existingRoleIds.has(role.id)) {
32
- core_1.ux.log(`Skipping existing role: ${role.name}`);
33
- continue;
13
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${roles.length} roles`));
14
+ if (roles && roles.length > 0) {
15
+ const { legacyAdminRoleId, newAdminRoleId } = await (0, get_role_ids_1.default)(dir);
16
+ // Fetch existing roles
17
+ const existingRoles = await sdk_2.api.client.request((0, sdk_1.readRoles)({
18
+ limit: -1,
19
+ }));
20
+ const existingRoleIds = new Set(existingRoles.map(role => role.id));
21
+ const existingRoleNames = new Set(existingRoles.map(role => role.name.toLowerCase()));
22
+ const cleanedUpRoles = roles
23
+ .filter(role => role.name !== 'Administrator') // Don't load legacy admin role
24
+ .filter(role => !existingRoleNames.has(role.name.toLowerCase())) // Filter out roles with existing names
25
+ .map(role => {
26
+ const r = { ...role };
27
+ delete r.users; // Alias field. User roles will be applied when the users are loaded.
28
+ delete r.parent; // We need to load all roles first
29
+ return r;
30
+ });
31
+ for await (const role of cleanedUpRoles) {
32
+ try {
33
+ if (existingRoleIds.has(role.id)) {
34
+ continue;
35
+ }
36
+ // Create new role
37
+ await sdk_2.api.client.request((0, sdk_1.createRole)(role));
38
+ // Add the new role ID and name to our sets of existing roles
39
+ existingRoleIds.add(role.id);
40
+ existingRoleNames.add(role.name.toLowerCase());
34
41
  }
35
- // Create new role
36
- await sdk_2.api.client.request((0, sdk_1.createRole)(role));
37
- // Add the new role ID and name to our sets of existing roles
38
- existingRoleIds.add(role.id);
39
- existingRoleNames.add(role.name.toLowerCase());
40
- }
41
- catch (error) {
42
- (0, catch_error_1.default)(error);
43
- }
44
- }
45
- // Now add in any parent fields
46
- const rolesWithParents = roles.filter(role => role.parent !== null);
47
- for await (const role of rolesWithParents) {
48
- try {
49
- // Remap any roles where the parent ID is the default admin role
50
- if (role.parent === legacyAdminRoleId) {
51
- role.parent = newAdminRoleId;
42
+ catch (error) {
43
+ (0, catch_error_1.default)(error);
52
44
  }
53
- const simplifiedRole = { parent: role.parent };
54
- await sdk_2.api.client.request((0, sdk_1.updateRole)(role.id, simplifiedRole));
55
- core_1.ux.log(`Updated parent for role: ${role.name}`);
56
45
  }
57
- catch (error) {
58
- (0, catch_error_1.default)(error);
46
+ // Now add in any parent fields
47
+ const rolesWithParents = roles.filter(role => role.parent !== null);
48
+ for await (const role of rolesWithParents) {
49
+ try {
50
+ // Remap any roles where the parent ID is the default admin role
51
+ if (role.parent === legacyAdminRoleId) {
52
+ role.parent = newAdminRoleId;
53
+ }
54
+ const simplifiedRole = { parent: role.parent };
55
+ await sdk_2.api.client.request((0, sdk_1.updateRole)(role.id, simplifiedRole));
56
+ }
57
+ catch (error) {
58
+ (0, catch_error_1.default)(error);
59
+ }
59
60
  }
60
61
  }
61
62
  core_1.ux.action.stop();
62
- core_1.ux.log('Loaded roles');
63
63
  }
64
64
  exports.default = loadRoles;
@@ -2,20 +2,57 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@directus/sdk");
5
+ const core_1 = require("@oclif/core");
5
6
  const defu_1 = require("defu");
7
+ const constants_1 = require("../constants");
6
8
  const sdk_2 = require("../sdk");
7
9
  const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
8
10
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
11
+ const customDefu = (0, defu_1.createDefu)((obj, key, value) => {
12
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
13
+ // @ts-expect-error
14
+ obj[key] = mergeArrays(key, obj[key], value);
15
+ return true;
16
+ }
17
+ if (typeof obj[key] === 'string' && typeof value === 'string') {
18
+ // @ts-expect-error
19
+ obj[key] = mergeJsonStrings(obj[key], value);
20
+ return true;
21
+ }
22
+ });
23
+ function mergeArrays(key, current, incoming) {
24
+ const mergeKeys = {
25
+ /* eslint-disable camelcase */
26
+ basemaps: ['key'],
27
+ custom_aspect_ratios: ['key'],
28
+ module_bar: ['id', 'type'],
29
+ storage_asset_presets: ['key'],
30
+ /* eslint-enable camelcase */
31
+ };
32
+ const keys = mergeKeys[key];
33
+ if (!keys)
34
+ return [...new Set([...current, ...incoming])];
35
+ return current.concat(incoming.filter(item => !current.some(currentItem => keys.every(k => currentItem[k] === item[k]))));
36
+ }
37
+ function mergeJsonStrings(current, incoming) {
38
+ try {
39
+ return JSON.stringify(customDefu(JSON.parse(current), JSON.parse(incoming)));
40
+ }
41
+ catch {
42
+ return incoming; // If not valid JSON, return the incoming value
43
+ }
44
+ }
9
45
  async function loadSettings(dir) {
46
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, 'Loading settings'));
10
47
  const settings = (0, read_file_1.default)('settings', dir);
11
48
  try {
12
- // Get the current settings and merge them with current settings as defaults. To prevent overriding any logos, themes, etc.
13
49
  const currentSettings = await sdk_2.api.client.request((0, sdk_1.readSettings)());
14
- const mergedSettings = (0, defu_1.defu)(currentSettings, settings);
50
+ const mergedSettings = customDefu(currentSettings, settings);
15
51
  await sdk_2.api.client.request((0, sdk_1.updateSettings)(mergedSettings));
16
52
  }
17
53
  catch (error) {
18
54
  (0, catch_error_1.default)(error);
19
55
  }
56
+ core_1.ux.action.stop();
20
57
  }
21
58
  exports.default = loadSettings;