directus-template-cli 0.7.0-beta.4 → 0.7.0-beta.6

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 (105) hide show
  1. package/bin/dev.js +6 -0
  2. package/bin/run.js +5 -0
  3. package/dist/commands/apply.d.ts +17 -17
  4. package/dist/commands/apply.js +163 -173
  5. package/dist/commands/base.d.ts +15 -0
  6. package/dist/commands/base.js +45 -0
  7. package/dist/commands/extract.d.ts +16 -7
  8. package/dist/commands/extract.js +80 -73
  9. package/dist/commands/init.d.ts +20 -15
  10. package/dist/commands/init.js +189 -126
  11. package/dist/flags/common.d.ts +8 -7
  12. package/dist/flags/common.js +13 -11
  13. package/dist/index.js +1 -5
  14. package/dist/lib/constants.d.ts +3 -5
  15. package/dist/lib/constants.js +8 -13
  16. package/dist/lib/extract/extract-access.js +11 -15
  17. package/dist/lib/extract/extract-assets.js +20 -25
  18. package/dist/lib/extract/extract-collections.js +12 -16
  19. package/dist/lib/extract/extract-content.js +14 -19
  20. package/dist/lib/extract/extract-dashboards.js +22 -28
  21. package/dist/lib/extract/extract-extensions.js +12 -16
  22. package/dist/lib/extract/extract-fields.js +13 -17
  23. package/dist/lib/extract/extract-files.js +15 -19
  24. package/dist/lib/extract/extract-flows.js +22 -28
  25. package/dist/lib/extract/extract-folders.js +15 -19
  26. package/dist/lib/extract/extract-permissions.js +12 -16
  27. package/dist/lib/extract/extract-policies.js +12 -16
  28. package/dist/lib/extract/extract-presets.js +12 -16
  29. package/dist/lib/extract/extract-relations.js +14 -18
  30. package/dist/lib/extract/extract-roles.js +15 -19
  31. package/dist/lib/extract/extract-schema.js +17 -21
  32. package/dist/lib/extract/extract-settings.js +12 -16
  33. package/dist/lib/extract/extract-translations.js +12 -16
  34. package/dist/lib/extract/extract-users.js +15 -19
  35. package/dist/lib/extract/index.js +47 -51
  36. package/dist/lib/init/config.d.ts +1 -1
  37. package/dist/lib/init/config.js +3 -6
  38. package/dist/lib/init/index.d.ts +5 -9
  39. package/dist/lib/init/index.js +105 -85
  40. package/dist/lib/init/types.js +1 -2
  41. package/dist/lib/load/apply-flags.js +17 -23
  42. package/dist/lib/load/index.d.ts +1 -12
  43. package/dist/lib/load/index.js +40 -44
  44. package/dist/lib/load/load-access.js +15 -20
  45. package/dist/lib/load/load-collections.js +27 -32
  46. package/dist/lib/load/load-dashboards.js +19 -25
  47. package/dist/lib/load/load-data.js +43 -49
  48. package/dist/lib/load/load-extensions.js +30 -38
  49. package/dist/lib/load/load-files.js +20 -24
  50. package/dist/lib/load/load-flows.js +23 -29
  51. package/dist/lib/load/load-folders.js +16 -20
  52. package/dist/lib/load/load-permissions.js +13 -17
  53. package/dist/lib/load/load-policies.js +14 -18
  54. package/dist/lib/load/load-presets.js +14 -18
  55. package/dist/lib/load/load-relations.d.ts +2 -0
  56. package/dist/lib/load/load-relations.js +16 -18
  57. package/dist/lib/load/load-roles.js +19 -23
  58. package/dist/lib/load/load-settings.js +18 -21
  59. package/dist/lib/load/load-translations.js +14 -18
  60. package/dist/lib/load/load-users.js +21 -25
  61. package/dist/lib/load/update-required-fields.js +13 -17
  62. package/dist/lib/sdk.d.ts +1 -2
  63. package/dist/lib/sdk.js +27 -27
  64. package/dist/lib/types/extension.js +1 -2
  65. package/dist/lib/types.d.ts +18 -0
  66. package/dist/lib/types.js +1 -0
  67. package/dist/lib/utils/animated-bunny.js +9 -14
  68. package/dist/lib/utils/auth.d.ts +8 -6
  69. package/dist/lib/utils/auth.js +48 -39
  70. package/dist/lib/utils/catch-error.js +8 -11
  71. package/dist/lib/utils/check-template.js +4 -8
  72. package/dist/lib/utils/chunk-array.js +1 -5
  73. package/dist/lib/utils/ensure-dir.js +7 -12
  74. package/dist/lib/utils/filter-fields.js +1 -4
  75. package/dist/lib/utils/get-role-ids.d.ts +1 -1
  76. package/dist/lib/utils/get-role-ids.js +7 -12
  77. package/dist/lib/utils/get-template.js +33 -37
  78. package/dist/lib/utils/logger.js +11 -13
  79. package/dist/lib/utils/open-url.js +5 -8
  80. package/dist/lib/utils/parse-github-url.d.ts +10 -5
  81. package/dist/lib/utils/parse-github-url.js +80 -45
  82. package/dist/lib/utils/path.js +6 -10
  83. package/dist/lib/utils/protected-domains.js +1 -4
  84. package/dist/lib/utils/read-file.js +8 -12
  85. package/dist/lib/utils/read-templates.js +9 -15
  86. package/dist/lib/utils/sanitize-flags.d.ts +3 -0
  87. package/dist/lib/utils/sanitize-flags.js +4 -0
  88. package/dist/lib/utils/system-fields.js +19 -22
  89. package/dist/lib/utils/template-config.d.ts +16 -0
  90. package/dist/lib/utils/template-config.js +34 -0
  91. package/dist/lib/utils/template-defaults.d.ts +1 -1
  92. package/dist/lib/utils/template-defaults.js +5 -14
  93. package/dist/lib/utils/transform-github-url.js +1 -5
  94. package/dist/lib/utils/validate-url.js +3 -6
  95. package/dist/lib/utils/wait.js +1 -5
  96. package/dist/lib/utils/write-to-file.js +8 -11
  97. package/dist/services/docker.js +68 -21
  98. package/dist/services/github.d.ts +1 -1
  99. package/dist/services/github.js +53 -22
  100. package/dist/services/posthog.d.ts +37 -0
  101. package/dist/services/posthog.js +104 -0
  102. package/oclif.manifest.json +32 -13
  103. package/package.json +38 -33
  104. package/bin/dev +0 -17
  105. package/bin/run +0 -5
