directus-template-cli 0.5.0-beta.11 → 0.5.0-beta.13

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 (43) hide show
  1. package/README.md +176 -15
  2. package/dist/commands/apply.d.ts +25 -3
  3. package/dist/commands/apply.js +73 -120
  4. package/dist/commands/extract.d.ts +29 -1
  5. package/dist/commands/extract.js +72 -50
  6. package/dist/flags/common.d.ts +7 -0
  7. package/dist/flags/common.js +41 -0
  8. package/dist/lib/extract/extract-access.js +5 -3
  9. package/dist/lib/extract/extract-assets.d.ts +0 -414
  10. package/dist/lib/extract/extract-assets.js +18 -20
  11. package/dist/lib/extract/extract-collections.js +5 -4
  12. package/dist/lib/extract/extract-content.d.ts +0 -2
  13. package/dist/lib/extract/extract-content.js +16 -15
  14. package/dist/lib/extract/extract-dashboards.js +8 -6
  15. package/dist/lib/extract/extract-extensions.js +5 -3
  16. package/dist/lib/extract/extract-fields.js +4 -2
  17. package/dist/lib/extract/extract-files.js +5 -3
  18. package/dist/lib/extract/extract-flows.js +8 -6
  19. package/dist/lib/extract/extract-folders.js +5 -3
  20. package/dist/lib/extract/extract-permissions.js +5 -3
  21. package/dist/lib/extract/extract-policies.js +5 -3
  22. package/dist/lib/extract/extract-presets.js +5 -3
  23. package/dist/lib/extract/extract-relations.js +5 -3
  24. package/dist/lib/extract/extract-roles.js +5 -3
  25. package/dist/lib/extract/extract-schema.js +6 -8
  26. package/dist/lib/extract/extract-settings.js +5 -3
  27. package/dist/lib/extract/extract-translations.js +6 -6
  28. package/dist/lib/extract/extract-users.js +6 -6
  29. package/dist/lib/load/apply-flags.d.ts +22 -0
  30. package/dist/lib/load/apply-flags.js +67 -0
  31. package/dist/lib/load/index.js +5 -5
  32. package/dist/lib/load/load-collections.js +1 -0
  33. package/dist/lib/load/load-data.js +3 -3
  34. package/dist/lib/sdk.d.ts +20 -2
  35. package/dist/lib/sdk.js +122 -9
  36. package/dist/lib/utils/auth.d.ts +26 -0
  37. package/dist/lib/utils/auth.js +48 -4
  38. package/dist/lib/utils/catch-error.d.ts +15 -2
  39. package/dist/lib/utils/catch-error.js +31 -25
  40. package/oclif.manifest.json +74 -28
  41. package/package.json +1 -1
  42. package/dist/lib/interfaces.d.ts +0 -8
  43. package/dist/lib/interfaces.js +0 -2
package/README.md CHANGED
@@ -4,21 +4,16 @@ A CLI tool to make applying or extracting Directus "templates" a little easier..
4
4
 
5
5
  **Notes:**
6
6
 
7
- - This is a pre-release. It is recommended for use on POC, demo, or greenfield projects only.
8
- - ⚠️ Known issues with using MySQL currently, please use ONLY PostgreSQL or SQLite for your database provider.
9
- - Templates are applied / extracted on an all or nothing basis – meaning that all the schema, content, and system settings are extracted or applied. We'd love to support more granular operations in the future. (PRs welcome 🙏)
7
+ - This is a beta release. It is recommended for use on POC, demo, or greenfield projects only. When applying templates, you should always backup your project/database before applying a template.
8
+ - ⚠️ Known issues with using MySQL currently. We highly recommend using PostgreSQL or SQLite for your database provider. If you're using PostgreSQL in production, we recommend using PostgreSQL in local development as well.
10
9
  - If you are extracting or applying from a remote source, the script can take quite a while depending on the "size" of your instance (how many collections, how many items in each collection, number and size of assets, etc). The script applies a strict rate limit of 10 requests per second using bottleneck.
