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
@@ -8,11 +8,39 @@ export default class ExtractCommand extends Command {
8
8
  programmatic: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
9
  templateLocation: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
10
  templateName: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ userEmail: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ userPassword: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
13
  };
14
+ /**
15
+ * Main run method for the ExtractCommand
16
+ * @returns {Promise<void>} - Returns nothing
17
+ */
12
18
  run(): Promise<void>;
19
+ /**
20
+ * Extracts the template to the specified directory
21
+ * @param {string} templateName - The name of the template to extract
22
+ * @param {string} directory - The directory to extract the template to
23
+ * @param {ExtractFlags} flags - The command flags
24
+ * @returns {Promise<void>} - Returns nothing
25
+ */
13
26
  private extractTemplate;
14
- private initializeDirectusApi;
27
+ /**
28
+ * Runs the interactive mode for template extraction
29
+ * @param {ExtractFlags} flags - The command flags
30
+ * @returns {Promise<void>} - Returns nothing
31
+ */
15
32
  private runInteractive;
33
+ /**
34
+ * Runs the programmatic mode for template extraction
35
+ * @param {ExtractFlags} flags - The command flags
36
+ * @returns {Promise<void>} - Returns nothing
37
+ */
16
38
  private runProgrammatic;
39
+ /**
40
+ * Validates the flags for programmatic mode
41
+ * @param {ExtractFlags} flags - The command flags to validate
42
+ * @throws {Error} If required flags are missing
43
+ * @returns {void}
44
+ */
17
45
  private validateProgrammaticFlags;
18
46
  }
@@ -1,22 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const sdk_1 = require("@directus/sdk");
5
4
  const core_1 = require("@oclif/core");
5
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
6
6
  const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
7
7
  const node_path_1 = tslib_1.__importDefault(require("node:path"));
8
8
  const slugify_1 = tslib_1.__importDefault(require("slugify"));
9
+ const customFlags = tslib_1.__importStar(require("../flags/common"));
10
+ const constants_1 = require("../lib/constants");
9
11
  const extract_1 = tslib_1.__importDefault(require("../lib/extract/"));
10
- const sdk_2 = require("../lib/sdk");
11
12
  const auth_1 = require("../lib/utils/auth");
13
+ const catch_error_1 = tslib_1.__importDefault(require("../lib/utils/catch-error"));
12
14
  const template_defaults_1 = require("../lib/utils/template-defaults");
