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.
- package/README.md +176 -15
- package/dist/commands/apply.d.ts +41 -18
- package/dist/commands/apply.js +113 -122
- package/dist/commands/extract.d.ts +29 -1
- package/dist/commands/extract.js +76 -51
- package/dist/flags/common.d.ts +7 -0
- package/dist/flags/common.js +41 -0
- package/dist/lib/constants.d.ts +3 -0
- package/dist/lib/constants.js +6 -0
- package/dist/lib/extract/extract-access.js +5 -3
- package/dist/lib/extract/extract-assets.d.ts +0 -414
- package/dist/lib/extract/extract-assets.js +29 -25
- package/dist/lib/extract/extract-collections.js +5 -4
- package/dist/lib/extract/extract-content.d.ts +0 -2
- package/dist/lib/extract/extract-content.js +16 -15
- package/dist/lib/extract/extract-dashboards.js +8 -6
- package/dist/lib/extract/extract-extensions.js +5 -3
- package/dist/lib/extract/extract-fields.js +5 -4
- package/dist/lib/extract/extract-files.js +5 -3
- package/dist/lib/extract/extract-flows.js +8 -6
- package/dist/lib/extract/extract-folders.js +5 -3
- package/dist/lib/extract/extract-permissions.js +5 -3
- package/dist/lib/extract/extract-policies.js +5 -3
- package/dist/lib/extract/extract-presets.js +5 -3
- package/dist/lib/extract/extract-relations.js +5 -3
- package/dist/lib/extract/extract-roles.js +5 -3
- package/dist/lib/extract/extract-schema.js +6 -8
- package/dist/lib/extract/extract-settings.js +5 -3
- package/dist/lib/extract/extract-translations.js +6 -6
- package/dist/lib/extract/extract-users.js +6 -6
- package/dist/lib/load/apply-flags.d.ts +22 -0
- package/dist/lib/load/apply-flags.js +67 -0
- package/dist/lib/load/index.js +9 -5
- package/dist/lib/load/load-access.js +47 -41
- package/dist/lib/load/load-collections.js +61 -17
- package/dist/lib/load/load-dashboards.js +30 -30
- package/dist/lib/load/load-data.js +47 -11
- package/dist/lib/load/load-extensions.js +49 -43
- package/dist/lib/load/load-files.js +44 -51
- package/dist/lib/load/load-flows.d.ts +1 -1
- package/dist/lib/load/load-flows.js +44 -38
- package/dist/lib/load/load-folders.js +34 -35
- package/dist/lib/load/load-permissions.js +15 -17
- package/dist/lib/load/load-policies.js +23 -21
- package/dist/lib/load/load-presets.js +27 -26
- package/dist/lib/load/load-relations.js +19 -18
- package/dist/lib/load/load-roles.js +45 -45
- package/dist/lib/load/load-settings.js +39 -2
- package/dist/lib/load/load-translations.js +24 -24
- package/dist/lib/load/load-users.js +44 -34
- package/dist/lib/load/update-required-fields.d.ts +1 -0
- package/dist/lib/load/update-required-fields.js +24 -0
- package/dist/lib/sdk.d.ts +20 -2
- package/dist/lib/sdk.js +124 -9
- package/dist/lib/utils/auth.d.ts +26 -0
- package/dist/lib/utils/auth.js +48 -4
- package/dist/lib/utils/catch-error.d.ts +15 -2
- package/dist/lib/utils/catch-error.js +31 -25
- package/dist/lib/utils/get-template.d.ts +1 -0
- package/dist/lib/utils/get-template.js +42 -1
- package/dist/lib/utils/read-file.js +2 -1
- package/dist/lib/utils/read-templates.js +4 -2
- package/oclif.manifest.json +74 -28
- package/package.json +2 -2
- package/dist/lib/interfaces.d.ts +0 -8
- 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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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 = (
|
|
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;
|