package/bin/dev.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning
2
+
3
+ // eslint-disable-next-line n/shebang
4
+ import {execute} from '@oclif/core'
5
+
6
+ await execute({development: true, dir: import.meta.url})
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -3,23 +3,23 @@ export default class ApplyCommand extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- content: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
- dashboards: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- directusToken: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
9
- directusUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
- extensions: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
- files: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
- flows: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
- partial: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
- permissions: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
- programmatic: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
- schema: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
- settings: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
- templateLocation: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
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>;
22
- users: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ content: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ dashboards: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ directusToken: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ directusUrl: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ extensions: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ files: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ flows: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ partial: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ permissions: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ programmatic: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
+ schema: import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
+ settings: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ templateLocation: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
19
+ templateType: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
20
+ userEmail: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
21
+ userPassword: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
22
+ users: import("@oclif/core/interfaces").BooleanFlag<boolean>;
23
23
  };
24
24
  /**
25
25
  * MAIN
@@ -1,19 +1,91 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const core_1 = require("@oclif/core");
5
- const inquirer = tslib_1.__importStar(require("inquirer"));
6
- const path = tslib_1.__importStar(require("node:path"));
7
- const customFlags = tslib_1.__importStar(require("../flags/common"));
8
- const constants_1 = require("../lib/constants");
9
- const apply_flags_1 = require("../lib/load/apply-flags");
10
- const index_js_1 = tslib_1.__importDefault(require("../lib/load/index.js"));
11
- const auth_1 = require("../lib/utils/auth");
12
- const catch_error_1 = tslib_1.__importDefault(require("../lib/utils/catch-error"));
13
- const get_template_1 = require("../lib/utils/get-template");
14
- const logger_1 = require("../lib/utils/logger");
15
- const open_url_1 = tslib_1.__importDefault(require("../lib/utils/open-url"));
16
- class ApplyCommand extends core_1.Command {
1
+ import { Command, Flags, ux } from '@oclif/core';
2
+ import { text, select, password, log, intro } from '@clack/prompts';
3
+ import * as path from 'pathe';
4
+ import { animatedBunny } from '../lib/utils/animated-bunny.js';
5
+ import * as customFlags from '../flags/common.js';
6
+ import { DIRECTUS_PINK, DIRECTUS_PURPLE, SEPARATOR } from '../lib/constants.js';
7
+ import { validateInteractiveFlags, validateProgrammaticFlags } from '../lib/load/apply-flags.js';
8
+ import apply from '../lib/load/index.js';
9
+ import { getDirectusToken, getDirectusUrl, initializeDirectusApi } from '../lib/utils/auth.js';
10
+ import catchError from '../lib/utils/catch-error.js';
11
+ import { getCommunityTemplates, getGithubTemplate, getInteractiveLocalTemplate, getLocalTemplate } from '../lib/utils/get-template.js';
12
+ import { logger } from '../lib/utils/logger.js';
13
+ import openUrl from '../lib/utils/open-url.js';
14
+ import chalk from 'chalk';
15
+ export default class ApplyCommand extends Command {
16
+ static description = 'Apply a template to a blank Directus instance.';
17
+ static examples = [
18
+ '$ directus-template-cli apply',
19
+ '$ directus-template-cli apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local"',
20
+ '$ directus-template-cli@beta apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local" --partial --no-content --no-users',
21
+ ];
22
+ static flags = {
23
+ content: Flags.boolean({
24
+ allowNo: true,
25
+ default: undefined,
26
+ description: 'Load Content (data)',
27
+ }),
28
+ dashboards: Flags.boolean({
29
+ allowNo: true,
30
+ default: undefined,
31
+ description: 'Load Dashboards (dashboards, panels)',
32
+ }),
33
+ directusToken: customFlags.directusToken,
34
+ directusUrl: customFlags.directusUrl,
35
+ extensions: Flags.boolean({
36
+ allowNo: true,
37
+ default: undefined,
38
+ description: 'Load Extensions',
39
+ }),
40
+ files: Flags.boolean({
41
+ allowNo: true,
42
+ default: undefined,
43
+ description: 'Load Files (files, folders)',
44
+ }),
45
+ flows: Flags.boolean({
46
+ allowNo: true,
47
+ default: undefined,
48
+ description: 'Load Flows (operations, flows)',
49
+ }),
50
+ partial: Flags.boolean({
51
+ dependsOn: ['programmatic'],
52
+ description: 'Enable partial template application (all components enabled by default)',
53
+ summary: 'Enable partial template application',
54
+ }),
55
+ permissions: Flags.boolean({
56
+ allowNo: true,
57
+ default: undefined,
58
+ description: 'Loads permissions data. Collections include: directus_roles, directus_policies, directus_access, directus_permissions.',
59
+ summary: 'Load permissions (roles, policies, access, permissions)',
60
+ }),
61
+ programmatic: customFlags.programmatic,
62
+ schema: Flags.boolean({
63
+ allowNo: true,
64
+ default: undefined,
65
+ description: 'Load schema (collections, relations)',
66
+ }),
67
+ settings: Flags.boolean({
68
+ allowNo: true,
69
+ default: undefined,
70
+ description: 'Load settings (project settings, translations, presets)',
71
+ }),
72
+ templateLocation: customFlags.templateLocation,
73
+ templateType: Flags.string({
74
+ default: 'local',
75
+ dependsOn: ['programmatic'],
76
+ description: 'Type of template to apply. You can apply templates from our community repo, local directories, or public repositories from Github. Defaults to local. ',
77
+ env: 'TEMPLATE_TYPE',
78
+ options: ['community', 'local', 'github'],
79
+ summary: 'Type of template to apply. Options: community, local, github.',
80
+ }),
81
+ userEmail: customFlags.userEmail,
82
+ userPassword: customFlags.userPassword,
83
+ users: Flags.boolean({
84
+ allowNo: true,
85
+ default: undefined,
86
+ description: 'Load users',
87
+ }),
88
+ };
17
89
  /**
18
90
  * MAIN
19
91
  * Run the command
@@ -31,88 +103,84 @@ class ApplyCommand extends core_1.Command {
31
103
  * @returns {Promise<void>} - Returns nothing
32
104
  */
