@directus/extensions-sdk 9.14.4 → 9.15.0

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 (52) hide show
  1. package/dist/cjs/cli/commands/build.d.ts +6 -8
  2. package/dist/cjs/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cjs/cli/commands/build.js +242 -71
  4. package/dist/cjs/cli/commands/create.d.ts.map +1 -1
  5. package/dist/cjs/cli/commands/create.js +27 -33
  6. package/dist/cjs/cli/run.js +5 -5
  7. package/dist/cjs/cli/types.d.ts +9 -0
  8. package/dist/cjs/cli/types.d.ts.map +1 -1
  9. package/dist/cjs/cli/utils/load-config.d.ts +2 -1
  10. package/dist/cjs/cli/utils/load-config.d.ts.map +1 -1
  11. package/dist/cjs/cli/utils/logger.d.ts +2 -1
  12. package/dist/cjs/cli/utils/logger.d.ts.map +1 -1
  13. package/dist/cjs/cli/utils/logger.js +11 -1
  14. package/dist/cjs/cli/utils/to-object.d.ts +2 -0
  15. package/dist/cjs/cli/utils/to-object.d.ts.map +1 -0
  16. package/dist/cjs/cli/utils/to-object.js +17 -0
  17. package/dist/cjs/index.d.ts +1 -1
  18. package/dist/cjs/index.d.ts.map +1 -1
  19. package/dist/cjs/index.js +3 -1
  20. package/dist/esm/cli/commands/build.d.ts +6 -8
  21. package/dist/esm/cli/commands/build.d.ts.map +1 -1
  22. package/dist/esm/cli/commands/build.js +242 -71
  23. package/dist/esm/cli/commands/create.d.ts.map +1 -1
  24. package/dist/esm/cli/commands/create.js +25 -31
  25. package/dist/esm/cli/run.js +5 -5
  26. package/dist/esm/cli/types.d.ts +9 -0
  27. package/dist/esm/cli/types.d.ts.map +1 -1
  28. package/dist/esm/cli/utils/load-config.d.ts +2 -1
  29. package/dist/esm/cli/utils/load-config.d.ts.map +1 -1
  30. package/dist/esm/cli/utils/logger.d.ts +2 -1
  31. package/dist/esm/cli/utils/logger.d.ts.map +1 -1
  32. package/dist/esm/cli/utils/logger.js +9 -1
  33. package/dist/esm/cli/utils/to-object.d.ts +2 -0
  34. package/dist/esm/cli/utils/to-object.d.ts.map +1 -0
  35. package/dist/esm/cli/utils/to-object.js +14 -0
  36. package/dist/esm/index.d.ts +1 -1
  37. package/dist/esm/index.d.ts.map +1 -1
  38. package/dist/esm/index.js +1 -1
  39. package/package.json +3 -3
  40. package/src/cli/commands/build.ts +358 -93
  41. package/src/cli/commands/create.ts +33 -30
  42. package/src/cli/run.ts +5 -5
  43. package/src/cli/types.ts +8 -0
  44. package/src/cli/utils/load-config.ts +2 -1
  45. package/src/cli/utils/logger.ts +11 -1
  46. package/src/cli/utils/to-object.ts +16 -0
  47. package/src/index.ts +2 -0
  48. package/templates/operation/javascript/src/api.js +6 -0
  49. package/templates/operation/javascript/src/app.js +23 -0
  50. package/templates/operation/typescript/src/api.ts +12 -0
  51. package/templates/operation/typescript/src/app.ts +25 -0
  52. package/templates/operation/typescript/src/shims.d.ts +5 -0
@@ -1,12 +1,10 @@
1
1
  declare type BuildOptions = {
2
- type: string;
3
- input: string;
4
- output: string;
5
- language: string;
6
- force: boolean;
7
- watch: boolean;
8
- minify: boolean;
9
- sourcemap: boolean;
2
+ type?: string;
3
+ input?: string;
4
+ output?: string;
5
+ watch?: boolean;
6
+ minify?: boolean;
7
+ sourcemap?: boolean;
10
8
  };
11
9
  export default function build(options: BuildOptions): Promise<void>;
12
10
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/build.ts"],"names":[],"mappings":"AA4BA,aAAK,YAAY,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAA8B,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGxE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/build.ts"],"names":[],"mappings":"AAoCA,aAAK,YAAY,GAAG;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAA8B,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4HxE"}
@@ -18,92 +18,261 @@ const rollup_plugin_styles_1 = __importDefault(require("rollup-plugin-styles"));
18
18
  const rollup_plugin_vue_1 = __importDefault(require("rollup-plugin-vue"));