13
- const separator = '------------------';
14
15
  class ExtractCommand extends core_1.Command {
16
+ /**
17
+ * Main run method for the ExtractCommand
18
+ * @returns {Promise<void>} - Returns nothing
19
+ */
15
20
  async run() {
16
21
  const { flags } = await this.parse(ExtractCommand);
17
22
  const typedFlags = flags;
18
23
  await (typedFlags.programmatic ? this.runProgrammatic(typedFlags) : this.runInteractive(typedFlags));
19
24
  }
25
+ /**
26
+ * Extracts the template to the specified directory
27
+ * @param {string} templateName - The name of the template to extract
28
+ * @param {string} directory - The directory to extract the template to
29
+ * @param {ExtractFlags} flags - The command flags
30
+ * @returns {Promise<void>} - Returns nothing
31
+ */
20
32
  async extractTemplate(templateName, directory, flags) {
21
33
  try {
22
34
  if (!node_fs_1.default.existsSync(directory)) {
@@ -30,48 +42,78 @@ class ExtractCommand extends core_1.Command {
30
42
  node_fs_1.default.writeFileSync(readmePath, readmeContent);
31
43
  }
32
44
  catch (error) {
33
- core_1.ux.error(`Failed to create directory or write files: ${error.message}`);
45
+ (0, catch_error_1.default)(error, {
46
+ context: { function: 'extractTemplate' },
47
+ fatal: true,
48
+ logToFile: true,
49
+ });
34
50
  }
35
- core_1.ux.log(separator);
36
- core_1.ux.action.start(`Extracting template - from ${flags.directusUrl} to ${directory}`);
51
+ core_1.ux.log(constants_1.SEPARATOR);
52
+ core_1.ux.action.start(`Extracting template - ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, templateName)} from ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, flags.directusUrl)} to ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, directory)}`);
37
53
  await (0, extract_1.default)(directory);
38
54
  core_1.ux.action.stop();
39
- core_1.ux.log(separator);
55
+ core_1.ux.log(constants_1.SEPARATOR);
40
56
  core_1.ux.log('Template extracted successfully.');
41
57
  this.exit(0);
42
58
  }
43
- async initializeDirectusApi(flags) {
44
- sdk_2.api.initialize(flags.directusUrl);
45
- try {
46
- sdk_2.api.setAuthToken(flags.directusToken);
47
- const response = await sdk_2.api.client.request((0, sdk_1.readMe)());
48
- core_1.ux.log(`Logged in as ${response.first_name} ${response.last_name}`);
49
- }
50
- catch {
51
- throw new Error('Invalid Directus token. Please check your credentials.');
52
- }
53
- }
59
+ /**
60
+ * Runs the interactive mode for template extraction
61
+ * @param {ExtractFlags} flags - The command flags
62
+ * @returns {Promise<void>} - Returns nothing
63
+ */
54
64
  async runInteractive(flags) {
55
- const templateName = await core_1.ux.prompt('What is the name of the template?');
65
+ core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, 'Directus Template CLI - Extract'));
66
+ const templateName = await core_1.ux.prompt('What is the name of the template you would like to extract?');
56
67
  const directory = await core_1.ux.prompt("What directory would you like to extract the template to? If it doesn't exist, it will be created.", { default: `templates/${(0, slugify_1.default)(templateName, { lower: true, strict: true })}` });
57
- core_1.ux.log(`You selected ${directory}`);
58
- // Get Directus URL and token
68
+ core_1.ux.log(`You selected ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, directory)}`);
69
+ core_1.ux.log(constants_1.SEPARATOR);
70
+ // Get Directus URL
59
71
  const directusUrl = await (0, auth_1.getDirectusUrl)();
60
- const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
61
72
  flags.directusUrl = directusUrl;
62
- flags.directusToken = directusToken;
73
+ // Prompt for login method
74
+ const loginMethod = await inquirer_1.default.prompt([
75
+ {
76
+ choices: [
77
+ { name: 'Directus Access Token', value: 'token' },
78
+ { name: 'Email and Password', value: 'email' },
79
+ ],
80
+ default: 'token',
81
+ message: 'How do you want to log in?',
82
+ name: 'loginMethod',
83
+ type: 'list',
84
+ },
85
+ ]);
86
+ if (loginMethod.loginMethod === 'token') {
87
+ const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
88
+ flags.directusToken = directusToken;
89
+ }
90
+ else {
91
+ flags.userEmail = await core_1.ux.prompt('What is your email?');
92
+ flags.userPassword = await core_1.ux.prompt('What is your password?', { type: 'hide' });
93
+ }
94
+ core_1.ux.log(constants_1.SEPARATOR);
95
+ await (0, auth_1.initializeDirectusApi)(flags);
63
96
  await this.extractTemplate(templateName, directory, flags);
64
97
  }
98
+ /**
99
+ * Runs the programmatic mode for template extraction
100
+ * @param {ExtractFlags} flags - The command flags
101
+ * @returns {Promise<void>} - Returns nothing
102
+ */
65
103
  async runProgrammatic(flags) {
66
104
  this.validateProgrammaticFlags(flags);
67
105
  const { templateLocation, templateName } = flags;
68
- await this.initializeDirectusApi(flags);
106
+ await (0, auth_1.initializeDirectusApi)(flags);
69
107
  await this.extractTemplate(templateName, templateLocation, flags);
70
108
  }
109
+ /**
110
+ * Validates the flags for programmatic mode
111
+ * @param {ExtractFlags} flags - The command flags to validate
112
+ * @throws {Error} If required flags are missing
113
+ * @returns {void}
114
+ */
71
115
  validateProgrammaticFlags(flags) {
72
- if (!flags.directusUrl || !flags.directusToken) {
73
- core_1.ux.error('Directus URL and token are required for programmatic mode.');
74
- }
116
+ (0, auth_1.validateAuthFlags)(flags);
75
117
  if (!flags.templateLocation) {
76
118
  core_1.ux.error('Template location is required for programmatic mode.');
77
119
  }
@@ -86,29 +128,12 @@ ExtractCommand.examples = [
86
128
  '$ directus-template-cli extract -p --templateName="My Template" --templateLocation="./my-template" --directusToken="admin-token-here" --directusUrl="http://localhost:8055"',
87
129
  ];
88
130
  ExtractCommand.flags = {
89
- directusToken: core_1.Flags.string({
90
- description: 'Token to use for the Directus instance',
91
- env: 'SOURCE_DIRECTUS_TOKEN',
92
- }),
93
- directusUrl: core_1.Flags.string({
94
- description: 'URL of the Directus instance to extract the template from',
95
- env: 'SOURCE_DIRECTUS_URL',
96
- }),
97
- programmatic: core_1.Flags.boolean({
98
- char: 'p',
99
- default: false,
100
- description: 'Run in programmatic mode (non-interactive) for use cases such as CI/CD pipelines.',
101
- summary: 'Run in programmatic mode',
102
- }),
103
- templateLocation: core_1.Flags.string({
104
- dependsOn: ['programmatic'],
105
- description: 'Directory to extract the template to',
106
- env: 'TEMPLATE_LOCATION',
107
- }),
108
- templateName: core_1.Flags.string({
109
- dependsOn: ['programmatic'],
110
- description: 'Name of the template',
111
- env: 'TEMPLATE_NAME',
112
- }),
131
+ directusToken: customFlags.directusToken,
132
+ directusUrl: customFlags.directusUrl,
133
+ programmatic: customFlags.programmatic,
134
+ templateLocation: customFlags.templateLocation,
135
+ templateName: customFlags.templateName,
136
+ userEmail: customFlags.userEmail,
137
+ userPassword: customFlags.userPassword,
113
138
  };
114
139
  exports.default = ExtractCommand;
@@ -0,0 +1,7 @@
1
+ export declare const directusToken: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
2
+ export declare const directusUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
3
+ export declare const userEmail: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
4
+ export declare const userPassword: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
5
+ export declare const programmatic: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ export declare const templateLocation: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ export declare const templateName: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templateName = exports.templateLocation = exports.programmatic = exports.userPassword = exports.userEmail = exports.directusUrl = exports.directusToken = void 0;
4
+ const core_1 = require("@oclif/core");
5
+ exports.directusToken = core_1.Flags.string({
6
+ description: 'Token to use for the Directus instance',
7
+ env: 'DIRECTUS_TOKEN',
8
+ exclusive: ['userEmail', 'userPassword'],
9
+ });
10
+ exports.directusUrl = core_1.Flags.string({
11
+ description: 'URL of the Directus instance',
12
+ env: 'DIRECTUS_URL',
13
+ });
14
+ exports.userEmail = core_1.Flags.string({
15
+ dependsOn: ['userPassword'],
16
+ description: 'Email for Directus authentication',
17
+ env: 'DIRECTUS_EMAIL',
18
+ exclusive: ['directusToken'],
19
+ });
20
+ exports.userPassword = core_1.Flags.string({
21
+ dependsOn: ['userEmail'],
22
+ description: 'Password for Directus authentication',
23
+ env: 'DIRECTUS_PASSWORD',
24
+ exclusive: ['directusToken'],
25
+ });
26
+ exports.programmatic = core_1.Flags.boolean({
27
+ char: 'p',
28
+ default: false,
29
+ description: 'Run in programmatic mode (non-interactive) for use cases such as CI/CD pipelines.',
30
+ summary: 'Run in programmatic mode',
31
+ });
32
+ exports.templateLocation = core_1.Flags.string({
33
+ dependsOn: ['programmatic'],
34
+ description: 'Location of the template',
35
+ env: 'TEMPLATE_LOCATION',
36
+ });
37
+ exports.templateName = core_1.Flags.string({
38
+ dependsOn: ['programmatic'],
39
+ description: 'Name of the template',
40
+ env: 'TEMPLATE_NAME',
41
+ });
@@ -0,0 +1,3 @@
1
+ export declare const DIRECTUS_PURPLE = "#6644ff";
2
+ export declare const DIRECTUS_PINK = "#FF99DD";
3
+ export declare const SEPARATOR = "------------------";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SEPARATOR = exports.DIRECTUS_PINK = exports.DIRECTUS_PURPLE = void 0;
4
+ exports.DIRECTUS_PURPLE = '#6644ff';
5
+ exports.DIRECTUS_PINK = '#FF99DD';
6
+ exports.SEPARATOR = '------------------';
@@ -2,9 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
+ const constants_1 = require("../constants");
5
6
  const sdk_1 = require("../sdk");
7
+ const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
6
8
  const write_to_file_1 = tslib_1.__importDefault(require("../utils/write-to-file"));
7
9
  async function extractAccess(dir) {
10
+ core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, 'Extracting access'));
8
11
  try {
9
12
  const response = await sdk_1.api.client.request(() => ({
10
13
  method: 'GET',
@@ -15,11 +18,10 @@ async function extractAccess(dir) {
15
18
  // delete access.id
16
19
  // }
17
20
  await (0, write_to_file_1.default)('access', response, dir);
18
- core_1.ux.log('Extracted access');
19
21
  }
20
22
  catch (error) {
21
- core_1.ux.warn('Error extracting access:');
22
- core_1.ux.warn(error.message);
23
+ (0, catch_error_1.default)(error);
23
24
  }
25
+ core_1.ux.action.stop();
24
26
  }
25
27
  exports.default = extractAccess;