33
105
  async runInteractive(flags) {
34
- const validatedFlags = (0, apply_flags_1.validateInteractiveFlags)(flags);
35
- core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, 'Directus Template CLI - Apply'));
36
- const templateType = await inquirer.prompt([
37
- {
38
- choices: [
39
- { name: 'Community templates', value: 'community' },
40
- { name: 'From a local directory', value: 'local' },
41
- { name: 'From a public GitHub repository', value: 'github' },
42
- { name: 'Get premium templates', value: 'directus-plus' },
43
- ],
44
- message: 'What type of template would you like to apply?',
45
- name: 'templateType',
46
- type: 'list',
47
- },
48
- ]);
106
+ const validatedFlags = validateInteractiveFlags(flags);
107
+ // Show animated intro
108
+ await animatedBunny('Let\'s apply a template!');
109
+ intro(`${chalk.bgHex(DIRECTUS_PURPLE).white.bold('Directus Template CLI')} - Apply Template`);
110
+ const templateType = await select({
111
+ options: [
112
+ { label: 'Community templates', value: 'community' },
113
+ { label: 'From a local directory', value: 'local' },
114
+ { label: 'From a public GitHub repository', value: 'github' },
115
+ { label: 'Get premium templates', value: 'directus-plus' },
116
+ ],
117
+ message: 'What type of template would you like to apply?',
118
+ });
49
119
  let template;
