@directus/extensions-sdk 9.20.4 → 9.21.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 (155) hide show
  1. package/dist/cjs/cli/commands/add.d.ts +2 -0
  2. package/dist/cjs/cli/commands/add.js +242 -0
  3. package/dist/cjs/cli/commands/build.d.ts +1 -1
  4. package/dist/cjs/cli/commands/build.js +169 -43
  5. package/dist/cjs/cli/commands/create.d.ts +2 -2
  6. package/dist/cjs/cli/commands/create.js +66 -47
  7. package/dist/cjs/cli/commands/helpers/copy-template.d.ts +4 -0
  8. package/dist/cjs/cli/commands/helpers/copy-template.js +53 -0
  9. package/dist/cjs/cli/commands/helpers/generate-bundle-entrypoint.d.ts +3 -0
  10. package/dist/cjs/cli/commands/helpers/generate-bundle-entrypoint.js +24 -0
  11. package/dist/cjs/cli/commands/helpers/get-extension-dev-deps.d.ts +4 -0
  12. package/dist/cjs/cli/commands/helpers/get-extension-dev-deps.js +27 -0
  13. package/dist/cjs/cli/commands/helpers/load-config.d.ts +3 -0
  14. package/dist/cjs/cli/{utils → commands/helpers}/load-config.js +0 -0
  15. package/dist/cjs/cli/commands/helpers/validate-cli-options.d.ts +4 -0
  16. package/dist/cjs/cli/commands/helpers/validate-cli-options.js +39 -0
  17. package/dist/cjs/cli/run.js +3 -1
  18. package/dist/cjs/cli/types.d.ts +5 -5
  19. package/dist/cjs/cli/utils/detect-json-indent.d.ts +2 -0
  20. package/dist/cjs/cli/utils/detect-json-indent.js +14 -0
  21. package/dist/cjs/cli/utils/get-package-manager-agent.d.ts +5 -0
  22. package/dist/cjs/cli/utils/get-package-manager-agent.js +15 -0
  23. package/dist/cjs/cli/utils/get-package-manager-agent.test.d.ts +2 -0
  24. package/dist/cjs/cli/utils/get-package-manager-agent.test.js +24 -0
  25. package/dist/cjs/cli/utils/get-package-manager.d.ts +5 -0
  26. package/dist/cjs/cli/utils/get-package-manager.js +20 -0
  27. package/dist/cjs/cli/utils/get-package-manager.test.d.ts +2 -0
  28. package/dist/cjs/cli/utils/get-package-manager.test.js +42 -0
  29. package/dist/cjs/cli/utils/get-sdk-version.d.ts +2 -0
  30. package/dist/cjs/cli/utils/get-sdk-version.js +7 -0
  31. package/dist/cjs/cli/utils/get-template-path.d.ts +2 -0
  32. package/dist/cjs/cli/utils/get-template-path.js +10 -0
  33. package/dist/cjs/cli/utils/try-parse-json.d.ts +3 -0
  34. package/dist/cjs/cli/utils/try-parse-json.js +11 -0
  35. package/dist/esm/cli/commands/add.d.ts +2 -0
  36. package/dist/esm/cli/commands/add.js +236 -0
  37. package/dist/esm/cli/commands/build.d.ts +1 -1
  38. package/dist/esm/cli/commands/build.js +167 -41
  39. package/dist/esm/cli/commands/create.d.ts +2 -2
  40. package/dist/esm/cli/commands/create.js +66 -47
  41. package/dist/esm/cli/commands/helpers/copy-template.d.ts +4 -0
  42. package/dist/esm/cli/commands/helpers/copy-template.js +47 -0
  43. package/dist/esm/cli/commands/helpers/generate-bundle-entrypoint.d.ts +3 -0
  44. package/dist/esm/cli/commands/helpers/generate-bundle-entrypoint.js +18 -0
  45. package/dist/esm/cli/commands/helpers/get-extension-dev-deps.d.ts +4 -0
  46. package/dist/esm/cli/commands/helpers/get-extension-dev-deps.js +21 -0
  47. package/dist/esm/cli/commands/helpers/load-config.d.ts +3 -0
  48. package/dist/esm/cli/{utils → commands/helpers}/load-config.js +0 -0
  49. package/dist/esm/cli/commands/helpers/validate-cli-options.d.ts +4 -0
  50. package/dist/esm/cli/commands/helpers/validate-cli-options.js +34 -0
  51. package/dist/esm/cli/run.js +3 -1
  52. package/dist/esm/cli/types.d.ts +5 -5
  53. package/dist/esm/cli/utils/detect-json-indent.d.ts +2 -0
  54. package/dist/esm/cli/utils/detect-json-indent.js +11 -0
  55. package/dist/esm/cli/utils/get-package-manager-agent.d.ts +5 -0
  56. package/dist/esm/cli/utils/get-package-manager-agent.js +12 -0
  57. package/dist/esm/cli/utils/get-package-manager-agent.test.d.ts +2 -0
  58. package/dist/esm/cli/utils/get-package-manager-agent.test.js +19 -0
  59. package/dist/esm/cli/utils/get-package-manager.d.ts +5 -0
  60. package/dist/esm/cli/utils/get-package-manager.js +14 -0
  61. package/dist/esm/cli/utils/get-package-manager.test.d.ts +2 -0
  62. package/dist/esm/cli/utils/get-package-manager.test.js +37 -0
  63. package/dist/esm/cli/utils/get-sdk-version.d.ts +2 -0
  64. package/dist/esm/cli/utils/get-sdk-version.js +4 -0
  65. package/dist/esm/cli/utils/get-template-path.d.ts +2 -0
  66. package/dist/esm/cli/utils/get-template-path.js +4 -0
  67. package/dist/esm/cli/utils/try-parse-json.d.ts +3 -0
  68. package/dist/esm/cli/utils/try-parse-json.js +8 -0
  69. package/package.json +51 -21
  70. package/templates/common/{javascript → common/config}/_gitignore +0 -0
  71. package/templates/common/typescript/{tsconfig.json → config/tsconfig.json} +0 -0
  72. package/templates/display/javascript/{src → source}/display.vue +0 -0
  73. package/templates/display/javascript/{src → source}/index.js +0 -0
  74. package/templates/display/typescript/{src → source}/display.vue +0 -0
  75. package/templates/display/typescript/{src → source}/index.ts +0 -0
  76. package/templates/display/typescript/{src → source}/shims.d.ts +0 -0
  77. package/templates/endpoint/javascript/{src → source}/index.js +0 -0
  78. package/templates/endpoint/typescript/{src → source}/index.ts +0 -0
  79. package/templates/hook/javascript/{src → source}/index.js +0 -0
  80. package/templates/hook/typescript/{src → source}/index.ts +0 -0
  81. package/templates/interface/javascript/{src → source}/index.js +0 -0
  82. package/templates/interface/javascript/{src → source}/interface.vue +0 -0
  83. package/templates/interface/typescript/{src → source}/index.ts +0 -0
  84. package/templates/interface/typescript/{src → source}/interface.vue +0 -0
  85. package/templates/interface/typescript/{src → source}/shims.d.ts +0 -0
  86. package/templates/layout/javascript/{src → source}/index.js +0 -0
  87. package/templates/layout/javascript/{src → source}/layout.vue +0 -0
  88. package/templates/layout/typescript/{src → source}/index.ts +0 -0
  89. package/templates/layout/typescript/{src → source}/layout.vue +0 -0
  90. package/templates/layout/typescript/{src → source}/shims.d.ts +0 -0
  91. package/templates/module/javascript/{src → source}/index.js +0 -0
  92. package/templates/module/javascript/{src → source}/module.vue +0 -0
  93. package/templates/module/typescript/{src → source}/index.ts +0 -0
  94. package/templates/module/typescript/{src → source}/module.vue +0 -0
  95. package/templates/module/typescript/{src → source}/shims.d.ts +0 -0
  96. package/templates/operation/javascript/{src → source}/api.js +0 -0
  97. package/templates/operation/javascript/{src → source}/app.js +0 -0
  98. package/templates/operation/typescript/{src → source}/api.ts +0 -0
  99. package/templates/operation/typescript/{src → source}/app.ts +0 -0
  100. package/templates/operation/typescript/{src → source}/shims.d.ts +0 -0
  101. package/templates/panel/javascript/{src → source}/index.js +0 -0
  102. package/templates/panel/javascript/{src → source}/panel.vue +0 -0
  103. package/templates/panel/typescript/{src → source}/index.ts +0 -0
  104. package/templates/panel/typescript/{src → source}/panel.vue +0 -0
  105. package/templates/panel/typescript/{src → source}/shims.d.ts +0 -0
  106. package/.editorconfig +0 -12
  107. package/cli.d.ts +0 -1
  108. package/dist/cjs/cli/commands/build.d.ts.map +0 -1
  109. package/dist/cjs/cli/commands/create.d.ts.map +0 -1
  110. package/dist/cjs/cli/index.d.ts.map +0 -1
  111. package/dist/cjs/cli/run.d.ts.map +0 -1
  112. package/dist/cjs/cli/types.d.ts.map +0 -1
  113. package/dist/cjs/cli/utils/get-package-version.d.ts.map +0 -1
  114. package/dist/cjs/cli/utils/languages.d.ts.map +0 -1
  115. package/dist/cjs/cli/utils/load-config.d.ts +0 -3
  116. package/dist/cjs/cli/utils/load-config.d.ts.map +0 -1
  117. package/dist/cjs/cli/utils/logger.d.ts.map +0 -1
  118. package/dist/cjs/cli/utils/rename-map.d.ts +0 -2
  119. package/dist/cjs/cli/utils/rename-map.d.ts.map +0 -1
  120. package/dist/cjs/cli/utils/rename-map.js +0 -23
  121. package/dist/cjs/cli/utils/to-object.d.ts +0 -2
  122. package/dist/cjs/cli/utils/to-object.d.ts.map +0 -1
  123. package/dist/cjs/cli/utils/to-object.js +0 -17
  124. package/dist/cjs/index.d.ts.map +0 -1
  125. package/dist/esm/cli/commands/build.d.ts.map +0 -1
  126. package/dist/esm/cli/commands/create.d.ts.map +0 -1
  127. package/dist/esm/cli/index.d.ts.map +0 -1
  128. package/dist/esm/cli/run.d.ts.map +0 -1
  129. package/dist/esm/cli/types.d.ts.map +0 -1
  130. package/dist/esm/cli/utils/get-package-version.d.ts.map +0 -1
  131. package/dist/esm/cli/utils/languages.d.ts.map +0 -1
  132. package/dist/esm/cli/utils/load-config.d.ts +0 -3
  133. package/dist/esm/cli/utils/load-config.d.ts.map +0 -1
  134. package/dist/esm/cli/utils/logger.d.ts.map +0 -1
  135. package/dist/esm/cli/utils/rename-map.d.ts +0 -2
  136. package/dist/esm/cli/utils/rename-map.d.ts.map +0 -1
  137. package/dist/esm/cli/utils/rename-map.js +0 -17
  138. package/dist/esm/cli/utils/to-object.d.ts +0 -2
  139. package/dist/esm/cli/utils/to-object.d.ts.map +0 -1
  140. package/dist/esm/cli/utils/to-object.js +0 -14
  141. package/dist/esm/index.d.ts.map +0 -1
  142. package/src/cli/commands/build.ts +0 -493
  143. package/src/cli/commands/create.ts +0 -135
  144. package/src/cli/index.ts +0 -4
  145. package/src/cli/run.ts +0 -32
  146. package/src/cli/types.ts +0 -12
  147. package/src/cli/utils/get-package-version.ts +0 -9
  148. package/src/cli/utils/languages.ts +0 -26
  149. package/src/cli/utils/load-config.ts +0 -21
  150. package/src/cli/utils/logger.ts +0 -25
  151. package/src/cli/utils/rename-map.ts +0 -20
  152. package/src/cli/utils/to-object.ts +0 -16
  153. package/src/index.ts +0 -23
  154. package/templates/common/typescript/_gitignore +0 -3
  155. package/tsconfig.json +0 -30