11
-
12
- ## Breaking Changes in v0.4.0
13
-
14
- - Templates are no longer being bundled with the CLI or included in this repository. Templates are stored in this repository - https://github.com/directus-community/directus-templates.
15
- - When applying templates, the schema snapshot / schema diff is no longer used to create collections, fields, and relations. This allows support for loading multiple templates into a single instance.
16
-
17
- ## Usage
10
+ - As of v0.5.0, the CLI is compatible with Directus 11 and up. If you need to apply or extract to an instance of Directus 10, you can use v0.4.0 of the CLI. `npx directus-template-cli@0.4 extract` or `npx directus-template-cli@0.4 apply`.
18
11
 
19
12
  Using the @latest tag ensures you're receiving the latest version of the packaged templates with the CLI. You can review [the specific versions on NPM](https://www.npmjs.com/package/directus-template-cli) and use @{version} syntax to apply the templates included with that version.
20
13
 
21
- ### Applying a Template
14
+ ## Applying a Template
15
+
16
+ 🚧 Make backups of your project/database before applying templates.
22
17
 
23
18
  1. Create a Directus instance on [Directus Cloud](https://directus.cloud) or using self-hosted version.
24
19
  2. Login and create a Static Access Token for the admin user.
@@ -26,24 +21,190 @@ Using the @latest tag ensures you're receiving the latest version of the package
26
21
  4. Run the following command on the terminal and follow the prompts.
27
22
 
28
23
  ```
29
- $ npx directus-template-cli@latest apply
24
+ npx directus-template-cli@latest apply
25
+ ```
26
+
27
+ You can choose from our community maintained templates or you can also choose a template from a local directory or a public GitHub repository.
28
+
29
+
30
+ ### Programmatic Mode
31
+
32
+ By default, the CLI will run in interactive mode. For CI/CD pipelines or automated scripts, you can use the programmatic mode:
33
+
34
+
35
+ Using a token:
36
+
37
+ ```
38
+ npx directus-template-cli@latest apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local"
39
+ ```
40
+
41
+ Using email/password:
42
+
43
+ ```
44
+ npx directus-template-cli@latest apply -p --directusUrl="http://localhost:8055" --userEmail="admin@example.com" --userPassword="admin" --templateLocation="./my-template" --templateType="local"
45
+ ```
46
+
47
+ Partial apply (apply only some of the parts of a template to the instance):
48
+
49
+ ```
50
+ npx directus-template-cli@latest apply -p --directusUrl="http://localhost:8055" --userEmail="admin@example.com" --userPassword="your-password" --templateLocation="./my-template" --templateType="local" --partial --schema --permissions --no-content
51
+
52
+ ```
53
+
54
+ Available flags for programmatic mode:
55
+
56
+ - `--directusUrl`: URL of the Directus instance to apply the template to (required)
57
+ - `--directusToken`: Token to use for the Directus instance (required if not using email/password)
58
+ - `--userEmail`: Email for Directus authentication (required if not using token)
59
+ - `--userPassword`: Password for Directus authentication (required if not using token)
60
+ - `--templateLocation`: Location of the template to apply (required)
61
+ - `--templateType`: Type of template to apply. Options: community, local, github. Defaults to `local`.
62
+ - `--partial`: Enable partial template application
63
+ - `--content`: Load Content (data)
64
+ - `--dashboards`: Load Dashboards
65
+ - `--extensions`: Load Extensions
66
+ - `--files`: Load Files
67
+ - `--flows`: Load Flows
68
+ - `--permissions`: Load Permissions
69
+ - `--schema`: Load Schema
70
+ - `--settings`: Load Settings
71
+ - `--users`: Load Users
72
+
73
+ When using `--partial`, you can also use `--no` flags to exclude specific components from being applied. For example:
74
+
75
+ ```
76
+ npx directus-template-cli@latest apply -p --directusUrl="http://localhost:8055" --userEmail="admin@example.com" --userPassword="your-password" --templateLocation="./my-template" --templateType="local" --partial --no-content --no-users
77
+ ```
78
+
79
+ This command will apply the template but exclude content and users. Available `--no` flags include:
80
+
81
+ - `--no-content`: Skip loading Content (data)
82
+ - `--no-dashboards`: Skip loading Dashboards
83
+ - `--no-extensions`: Skip loading Extensions
84
+ - `--no-files`: Skip loading Files
85
+ - `--no-flows`: Skip loading Flows
86
+ - `--no-permissions`: Skip loading PermissionsI
87
+ - `--no-schema`: Skip loading Schema
88
+ - `--no-settings`: Skip loading Settings
89
+ - `--no-users`: Skip loading Users
90
+
91
+
92
+ #### Template Component Dependencies
93
+
94
+ When applying templates, certain components have dependencies on others. Here are the key relationships to be aware of:
95
+
96
+ - `--users`: Depends on `--permissions`. If you include users, permissions will automatically be included.
97
+ - `--permissions`: Depends on `--schema`. If you include permissions, the schema will automatically be included.
98
+ - `--content`: Depends on `--schema`. If you include content, the schema will automatically be included.
99
+ - `--files`: No direct dependencies, but often related to content. Consider including `--content` if you're including files.
100
+ - `--flows`: No direct dependencies, but may interact with other components. Consider your specific use case.
101
+ - `--dashboards`: No direct dependencies, but often rely on data from other components.
102
+ - `--extensions`: No direct dependencies, but may interact with other components.
103
+ - `--settings`: No direct dependencies, but affects the overall system configuration.
104
+
105
+ When using the `--partial` flag, keep these dependencies in mind. For example:
106
+
107
+ ```
108
+ npx directus-template-cli@latest apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local" --partial --users
30
109
  ```
31
110
 
32
- You can choose from our templates bundled with the CLI or you can also choose a template from a local directory.
111
+ This command will automatically include `--permissions` and `--schema` along with `--users`, even if not explicitly specified.
112
+
113
+ If you use `--no-` flags, be cautious about excluding dependencies. For instance, using `--no-schema` while including `--content` may lead to errors or incomplete application of the template.
114
+
115
+ #### Using Environment Variables
116
+
117
+ You can also pass flags as environment variables. This can be useful for CI/CD pipelines or when you want to avoid exposing sensitive information in command-line arguments. Here are the available environment variables:
118
+
119
+ - `TARGET_DIRECTUS_URL`: Equivalent to `--directusUrl`
120
+ - `TARGET_DIRECTUS_TOKEN`: Equivalent to `--directusToken`
121
+ - `TARGET_DIRECTUS_EMAIL`: Equivalent to `--userEmail`
122
+ - `TARGET_DIRECTUS_PASSWORD`: Equivalent to `--userPassword`
123
+ - `TEMPLATE_LOCATION`: Equivalent to `--templateLocation`
124
+ - `TEMPLATE_TYPE`: Equivalent to `--templateType`
125
+ -
126
+
127
+ ### Existing Data
128
+
129
+ You can apply a template to an existing Directus instance. This is nice because you can have smaller templates that you can "compose" for various use cases. The CLI tries to be smart about existing items in the target Directus instance. But mileage may vary depending on the size and complexity of the template and the existing instance.
130
+
131
+ **System Collections**
132
+
133
+ In most of the system collections (collections,roles, permissions, etc.), if an item with the same identifier already exists, it will be typically be SKIPPED vs overwritten.
33
134
 
34
- ### Extracting a Template
135
+ Exceptions:
136
+
137
+ - directus_settings: The CLI attempts to merge the template's project settings with the existing settings in the target instance. Using the existing settings as a base and updating them with the values from the template. This should prevent overwriting branding, themes, and other customizations.
138
+
139
+ **Your Collections:**
140
+
141
+ For data in your own user-created collections, if an item has the same primary key, the data will be overwritten with the incoming data from the template.
142
+
143
+ ---
144
+
145
+ ## Extracting a Template
35
146
 
36
147
  The CLI can also extract a template from a Directus instance so that it can be applied to other instances.
37
148
 
149
+ Note: We do not currently support partial extraction. The entire template will be extracted. We thought it better to have the data and not need it, than need it and not have it.
150
+
38
151
  1. Make sure you remove any sensitive data from the Directus instance you don't want to include in the template.
39
152
  2. Login and create a Static Access Token for the admin user.
40
153
  3. Copy the static token and your Directus URL.
41
154
  4. Run the following command on the terminal and follow the prompts.
42
155
 
43
156
  ```
44
- $ npx directus-template-cli@latest extract
157
+ npx directus-template-cli@latest extract
45
158
  ```
46
159
 
160
+ ### Programmatic Mode
161
+
162
+ By default, the CLI will run in interactive mode. For CI/CD pipelines or automated scripts, you can use the programmatic mode:
163
+
164
+ Using a token:
165
+
166
+ ```
167
+ npx directus-template-cli@latest extract -p --templateName="My Template" --templateLocation="./my-template" --directusToken="admin-token-here" --directusUrl="http://localhost:8055"
168
+ ```
169
+
170
+ Using email/password:
171
+
172
+ ```
173
+ npx directus-template-cli@latest extract -p --templateName="My Template" --templateLocation="./my-template" --userEmail="admin@example.com" --userPassword="admin" --directusUrl="http://localhost:8055"
174
+ ```
175
+
176
+ Available flags for programmatic mode:
177
+
178
+ - `--directusUrl`: URL of the Directus instance to extract the template from (required)
179
+ - `--directusToken`: Token to use for the Directus instance (required if not using email/password)
180
+ - `--userEmail`: Email for Directus authentication (required if not using token)
181
+ - `--userPassword`: Password for Directus authentication (required if not using token)
182
+ - `--templateLocation`: Directory to extract the template to (required)
183
+ - `--templateName`: Name of the template (required)
184
+
185
+ #### Using Environment Variables
186
+
187
+ Similar to the Apply command, you can use environment variables for the Extract command as well:
188
+
189
+ - `SOURCE_DIRECTUS_URL`: Equivalent to `--directusUrl`
190
+ - `SOURCE_DIRECTUS_TOKEN`: Equivalent to `--directusToken`
191
+ - `SOURCE_DIRECTUS_EMAIL`: Equivalent to `--userEmail`
192
+ - `SOURCE_DIRECTUS_PASSWORD`: Equivalent to `--userPassword`
193
+ - `TEMPLATE_LOCATION`: Equivalent to `--templateLocation`
194
+
195
+ ## Logs
196
+
197
+ The Directus Template CLI logs information to a file in the `.directus-template-cli/logs` directory.
198
+
199
+ Logs are automatically generated for each run of the CLI. Here's how the logging system works:
200
+ - A new log file is created for each CLI run.
201
+ - Log files are stored in the `.directus-template-cli/logs` directory within your current working directory.
202
+ - Each log file is named `run-[timestamp].log`, where `[timestamp]` is the ISO timestamp of when the CLI was initiated.
203
+
204
+ The logger automatically sanitizes sensitive information such as passwords, tokens, and keys before writing to the log file. But it may not catch everything. Just be aware of this and make sure to remove the log files when they are no longer needed.
205
+
206
+ Note: If you encounter any issues with the CLI, providing these log files can greatly assist in diagnosing and resolving the problem.
207
+
47
208
  ## License
48
209
 
49
210
  This tool is licensed under the [MIT License](https://opensource.org/licenses/MIT).
@@ -17,13 +17,35 @@ export default class ApplyCommand extends Command {
17
17
  settings: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
18
  templateLocation: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
19
19
  templateType: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
20
+ userEmail: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ userPassword: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
20
22
  users: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
21
23
  };
24
+ /**
25
+ * MAIN
26
+ * Run the command
27
+ * @returns {Promise<void>} - Returns nothing
28
+ */
22
29
  run(): Promise<void>;
23
- private initializeDirectusApi;
24
- private redirectToDirectusPlus;
30
+ /**
31
+ * INTERACTIVE
32
+ * Run the command in interactive mode
33
+ * @param flags - The ApplyFlags
34
+ * @returns {Promise<void>} - Returns nothing
35
+ */
25
36
  private runInteractive;
37
+ /**
38
+ * PROGRAMMATIC
39
+ * Run the command in programmatic mode
40
+ * @param flags - The ApplyFlags
41
+ * @returns {Promise<void>} - Returns nothing
42
+ */
26
43
  private runProgrammatic;
44
+ /**
45
+ * INTERACTIVE
46
+ * Select a local template from the given directory
47
+ * @param localTemplateDir - The local template directory path
48
+ * @returns {Promise<Template>} - Returns the selected template
49
+ */
27
50
  private selectLocalTemplate;
28
- private validateFlags;
29
51
  }
@@ -1,45 +1,37 @@
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");
6
5
  const inquirer = tslib_1.__importStar(require("inquirer"));
6
+ const customFlags = tslib_1.__importStar(require("../flags/common"));
7
7
  const constants_1 = require("../lib/constants");
8
+ const apply_flags_1 = require("../lib/load/apply-flags");
8
9
  const index_js_1 = tslib_1.__importDefault(require("../lib/load/index.js"));
9
- const sdk_2 = require("../lib/sdk");
10
10
  const auth_1 = require("../lib/utils/auth");
11
11
  const catch_error_1 = tslib_1.__importDefault(require("../lib/utils/catch-error"));
12
12
  const get_template_1 = require("../lib/utils/get-template");
13
13
  const logger_1 = require("../lib/utils/logger");
14
14
  const open_url_1 = tslib_1.__importDefault(require("../lib/utils/open-url"));
15
15
  class ApplyCommand extends core_1.Command {
16
- // MAIN FUNCTION
16
+ /**
17
+ * MAIN
18
+ * Run the command
19
+ * @returns {Promise<void>} - Returns nothing
20
+ */
17
21
  async run() {
18
22
  const { flags } = await this.parse(ApplyCommand);
19
23
  const typedFlags = flags;
20
24
  await (typedFlags.programmatic ? this.runProgrammatic(typedFlags) : this.runInteractive(typedFlags));
21
25
  }
22
- async initializeDirectusApi(flags) {
23
- sdk_2.api.initialize(flags.directusUrl);
24
- try {
25
- sdk_2.api.setAuthToken(flags.directusToken);
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}`);
28
- }
29
- catch {
30
- (0, catch_error_1.default)('-- Invalid Directus token. Please check your credentials.', {
31
- fatal: true,
32
- });
33
- }
34
- }
35
- redirectToDirectusPlus() {
36
- (0, open_url_1.default)('https://directus.io/plus?utm_source=directus-template-cli&utm_content=apply-command');
37
- core_1.ux.log('Redirecting to Directus website.');
38
- core_1.ux.exit(0);
39
- }
26
+ /**
27
+ * INTERACTIVE
28
+ * Run the command in interactive mode
29
+ * @param flags - The ApplyFlags
30
+ * @returns {Promise<void>} - Returns nothing
31
+ */
40
32
  async runInteractive(flags) {
41
- const validatedFlags = this.validateFlags(flags);
42
- core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, 'Welcome to the Directus Template CLI'));
33
+ const validatedFlags = (0, apply_flags_1.validateInteractiveFlags)(flags);
34
+ core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, 'Directus Template CLI - Apply'));
43
35
  const templateType = await inquirer.prompt([
44
36
  {
45
37
  choices: [
@@ -79,16 +71,40 @@ class ApplyCommand extends core_1.Command {
79
71
  break;
80
72
  }
81
73
  case 'directus-plus': {
82
- this.redirectToDirectusPlus();
74
+ (0, open_url_1.default)('https://directus.io/plus?utm_source=directus-template-cli&utm_content=apply-command');
75
+ core_1.ux.log('Redirecting to Directus website.');
76
+ core_1.ux.exit(0);
83
77
  }
84
78
  }
85
79
  core_1.ux.log(`You selected ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, template.templateName)}`);
86
80
  core_1.ux.log(constants_1.SEPARATOR);
87
- // Get Directus URL and token
81
+ // Get Directus URL
88
82
  const directusUrl = await (0, auth_1.getDirectusUrl)();
89
- const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
90
- flags.directusUrl = directusUrl;
91
- flags.directusToken = directusToken;
83
+ validatedFlags.directusUrl = directusUrl;
84
+ // Prompt for login method
85
+ const loginMethod = await inquirer.prompt([
86
+ {
87
+ choices: [
88
+ { name: 'Directus Access Token', value: 'token' },
89
+ { name: 'Email and Password', value: 'email' },
90
+ ],
91
+ default: 'token',
92
+ message: 'How do you want to log in?',
93
+ name: 'loginMethod',
94
+ type: 'list',
95
+ },
96
+ ]);
97
+ if (loginMethod.loginMethod === 'token') {
98
+ const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
99
+ validatedFlags.directusToken = directusToken;
100
+ }
101
+ else {
102
+ const userEmail = await core_1.ux.prompt('What is your email?');
103
+ validatedFlags.userEmail = userEmail;
104
+ const userPassword = await core_1.ux.prompt('What is your password?');
105
+ validatedFlags.userPassword = userPassword;
106
+ }
107
+ await (0, auth_1.initializeDirectusApi)(validatedFlags);
92
108
  if (template) {
93
109
  core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, `Applying template - ${template.templateName} to ${directusUrl}`));
94
110
  await (0, index_js_1.default)(template.directoryPath, validatedFlags);
@@ -98,8 +114,14 @@ class ApplyCommand extends core_1.Command {
98
114
  core_1.ux.exit(0);
99
115
  }
100
116
  }
117
+ /**
118
+ * PROGRAMMATIC
119
+ * Run the command in programmatic mode
120
+ * @param flags - The ApplyFlags
121
+ * @returns {Promise<void>} - Returns nothing
122
+ */
101
123
  async runProgrammatic(flags) {
102
- const validatedFlags = this.validateFlags(flags);
124
+ const validatedFlags = (0, apply_flags_1.validateProgrammaticFlags)(flags);
103
125
  let template;
104
126
  switch (validatedFlags.templateType) {
105
127
  case 'community': {
@@ -121,7 +143,7 @@ class ApplyCommand extends core_1.Command {
121
143
  });
122
144
  }
123
145
  }
124
- await this.initializeDirectusApi(validatedFlags);
146
+ await (0, auth_1.initializeDirectusApi)(validatedFlags);
125
147
  const logMessage = `Applying template - ${template.templateName} to ${validatedFlags.directusUrl}`;
126
148
  core_1.ux.styledHeader(logMessage);
127
149
  logger_1.logger.log('info', logMessage);
@@ -131,6 +153,12 @@ class ApplyCommand extends core_1.Command {
131
153
  core_1.ux.info('Template applied successfully.');
132
154
  core_1.ux.exit(0);
133
155
  }
156
+ /**
157
+ * INTERACTIVE
158
+ * Select a local template from the given directory
159
+ * @param localTemplateDir - The local template directory path
160
+ * @returns {Promise<Template>} - Returns the selected template
161
+ */
134
162
  async selectLocalTemplate(localTemplateDir) {
135
163
  try {
136
164
  const templates = await (0, get_template_1.getInteractiveLocalTemplate)(localTemplateDir);
@@ -156,55 +184,6 @@ class ApplyCommand extends core_1.Command {
156
184
  }
157
185
  }
158
186
  }
159
- validateFlags(flags) {
160
- if (flags.programmatic) {
161
- if (!flags.directusUrl || !flags.directusToken) {
162
- core_1.ux.error('Directus URL and token are required for programmatic mode.');
163
- }
164
- if (!flags.templateLocation) {
165
- core_1.ux.error('Template location is required for programmatic mode.');
166
- }
167
- }
168
- const loadFlags = [
169
- 'content',
170
- 'dashboards',
171
- 'extensions',
172
- 'files',
173
- 'flows',
174
- 'permissions',
175
- 'schema',
176
- 'settings',
177
- 'users',
178
- ];
179
- const validatedFlags = { ...flags };
180
- if (flags.partial) {
181
- const enabledFlags = loadFlags.filter(flag => flags[flag] === true);
182
- if (enabledFlags.length === 0) {
183
- core_1.ux.error('When using --partial, at least one component flag must be set to true.');
184
- }
185
- // Handle dependencies
186
- if (flags.content) {
187
- validatedFlags.schema = true;
188
- validatedFlags.files = true;
189
- if (!flags.schema || !flags.files) {
190
- core_1.ux.warn('Content loading requires schema and files. Enabling schema and files flags.');
191
- }
192
- }
193
- if (flags.users) {
194
- validatedFlags.permissions = true;
195
- if (!flags.permissions) {
196
- core_1.ux.warn('User loading requires permissions. Enabling permissions flag.');
197
- }
198
- }
199
- }
200
- else {
201
- // If not partial, set all flags to true
202
- for (const flag of loadFlags) {
203
- validatedFlags[flag] = true;
204
- }
205
- }
206
- return validatedFlags;
207
- }
208
187
  }
209
188
  ApplyCommand.description = 'Apply a template to a blank Directus instance.';
210
189
  ApplyCommand.examples = [
@@ -215,38 +194,29 @@ ApplyCommand.examples = [
215
194
  ApplyCommand.flags = {
216
195
  content: core_1.Flags.boolean({
217
196
  allowNo: true,
218
- default: templateFlagsDefault,
197
+ default: undefined,
219
198
  description: 'Load Content (data)',
220
- relationships: [
221
- { flags: ['schema', 'files'], type: 'all' },
222
- ],
223
199
  }),
224
200
  dashboards: core_1.Flags.boolean({
225
201
  allowNo: true,
226
- default: templateFlagsDefault,
202
+ default: undefined,
227
203
  description: 'Load Dashboards (dashboards, panels)',
228
204
  }),
229
- directusToken: core_1.Flags.string({
230
- description: 'Token to use for the Directus instance',
231
- env: 'TARGET_DIRECTUS_TOKEN',
232
- }),
233
- directusUrl: core_1.Flags.string({
234
- description: 'URL of the Directus instance to apply the template to',
235
- env: 'TARGET_DIRECTUS_URL',
236
- }),
205
+ directusToken: customFlags.directusToken,
206
+ directusUrl: customFlags.directusUrl,
237
207
  extensions: core_1.Flags.boolean({
238
208
  allowNo: true,
239
- default: templateFlagsDefault,
209
+ default: undefined,
240
210
  description: 'Load Extensions',
241
211
  }),
242
212
  files: core_1.Flags.boolean({
243
213
  allowNo: true,
244
- default: templateFlagsDefault,
214
+ default: undefined,
245
215
  description: 'Load Files (files, folders)',
246
216
  }),
247
217
  flows: core_1.Flags.boolean({
248
218
  allowNo: true,
249
- default: templateFlagsDefault,
219
+ default: undefined,
250
220
  description: 'Load Flows (operations, flows)',
251
221
  }),
252
222
  partial: core_1.Flags.boolean({
@@ -256,31 +226,22 @@ ApplyCommand.flags = {
256
226
  }),
257
227
  permissions: core_1.Flags.boolean({
258
228
  allowNo: true,
259
- default: templateFlagsDefault,
229
+ default: undefined,
260
230
  description: 'Loads permissions data. Collections include: directus_roles, directus_policies, directus_access, directus_permissions.',
261
231
  summary: 'Load permissions (roles, policies, access, permissions)',
262
232
  }),
263
- programmatic: core_1.Flags.boolean({
264
- char: 'p',
265
- default: false,
266
- description: 'Run in programmatic mode (non-interactive) for use cases such as CI/CD pipelines.',
267
- summary: 'Run in programmatic mode',
268
- }),
233
+ programmatic: customFlags.programmatic,
269
234
  schema: core_1.Flags.boolean({
270
235
  allowNo: true,
271
- default: templateFlagsDefault,
236
+ default: undefined,
272
237
  description: 'Load schema (collections, relations)',
273
238
  }),
274
239
  settings: core_1.Flags.boolean({
275
240
  allowNo: true,
276
- default: templateFlagsDefault,
241
+ default: undefined,
277
242
  description: 'Load settings (project settings, translations, presets)',
278
243
  }),
279
- templateLocation: core_1.Flags.string({
280
- dependsOn: ['programmatic', 'templateType'],
281
- description: 'Location of the template to apply',
282
- env: 'TEMPLATE_LOCATION',
283
- }),
244
+ templateLocation: customFlags.templateLocation,
284
245
  templateType: core_1.Flags.string({
285
246
  default: 'local',
286
247
  dependsOn: ['programmatic'],
@@ -289,20 +250,12 @@ ApplyCommand.flags = {
289
250
  options: ['community', 'local', 'github'],
290
251
  summary: 'Type of template to apply. Options: community, local, github.',
291
252
  }),
253
+ userEmail: customFlags.userEmail,
254
+ userPassword: customFlags.userPassword,
292
255
  users: core_1.Flags.boolean({
293
256
  allowNo: true,
294
- default: templateFlagsDefault,
257
+ default: undefined,
295
258
  description: 'Load users',
296
- relationships: [
297
- { flags: ['permissions'], type: 'all' },
298
- ],
299
259
  }),
300
260
  };
301
261
  exports.default = ApplyCommand;
302
- function templateFlagsDefault({ flags }) {
303
- // If programmatic is true, and partial is not set, return true
304
- if (flags.programmatic && !flags.partial) {
305
- return true;
306
- }
307
- return false;
308
- }
@@ -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
  }