19
19
  const constants_1 = require("@directus/shared/constants");
20
20
  const utils_1 = require("@directus/shared/utils");
21
- const logger_1 = __importDefault(require("../utils/logger"));
21
+ const logger_1 = require("../utils/logger");
22
22
  const languages_1 = require("../utils/languages");
23
23
  const load_config_1 = __importDefault(require("../utils/load-config"));
24
+ const to_object_1 = __importDefault(require("../utils/to-object"));
24
25
  async function build(options) {
25
- var _a, _b;
26
- const packagePath = path_1.default.resolve('package.json');
27
- let extensionManifest = {};
28
- if (!(await fs_extra_1.default.pathExists(packagePath))) {
29
- (0, logger_1.default)(`Current directory is not a package.`, !options.force ? 'error' : 'warn');
30
- if (!options.force)
26
+ var _a, _b, _c;
27
+ const watch = (_a = options.watch) !== null && _a !== void 0 ? _a : false;
28
+ const sourcemap = (_b = options.sourcemap) !== null && _b !== void 0 ? _b : false;
29
+ const minify = (_c = options.minify) !== null && _c !== void 0 ? _c : false;
30
+ if (!options.type && !options.input && !options.output) {
31
+ const packagePath = path_1.default.resolve('package.json');
32
+ let extensionManifest = {};
33
+ if (!(await fs_extra_1.default.pathExists(packagePath))) {
34
+ (0, logger_1.log)(`Current directory is not a valid package.`, 'error');
31
35
  process.exit(1);
36
+ }
37
+ else {
38
+ extensionManifest = await fs_extra_1.default.readJSON(packagePath);
39
+ if (!(0, utils_1.validateExtensionManifest)(extensionManifest)) {
40
+ (0, logger_1.log)(`Current directory is not a valid Directus extension.`, 'error');
41
+ process.exit(1);
42
+ }
43
+ }
44
+ const extensionOptions = extensionManifest[constants_1.EXTENSION_PKG_KEY];
45
+ if (!(0, utils_1.isTypeIn)(extensionOptions, constants_1.EXTENSION_TYPES)) {
46
+ (0, logger_1.log)(`Extension type ${chalk_1.default.bold(extensionOptions.type)} is not supported. Available extension types: ${constants_1.EXTENSION_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
47
+ process.exit(1);
48
+ }
49
+ if ((0, utils_1.isTypeIn)(extensionOptions, constants_1.HYBRID_EXTENSION_TYPES)) {
50
+ await buildHybridExtension({
51
+ inputApp: extensionOptions.source.app,
52
+ inputApi: extensionOptions.source.api,
53
+ outputApp: extensionOptions.path.app,
54
+ outputApi: extensionOptions.path.api,
55
+ watch,
56
+ sourcemap,
57
+ minify,
58
+ });
59
+ }
60
+ else {
61
+ await buildAppOrApiExtension({
62
+ type: extensionOptions.type,
63
+ input: extensionOptions.source,
64
+ output: extensionOptions.path,
65
+ watch,
66
+ sourcemap,
67
+ minify,
68
+ });
69
+ }
32
70
  }
33
71
  else {
34
- extensionManifest = await fs_extra_1.default.readJSON(packagePath);
35
- if (!(0, utils_1.validateExtensionManifest)(extensionManifest)) {
36
- (0, logger_1.default)(`Current directory is not a Directus extension.`, !options.force ? 'error' : 'warn');
37
- if (!options.force)
72
+ const type = options.type;
73
+ const input = options.input;
74
+ const output = options.output;
75
+ if (!type) {
76
+ (0, logger_1.log)(`Extension type has to be specified using the ${chalk_1.default.blue('[-t, --type <type>]')} option.`, 'error');
77
+ process.exit(1);
78
+ }
79
+ else if (!(0, utils_1.isIn)(type, constants_1.EXTENSION_TYPES)) {
80
+ (0, logger_1.log)(`Extension type ${chalk_1.default.bold(type)} is not supported. Available extension types: ${constants_1.EXTENSION_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
81
+ process.exit(1);
82
+ }
83
+ if (!input) {
84
+ (0, logger_1.log)(`Extension entrypoint has to be specified using the ${chalk_1.default.blue('[-i, --input <file>]')} option.`, 'error');
85
+ process.exit(1);
86
+ }
87
+ if (!output) {
88
+ (0, logger_1.log)(`Extension output file has to be specified using the ${chalk_1.default.blue('[-o, --output <file>]')} option.`, 'error');
89
+ process.exit(1);
90
+ }
91
+ if ((0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES)) {
92
+ const inputObject = (0, to_object_1.default)(input);
93
+ const outputObject = (0, to_object_1.default)(output);
94
+ if (!inputObject || !inputObject.app || !inputObject.api) {
95
+ (0, logger_1.log)(`Input option needs to be of the format ${chalk_1.default.blue('[-i app:<app-entrypoint>,api:<api-entrypoint>]')}.`, 'error');
96
+ process.exit(1);
97
+ }
98
+ if (!outputObject || !outputObject.app || !outputObject.api) {
99
+ (0, logger_1.log)(`Output option needs to be of the format ${chalk_1.default.blue('[-o app:<app-output-file>,api:<api-output-file>]')}.`, 'error');
38
100
  process.exit(1);
101
+ }
102
+ await buildHybridExtension({
103
+ inputApp: inputObject.app,
104
+ inputApi: inputObject.api,
105
+ outputApp: outputObject.app,
106
+ outputApi: outputObject.api,
107
+ watch,
108
+ sourcemap,
109
+ minify,
110
+ });
111
+ }
112
+ else {
113
+ await buildAppOrApiExtension({
114
+ type,
115
+ input,
116
+ output,
117
+ watch,
118
+ sourcemap,
119
+ minify,
120
+ });
39
121
  }
40
122
  }
41
- const extensionOptions = extensionManifest[constants_1.EXTENSION_PKG_KEY];
42
- const type = options.type || (extensionOptions === null || extensionOptions === void 0 ? void 0 : extensionOptions.type);
43
- if (!type || !(0, utils_1.isExtension)(type)) {
44
- (0, logger_1.default)(`Extension type ${chalk_1.default.bold(type)} does not exist. Available extension types: ${constants_1.EXTENSION_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
123
+ }
124
+ exports.default = build;
125
+ async function buildAppOrApiExtension({ type, input, output, watch, sourcemap, minify, }) {
126
+ var _a;
127
+ if (!(await fs_extra_1.default.pathExists(input)) || !(await fs_extra_1.default.stat(input)).isFile()) {
128
+ (0, logger_1.log)(`Entrypoint ${chalk_1.default.bold(input)} does not exist.`, 'error');
45
129
  process.exit(1);
46
130
  }
47
- const input = options.input || ((_a = extensionOptions) === null || _a === void 0 ? void 0 : _a.source);
48
- const output = options.output || ((_b = extensionOptions) === null || _b === void 0 ? void 0 : _b.path);
49
- if (!input || !(await fs_extra_1.default.pathExists(input)) || !(await fs_extra_1.default.stat(input)).isFile()) {
50
- (0, logger_1.default)(`Entrypoint ${chalk_1.default.bold(input)} does not exist.`, 'error');
131
+ if (output.length === 0) {
132
+ (0, logger_1.log)(`Output file ${chalk_1.default.bold(output)} must be a valid path.`, 'error');
51
133
  process.exit(1);
52
134
  }
53
- if (!output) {
54
- (0, logger_1.default)(`Output file must be a valid path.`, 'error');
135
+ const language = (0, languages_1.getLanguageFromPath)(input);
136
+ if (!(0, languages_1.isLanguage)(language)) {
137
+ (0, logger_1.log)(`Language ${chalk_1.default.bold(language)} is not supported.`, 'error');
55
138
  process.exit(1);
56
139
  }
57
- const language = options.language || (0, languages_1.getLanguageFromPath)(input);
58
- if (!(0, languages_1.isLanguage)(language)) {
59
- (0, logger_1.default)(`Language ${chalk_1.default.bold(language)} is not supported.`, 'error');
140
+ const config = await (0, load_config_1.default)();
141
+ const plugins = (_a = config.plugins) !== null && _a !== void 0 ? _a : [];
142
+ const mode = (0, utils_1.isIn)(type, constants_1.APP_EXTENSION_TYPES) ? 'browser' : 'node';
143
+ const rollupOptions = getRollupOptions({ mode, input, language, sourcemap, minify, plugins });
144
+ const rollupOutputOptions = getRollupOutputOptions({ mode, output, sourcemap });
145
+ if (watch) {
146
+ await watchExtension({ rollupOptions, rollupOutputOptions });
147
+ }
148
+ else {
149
+ await buildExtension({ rollupOptions, rollupOutputOptions });
150
+ }
151
+ }
152
+ async function buildHybridExtension({ inputApp, inputApi, outputApp, outputApi, watch, sourcemap, minify, }) {
153
+ var _a;
154
+ if (!(await fs_extra_1.default.pathExists(inputApp)) || !(await fs_extra_1.default.stat(inputApp)).isFile()) {
155
+ (0, logger_1.log)(`App entrypoint ${chalk_1.default.bold(inputApp)} does not exist.`, 'error');
156
+ process.exit(1);
157
+ }
158
+ if (!(await fs_extra_1.default.pathExists(inputApi)) || !(await fs_extra_1.default.stat(inputApi)).isFile()) {
159
+ (0, logger_1.log)(`API entrypoint ${chalk_1.default.bold(inputApi)} does not exist.`, 'error');
160
+ process.exit(1);
161
+ }
162
+ if (outputApp.length === 0) {
163
+ (0, logger_1.log)(`App output file ${chalk_1.default.bold(outputApp)} must be a valid path.`, 'error');
164
+ process.exit(1);
165
+ }
166
+ if (outputApi.length === 0) {
167
+ (0, logger_1.log)(`API output file ${chalk_1.default.bold(outputApi)} must be a valid path.`, 'error');
168
+ process.exit(1);
169
+ }
170
+ const languageApp = (0, languages_1.getLanguageFromPath)(inputApp);
171
+ const languageApi = (0, languages_1.getLanguageFromPath)(inputApi);
172
+ if (!(0, languages_1.isLanguage)(languageApp)) {
173
+ (0, logger_1.log)(`App language ${chalk_1.default.bold(languageApp)} is not supported.`, 'error');
174
+ process.exit(1);
175
+ }
176
+ if (!(0, languages_1.isLanguage)(languageApi)) {
177
+ (0, logger_1.log)(`API language ${chalk_1.default.bold(languageApp)} is not supported.`, 'error');
60
178
  process.exit(1);
61
179
  }
62
180
  const config = await (0, load_config_1.default)();
63
- const spinner = (0, ora_1.default)('Building Directus extension...').start();
64
- const rollupOptions = getRollupOptions(type, language, input, config.plugins, options);
65
- const rollupOutputOptions = getRollupOutputOptions(type, output, options);
66
- if (options.watch) {
181
+ const plugins = (_a = config.plugins) !== null && _a !== void 0 ? _a : [];
182
+ const rollupOptionsApp = getRollupOptions({
183
+ mode: 'browser',
184
+ input: inputApp,
185
+ language: languageApp,
186
+ sourcemap,
187
+ minify,
188
+ plugins,
189
+ });
190
+ const rollupOptionsApi = getRollupOptions({
191
+ mode: 'node',
192
+ input: inputApi,
193
+ language: languageApi,
194
+ sourcemap,
195
+ minify,
196
+ plugins,
197
+ });
198
+ const rollupOutputOptionsApp = getRollupOutputOptions({ mode: 'browser', output: outputApp, sourcemap });
199
+ const rollupOutputOptionsApi = getRollupOutputOptions({ mode: 'node', output: outputApi, sourcemap });
200
+ const rollupOptionsAll = [
201
+ { rollupOptions: rollupOptionsApp, rollupOutputOptions: rollupOutputOptionsApp },
202
+ { rollupOptions: rollupOptionsApi, rollupOutputOptions: rollupOutputOptionsApi },
203
+ ];
204
+ if (watch) {
205
+ await watchExtension(rollupOptionsAll);
206
+ }
207
+ else {
208
+ await buildExtension(rollupOptionsAll);
209
+ }
210
+ }
211
+ async function buildExtension(config) {
212
+ const configs = Array.isArray(config) ? config : [config];
213
+ const spinner = (0, ora_1.default)(chalk_1.default.bold('Building Directus extension...')).start();
214
+ const result = await Promise.all(configs.map(async (c) => {
215
+ try {
216
+ const bundle = await (0, rollup_1.rollup)(c.rollupOptions);
217
+ await bundle.write(c.rollupOutputOptions);
218
+ await bundle.close();
219
+ }
220
+ catch (error) {
221
+ return formatRollupError(error);
222
+ }
223
+ return null;
224
+ }));
225
+ const resultErrors = result.filter((r) => r !== null);
226
+ if (resultErrors.length > 0) {
227
+ spinner.fail(chalk_1.default.bold('Failed'));
228
+ (0, logger_1.log)(resultErrors.join('\n\n'));
229
+ process.exit(1);
230
+ }
231
+ else {
232
+ spinner.succeed(chalk_1.default.bold('Done'));
233
+ }
234
+ }
235
+ async function watchExtension(config) {
236
+ const configs = Array.isArray(config) ? config : [config];
237
+ const spinner = (0, ora_1.default)(chalk_1.default.bold('Building Directus extension...'));
238
+ let buildCount = 0;
239
+ for (const c of configs) {
67
240
  const watcher = (0, rollup_1.watch)({
68
- ...rollupOptions,
69
- output: rollupOutputOptions,
241
+ ...c.rollupOptions,
242
+ output: c.rollupOutputOptions,
70
243
  });
71
244
  watcher.on('event', async (event) => {
72
245
  switch (event.code) {
73
- case 'ERROR': {
74
- spinner.fail(chalk_1.default.bold('Failed'));
75
- handleRollupError(event.error);
76
- spinner.start(chalk_1.default.bold('Watching files for changes...'));
246
+ case 'BUNDLE_START':
247
+ if (buildCount === 0) {
248
+ (0, logger_1.clear)();
249
+ spinner.start();
250
+ }
251
+ buildCount++;
77
252
  break;
78
- }
79
253
  case 'BUNDLE_END':
80
254
  await event.result.close();
81
- spinner.succeed(chalk_1.default.bold('Done'));
82
- spinner.start(chalk_1.default.bold('Watching files for changes...'));
255
+ buildCount--;
256
+ if (buildCount === 0) {
257
+ spinner.succeed(chalk_1.default.bold('Done'));
258
+ (0, logger_1.log)(chalk_1.default.bold.green('Watching files for changes...'));
259
+ }
83
260
  break;
84
- case 'BUNDLE_START':
85
- spinner.text = 'Building Directus extension...';
261
+ case 'ERROR': {
262
+ buildCount--;
263
+ spinner.fail(chalk_1.default.bold('Failed'));
264
+ (0, logger_1.log)(formatRollupError(event.error));
265
+ if (buildCount > 0) {
266
+ spinner.start();
267
+ }
86
268
  break;
269
+ }
87
270
  }
88
271
  });
89
272
  }
90
- else {
91
- try {
92
- const bundle = await (0, rollup_1.rollup)(rollupOptions);
93
- await bundle.write(rollupOutputOptions);
94
- await bundle.close();
95
- spinner.succeed(chalk_1.default.bold('Done'));
96
- }
97
- catch (error) {
98
- spinner.fail(chalk_1.default.bold('Failed'));
99
- handleRollupError(error);
100
- process.exitCode = 1;
101
- }
102
- }
103
273
  }
104
- exports.default = build;
105
- function getRollupOptions(type, language, input, plugins = [], options) {
106
- if ((0, utils_1.isAppExtension)(type)) {
274
+ function getRollupOptions({ mode, input, language, sourcemap, minify, plugins, }) {
275
+ if (mode === 'browser') {
107
276
  return {
108
277
  input,
109
278
  external: constants_1.APP_SHARED_DEPS,
@@ -113,7 +282,7 @@ function getRollupOptions(type, language, input, plugins = [], options) {
113
282
  (0, rollup_plugin_styles_1.default)(),
114
283
  ...plugins,
115
284
  (0, plugin_node_resolve_1.nodeResolve)({ browser: true }),
116
- (0, plugin_commonjs_1.default)({ esmExternals: true, sourceMap: options.sourcemap }),
285
+ (0, plugin_commonjs_1.default)({ esmExternals: true, sourceMap: sourcemap }),
117
286
  (0, plugin_json_1.default)(),
118
287
  (0, plugin_replace_1.default)({
119
288
  values: {
@@ -121,7 +290,7 @@ function getRollupOptions(type, language, input, plugins = [], options) {
121
290
  },
122
291
  preventAssignment: true,
123
292
  }),
124
- options.minify ? (0, rollup_plugin_terser_1.terser)() : null,
293
+ minify ? (0, rollup_plugin_terser_1.terser)() : null,
125
294
  ],
126
295
  };
127
296
  }
@@ -133,7 +302,7 @@ function getRollupOptions(type, language, input, plugins = [], options) {
133
302
  language === 'typescript' ? (0, rollup_plugin_typescript2_1.default)({ check: false }) : null,
134
303
  ...plugins,
135
304
  (0, plugin_node_resolve_1.nodeResolve)(),
136
- (0, plugin_commonjs_1.default)({ sourceMap: options.sourcemap }),
305
+ (0, plugin_commonjs_1.default)({ sourceMap: sourcemap }),
137
306
  (0, plugin_json_1.default)(),
138
307
  (0, plugin_replace_1.default)({
139
308
  values: {
@@ -141,18 +310,18 @@ function getRollupOptions(type, language, input, plugins = [], options) {
141
310
  },
142
311
  preventAssignment: true,
143
312
  }),
144
- options.minify ? (0, rollup_plugin_terser_1.terser)() : null,
313
+ minify ? (0, rollup_plugin_terser_1.terser)() : null,
145
314
  ],
146
315
  };
147
316
  }
148
317
  }
149
- function getRollupOutputOptions(type, output, options) {
150
- if ((0, utils_1.isAppExtension)(type)) {
318
+ function getRollupOutputOptions({ mode, output, sourcemap, }) {
319
+ if (mode === 'browser') {
151
320
  return {
152
321
  file: output,
153
322
  format: 'es',
154
323
  inlineDynamicImports: true,
155
- sourcemap: options.sourcemap,
324
+ sourcemap,
156
325
  };
157
326
  }
158
327
  else {
@@ -161,26 +330,28 @@ function getRollupOutputOptions(type, output, options) {
161
330
  format: 'cjs',
162
331
  exports: 'default',
163
332
  inlineDynamicImports: true,
164
- sourcemap: options.sourcemap,
333
+ sourcemap,
165
334
  };
166
335
  }
167
336
  }
168
- function handleRollupError(error) {
169
- const pluginPrefix = error.plugin ? `(plugin ${error.plugin}) ` : '';
170
- (0, logger_1.default)('\n' + chalk_1.default.red.bold(`${pluginPrefix}${error.name}: ${error.message}`));
337
+ function formatRollupError(error) {
338
+ var _a;
339
+ let message = '';
340
+ message += `${chalk_1.default.bold.red(`[${error.name}]`)} ${error.message}${error.plugin ? ` (plugin ${error.plugin})` : ''}\n`;
171
341
  if (error.url) {
172
- (0, logger_1.default)(chalk_1.default.cyan(error.url), 'error');
342
+ message += '\n' + chalk_1.default.green(error.url);
173
343
  }
174
344
  if (error.loc) {
175
- (0, logger_1.default)(`${(error.loc.file || error.id)} (${error.loc.line}:${error.loc.column})`);
345
+ message += '\n' + chalk_1.default.green(`${(_a = error.loc.file) !== null && _a !== void 0 ? _a : error.id}:${error.loc.line}:${error.loc.column}`);
176
346
  }
177
347
  else if (error.id) {
178
- (0, logger_1.default)(error.id);
348
+ message += '\n' + chalk_1.default.green(error.id);
179
349
  }
180
350
  if (error.frame) {
181
- (0, logger_1.default)(chalk_1.default.dim(error.frame));
351
+ message += '\n' + chalk_1.default.dim(error.frame);
182
352
  }
183
353
  if (error.stack) {
184
- (0, logger_1.default)(chalk_1.default.dim(error.stack));
354
+ message += '\n' + chalk_1.default.dim(error.stack);
185
355
  }
356
+ return message;
186
357
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAkBA,aAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,wBAA8B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFtG"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAyBA,aAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,wBAA8B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFtG"}
@@ -10,7 +10,7 @@ const execa_1 = __importDefault(require("execa"));
10
10
  const ora_1 = __importDefault(require("ora"));
11
11
  const constants_1 = require("@directus/shared/constants");
12
12
  const utils_1 = require("@directus/shared/utils");
13
- const logger_1 = __importDefault(require("../utils/logger"));
13
+ const logger_1 = require("../utils/logger");
14
14
  const languages_1 = require("../utils/languages");
15
15
  const rename_map_1 = __importDefault(require("../utils/rename-map"));
16
16
  const get_package_version_1 = __importDefault(require("../utils/get-package-version"));
@@ -18,39 +18,43 @@ const pkg = require('../../../../package.json');
18
18
  const TEMPLATE_PATH = path_1.default.resolve(__dirname, '../../../../templates');
19
19
  async function create(type, name, options) {
20
20
  const targetPath = path_1.default.resolve(name);
21
- if (!(0, utils_1.isExtension)(type)) {
22
- (0, logger_1.default)(`Extension type ${chalk_1.default.bold(type)} does not exist. Available extension types: ${constants_1.EXTENSION_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
21
+ if (!(0, utils_1.isIn)(type, constants_1.EXTENSION_TYPES)) {
22
+ (0, logger_1.log)(`Extension type ${chalk_1.default.bold(type)} is not supported. Available extension types: ${constants_1.EXTENSION_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
23
23
  process.exit(1);
24
24
  }
25
25
  if (await fs_extra_1.default.pathExists(targetPath)) {
26
26
  const info = await fs_extra_1.default.stat(targetPath);
27
27
  if (!info.isDirectory()) {
28
- (0, logger_1.default)(`Destination ${chalk_1.default.bold(name)} already exists and is not a directory.`, 'error');
28
+ (0, logger_1.log)(`Destination ${chalk_1.default.bold(name)} already exists and is not a directory.`, 'error');
29
29
  process.exit(1);
30
30
  }
31
31
  const files = await fs_extra_1.default.readdir(targetPath);
32
32
  if (files.length > 0) {
33
- (0, logger_1.default)(`Destination ${chalk_1.default.bold(name)} already exists and is not empty.`, 'error');
33
+ (0, logger_1.log)(`Destination ${chalk_1.default.bold(name)} already exists and is not empty.`, 'error');
34
34
  process.exit(1);
35
35
  }
36
36
  }
37
37
  if (!(0, languages_1.isLanguage)(options.language)) {
38
- (0, logger_1.default)(`Language ${chalk_1.default.bold(options.language)} is not supported. Available languages: ${constants_1.EXTENSION_LANGUAGES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
38
+ (0, logger_1.log)(`Language ${chalk_1.default.bold(options.language)} is not supported. Available languages: ${constants_1.EXTENSION_LANGUAGES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
39
39
  process.exit(1);
40
40
  }
41
- const spinner = (0, ora_1.default)(`Scaffolding Directus extension...`).start();
41
+ const spinner = (0, ora_1.default)(chalk_1.default.bold('Scaffolding Directus extension...')).start();
42
42
  await fs_extra_1.default.ensureDir(targetPath);
43
43
  await fs_extra_1.default.copy(path_1.default.join(TEMPLATE_PATH, 'common', options.language), targetPath);
44
44
  await fs_extra_1.default.copy(path_1.default.join(TEMPLATE_PATH, type, options.language), targetPath);
45
45
  await (0, rename_map_1.default)(targetPath, (name) => (name.startsWith('_') ? `.${name.substring(1)}` : null));
46
+ const entryPath = (0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES) ? { app: 'dist/app.js', api: 'dist/api.js' } : 'dist/index.js';
47
+ const sourcePath = (0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES)
48
+ ? { app: `src/app.${(0, languages_1.languageToShort)(options.language)}`, api: `src/api.${(0, languages_1.languageToShort)(options.language)}` }
49
+ : `src/index.${(0, languages_1.languageToShort)(options.language)}`;
46
50
  const packageManifest = {
47
51
  name: `directus-extension-${name}`,
48
52
  version: '1.0.0',
49
53
  keywords: ['directus', 'directus-extension', `directus-custom-${type}`],
50
54
  [constants_1.EXTENSION_PKG_KEY]: {
51
55
  type,
52
- path: 'dist/index.js',
53
- source: `src/index.${(0, languages_1.languageToShort)(options.language)}`,
56
+ path: entryPath,
57
+ source: sourcePath,
54
58
  host: `^${pkg.version}`,
55
59
  },
56
60
  scripts: {
@@ -62,11 +66,11 @@ async function create(type, name, options) {
62
66
  await fs_extra_1.default.writeJSON(path_1.default.join(targetPath, 'package.json'), packageManifest, { spaces: '\t' });
63
67
  await (0, execa_1.default)('npm', ['install'], { cwd: targetPath });
64
68
  spinner.succeed(chalk_1.default.bold('Done'));
65
- (0, logger_1.default)(`
69
+ (0, logger_1.log)(`
66
70
  Your ${type} extension has been created at ${chalk_1.default.green(targetPath)}
67
71
 
68
72
  To start developing, run:
69
- ${chalk_1.default.blue('cd')} c
73
+ ${chalk_1.default.blue('cd')} ${name}
70
74
  ${chalk_1.default.blue('npm run')} dev
71
75
 
72
76
  and then to build for production, run:
@@ -75,26 +79,16 @@ and then to build for production, run:
75
79
  }
76
80
  exports.default = create;
77
81
  async function getPackageDeps(type, language) {
78
- if ((0, utils_1.isAppExtension)(type)) {
79
- return {
80
- '@directus/extensions-sdk': pkg.version,
81
- ...(language === 'typescript'
82
- ? {
83
- typescript: `^${await (0, get_package_version_1.default)('typescript')}`,
84
- }
85
- : {}),
86
- vue: `^${await (0, get_package_version_1.default)('vue')}`,
87
- };
88
- }
89
- else {
90
- return {
91
- '@directus/extensions-sdk': pkg.version,
92
- ...(language === 'typescript'
93
- ? {
94
- '@types/node': `^${await (0, get_package_version_1.default)('@types/node')}`,
95
- typescript: `^${await (0, get_package_version_1.default)('typescript')}`,
96
- }
97
- : {}),
98
- };
99
- }
82
+ return {
83
+ '@directus/extensions-sdk': pkg.version,
84
+ ...(language === 'typescript'
85
+ ? {
86
+ ...((0, utils_1.isIn)(type, constants_1.API_OR_HYBRID_EXTENSION_TYPES)
87
+ ? { '@types/node': `^${await (0, get_package_version_1.default)('@types/node')}` }
88
+ : {}),
89
+ typescript: `^${await (0, get_package_version_1.default)('typescript')}`,
90
+ }
91
+ : {}),
92
+ ...((0, utils_1.isIn)(type, constants_1.APP_OR_HYBRID_EXTENSION_TYPES) ? { vue: `^${await (0, get_package_version_1.default)('vue')}` } : {}),
93
+ };
100
94
  }
@@ -19,11 +19,11 @@ program
19
19
  program
20
20
  .command('build')
21
21
  .description('Bundle a Directus extension to a single entrypoint')
22
- .option('-t, --type <type>', 'overwrite the extension type read from package manifest')
23
- .option('-i, --input <file>', 'overwrite the entrypoint read from package manifest')
24
- .option('-o, --output <file>', 'overwrite the output file read from package manifest')
25
- .option('-l, --language <language>', 'overwrite the language to use')
26
- .option('-f, --force', 'ignore the package manifest')
22
+ .option('-t, --type <type>', 'specify the extension type instead of reading from package manifest')
23
+ .option('-i, --input <file>', 'specify the entrypoint instead of reading from package manifest')
24
+ .option('-o, --output <file>', 'specify the output file instead of reading from package manifest')
25
+ .option('-l, --language <language>', '[DEPRECATED]')
26
+ .option('-f, --force', '[DEPRECATED]')
27
27
  .option('-w, --watch', 'watch and rebuild on changes')
28
28
  .option('--no-minify', 'disable minification')
29
29
  .option('--sourcemap', 'include source maps in output')
@@ -1,4 +1,13 @@
1
1
  import { EXTENSION_LANGUAGES } from '@directus/shared/constants';
2
+ import { Plugin, RollupOptions, OutputOptions as RollupOutputOptions } from 'rollup';
2
3
  export declare type Language = typeof EXTENSION_LANGUAGES[number];
3
4
  export declare type LanguageShort = 'js' | 'ts';
5
+ export declare type Config = {
6
+ plugins?: Plugin[];
7
+ };
8
+ export declare type RollupConfig = {
9
+ rollupOptions: RollupOptions;
10
+ rollupOutputOptions: RollupOutputOptions;
11
+ };
12
+ export declare type RollupMode = 'browser' | 'node';
4
13
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,oBAAY,QAAQ,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC1D,oBAAY,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,IAAI,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAErF,oBAAY,QAAQ,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC1D,oBAAY,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;AAExC,oBAAY,MAAM,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,oBAAY,YAAY,GAAG;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,mBAAmB,EAAE,mBAAmB,CAAA;CAAE,CAAC;AACtG,oBAAY,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC"}
@@ -1,2 +1,3 @@
1
- export default function loadConfig(): Promise<Record<string, any>>;
1
+ import { Config } from '../types';
2
+ export default function loadConfig(): Promise<Config>;
2
3
  //# sourceMappingURL=load-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/load-config.ts"],"names":[],"mappings":"AAQA,wBAA8B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAYvE"}
1
+ {"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/load-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC,wBAA8B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAY1D"}
@@ -1,2 +1,3 @@
1
- export default function log(message: string, type?: 'info' | 'warn' | 'error'): void;
1
+ export declare function log(message: string, type?: 'info' | 'warn' | 'error'): void;
2
+ export declare function clear(): void;
2
3
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/logger.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAUnF"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/logger.ts"],"names":[],"mappings":"AAKA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAU3E;AAED,wBAAgB,KAAK,SAOpB"}
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.clear = exports.log = void 0;
8
+ const readline_1 = __importDefault(require("readline"));
7
9
  const chalk_1 = __importDefault(require("chalk"));
8
10
  function log(message, type) {
9
11
  if (type === 'info') {
@@ -19,4 +21,12 @@ function log(message, type) {
19
21
  console.log(message);
20
22
  }
21
23
  }
22
- exports.default = log;
24
+ exports.log = log;
25
+ function clear() {
26
+ const repeatCount = process.stdout.rows - 2;
27
+ const blank = repeatCount > 0 ? '\n'.repeat(repeatCount) : '';
28
+ console.log(blank);
29
+ readline_1.default.cursorTo(process.stdout, 0, 0);
30
+ readline_1.default.clearScreenDown(process.stdout);
31
+ }
32
+ exports.clear = clear;
@@ -0,0 +1,2 @@
1
+ export default function toObject(val: string): Record<string, string> | null;
2
+ //# sourceMappingURL=to-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-object.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/to-object.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAe3E"}