@@ -0,0 +1,2 @@
1
+ export default function add(): Promise<void>;
2
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const logger_1 = require("../utils/logger");
11
+ const utils_1 = require("@directus/shared/utils");
12
+ const node_1 = require("@directus/shared/utils/node");
13
+ const constants_1 = require("@directus/shared/constants");
14
+ const languages_1 = require("../utils/languages");
15
+ const get_extension_dev_deps_1 = __importDefault(require("./helpers/get-extension-dev-deps"));
16
+ const execa_1 = __importDefault(require("execa"));
17
+ const ora_1 = __importDefault(require("ora"));
18
+ const copy_template_1 = __importDefault(require("./helpers/copy-template"));
19
+ const detect_json_indent_1 = __importDefault(require("../utils/detect-json-indent"));
20
+ const get_package_manager_1 = __importDefault(require("../utils/get-package-manager"));
21
+ async function add() {
22
+ var _a, _b;
23
+ const extensionPath = process.cwd();
24
+ const packagePath = path_1.default.resolve('package.json');
25
+ if (!(await fs_extra_1.default.pathExists(packagePath))) {
26
+ (0, logger_1.log)(`Current directory is not a valid package.`, 'error');
27
+ process.exit(1);
28
+ }
29
+ const extensionManifestFile = await fs_extra_1.default.readFile(packagePath, 'utf8');
30
+ const extensionManifest = JSON.parse(extensionManifestFile);
31
+ const indent = (0, detect_json_indent_1.default)(extensionManifestFile);
32
+ if (!(0, utils_1.validateExtensionManifest)(extensionManifest)) {
33
+ (0, logger_1.log)(`Current directory is not a valid Directus extension.`, 'error');
34
+ process.exit(1);
35
+ }
36
+ const extensionOptions = extensionManifest[constants_1.EXTENSION_PKG_KEY];
37
+ if (extensionOptions.type === 'pack') {
38
+ (0, logger_1.log)(`Adding entries to extensions with type ${chalk_1.default.bold('pack')} is not currently supported.`, 'error');
39
+ process.exit(1);
40
+ }
41
+ const sourceExists = await fs_extra_1.default.pathExists(path_1.default.resolve('src'));
42
+ if (extensionOptions.type === 'bundle') {
43
+ const { type, name, language, alternativeSource } = await inquirer_1.default.prompt([
44
+ {
45
+ type: 'list',
46
+ name: 'type',
47
+ message: 'Choose the extension type',
48
+ choices: constants_1.EXTENSION_TYPES,
49
+ },
50
+ {
51
+ type: 'input',
52
+ name: 'name',
53
+ message: 'Choose a name for the entry',
54
+ validate: (name) => (name.length === 0 ? 'Entry name can not be empty.' : true),
55
+ },
56
+ {
57
+ type: 'list',
58
+ name: 'language',
59
+ message: 'Choose the language to use',
60
+ choices: constants_1.EXTENSION_LANGUAGES,
61
+ },
62
+ {
63
+ type: 'input',
64
+ name: 'alternativeSource',
65
+ message: 'Specify the path to the extension source',
66
+ when: !sourceExists && extensionOptions.entries.length > 0,
67
+ },
68
+ ]);
69
+ const spinner = (0, ora_1.default)(chalk_1.default.bold('Modifying Directus extension...')).start();
70
+ const source = alternativeSource !== null && alternativeSource !== void 0 ? alternativeSource : 'src';
71
+ const sourcePath = path_1.default.resolve(source, name);
72
+ await fs_extra_1.default.ensureDir(sourcePath);
73
+ await (0, copy_template_1.default)(type, extensionPath, sourcePath, language);
74
+ const newEntries = [
75
+ ...extensionOptions.entries,
76
+ (0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES)
77
+ ? {
78
+ type,
79
+ name,
80
+ source: {
81
+ app: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/app.${(0, languages_1.languageToShort)(language)}`,
82
+ api: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/api.${(0, languages_1.languageToShort)(language)}`,
83
+ },
84
+ }
85
+ : {
86
+ type,
87
+ name,
88
+ source: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/index.${(0, languages_1.languageToShort)(language)}`,
89
+ },
90
+ ];
91
+ const newExtensionOptions = { ...extensionOptions, entries: newEntries };
92
+ const newExtensionManifest = {
93
+ ...extensionManifest,
94
+ [constants_1.EXTENSION_PKG_KEY]: newExtensionOptions,
95
+ devDependencies: await (0, get_extension_dev_deps_1.default)(newEntries.map((entry) => entry.type), getLanguageFromEntries(newEntries)),
96
+ };
97
+ await fs_extra_1.default.writeJSON(packagePath, newExtensionManifest, { spaces: indent !== null && indent !== void 0 ? indent : '\t' });
98
+ const packageManager = (0, get_package_manager_1.default)();
99
+ await (0, execa_1.default)(packageManager, ['install'], { cwd: extensionPath });
100
+ spinner.succeed(chalk_1.default.bold('Done'));
101
+ }
102
+ else {
103
+ const { proceed } = await inquirer_1.default.prompt([
104
+ {
105
+ type: 'confirm',
106
+ name: 'proceed',
107
+ message: 'This will convert your extension to a bundle. Do you want to proceed?',
108
+ },
109
+ ]);
110
+ if (!proceed) {
111
+ (0, logger_1.log)(`Extension has not been modified.`, 'info');
112
+ process.exit(1);
113
+ }
114
+ const oldName = (_b = (_a = extensionManifest.name.match(constants_1.EXTENSION_NAME_REGEX)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : extensionManifest.name;
115
+ const { type, name, language, convertName, extensionName, alternativeSource } = await inquirer_1.default.prompt([
116
+ {
117
+ type: 'list',
118
+ name: 'type',
119
+ message: 'Choose the extension type',
120
+ choices: constants_1.EXTENSION_TYPES,
121
+ },
122
+ {
123
+ type: 'input',
124
+ name: 'name',
125
+ message: 'Choose a name for the entry',
126
+ validate: (name) => (name.length === 0 ? 'Entry name can not be empty.' : true),
127
+ },
128
+ {
129
+ type: 'list',
130
+ name: 'language',
131
+ message: 'Choose the language to use',
132
+ choices: constants_1.EXTENSION_LANGUAGES,
133
+ },
134
+ {
135
+ type: 'input',
136
+ name: 'convertName',
137
+ message: 'Choose a name for the extension that is converted to an entry',
138
+ default: oldName,
139
+ validate: (name) => (name.length === 0 ? 'Entry name can not be empty.' : true),
140
+ },
141
+ {
142
+ type: 'input',
143
+ name: 'extensionName',
144
+ message: 'Choose a name for the extension',
145
+ default: ({ convertName }) => (convertName !== oldName ? oldName : null),
146
+ validate: (name) => (name.length === 0 ? 'Extension name can not be empty.' : true),
147
+ },
148
+ {
149
+ type: 'input',
150
+ name: 'alternativeSource',
151
+ message: 'Specify the path to the extension source',
152
+ when: !sourceExists,
153
+ },
154
+ ]);
155
+ const spinner = (0, ora_1.default)(chalk_1.default.bold('Modifying Directus extension...')).start();
156
+ const source = alternativeSource !== null && alternativeSource !== void 0 ? alternativeSource : 'src';
157
+ const convertSourcePath = path_1.default.resolve(source, convertName);
158
+ const entrySourcePath = path_1.default.resolve(source, name);
159
+ const convertFiles = await fs_extra_1.default.readdir(source);
160
+ await Promise.all(convertFiles.map((file) => fs_extra_1.default.move(path_1.default.resolve(source, file), path_1.default.join(convertSourcePath, file))));
161
+ await fs_extra_1.default.ensureDir(entrySourcePath);
162
+ await (0, copy_template_1.default)(type, extensionPath, entrySourcePath, language);
163
+ const toConvertSourceUrl = (entrypoint) => path_1.default.posix.join((0, node_1.pathToRelativeUrl)(source), convertName, path_1.default.posix.relative(source, entrypoint));
164
+ const entries = [
165
+ (0, utils_1.isTypeIn)(extensionOptions, constants_1.HYBRID_EXTENSION_TYPES)
166
+ ? {
167
+ type: extensionOptions.type,
168
+ name: convertName,
169
+ source: {
170
+ app: toConvertSourceUrl(extensionOptions.source.app),
171
+ api: toConvertSourceUrl(extensionOptions.source.api),
172
+ },
173
+ }
174
+ : {
175
+ type: extensionOptions.type,
176
+ name: convertName,
177
+ source: toConvertSourceUrl(extensionOptions.source),
178
+ },
179
+ (0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES)
180
+ ? {
181
+ type,
182
+ name,
183
+ source: {
184
+ app: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/app.${(0, languages_1.languageToShort)(language)}`,
185
+ api: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/api.${(0, languages_1.languageToShort)(language)}`,
186
+ },
187
+ }
188
+ : {
189
+ type,
190
+ name,
191
+ source: `${(0, node_1.pathToRelativeUrl)(source)}/${name}/index.${(0, languages_1.languageToShort)(language)}`,
192
+ },
193
+ ];
194
+ const newExtensionOptions = {
195
+ type: 'bundle',
196
+ path: { app: 'dist/app.js', api: 'dist/api.js' },
197
+ entries,
198
+ host: extensionOptions.host,
199
+ hidden: extensionOptions.hidden,
200
+ };
201
+ const newExtensionManifest = {
202
+ ...extensionManifest,
203
+ name: constants_1.EXTENSION_NAME_REGEX.test(extensionName) ? extensionName : `directus-extension-${extensionName}`,
204
+ keywords: ['directus', 'directus-extension', `directus-custom-bundle`],
205
+ [constants_1.EXTENSION_PKG_KEY]: newExtensionOptions,
206
+ devDependencies: await (0, get_extension_dev_deps_1.default)(entries.map((entry) => entry.type), getLanguageFromEntries(entries)),
207
+ };
208
+ await fs_extra_1.default.writeJSON(packagePath, newExtensionManifest, { spaces: indent !== null && indent !== void 0 ? indent : '\t' });
209
+ const packageManager = (0, get_package_manager_1.default)();
210
+ await (0, execa_1.default)(packageManager, ['install'], { cwd: extensionPath });
211
+ spinner.succeed(chalk_1.default.bold('Done'));
212
+ }
213
+ }
214
+ exports.default = add;
215
+ function getLanguageFromEntries(entries) {
216
+ const languages = new Set();
217
+ for (const entry of entries) {
218
+ if ((0, utils_1.isTypeIn)(entry, constants_1.HYBRID_EXTENSION_TYPES)) {
219
+ const languageApp = (0, languages_1.getLanguageFromPath)(entry.source.app);
220
+ const languageApi = (0, languages_1.getLanguageFromPath)(entry.source.api);
221
+ if (!(0, languages_1.isLanguage)(languageApp)) {
222
+ (0, logger_1.log)(`App language ${chalk_1.default.bold(languageApp)} is not supported.`, 'error');
223
+ process.exit(1);
224
+ }
225
+ if (!(0, languages_1.isLanguage)(languageApi)) {
226
+ (0, logger_1.log)(`API language ${chalk_1.default.bold(languageApi)} is not supported.`, 'error');
227
+ process.exit(1);
228
+ }
229
+ languages.add(languageApp);
230
+ languages.add(languageApi);
231
+ }
232
+ else {
233
+ const language = (0, languages_1.getLanguageFromPath)(entry.source);
234
+ if (!(0, languages_1.isLanguage)(language)) {
235
+ (0, logger_1.log)(`Language ${chalk_1.default.bold(language)} is not supported.`, 'error');
236
+ process.exit(1);
237
+ }
238
+ languages.add(language);
239
+ }
240
+ }
241
+ return Array.from(languages);
242
+ }
@@ -1,4 +1,4 @@
1
- declare type BuildOptions = {
1
+ type BuildOptions = {
2
2
  type?: string;
3
3
  input?: string;
4
4
  output?: string;
@@ -3,25 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const path_1 = __importDefault(require("path"));
6
+ const constants_1 = require("@directus/shared/constants");
7
+ const utils_1 = require("@directus/shared/utils");
8
+ const plugin_commonjs_1 = __importDefault(require("@rollup/plugin-commonjs"));
9
+ const plugin_json_1 = __importDefault(require("@rollup/plugin-json"));
10
+ const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve");
11
+ const plugin_replace_1 = __importDefault(require("@rollup/plugin-replace"));
12
+ const plugin_terser_1 = __importDefault(require("@rollup/plugin-terser"));
13
+ const plugin_virtual_1 = __importDefault(require("@rollup/plugin-virtual"));
7
14
  const chalk_1 = __importDefault(require("chalk"));
8
15
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
16
  const ora_1 = __importDefault(require("ora"));
17
+ const path_1 = __importDefault(require("path"));
10
18
  const rollup_1 = require("rollup");
11
- const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve");
12
- const plugin_commonjs_1 = __importDefault(require("@rollup/plugin-commonjs"));
13
- const plugin_json_1 = __importDefault(require("@rollup/plugin-json"));
14
- const plugin_replace_1 = __importDefault(require("@rollup/plugin-replace"));
15
- const rollup_plugin_typescript2_1 = __importDefault(require("rollup-plugin-typescript2"));
16
- const rollup_plugin_terser_1 = require("rollup-plugin-terser");
17
19
  const rollup_plugin_styles_1 = __importDefault(require("rollup-plugin-styles"));
20
+ const rollup_plugin_typescript2_1 = __importDefault(require("rollup-plugin-typescript2"));
18
21
  const rollup_plugin_vue_1 = __importDefault(require("rollup-plugin-vue"));
19
- const constants_1 = require("@directus/shared/constants");
20
- const utils_1 = require("@directus/shared/utils");
21
- const logger_1 = require("../utils/logger");
22
22
  const languages_1 = require("../utils/languages");
23
- const load_config_1 = __importDefault(require("../utils/load-config"));
24
- const to_object_1 = __importDefault(require("../utils/to-object"));
23
+ const logger_1 = require("../utils/logger");
24
+ const try_parse_json_1 = __importDefault(require("../utils/try-parse-json"));
25
+ const generate_bundle_entrypoint_1 = __importDefault(require("./helpers/generate-bundle-entrypoint"));
26
+ const load_config_1 = __importDefault(require("./helpers/load-config"));
27
+ const validate_cli_options_1 = require("./helpers/validate-cli-options");
25
28
  async function build(options) {
26
29
  var _a, _b, _c;
27
30
  const watch = (_a = options.watch) !== null && _a !== void 0 ? _a : false;
@@ -29,24 +32,31 @@ async function build(options) {
29
32
  const minify = (_c = options.minify) !== null && _c !== void 0 ? _c : false;
30
33
  if (!options.type && !options.input && !options.output) {
31
34
  const packagePath = path_1.default.resolve('package.json');
32
- let extensionManifest = {};
33
35
  if (!(await fs_extra_1.default.pathExists(packagePath))) {
34
36
  (0, logger_1.log)(`Current directory is not a valid package.`, 'error');
35
37
  process.exit(1);
36
38
  }
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
- }
39
+ const extensionManifest = await fs_extra_1.default.readJSON(packagePath);
40
+ if (!(0, utils_1.validateExtensionManifest)(extensionManifest)) {
41
+ (0, logger_1.log)(`Current directory is not a valid Directus extension.`, 'error');
42
+ process.exit(1);
43
43
  }
44
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');
45
+ if (extensionOptions.type === 'pack') {
46
+ (0, logger_1.log)(`Building extension type ${chalk_1.default.bold('pack')} is not currently supported.`, 'error');
47
47
  process.exit(1);
48
48
  }
49
- if ((0, utils_1.isTypeIn)(extensionOptions, constants_1.HYBRID_EXTENSION_TYPES)) {
49
+ if (extensionOptions.type === 'bundle') {
50
+ await buildBundleExtension({
51
+ entries: extensionOptions.entries,
52
+ outputApp: extensionOptions.path.app,
53
+ outputApi: extensionOptions.path.api,
54
+ watch,
55
+ sourcemap,
56
+ minify,
57
+ });
58
+ }
59
+ else if ((0, utils_1.isTypeIn)(extensionOptions, constants_1.HYBRID_EXTENSION_TYPES)) {
50
60
  await buildHybridExtension({
51
61
  inputApp: extensionOptions.source.app,
52
62
  inputApi: extensionOptions.source.api,
@@ -76,8 +86,12 @@ async function build(options) {
76
86
  (0, logger_1.log)(`Extension type has to be specified using the ${chalk_1.default.blue('[-t, --type <type>]')} option.`, 'error');
77
87
  process.exit(1);
78
88
  }
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');
89
+ if (!(0, utils_1.isIn)(type, constants_1.EXTENSION_PACKAGE_TYPES)) {
90
+ (0, logger_1.log)(`Extension type ${chalk_1.default.bold(type)} is not supported. Available extension types: ${constants_1.EXTENSION_PACKAGE_TYPES.map((t) => chalk_1.default.bold.magenta(t)).join(', ')}.`, 'error');
91
+ process.exit(1);
92
+ }
93
+ if (type === 'pack') {
94
+ (0, logger_1.log)(`Building extension type ${chalk_1.default.bold('pack')} is not currently supported.`, 'error');
81
95
  process.exit(1);
82
96
  }
83
97
  if (!input) {
@@ -88,22 +102,42 @@ async function build(options) {
88
102
  (0, logger_1.log)(`Extension output file has to be specified using the ${chalk_1.default.blue('[-o, --output <file>]')} option.`, 'error');
89
103
  process.exit(1);
90
104
  }
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');
105
+ if (type === 'bundle') {
106
+ const entries = (0, try_parse_json_1.default)(input);
107
+ const splitOutput = (0, try_parse_json_1.default)(output);
108
+ if (!(0, validate_cli_options_1.validateBundleEntriesOption)(entries)) {
109
+ (0, logger_1.log)(`Input option needs to be of the format ${chalk_1.default.blue(`[-i '[{"type":"<extension-type>","name":"<extension-name>","source":<entrypoint>}]']`)}.`, 'error');
96
110
  process.exit(1);
97
111
  }
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');
112
+ if (!(0, validate_cli_options_1.validateSplitEntrypointOption)(splitOutput)) {
113
+ (0, logger_1.log)(`Output option needs to be of the format ${chalk_1.default.blue(`[-o '{"app":"<app-entrypoint>","api":"<api-entrypoint>"}']`)}.`, 'error');
114
+ process.exit(1);
115
+ }
116
+ await buildBundleExtension({
117
+ entries,
118
+ outputApp: splitOutput.app,
119
+ outputApi: splitOutput.api,
120
+ watch,
121
+ sourcemap,
122
+ minify,
123
+ });
124
+ }
125
+ else if ((0, utils_1.isIn)(type, constants_1.HYBRID_EXTENSION_TYPES)) {
126
+ const splitInput = (0, try_parse_json_1.default)(input);
127
+ const splitOutput = (0, try_parse_json_1.default)(output);
128
+ if (!(0, validate_cli_options_1.validateSplitEntrypointOption)(splitInput)) {
129
+ (0, logger_1.log)(`Input option needs to be of the format ${chalk_1.default.blue(`[-i '{"app":"<app-entrypoint>","api":"<api-entrypoint>"}']`)}.`, 'error');
130
+ process.exit(1);
131
+ }
132
+ if (!(0, validate_cli_options_1.validateSplitEntrypointOption)(splitOutput)) {
133
+ (0, logger_1.log)(`Output option needs to be of the format ${chalk_1.default.blue(`[-o '{"app":"<app-entrypoint>","api":"<api-entrypoint>"}']`)}.`, 'error');
100
134
  process.exit(1);
101
135
  }
102
136
  await buildHybridExtension({
103
- inputApp: inputObject.app,
104
- inputApi: inputObject.api,
105
- outputApp: outputObject.app,
106
- outputApi: outputObject.api,
137
+ inputApp: splitInput.app,
138
+ inputApi: splitInput.api,
139
+ outputApp: splitOutput.app,
140
+ outputApi: splitOutput.api,
107
141
  watch,
108
142
  sourcemap,
109
143
  minify,
@@ -174,7 +208,7 @@ async function buildHybridExtension({ inputApp, inputApi, outputApp, outputApi,
174
208
  process.exit(1);
175
209
  }
176
210
  if (!(0, languages_1.isLanguage)(languageApi)) {
177
- (0, logger_1.log)(`API language ${chalk_1.default.bold(languageApp)} is not supported.`, 'error');
211
+ (0, logger_1.log)(`API language ${chalk_1.default.bold(languageApi)} is not supported.`, 'error');
178
212
  process.exit(1);
179
213
  }
180
214
  const config = await (0, load_config_1.default)();
@@ -208,6 +242,95 @@ async function buildHybridExtension({ inputApp, inputApi, outputApp, outputApi,
208
242
  await buildExtension(rollupOptionsAll);
209
243
  }
210
244
  }
245
+ async function buildBundleExtension({ entries, outputApp, outputApi, watch, sourcemap, minify, }) {
246
+ var _a;
247
+ if (outputApp.length === 0) {
248
+ (0, logger_1.log)(`App output file can not be empty.`, 'error');
249
+ process.exit(1);
250
+ }
251
+ if (outputApi.length === 0) {
252
+ (0, logger_1.log)(`API output file can not be empty.`, 'error');
253
+ process.exit(1);
254
+ }
255
+ const languagesApp = new Set();
256
+ const languagesApi = new Set();
257
+ for (const entry of entries) {
258
+ if ((0, utils_1.isTypeIn)(entry, constants_1.HYBRID_EXTENSION_TYPES)) {
259
+ const inputApp = entry.source.app;
260
+ const inputApi = entry.source.api;
261
+ if (!(await fs_extra_1.default.pathExists(inputApp)) || !(await fs_extra_1.default.stat(inputApp)).isFile()) {
262
+ (0, logger_1.log)(`App entrypoint ${chalk_1.default.bold(inputApp)} does not exist.`, 'error');
263
+ process.exit(1);
264
+ }
265
+ if (!(await fs_extra_1.default.pathExists(inputApi)) || !(await fs_extra_1.default.stat(inputApi)).isFile()) {
266
+ (0, logger_1.log)(`API entrypoint ${chalk_1.default.bold(inputApi)} does not exist.`, 'error');
267
+ process.exit(1);
268
+ }
269
+ const languageApp = (0, languages_1.getLanguageFromPath)(inputApp);
270
+ const languageApi = (0, languages_1.getLanguageFromPath)(inputApi);
271
+ if (!(0, languages_1.isLanguage)(languageApp)) {
272
+ (0, logger_1.log)(`App language ${chalk_1.default.bold(languageApp)} is not supported.`, 'error');
273
+ process.exit(1);
274
+ }
275
+ if (!(0, languages_1.isLanguage)(languageApi)) {
276
+ (0, logger_1.log)(`API language ${chalk_1.default.bold(languageApi)} is not supported.`, 'error');
277
+ process.exit(1);
278
+ }
279
+ languagesApp.add(languageApp);
280
+ languagesApi.add(languageApi);
281
+ }
282
+ else {
283
+ const input = entry.source;
284
+ if (!(await fs_extra_1.default.pathExists(input)) || !(await fs_extra_1.default.stat(input)).isFile()) {
285
+ (0, logger_1.log)(`Entrypoint ${chalk_1.default.bold(input)} does not exist.`, 'error');
286
+ process.exit(1);
287
+ }
288
+ const language = (0, languages_1.getLanguageFromPath)(input);
289
+ if (!(0, languages_1.isLanguage)(language)) {
290
+ (0, logger_1.log)(`Language ${chalk_1.default.bold(language)} is not supported.`, 'error');
291
+ process.exit(1);
292
+ }
293
+ if ((0, utils_1.isIn)(entry.type, constants_1.APP_EXTENSION_TYPES)) {
294
+ languagesApp.add(language);
295
+ }
296
+ else {
297
+ languagesApi.add(language);
298
+ }
299
+ }
300
+ }
301
+ const config = await (0, load_config_1.default)();
302
+ const plugins = (_a = config.plugins) !== null && _a !== void 0 ? _a : [];
303
+ const entrypointApp = (0, generate_bundle_entrypoint_1.default)('app', entries);
304
+ const entrypointApi = (0, generate_bundle_entrypoint_1.default)('api', entries);
305
+ const rollupOptionsApp = getRollupOptions({
306
+ mode: 'browser',
307
+ input: { entry: entrypointApp },
308
+ language: Array.from(languagesApp),
309
+ sourcemap,
310
+ minify,
311
+ plugins,
312
+ });
313
+ const rollupOptionsApi = getRollupOptions({
314
+ mode: 'node',
315
+ input: { entry: entrypointApi },
316
+ language: Array.from(languagesApi),
317
+ sourcemap,
318
+ minify,
319
+ plugins,
320
+ });
321
+ const rollupOutputOptionsApp = getRollupOutputOptions({ mode: 'browser', output: outputApp, sourcemap });
322
+ const rollupOutputOptionsApi = getRollupOutputOptions({ mode: 'node', output: outputApi, sourcemap });
323
+ const rollupOptionsAll = [
324
+ { rollupOptions: rollupOptionsApp, rollupOutputOptions: rollupOutputOptionsApp },
325
+ { rollupOptions: rollupOptionsApi, rollupOutputOptions: rollupOutputOptionsApi },
326
+ ];
327
+ if (watch) {
328
+ await watchExtension(rollupOptionsAll);
329
+ }
330
+ else {
331
+ await buildExtension(rollupOptionsAll);
332
+ }
333
+ }
211
334
  async function buildExtension(config) {
212
335
  const configs = Array.isArray(config) ? config : [config];
213
336
  const spinner = (0, ora_1.default)(chalk_1.default.bold('Building Directus extension...')).start();
@@ -272,13 +395,15 @@ async function watchExtension(config) {
272
395
  }
273
396
  }
274
397
  function getRollupOptions({ mode, input, language, sourcemap, minify, plugins, }) {
398
+ const languages = Array.isArray(language) ? language : [language];
275
399
  if (mode === 'browser') {
276
400
  return {
277
- input,
401
+ input: typeof input !== 'string' ? 'entry' : input,
278
402
  external: constants_1.APP_SHARED_DEPS,
279
403
  plugins: [
404
+ typeof input !== 'string' ? (0, plugin_virtual_1.default)(input) : null,
280
405
  (0, rollup_plugin_vue_1.default)({ preprocessStyles: true }),
281
- language === 'typescript' ? (0, rollup_plugin_typescript2_1.default)({ check: false }) : null,
406
+ languages.includes('typescript') ? (0, rollup_plugin_typescript2_1.default)({ check: false }) : null,
282
407
  (0, rollup_plugin_styles_1.default)(),
283
408
  ...plugins,
284
409
  (0, plugin_node_resolve_1.nodeResolve)({ browser: true }),
@@ -290,16 +415,17 @@ function getRollupOptions({ mode, input, language, sourcemap, minify, plugins, }
290
415
  },
291
416
  preventAssignment: true,
292
417
  }),
293
- minify ? (0, rollup_plugin_terser_1.terser)() : null,
418
+ minify ? (0, plugin_terser_1.default)() : null,
294
419
  ],
295
420
  };
296
421
  }
297
422
  else {
298
423
  return {
299
- input,
424
+ input: typeof input !== 'string' ? 'entry' : input,
300
425
  external: constants_1.API_SHARED_DEPS,
301
426
  plugins: [
302
- language === 'typescript' ? (0, rollup_plugin_typescript2_1.default)({ check: false }) : null,
427
+ typeof input !== 'string' ? (0, plugin_virtual_1.default)(input) : null,
428
+ languages.includes('typescript') ? (0, rollup_plugin_typescript2_1.default)({ check: false }) : null,
303
429
  ...plugins,
304
430
  (0, plugin_node_resolve_1.nodeResolve)(),
305
431
  (0, plugin_commonjs_1.default)({ sourceMap: sourcemap }),
@@ -310,7 +436,7 @@ function getRollupOptions({ mode, input, language, sourcemap, minify, plugins, }
310
436
  },
311
437
  preventAssignment: true,
312
438
  }),
313
- minify ? (0, rollup_plugin_terser_1.terser)() : null,
439
+ minify ? (0, plugin_terser_1.default)() : null,
314
440
  ],
315
441
  };
316
442
  }
@@ -328,7 +454,7 @@ function getRollupOutputOptions({ mode, output, sourcemap, }) {
328
454
  return {
329
455
  file: output,
330
456
  format: 'cjs',
331
- exports: 'default',
457
+ exports: 'auto',
332
458
  inlineDynamicImports: true,
333
459
  sourcemap,
334
460
  };
@@ -1,5 +1,5 @@
1
- declare type CreateOptions = {
2
- language: string;
1
+ type CreateOptions = {
2
+ language?: string;
3
3
  };
4
4
  export default function create(type: string, name: string, options: CreateOptions): Promise<void>;
5
5
  export {};