50
- switch (templateType.templateType) {
120
+ switch (templateType) {
51
121
  case 'community': {
52
- const templates = await (0, get_template_1.getCommunityTemplates)();
53
- const { selectedTemplate } = await inquirer.prompt([
54
- {
55
- choices: templates.map(t => ({ name: t.templateName, value: t })),
56
- message: 'Select a template.',
57
- name: 'selectedTemplate',
58
- type: 'list',
59
- },
60
- ]);
122
+ const templates = await getCommunityTemplates();
123
+ const selectedTemplate = await select({
124
+ options: templates.map(t => ({ label: t.templateName, value: t })),
125
+ message: 'Select a template.',
126
+ });
61
127
  template = selectedTemplate;
62
128
  break;
63
129
  }
64
130
  case 'local': {
65
- const localTemplateDir = await core_1.ux.prompt('What is the local template directory?');
131
+ const localTemplateDir = await text({
132
+ message: 'What is the local template directory?',
133
+ });
66
134
  template = await this.selectLocalTemplate(localTemplateDir);
67
135
  break;
68
136
  }
69
137
  case 'github': {
70
- const ghTemplateUrl = await core_1.ux.prompt('What is the public GitHub repository URL?');
71
- template = await (0, get_template_1.getGithubTemplate)(ghTemplateUrl);
138
+ const ghTemplateUrl = await text({
139
+ message: 'What is the public GitHub repository URL?',
140
+ });
141
+ template = await getGithubTemplate(ghTemplateUrl);
72
142
  break;
73
143
  }
74
144
  case 'directus-plus': {
75
- (0, open_url_1.default)('https://directus.io/plus?utm_source=directus-template-cli&utm_content=apply-command');
76
- core_1.ux.log('Redirecting to Directus website.');
77
- core_1.ux.exit(0);
145
+ openUrl('https://directus.io/plus?utm_source=directus-template-cli&utm_content=apply-command');
146
+ log.info('Redirecting to Directus website.');
147
+ ux.exit(0);
78
148
  }
79
149
  }
80
- core_1.ux.log(`You selected ${core_1.ux.colorize(constants_1.DIRECTUS_PINK, template.templateName)}`);
81
- core_1.ux.log(constants_1.SEPARATOR);
150
+ log.info(`You selected ${ux.colorize(DIRECTUS_PINK, template.templateName)}`);
82
151
  // Get Directus URL
83
- const directusUrl = await (0, auth_1.getDirectusUrl)();
152
+ const directusUrl = await getDirectusUrl();
84
153
  validatedFlags.directusUrl = directusUrl;
85
154
  // Prompt for login method
86
- const loginMethod = await inquirer.prompt([
87
- {
88
- choices: [
89
- { name: 'Directus Access Token', value: 'token' },
90
- { name: 'Email and Password', value: 'email' },
91
- ],
92
- default: 'token',
93
- message: 'How do you want to log in?',
94
- name: 'loginMethod',
95
- type: 'list',
96
- },
97
- ]);
98
- if (loginMethod.loginMethod === 'token') {
99
- const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
155
+ const loginMethod = await select({
156
+ options: [
157
+ { label: 'Directus Access Token', value: 'token' },
158
+ { label: 'Email and Password', value: 'email' },
159
+ ],
160
+ message: 'How do you want to log in?',
161
+ });
162
+ if (loginMethod === 'token') {
163
+ const directusToken = await getDirectusToken(directusUrl);
100
164
  validatedFlags.directusToken = directusToken;
101
165
  }
102
166
  else {
103
- const userEmail = await core_1.ux.prompt('What is your email?');
167
+ const userEmail = await text({
168
+ message: 'What is your email?',
169
+ });
104
170
  validatedFlags.userEmail = userEmail;
105
- const userPassword = await core_1.ux.prompt('What is your password?', { type: 'hide' });
171
+ const userPassword = await password({
172
+ message: 'What is your password?',
173
+ });
106
174
  validatedFlags.userPassword = userPassword;
107
175
  }
108
- await (0, auth_1.initializeDirectusApi)(validatedFlags);
176
+ await initializeDirectusApi(validatedFlags);
109
177
  if (template) {
110
- core_1.ux.styledHeader(core_1.ux.colorize(constants_1.DIRECTUS_PURPLE, `Applying template - ${template.templateName} to ${directusUrl}`));
111
- await (0, index_js_1.default)(template.directoryPath, validatedFlags);
112
- core_1.ux.action.stop();
113
- core_1.ux.log(constants_1.SEPARATOR);
114
- core_1.ux.info('Template applied successfully.');
115
- core_1.ux.exit(0);
178
+ // /* TODO: Replace with custom styledHeader function */ ux.styledHeader(ux.colorize(DIRECTUS_PURPLE, `Applying template - ${template.templateName} to ${directusUrl}`))
179
+ await apply(template.directoryPath, validatedFlags);
180
+ ux.action.stop();
181
+ ux.stdout(SEPARATOR);
182
+ ux.stdout('Template applied successfully.');
183
+ ux.exit(0);
116
184
  }
117
185
  }
118
186
  /**
@@ -122,36 +190,36 @@ class ApplyCommand extends core_1.Command {
122
190
  * @returns {Promise<void>} - Returns nothing
123
191
  */
124
192
  async runProgrammatic(flags) {
125
- const validatedFlags = (0, apply_flags_1.validateProgrammaticFlags)(flags);
193
+ const validatedFlags = validateProgrammaticFlags(flags);
126
194
  let template;
127
195
  switch (validatedFlags.templateType) {
128
196
  case 'community': {
129
- const templates = await (0, get_template_1.getCommunityTemplates)();
197
+ const templates = await getCommunityTemplates();
130
198
  template = templates.find(t => t.templateName === validatedFlags.templateLocation) || templates[0];
131
199
  break;
132
200
  }
133
201
  case 'local': {
134
- template = await (0, get_template_1.getLocalTemplate)(validatedFlags.templateLocation);
202
+ template = await getLocalTemplate(validatedFlags.templateLocation);
135
203
  break;
136
204
  }
137
205
  case 'github': {
138
- template = await (0, get_template_1.getGithubTemplate)(validatedFlags.templateLocation);
206
+ template = await getGithubTemplate(validatedFlags.templateLocation);
139
207
  break;
140
208
  }
141
209
  default: {
142
- (0, catch_error_1.default)('Invalid template type. Please check your template type.', {
210
+ catchError('Invalid template type. Please check your template type.', {
143
211
  fatal: true,
144
212
  });
145
213
  }
146
214
  }
147
- await (0, auth_1.initializeDirectusApi)(validatedFlags);
215
+ await initializeDirectusApi(validatedFlags);
148
216
  const logMessage = `Applying template - ${template.templateName} to ${validatedFlags.directusUrl}`;
149
- core_1.ux.styledHeader(logMessage);
150
- logger_1.logger.log('info', logMessage);
151
- await (0, index_js_1.default)(template.directoryPath, validatedFlags);
152
- core_1.ux.action.stop();
153
- core_1.ux.log(constants_1.SEPARATOR);
154
- core_1.ux.info('Template applied successfully.');
217
+ // /* TODO: Replace with custom styledHeader function */ ux.styledHeader(logMessage)
218
+ logger.log('info', logMessage);
219
+ await apply(template.directoryPath, validatedFlags);
220
+ ux.action.stop();
221
+ ux.stdout(SEPARATOR);
222
+ ux.stdout('Template applied successfully.');
155
223
  // ux.exit(0)
156
224
  }
157
225
  /**
@@ -162,104 +230,26 @@ class ApplyCommand extends core_1.Command {
162
230
  */
163
231
  async selectLocalTemplate(localTemplateDir) {
164
232
  try {
165
- const templates = await (0, get_template_1.getInteractiveLocalTemplate)(localTemplateDir);
233
+ const templates = await getInteractiveLocalTemplate(localTemplateDir);
166
234
  if (templates.length === 1) {
167
235
  return templates[0];
168
236
  }
169
- const { selectedTemplate } = await inquirer.prompt([
170
- {
171
- choices: templates.map(t => ({
172
- name: `${t.templateName} (${path.basename(t.directoryPath)})`,
173
- value: t,
174
- })),
175
- message: 'Multiple templates found. Please select one:',
176
- name: 'selectedTemplate',
177
- type: 'list',
178
- },
179
- ]);
237
+ const selectedTemplate = await select({
238
+ options: templates.map(t => ({
239
+ label: `${t.templateName} (${path.basename(t.directoryPath)})`,
240
+ value: t,
241
+ })),
242
+ message: 'Multiple templates found. Please select one:',
243
+ });
180
244
  return selectedTemplate;
181
245
  }
182
246
  catch (error) {
183
247
  if (error instanceof Error) {
184
- core_1.ux.error(error.message);
248
+ ux.error(error.message);
185
249
  }
186
250
  else {
187
- core_1.ux.error('An unknown error occurred while getting the local template.');
251
+ ux.error('An unknown error occurred while getting the local template.');
188
252
  }
189
253
  }
190
254
  }
191
255
  }
192
- ApplyCommand.description = 'Apply a template to a blank Directus instance.';
193
- ApplyCommand.examples = [
194
- '$ directus-template-cli apply',
195
- '$ directus-template-cli apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local"',
196
- '$ directus-template-cli@beta apply -p --directusUrl="http://localhost:8055" --directusToken="admin-token-here" --templateLocation="./my-template" --templateType="local" --partial --no-content --no-users',
197
- ];
198
- ApplyCommand.flags = {
199
- content: core_1.Flags.boolean({
200
- allowNo: true,
201
- default: undefined,
202
- description: 'Load Content (data)',
203
- }),
204
- dashboards: core_1.Flags.boolean({
205
- allowNo: true,
206
- default: undefined,
207
- description: 'Load Dashboards (dashboards, panels)',
208
- }),
209
- directusToken: customFlags.directusToken,
210
- directusUrl: customFlags.directusUrl,
211
- extensions: core_1.Flags.boolean({
212
- allowNo: true,
213
- default: undefined,
214
- description: 'Load Extensions',
215
- }),
216
- files: core_1.Flags.boolean({
217
- allowNo: true,
218
- default: undefined,
219
- description: 'Load Files (files, folders)',
220
- }),
221
- flows: core_1.Flags.boolean({
222
- allowNo: true,
223
- default: undefined,
224
- description: 'Load Flows (operations, flows)',
225
- }),
226
- partial: core_1.Flags.boolean({
227
- dependsOn: ['programmatic'],
228
- description: 'Enable partial template application (all components enabled by default)',
229
- summary: 'Enable partial template application',
230
- }),
231
- permissions: core_1.Flags.boolean({
232
- allowNo: true,
233
- default: undefined,
234
- description: 'Loads permissions data. Collections include: directus_roles, directus_policies, directus_access, directus_permissions.',
235
- summary: 'Load permissions (roles, policies, access, permissions)',
236
- }),
237
- programmatic: customFlags.programmatic,
238
- schema: core_1.Flags.boolean({
239
- allowNo: true,
240
- default: undefined,
241
- description: 'Load schema (collections, relations)',
242
- }),
243
- settings: core_1.Flags.boolean({
244
- allowNo: true,
245
- default: undefined,
246
- description: 'Load settings (project settings, translations, presets)',
247
- }),
248
- templateLocation: customFlags.templateLocation,
249
- templateType: core_1.Flags.string({
250
- default: 'local',
251
- dependsOn: ['programmatic'],
252
- description: 'Type of template to apply. You can apply templates from our community repo, local directories, or public repositories from Github. Defaults to local. ',
253
- env: 'TEMPLATE_TYPE',
254
- options: ['community', 'local', 'github'],
255
- summary: 'Type of template to apply. Options: community, local, github.',
256
- }),
257
- userEmail: customFlags.userEmail,
258
- userPassword: customFlags.userPassword,
259
- users: core_1.Flags.boolean({
260
- allowNo: true,
261
- default: undefined,
262
- description: 'Load users',
263
- }),
264
- };
265
- exports.default = ApplyCommand;
@@ -0,0 +1,15 @@
1
+ import { Command, type Config } from '@oclif/core';
2
+ interface UserConfig {
3
+ distinctId?: string | null;
4
+ }
5
+ export declare abstract class BaseCommand extends Command {
6
+ runId: string;
7
+ userConfig: UserConfig;
8
+ constructor(argv: string[], config: Config);
9
+ private loadUserConfig;
10
+ /**
11
+ * Save the current user configuration to disk
12
+ */
13
+ protected saveUserConfig(): void;
14
+ }
15
+ export {};
@@ -0,0 +1,45 @@
1
+ import { Command } from '@oclif/core';
2
+ import { randomUUID } from 'node:crypto';
3
+ import fs from 'node:fs';
4
+ import path from 'pathe';
5
+ export class BaseCommand extends Command {
6
+ runId;
7
+ userConfig = {};
8
+ constructor(argv, config) {
9
+ super(argv, config);
10
+ this.runId = randomUUID();
11
+ this.loadUserConfig();
12
+ }
13
+ loadUserConfig() {
14
+ try {
15
+ const configPath = path.join(this.config.configDir, 'config.json');
16
+ if (fs.existsSync(configPath)) {
17
+ this.userConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
18
+ }
19
+ else {
20
+ // Create default config if it doesn't exist
21
+ const defaultConfig = {
22
+ distinctId: randomUUID(),
23
+ };
24
+ fs.mkdirSync(this.config.configDir, { recursive: true });
25
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
26
+ this.userConfig = defaultConfig;
27
+ }
28
+ }
29
+ catch (error) {
30
+ this.warn(`Failed to load user config: ${error}`);
31
+ }
32
+ }
33
+ /**
34
+ * Save the current user configuration to disk
35
+ */
36
+ saveUserConfig() {
37
+ try {
38
+ const configPath = path.join(this.config.configDir, 'config.json');
39
+ fs.writeFileSync(configPath, JSON.stringify(this.userConfig, null, 2));
40
+ }
41
+ catch (error) {
42
+ this.warn(`Failed to save user config: ${error}`);
43
+ }
44
+ }
45
+ }
@@ -1,15 +1,24 @@
1
1
  import { Command } from '@oclif/core';
2
+ export interface ExtractFlags {
3
+ directusToken: string;
4
+ directusUrl: string;
5
+ programmatic: boolean;
6
+ templateLocation: string;
7
+ templateName: string;
8
+ userEmail: string;
9
+ userPassword: string;
10
+ }
2
11
  export default class ExtractCommand extends Command {
3
12
  static description: string;
4
13
  static examples: string[];
5
14
  static flags: {
6
- directusToken: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
- directusUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
- programmatic: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- templateLocation: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
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>;
15
+ directusToken: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ directusUrl: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ programmatic: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ templateLocation: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
19
+ templateName: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
20
+ userEmail: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
21
+ userPassword: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
22
  };
14
23
  /**
15
24
  * Main run method for the ExtractCommand