directus-template-cli 0.5.0-beta.7 → 0.5.0-beta.9

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.
@@ -1,2 +1,2 @@
1
1
  export default function loadFlows(dir: string): Promise<void>;
2
- export declare function loadOperations(dir: string): Promise<void>;
2
+ export declare function loadOperations(operations: any[]): Promise<void>;
@@ -4,61 +4,70 @@ 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) {
24
- try {
25
- if (existingFlowIds.has(flow.id)) {
26
- core_1.ux.log(`Skipping existing flow: ${flow.name}`);
27
- continue;
13
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${flows.length} flows`));
14
+ try {
15
+ // Fetch existing flows
16
+ const existingFlows = await sdk_2.api.client.request((0, sdk_1.readFlows)({
17
+ limit: -1,
18
+ }));
19
+ const existingFlowIds = new Set(existingFlows.map(flow => flow.id));
20
+ const cleanedUpFlows = flows.map(flow => {
21
+ const { operations, ...cleanFlow } = flow;
22
+ return { cleanFlow, operations };
23
+ });
24
+ const newFlows = cleanedUpFlows.filter(({ cleanFlow }) => !existingFlowIds.has(cleanFlow.id));
25
+ const results = await Promise.allSettled(newFlows.map(({ cleanFlow }) => sdk_2.api.client.request((0, sdk_1.createFlow)(cleanFlow))));
26
+ const createdFlowIds = new Set();
27
+ for (const [index, result] of results.entries()) {
28
+ if (result.status === 'fulfilled') {
29
+ createdFlowIds.add(newFlows[index].cleanFlow.id);
30
+ }
31
+ else {
32
+ (0, catch_error_1.default)(result.reason);
28
33
  }
29
- await sdk_2.api.client.request((0, sdk_1.createFlow)(flow));
30
- existingFlowIds.add(flow.id);
31
- }
32
- catch (error) {
33
- (0, catch_error_1.default)(error);
34
34
  }
35
+ // Only load operations for newly created flows
36
+ const newOperations = newFlows
37
+ .filter(({ cleanFlow }) => createdFlowIds.has(cleanFlow.id))
38
+ .flatMap(({ operations }) => operations);
39
+ await loadOperations(newOperations);
40
+ }
41
+ catch (error) {
42
+ (0, catch_error_1.default)(error);
43
+ }
44
+ finally {
45
+ core_1.ux.action.stop();
35
46
  }
36
- await loadOperations(dir);
37
- core_1.ux.action.stop();
38
- core_1.ux.log('Loaded Flows');
39
47
  }
40
48
  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 = {
49
+ async function loadOperations(operations) {
50
+ core_1.ux.action.status = `Loading ${operations.length} operations`;
51
+ try {
52
+ const opsIds = operations.map(operation => {
53
+ const opCopy = { ...operation };
54
+ delete opCopy.reject;
55
+ delete opCopy.resolve;
56
+ return opCopy;
57
+ });
58
+ await sdk_2.api.client.request((0, sdk_1.createOperations)(opsIds));
59
+ const results = await Promise.allSettled(operations.map(operation => sdk_2.api.client.request((0, sdk_1.updateOperation)(operation.id, {
53
60
  reject: operation.reject,
54
61
  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);
62
+ }))));
63
+ for (const [index, result] of results.entries()) {
64
+ if (result.status === 'rejected') {
65
+ (0, catch_error_1.default)(result.reason);
66
+ }
61
67
  }
62
68
  }
69
+ catch (error) {
70
+ (0, catch_error_1.default)(error);
71
+ }
63
72
  }
64
73
  exports.loadOperations = loadOperations;
@@ -3,12 +3,13 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${folders.length} folders`));
12
13
  try {
13
14
  // Fetch existing folders
14
15
  const existingFolders = await sdk_2.api.client.request((0, sdk_1.readFolders)({
@@ -17,7 +18,6 @@ async function loadFolders(dir) {
17
18
  const existingFolderIds = new Set(existingFolders.map(folder => folder.id));
18
19
  const foldersToAdd = folders.filter(folder => {
19
20
  if (existingFolderIds.has(folder.id)) {
20
- core_1.ux.log(`Skipping existing folder: ${folder.name}`);
21
21
  return false;
22
22
  }
23
23
  return true;
@@ -26,7 +26,6 @@ async function loadFolders(dir) {
26
26
  const folderSkeleton = foldersToAdd.map(folder => ({ id: folder.id, name: folder.name }));
27
27
  // Create the folders
28
28
  await sdk_2.api.client.request((0, sdk_1.createFolders)(folderSkeleton));
29
- core_1.ux.log(`Created ${foldersToAdd.length} new folders`);
30
29
  // Update the folders with relationships concurrently
31
30
  await Promise.all(foldersToAdd.map(async (folder) => {
32
31
  const { id, ...rest } = folder;
@@ -39,13 +38,12 @@ async function loadFolders(dir) {
39
38
  }));
40
39
  }
41
40
  else {
42
- core_1.ux.log('No new folders to create');
41
+ // ux.info('-- No new folders to create')
43
42
  }
44
43
  }
45
44
  catch (error) {
46
45
  (0, catch_error_1.default)(error);
47
46
  }
48
47
  core_1.ux.action.stop();
49
- core_1.ux.log('Loaded folders');
50
48
  }
51
49
  exports.default = loadFolders;
@@ -3,12 +3,13 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${permissions.length} permissions`));
12
13
  try {
13
14
  const existingPermissions = await sdk_2.api.client.request((0, sdk_1.readPermissions)({
14
15
  limit: -1,
@@ -18,16 +19,11 @@ async function loadPermissions(dir) {
18
19
  const newPermissions = permissions.filter(newPerm => !existingPermissionKeys.has(`${newPerm.collection}:${newPerm.action}:${newPerm.policy}`));
19
20
  if (newPermissions.length > 0) {
20
21
  await sdk_2.api.client.request((0, sdk_1.createPermissions)(newPermissions));
21
- core_1.ux.log(`Created ${newPermissions.length} new permissions`);
22
- }
23
- else {
24
- core_1.ux.log('No new permissions to create');
25
22
  }
26
23
  }
27
24
  catch (error) {
28
25
  (0, catch_error_1.default)(error);
29
26
  }
30
27
  core_1.ux.action.stop();
31
- core_1.ux.log('Loaded permissions');
32
28
  }
33
29
  exports.default = loadPermissions;
@@ -3,12 +3,13 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${policies.length} policies`));
12
13
  // Fetch existing policies
13
14
  const existingPolicies = await sdk_2.api.client.request((0, sdk_1.readPolicies)({
14
15
  limit: -1,
@@ -19,7 +20,7 @@ async function loadPolicies(dir) {
19
20
  for await (const policy of policiesWithoutPublic) {
20
21
  try {
21
22
  if (existingPolicyIds.has(policy.id)) {
22
- core_1.ux.log(`Skipping existing policy: ${policy.name}`);
23
+ core_1.ux.action.status = `Skipping existing policy: ${policy.name}`;
23
24
  continue;
24
25
  }
25
26
  // Create new policy
@@ -32,6 +33,5 @@ async function loadPolicies(dir) {
32
33
  }
33
34
  }
34
35
  core_1.ux.action.stop();
35
- core_1.ux.log('Loaded policies');
36
36
  }
37
37
  exports.default = loadPolicies;
@@ -3,12 +3,13 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${presets.length} presets`));
12
13
  // Fetch existing presets
13
14
  const existingPresets = await sdk_2.api.client.request((0, sdk_1.readPresets)({
14
15
  limit: -1,
@@ -27,16 +28,14 @@ async function loadPresets(dir) {
27
28
  if (presetsToAdd.length > 0) {
28
29
  try {
29
30
  await sdk_2.api.client.request((0, sdk_1.createPresets)(presetsToAdd));
30
- core_1.ux.log(`Created ${presetsToAdd.length} new presets`);
31
31
  }
32
32
  catch (error) {
33
33
  (0, catch_error_1.default)(error);
34
34
  }
35
35
  }
36
36
  else {
37
- core_1.ux.log('No new presets to create');
37
+ // ux.info('-- No new presets to create')
38
38
  }
39
39
  core_1.ux.action.stop();
40
- core_1.ux.log('Loaded presets');
41
40
  }
42
41
  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,14 +12,13 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${relations.length} relations`));
15
16
  // Fetch existing relations
16
17
  const existingRelations = await sdk_2.api.client.request((0, sdk_1.readRelations)());
17
18
  const existingRelationKeys = new Set(existingRelations.map(relation => `${relation.collection}:${relation.field}:${relation.related_collection}`));
18
19
  const relationsToAdd = relations.filter(relation => {
19
20
  const key = `${relation.collection}:${relation.field}:${relation.related_collection}`;
20
21
  if (existingRelationKeys.has(key)) {
21
- core_1.ux.log(`Skipping existing relation: ${key}`);
22
22
  return false;
23
23
  }
24
24
  return true;
@@ -29,7 +29,6 @@ async function loadRelations(dir) {
29
29
  });
30
30
  await addRelations(relationsToAdd);
31
31
  core_1.ux.action.stop();
32
- core_1.ux.log('Loaded relations');
33
32
  }
34
33
  exports.default = loadRelations;
35
34
  async function addRelations(relations) {
@@ -3,13 +3,14 @@ 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
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${roles.length} roles`));
13
14
  const { legacyAdminRoleId, newAdminRoleId } = await (0, get_role_ids_1.default)(dir);
14
15
  // Fetch existing roles
15
16
  const existingRoles = await sdk_2.api.client.request((0, sdk_1.readRoles)({
@@ -29,7 +30,6 @@ async function loadRoles(dir) {
29
30
  for await (const role of cleanedUpRoles) {
30
31
  try {
31
32
  if (existingRoleIds.has(role.id)) {
32
- core_1.ux.log(`Skipping existing role: ${role.name}`);
33
33
  continue;
34
34
  }
35
35
  // Create new role
@@ -52,13 +52,11 @@ async function loadRoles(dir) {
52
52
  }
53
53
  const simplifiedRole = { parent: role.parent };
54
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
55
  }
57
56
  catch (error) {
58
57
  (0, catch_error_1.default)(error);
59
58
  }
60
59
  }
61
60
  core_1.ux.action.stop();
62
- core_1.ux.log('Loaded roles');
63
61
  }
64
62
  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;
@@ -3,12 +3,13 @@ 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 loadTranslations(dir) {
10
- core_1.ux.action.start('Loading translations');
11
11
  const translations = (0, read_file_1.default)('translations', dir);
12
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${translations.length} translations`));
12
13
  // Fetch existing translations
13
14
  const existingTranslations = await sdk_2.api.client.request((0, sdk_1.readTranslations)({
14
15
  limit: -1,
@@ -17,7 +18,6 @@ async function loadTranslations(dir) {
17
18
  const newTranslations = translations.filter(t => {
18
19
  const key = `${t.language}_${t.key}`;
19
20
  if (existingTranslationKeys.has(key)) {
20
- core_1.ux.log(`Skipping existing translation: ${key}`);
21
21
  return false;
22
22
  }
23
23
  return true;
@@ -25,16 +25,14 @@ async function loadTranslations(dir) {
25
25
  if (newTranslations.length > 0) {
26
26
  try {
27
27
  await sdk_2.api.client.request((0, sdk_1.createTranslations)(newTranslations));
28
- core_1.ux.log(`Created ${newTranslations.length} new translations`);
29
28
  }
30
29
  catch (error) {
31
30
  (0, catch_error_1.default)(error);
32
31
  }
33
32
  }
34
33
  else {
35
- core_1.ux.log('No new translations to create');
34
+ // ux.info('-- No new translations to create')
36
35
  }
37
36
  core_1.ux.action.stop();
38
- core_1.ux.log('Loaded translations');
39
37
  }
40
38
  exports.default = loadTranslations;
@@ -3,20 +3,23 @@ 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 loadUsers(dir) {
11
12
  const users = (0, read_file_1.default)('users', dir);
12
- core_1.ux.action.start(`Loading ${users.length} users`);
13
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${users.length} users`));
13
14
  const { legacyAdminRoleId, newAdminRoleId } = await (0, get_role_ids_1.default)(dir);
14
15
  const incomingUserEmails = users.map(user => user.email);
16
+ const incomingUserIds = users.map(user => user.id).filter(Boolean);
15
17
  const existingUsers = await sdk_2.api.client.request((0, sdk_1.readUsers)({
16
18
  filter: {
17
- email: {
18
- _in: incomingUserEmails,
19
- },
19
+ _or: [
20
+ { email: { _in: incomingUserEmails } },
21
+ { id: { _in: incomingUserIds } },
22
+ ],
20
23
  },
21
24
  limit: -1,
22
25
  }));
@@ -33,9 +36,14 @@ async function loadUsers(dir) {
33
36
  return user;
34
37
  });
35
38
  for await (const user of filteredUsers) {
36
- // If user email is null or already in use, we just delete the email key to pass validation and retain the user and any realationship data
37
- if (user.email === null || existingUsers.some(existingUser => existingUser.email === user.email)) {
39
+ const existingUser = existingUsers.find(existing => existing.email === user.email || existing.id === user.id);
40
+ if (existingUser) {
41
+ // If user already exists, we'll skip creating a new one
38
42
  delete user.email;
43
+ delete user.id;
44
+ // You might want to update the existing user here instead
45
+ // await api.client.request(updateUser(existingUser.id, user))
46
+ continue;
39
47
  }
40
48
  try {
41
49
  await sdk_2.api.client.request((0, sdk_1.createUser)(user));
@@ -45,6 +53,5 @@ async function loadUsers(dir) {
45
53
  }
46
54
  }
47
55
  core_1.ux.action.stop();
48
- core_1.ux.log('Loaded users');
49
56
  }
50
57
  exports.default = loadUsers;
@@ -24,7 +24,7 @@ async function getDirectusToken(directusUrl) {
24
24
  try {
25
25
  sdk_2.api.setAuthToken(directusToken);
26
26
  const response = await sdk_2.api.client.request((0, sdk_1.readMe)());
27
- core_1.ux.log(`Logged in as ${response.first_name} ${response.last_name}`);
27
+ core_1.ux.log(`-- Logged in as ${response.first_name} ${response.last_name}`);
28
28
  return directusToken;
29
29
  }
30
30
  catch (error) {
@@ -5,14 +5,14 @@ const logger_1 = require("./logger");
5
5
  function catchError(error, options = {}, logToFile = true) {
6
6
  const errorMessage = isDirectusError(error) ? formatDirectusError(error)
7
7
  : (error instanceof Error ? formatGenericError(error)
8
- : `Unknown error: ${JSON.stringify(error)}`);
8
+ : `${JSON.stringify(error)}`);
9
9
  const contextString = options.context
10
10
  ? Object.entries(options.context)
11
11
  .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
12
12
  .join(', ') : '';
13
13
  const formattedMessage = [
14
- contextString && `Context: ${contextString}`,
15
14
  errorMessage,
15
+ contextString && `Context: ${contextString}`,
16
16
  ].filter(Boolean).join('\n');
17
17
  options.fatal ? core_1.ux.error(formattedMessage) : core_1.ux.warn(formattedMessage);
18
18
  if (logToFile) {
@@ -4,5 +4,6 @@ interface Template {
4
4
  }
5
5
  export declare function getCommunityTemplates(): Promise<Template[]>;
6
6
  export declare function getLocalTemplate(localTemplateDir: string): Promise<Template>;
7
+ export declare function getInteractiveLocalTemplate(localTemplateDir: string): Promise<Template[]>;
7
8
  export declare function getGithubTemplate(ghTemplateUrl: string): Promise<Template>;
8
9
  export {};
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getGithubTemplate = exports.getLocalTemplate = exports.getCommunityTemplates = void 0;
3
+ exports.getGithubTemplate = exports.getInteractiveLocalTemplate = exports.getLocalTemplate = exports.getCommunityTemplates = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const giget_1 = require("giget");
6
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
6
7
  const node_path_1 = tslib_1.__importDefault(require("node:path"));
7
8
  const path_1 = tslib_1.__importDefault(require("./path"));
8
9
  const read_templates_1 = require("./read-templates");
@@ -33,6 +34,46 @@ async function getLocalTemplate(localTemplateDir) {
33
34
  return (0, read_templates_1.readTemplate)(resolvedDir);
34
35
  }
35
36
  exports.getLocalTemplate = getLocalTemplate;
37
+ async function getInteractiveLocalTemplate(localTemplateDir) {
38
+ const resolvedDir = (0, path_1.default)(localTemplateDir);
39
+ if (!resolvedDir) {
40
+ throw new Error('Directory does not exist.');
41
+ }
42
+ const directTemplate = await (0, read_templates_1.readTemplate)(resolvedDir);
43
+ if (directTemplate) {
44
+ return [directTemplate];
45
+ }
46
+ const templates = await (0, read_templates_1.readAllTemplates)(resolvedDir);
47
+ if (templates.length === 0) {
48
+ // If no templates found, search nested directories
49
+ const nestedTemplates = await findNestedTemplates(resolvedDir, 2);
50
+ if (nestedTemplates.length === 0) {
51
+ throw new Error('No valid templates found in the specified directory or its subdirectories.');
52
+ }
53
+ return nestedTemplates;
54
+ }
55
+ return templates;
56
+ }
57
+ exports.getInteractiveLocalTemplate = getInteractiveLocalTemplate;
58
+ async function findNestedTemplates(dir, depth) {
59
+ if (depth === 0)
60
+ return [];
61
+ const templates = [];
62
+ const entries = await node_fs_1.default.promises.readdir(dir, { withFileTypes: true });
63
+ for (const entry of entries) {
64
+ if (entry.isDirectory()) {
65
+ const fullPath = node_path_1.default.join(dir, entry.name);
66
+ const dirTemplates = await (0, read_templates_1.readAllTemplates)(fullPath);
67
+ templates.push(...dirTemplates);
68
+ if (dirTemplates.length === 0 && depth > 1) {
69
+ // If no templates found and we can go deeper, search subdirectories
70
+ const nestedTemplates = await findNestedTemplates(fullPath, depth - 1);
71
+ templates.push(...nestedTemplates);
72
+ }
73
+ }
74
+ }
75
+ return templates;
76
+ }
36
77
  async function getGithubTemplate(ghTemplateUrl) {
37
78
  try {
38
79
  const ghString = await (0, transform_github_url_1.transformGitHubUrl)(ghTemplateUrl);
@@ -17,8 +17,10 @@ async function readTemplate(directoryPath) {
17
17
  }
18
18
  return null;
19
19
  }
20
- catch (error) {
21
- console.error(`Failed to read package.json file in directory ${directoryPath}: ${error}`);
20
+ catch {
21
+ // console.error(
22
+ // `Failed to read package.json file in directory ${directoryPath}: ${error}`,
23
+ // )
22
24
  return null;
23
25
  }
24
26
  }
@@ -234,5 +234,5 @@
234
234
  ]
235
235
  }
236
236
  },
237
- "version": "0.5.0-beta.7"
237
+ "version": "0.5.0-beta.9"
238
238
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "directus-template-cli",
3
- "version": "0.5.0-beta.7",
3
+ "version": "0.5.0-beta.9",
4
4
  "description": "CLI Utility for applying templates to a Directus instance.",
5
5
  "author": "bryantgillespie @bryantgillespie",
6
6
  "bin": {