@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.
- package/dist/cjs/cli/commands/add.d.ts +2 -0
- package/dist/cjs/cli/commands/add.js +242 -0
- package/dist/cjs/cli/commands/build.d.ts +1 -1
- package/dist/cjs/cli/commands/build.js +169 -43
- package/dist/cjs/cli/commands/create.d.ts +2 -2
- package/dist/cjs/cli/commands/create.js +66 -47
- package/dist/cjs/cli/commands/helpers/copy-template.d.ts +4 -0
- package/dist/cjs/cli/commands/helpers/copy-template.js +53 -0
- package/dist/cjs/cli/commands/helpers/generate-bundle-entrypoint.d.ts +3 -0
- package/dist/cjs/cli/commands/helpers/generate-bundle-entrypoint.js +24 -0
- package/dist/cjs/cli/commands/helpers/get-extension-dev-deps.d.ts +4 -0
- package/dist/cjs/cli/commands/helpers/get-extension-dev-deps.js +27 -0
- package/dist/cjs/cli/commands/helpers/load-config.d.ts +3 -0
- package/dist/cjs/cli/{utils → commands/helpers}/load-config.js +0 -0
- package/dist/cjs/cli/commands/helpers/validate-cli-options.d.ts +4 -0
- package/dist/cjs/cli/commands/helpers/validate-cli-options.js +39 -0
- package/dist/cjs/cli/run.js +3 -1
- package/dist/cjs/cli/types.d.ts +5 -5
- package/dist/cjs/cli/utils/detect-json-indent.d.ts +2 -0
- package/dist/cjs/cli/utils/detect-json-indent.js +14 -0
- package/dist/cjs/cli/utils/get-package-manager-agent.d.ts +5 -0
- package/dist/cjs/cli/utils/get-package-manager-agent.js +15 -0
- package/dist/cjs/cli/utils/get-package-manager-agent.test.d.ts +2 -0
- package/dist/cjs/cli/utils/get-package-manager-agent.test.js +24 -0
- package/dist/cjs/cli/utils/get-package-manager.d.ts +5 -0
- package/dist/cjs/cli/utils/get-package-manager.js +20 -0
- package/dist/cjs/cli/utils/get-package-manager.test.d.ts +2 -0
- package/dist/cjs/cli/utils/get-package-manager.test.js +42 -0
- package/dist/cjs/cli/utils/get-sdk-version.d.ts +2 -0
- package/dist/cjs/cli/utils/get-sdk-version.js +7 -0
- package/dist/cjs/cli/utils/get-template-path.d.ts +2 -0
- package/dist/cjs/cli/utils/get-template-path.js +10 -0
- package/dist/cjs/cli/utils/try-parse-json.d.ts +3 -0
- package/dist/cjs/cli/utils/try-parse-json.js +11 -0
- package/dist/esm/cli/commands/add.d.ts +2 -0
- package/dist/esm/cli/commands/add.js +236 -0
- package/dist/esm/cli/commands/build.d.ts +1 -1
- package/dist/esm/cli/commands/build.js +167 -41
- package/dist/esm/cli/commands/create.d.ts +2 -2
- package/dist/esm/cli/commands/create.js +66 -47
- package/dist/esm/cli/commands/helpers/copy-template.d.ts +4 -0
- package/dist/esm/cli/commands/helpers/copy-template.js +47 -0
- package/dist/esm/cli/commands/helpers/generate-bundle-entrypoint.d.ts +3 -0
- package/dist/esm/cli/commands/helpers/generate-bundle-entrypoint.js +18 -0
- package/dist/esm/cli/commands/helpers/get-extension-dev-deps.d.ts +4 -0
- package/dist/esm/cli/commands/helpers/get-extension-dev-deps.js +21 -0
- package/dist/esm/cli/commands/helpers/load-config.d.ts +3 -0
- package/dist/esm/cli/{utils → commands/helpers}/load-config.js +0 -0
- package/dist/esm/cli/commands/helpers/validate-cli-options.d.ts +4 -0
- package/dist/esm/cli/commands/helpers/validate-cli-options.js +34 -0
- package/dist/esm/cli/run.js +3 -1
- package/dist/esm/cli/types.d.ts +5 -5
- package/dist/esm/cli/utils/detect-json-indent.d.ts +2 -0
- package/dist/esm/cli/utils/detect-json-indent.js +11 -0
- package/dist/esm/cli/utils/get-package-manager-agent.d.ts +5 -0
- package/dist/esm/cli/utils/get-package-manager-agent.js +12 -0
- package/dist/esm/cli/utils/get-package-manager-agent.test.d.ts +2 -0
- package/dist/esm/cli/utils/get-package-manager-agent.test.js +19 -0
- package/dist/esm/cli/utils/get-package-manager.d.ts +5 -0
- package/dist/esm/cli/utils/get-package-manager.js +14 -0
- package/dist/esm/cli/utils/get-package-manager.test.d.ts +2 -0
- package/dist/esm/cli/utils/get-package-manager.test.js +37 -0
- package/dist/esm/cli/utils/get-sdk-version.d.ts +2 -0
- package/dist/esm/cli/utils/get-sdk-version.js +4 -0
- package/dist/esm/cli/utils/get-template-path.d.ts +2 -0
- package/dist/esm/cli/utils/get-template-path.js +4 -0
- package/dist/esm/cli/utils/try-parse-json.d.ts +3 -0
- package/dist/esm/cli/utils/try-parse-json.js +8 -0
- package/package.json +51 -21
- package/templates/common/{javascript → common/config}/_gitignore +0 -0
- package/templates/common/typescript/{tsconfig.json → config/tsconfig.json} +0 -0
- package/templates/display/javascript/{src → source}/display.vue +0 -0
- package/templates/display/javascript/{src → source}/index.js +0 -0
- package/templates/display/typescript/{src → source}/display.vue +0 -0
- package/templates/display/typescript/{src → source}/index.ts +0 -0
- package/templates/display/typescript/{src → source}/shims.d.ts +0 -0
- package/templates/endpoint/javascript/{src → source}/index.js +0 -0
- package/templates/endpoint/typescript/{src → source}/index.ts +0 -0
- package/templates/hook/javascript/{src → source}/index.js +0 -0
- package/templates/hook/typescript/{src → source}/index.ts +0 -0
- package/templates/interface/javascript/{src → source}/index.js +0 -0
- package/templates/interface/javascript/{src → source}/interface.vue +0 -0
- package/templates/interface/typescript/{src → source}/index.ts +0 -0
- package/templates/interface/typescript/{src → source}/interface.vue +0 -0
- package/templates/interface/typescript/{src → source}/shims.d.ts +0 -0
- package/templates/layout/javascript/{src → source}/index.js +0 -0
- package/templates/layout/javascript/{src → source}/layout.vue +0 -0
- package/templates/layout/typescript/{src → source}/index.ts +0 -0
- package/templates/layout/typescript/{src → source}/layout.vue +0 -0
- package/templates/layout/typescript/{src → source}/shims.d.ts +0 -0
- package/templates/module/javascript/{src → source}/index.js +0 -0
- package/templates/module/javascript/{src → source}/module.vue +0 -0
- package/templates/module/typescript/{src → source}/index.ts +0 -0
- package/templates/module/typescript/{src → source}/module.vue +0 -0
- package/templates/module/typescript/{src → source}/shims.d.ts +0 -0
- package/templates/operation/javascript/{src → source}/api.js +0 -0
- package/templates/operation/javascript/{src → source}/app.js +0 -0
- package/templates/operation/typescript/{src → source}/api.ts +0 -0
- package/templates/operation/typescript/{src → source}/app.ts +0 -0
- package/templates/operation/typescript/{src → source}/shims.d.ts +0 -0
- package/templates/panel/javascript/{src → source}/index.js +0 -0
- package/templates/panel/javascript/{src → source}/panel.vue +0 -0
- package/templates/panel/typescript/{src → source}/index.ts +0 -0
- package/templates/panel/typescript/{src → source}/panel.vue +0 -0
- package/templates/panel/typescript/{src → source}/shims.d.ts +0 -0
- package/.editorconfig +0 -12
- package/cli.d.ts +0 -1
- package/dist/cjs/cli/commands/build.d.ts.map +0 -1
- package/dist/cjs/cli/commands/create.d.ts.map +0 -1
- package/dist/cjs/cli/index.d.ts.map +0 -1
- package/dist/cjs/cli/run.d.ts.map +0 -1
- package/dist/cjs/cli/types.d.ts.map +0 -1
- package/dist/cjs/cli/utils/get-package-version.d.ts.map +0 -1
- package/dist/cjs/cli/utils/languages.d.ts.map +0 -1
- package/dist/cjs/cli/utils/load-config.d.ts +0 -3
- package/dist/cjs/cli/utils/load-config.d.ts.map +0 -1
- package/dist/cjs/cli/utils/logger.d.ts.map +0 -1
- package/dist/cjs/cli/utils/rename-map.d.ts +0 -2
- package/dist/cjs/cli/utils/rename-map.d.ts.map +0 -1
- package/dist/cjs/cli/utils/rename-map.js +0 -23
- package/dist/cjs/cli/utils/to-object.d.ts +0 -2
- package/dist/cjs/cli/utils/to-object.d.ts.map +0 -1
- package/dist/cjs/cli/utils/to-object.js +0 -17
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/esm/cli/commands/build.d.ts.map +0 -1
- package/dist/esm/cli/commands/create.d.ts.map +0 -1
- package/dist/esm/cli/index.d.ts.map +0 -1
- package/dist/esm/cli/run.d.ts.map +0 -1
- package/dist/esm/cli/types.d.ts.map +0 -1
- package/dist/esm/cli/utils/get-package-version.d.ts.map +0 -1
- package/dist/esm/cli/utils/languages.d.ts.map +0 -1
- package/dist/esm/cli/utils/load-config.d.ts +0 -3
- package/dist/esm/cli/utils/load-config.d.ts.map +0 -1
- package/dist/esm/cli/utils/logger.d.ts.map +0 -1
- package/dist/esm/cli/utils/rename-map.d.ts +0 -2
- package/dist/esm/cli/utils/rename-map.d.ts.map +0 -1
- package/dist/esm/cli/utils/rename-map.js +0 -17
- package/dist/esm/cli/utils/to-object.d.ts +0 -2
- package/dist/esm/cli/utils/to-object.d.ts.map +0 -1
- package/dist/esm/cli/utils/to-object.js +0 -14
- package/dist/esm/index.d.ts.map +0 -1
- package/src/cli/commands/build.ts +0 -493
- package/src/cli/commands/create.ts +0 -135
- package/src/cli/index.ts +0 -4
- package/src/cli/run.ts +0 -32
- package/src/cli/types.ts +0 -12
- package/src/cli/utils/get-package-version.ts +0 -9
- package/src/cli/utils/languages.ts +0 -26
- package/src/cli/utils/load-config.ts +0 -21
- package/src/cli/utils/logger.ts +0 -25
- package/src/cli/utils/rename-map.ts +0 -20
- package/src/cli/utils/to-object.ts +0 -16
- package/src/index.ts +0 -23
- package/templates/common/typescript/_gitignore +0 -3
- package/tsconfig.json +0 -30
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import fse from 'fs-extra';
|
|
4
|
-
import ora from 'ora';
|
|
5
|
-
import {
|
|
6
|
-
RollupError,
|
|
7
|
-
RollupOptions,
|
|
8
|
-
OutputOptions as RollupOutputOptions,
|
|
9
|
-
Plugin,
|
|
10
|
-
rollup,
|
|
11
|
-
watch as rollupWatch,
|
|
12
|
-
} from 'rollup';
|
|
13
|
-
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
14
|
-
import commonjs from '@rollup/plugin-commonjs';
|
|
15
|
-
import json from '@rollup/plugin-json';
|
|
16
|
-
import replace from '@rollup/plugin-replace';
|
|
17
|
-
import typescript from 'rollup-plugin-typescript2';
|
|
18
|
-
import { terser } from 'rollup-plugin-terser';
|
|
19
|
-
import styles from 'rollup-plugin-styles';
|
|
20
|
-
import vue from 'rollup-plugin-vue';
|
|
21
|
-
import {
|
|
22
|
-
EXTENSION_PKG_KEY,
|
|
23
|
-
EXTENSION_TYPES,
|
|
24
|
-
APP_SHARED_DEPS,
|
|
25
|
-
API_SHARED_DEPS,
|
|
26
|
-
APP_EXTENSION_TYPES,
|
|
27
|
-
HYBRID_EXTENSION_TYPES,
|
|
28
|
-
} from '@directus/shared/constants';
|
|
29
|
-
import { isIn, isTypeIn, validateExtensionManifest } from '@directus/shared/utils';
|
|
30
|
-
import { ApiExtensionType, AppExtensionType, ExtensionManifestRaw } from '@directus/shared/types';
|
|
31
|
-
import { log, clear } from '../utils/logger';
|
|
32
|
-
import { getLanguageFromPath, isLanguage } from '../utils/languages';
|
|
33
|
-
import { Language, RollupConfig, RollupMode } from '../types';
|
|
34
|
-
import loadConfig from '../utils/load-config';
|
|
35
|
-
import toObject from '../utils/to-object';
|
|
36
|
-
|
|
37
|
-
type BuildOptions = {
|
|
38
|
-
type?: string;
|
|
39
|
-
input?: string;
|
|
40
|
-
output?: string;
|
|
41
|
-
watch?: boolean;
|
|
42
|
-
minify?: boolean;
|
|
43
|
-
sourcemap?: boolean;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default async function build(options: BuildOptions): Promise<void> {
|
|
47
|
-
const watch = options.watch ?? false;
|
|
48
|
-
const sourcemap = options.sourcemap ?? false;
|
|
49
|
-
const minify = options.minify ?? false;
|
|
50
|
-
|
|
51
|
-
if (!options.type && !options.input && !options.output) {
|
|
52
|
-
const packagePath = path.resolve('package.json');
|
|
53
|
-
let extensionManifest: ExtensionManifestRaw = {};
|
|
54
|
-
|
|
55
|
-
if (!(await fse.pathExists(packagePath))) {
|
|
56
|
-
log(`Current directory is not a valid package.`, 'error');
|
|
57
|
-
process.exit(1);
|
|
58
|
-
} else {
|
|
59
|
-
extensionManifest = await fse.readJSON(packagePath);
|
|
60
|
-
|
|
61
|
-
if (!validateExtensionManifest(extensionManifest)) {
|
|
62
|
-
log(`Current directory is not a valid Directus extension.`, 'error');
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const extensionOptions = extensionManifest[EXTENSION_PKG_KEY];
|
|
68
|
-
|
|
69
|
-
if (!isTypeIn(extensionOptions, EXTENSION_TYPES)) {
|
|
70
|
-
log(
|
|
71
|
-
`Extension type ${chalk.bold(
|
|
72
|
-
extensionOptions.type
|
|
73
|
-
)} is not supported. Available extension types: ${EXTENSION_TYPES.map((t) => chalk.bold.magenta(t)).join(
|
|
74
|
-
', '
|
|
75
|
-
)}.`,
|
|
76
|
-
'error'
|
|
77
|
-
);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (isTypeIn(extensionOptions, HYBRID_EXTENSION_TYPES)) {
|
|
82
|
-
await buildHybridExtension({
|
|
83
|
-
inputApp: extensionOptions.source.app,
|
|
84
|
-
inputApi: extensionOptions.source.api,
|
|
85
|
-
outputApp: extensionOptions.path.app,
|
|
86
|
-
outputApi: extensionOptions.path.api,
|
|
87
|
-
watch,
|
|
88
|
-
sourcemap,
|
|
89
|
-
minify,
|
|
90
|
-
});
|
|
91
|
-
} else {
|
|
92
|
-
await buildAppOrApiExtension({
|
|
93
|
-
type: extensionOptions.type,
|
|
94
|
-
input: extensionOptions.source,
|
|
95
|
-
output: extensionOptions.path,
|
|
96
|
-
watch,
|
|
97
|
-
sourcemap,
|
|
98
|
-
minify,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
const type = options.type;
|
|
103
|
-
const input = options.input;
|
|
104
|
-
const output = options.output;
|
|
105
|
-
|
|
106
|
-
if (!type) {
|
|
107
|
-
log(`Extension type has to be specified using the ${chalk.blue('[-t, --type <type>]')} option.`, 'error');
|
|
108
|
-
process.exit(1);
|
|
109
|
-
} else if (!isIn(type, EXTENSION_TYPES)) {
|
|
110
|
-
log(
|
|
111
|
-
`Extension type ${chalk.bold(type)} is not supported. Available extension types: ${EXTENSION_TYPES.map((t) =>
|
|
112
|
-
chalk.bold.magenta(t)
|
|
113
|
-
).join(', ')}.`,
|
|
114
|
-
'error'
|
|
115
|
-
);
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (!input) {
|
|
120
|
-
log(`Extension entrypoint has to be specified using the ${chalk.blue('[-i, --input <file>]')} option.`, 'error');
|
|
121
|
-
process.exit(1);
|
|
122
|
-
}
|
|
123
|
-
if (!output) {
|
|
124
|
-
log(
|
|
125
|
-
`Extension output file has to be specified using the ${chalk.blue('[-o, --output <file>]')} option.`,
|
|
126
|
-
'error'
|
|
127
|
-
);
|
|
128
|
-
process.exit(1);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (isIn(type, HYBRID_EXTENSION_TYPES)) {
|
|
132
|
-
const inputObject = toObject(input);
|
|
133
|
-
const outputObject = toObject(output);
|
|
134
|
-
|
|
135
|
-
if (!inputObject || !inputObject.app || !inputObject.api) {
|
|
136
|
-
log(
|
|
137
|
-
`Input option needs to be of the format ${chalk.blue('[-i app:<app-entrypoint>,api:<api-entrypoint>]')}.`,
|
|
138
|
-
'error'
|
|
139
|
-
);
|
|
140
|
-
process.exit(1);
|
|
141
|
-
}
|
|
142
|
-
if (!outputObject || !outputObject.app || !outputObject.api) {
|
|
143
|
-
log(
|
|
144
|
-
`Output option needs to be of the format ${chalk.blue('[-o app:<app-output-file>,api:<api-output-file>]')}.`,
|
|
145
|
-
'error'
|
|
146
|
-
);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
await buildHybridExtension({
|
|
151
|
-
inputApp: inputObject.app,
|
|
152
|
-
inputApi: inputObject.api,
|
|
153
|
-
outputApp: outputObject.app,
|
|
154
|
-
outputApi: outputObject.api,
|
|
155
|
-
watch,
|
|
156
|
-
sourcemap,
|
|
157
|
-
minify,
|
|
158
|
-
});
|
|
159
|
-
} else {
|
|
160
|
-
await buildAppOrApiExtension({
|
|
161
|
-
type,
|
|
162
|
-
input,
|
|
163
|
-
output,
|
|
164
|
-
watch,
|
|
165
|
-
sourcemap,
|
|
166
|
-
minify,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async function buildAppOrApiExtension({
|
|
173
|
-
type,
|
|
174
|
-
input,
|
|
175
|
-
output,
|
|
176
|
-
watch,
|
|
177
|
-
sourcemap,
|
|
178
|
-
minify,
|
|
179
|
-
}: {
|
|
180
|
-
type: AppExtensionType | ApiExtensionType;
|
|
181
|
-
input: string;
|
|
182
|
-
output: string;
|
|
183
|
-
watch: boolean;
|
|
184
|
-
sourcemap: boolean;
|
|
185
|
-
minify: boolean;
|
|
186
|
-
}) {
|
|
187
|
-
if (!(await fse.pathExists(input)) || !(await fse.stat(input)).isFile()) {
|
|
188
|
-
log(`Entrypoint ${chalk.bold(input)} does not exist.`, 'error');
|
|
189
|
-
process.exit(1);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (output.length === 0) {
|
|
193
|
-
log(`Output file can not be empty.`, 'error');
|
|
194
|
-
process.exit(1);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const language = getLanguageFromPath(input);
|
|
198
|
-
|
|
199
|
-
if (!isLanguage(language)) {
|
|
200
|
-
log(`Language ${chalk.bold(language)} is not supported.`, 'error');
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const config = await loadConfig();
|
|
205
|
-
const plugins = config.plugins ?? [];
|
|
206
|
-
|
|
207
|
-
const mode = isIn(type, APP_EXTENSION_TYPES) ? 'browser' : 'node';
|
|
208
|
-
|
|
209
|
-
const rollupOptions = getRollupOptions({ mode, input, language, sourcemap, minify, plugins });
|
|
210
|
-
const rollupOutputOptions = getRollupOutputOptions({ mode, output, sourcemap });
|
|
211
|
-
|
|
212
|
-
if (watch) {
|
|
213
|
-
await watchExtension({ rollupOptions, rollupOutputOptions });
|
|
214
|
-
} else {
|
|
215
|
-
await buildExtension({ rollupOptions, rollupOutputOptions });
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
async function buildHybridExtension({
|
|
220
|
-
inputApp,
|
|
221
|
-
inputApi,
|
|
222
|
-
outputApp,
|
|
223
|
-
outputApi,
|
|
224
|
-
watch,
|
|
225
|
-
sourcemap,
|
|
226
|
-
minify,
|
|
227
|
-
}: {
|
|
228
|
-
inputApp: string;
|
|
229
|
-
inputApi: string;
|
|
230
|
-
outputApp: string;
|
|
231
|
-
outputApi: string;
|
|
232
|
-
watch: boolean;
|
|
233
|
-
sourcemap: boolean;
|
|
234
|
-
minify: boolean;
|
|
235
|
-
}) {
|
|
236
|
-
if (!(await fse.pathExists(inputApp)) || !(await fse.stat(inputApp)).isFile()) {
|
|
237
|
-
log(`App entrypoint ${chalk.bold(inputApp)} does not exist.`, 'error');
|
|
238
|
-
process.exit(1);
|
|
239
|
-
}
|
|
240
|
-
if (!(await fse.pathExists(inputApi)) || !(await fse.stat(inputApi)).isFile()) {
|
|
241
|
-
log(`API entrypoint ${chalk.bold(inputApi)} does not exist.`, 'error');
|
|
242
|
-
process.exit(1);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (outputApp.length === 0) {
|
|
246
|
-
log(`App output file can not be empty.`, 'error');
|
|
247
|
-
process.exit(1);
|
|
248
|
-
}
|
|
249
|
-
if (outputApi.length === 0) {
|
|
250
|
-
log(`API output file can not be empty.`, 'error');
|
|
251
|
-
process.exit(1);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const languageApp = getLanguageFromPath(inputApp);
|
|
255
|
-
const languageApi = getLanguageFromPath(inputApi);
|
|
256
|
-
|
|
257
|
-
if (!isLanguage(languageApp)) {
|
|
258
|
-
log(`App language ${chalk.bold(languageApp)} is not supported.`, 'error');
|
|
259
|
-
process.exit(1);
|
|
260
|
-
}
|
|
261
|
-
if (!isLanguage(languageApi)) {
|
|
262
|
-
log(`API language ${chalk.bold(languageApp)} is not supported.`, 'error');
|
|
263
|
-
process.exit(1);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const config = await loadConfig();
|
|
267
|
-
const plugins = config.plugins ?? [];
|
|
268
|
-
|
|
269
|
-
const rollupOptionsApp = getRollupOptions({
|
|
270
|
-
mode: 'browser',
|
|
271
|
-
input: inputApp,
|
|
272
|
-
language: languageApp,
|
|
273
|
-
sourcemap,
|
|
274
|
-
minify,
|
|
275
|
-
plugins,
|
|
276
|
-
});
|
|
277
|
-
const rollupOptionsApi = getRollupOptions({
|
|
278
|
-
mode: 'node',
|
|
279
|
-
input: inputApi,
|
|
280
|
-
language: languageApi,
|
|
281
|
-
sourcemap,
|
|
282
|
-
minify,
|
|
283
|
-
plugins,
|
|
284
|
-
});
|
|
285
|
-
const rollupOutputOptionsApp = getRollupOutputOptions({ mode: 'browser', output: outputApp, sourcemap });
|
|
286
|
-
const rollupOutputOptionsApi = getRollupOutputOptions({ mode: 'node', output: outputApi, sourcemap });
|
|
287
|
-
|
|
288
|
-
const rollupOptionsAll = [
|
|
289
|
-
{ rollupOptions: rollupOptionsApp, rollupOutputOptions: rollupOutputOptionsApp },
|
|
290
|
-
{ rollupOptions: rollupOptionsApi, rollupOutputOptions: rollupOutputOptionsApi },
|
|
291
|
-
];
|
|
292
|
-
|
|
293
|
-
if (watch) {
|
|
294
|
-
await watchExtension(rollupOptionsAll);
|
|
295
|
-
} else {
|
|
296
|
-
await buildExtension(rollupOptionsAll);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async function buildExtension(config: RollupConfig | RollupConfig[]) {
|
|
301
|
-
const configs = Array.isArray(config) ? config : [config];
|
|
302
|
-
|
|
303
|
-
const spinner = ora(chalk.bold('Building Directus extension...')).start();
|
|
304
|
-
|
|
305
|
-
const result = await Promise.all(
|
|
306
|
-
configs.map(async (c) => {
|
|
307
|
-
try {
|
|
308
|
-
const bundle = await rollup(c.rollupOptions);
|
|
309
|
-
|
|
310
|
-
await bundle.write(c.rollupOutputOptions);
|
|
311
|
-
await bundle.close();
|
|
312
|
-
} catch (error) {
|
|
313
|
-
return formatRollupError(error as RollupError);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return null;
|
|
317
|
-
})
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
const resultErrors = result.filter((r) => r !== null);
|
|
321
|
-
|
|
322
|
-
if (resultErrors.length > 0) {
|
|
323
|
-
spinner.fail(chalk.bold('Failed'));
|
|
324
|
-
|
|
325
|
-
log(resultErrors.join('\n\n'));
|
|
326
|
-
|
|
327
|
-
process.exit(1);
|
|
328
|
-
} else {
|
|
329
|
-
spinner.succeed(chalk.bold('Done'));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
async function watchExtension(config: RollupConfig | RollupConfig[]) {
|
|
334
|
-
const configs = Array.isArray(config) ? config : [config];
|
|
335
|
-
|
|
336
|
-
const spinner = ora(chalk.bold('Building Directus extension...'));
|
|
337
|
-
|
|
338
|
-
let buildCount = 0;
|
|
339
|
-
|
|
340
|
-
for (const c of configs) {
|
|
341
|
-
const watcher = rollupWatch({
|
|
342
|
-
...c.rollupOptions,
|
|
343
|
-
output: c.rollupOutputOptions,
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
watcher.on('event', async (event) => {
|
|
347
|
-
switch (event.code) {
|
|
348
|
-
case 'BUNDLE_START':
|
|
349
|
-
if (buildCount === 0) {
|
|
350
|
-
clear();
|
|
351
|
-
spinner.start();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
buildCount++;
|
|
355
|
-
break;
|
|
356
|
-
case 'BUNDLE_END':
|
|
357
|
-
await event.result.close();
|
|
358
|
-
|
|
359
|
-
buildCount--;
|
|
360
|
-
|
|
361
|
-
if (buildCount === 0) {
|
|
362
|
-
spinner.succeed(chalk.bold('Done'));
|
|
363
|
-
log(chalk.bold.green('Watching files for changes...'));
|
|
364
|
-
}
|
|
365
|
-
break;
|
|
366
|
-
case 'ERROR': {
|
|
367
|
-
buildCount--;
|
|
368
|
-
|
|
369
|
-
spinner.fail(chalk.bold('Failed'));
|
|
370
|
-
log(formatRollupError(event.error));
|
|
371
|
-
|
|
372
|
-
if (buildCount > 0) {
|
|
373
|
-
spinner.start();
|
|
374
|
-
}
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function getRollupOptions({
|
|
383
|
-
mode,
|
|
384
|
-
input,
|
|
385
|
-
language,
|
|
386
|
-
sourcemap,
|
|
387
|
-
minify,
|
|
388
|
-
plugins,
|
|
389
|
-
}: {
|
|
390
|
-
mode: RollupMode;
|
|
391
|
-
input: string;
|
|
392
|
-
language: Language;
|
|
393
|
-
sourcemap: boolean;
|
|
394
|
-
minify: boolean;
|
|
395
|
-
plugins: Plugin[];
|
|
396
|
-
}): RollupOptions {
|
|
397
|
-
if (mode === 'browser') {
|
|
398
|
-
return {
|
|
399
|
-
input,
|
|
400
|
-
external: APP_SHARED_DEPS,
|
|
401
|
-
plugins: [
|
|
402
|
-
vue({ preprocessStyles: true }) as Plugin,
|
|
403
|
-
language === 'typescript' ? typescript({ check: false }) : null,
|
|
404
|
-
styles(),
|
|
405
|
-
...plugins,
|
|
406
|
-
nodeResolve({ browser: true }),
|
|
407
|
-
commonjs({ esmExternals: true, sourceMap: sourcemap }),
|
|
408
|
-
json(),
|
|
409
|
-
replace({
|
|
410
|
-
values: {
|
|
411
|
-
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
412
|
-
},
|
|
413
|
-
preventAssignment: true,
|
|
414
|
-
}),
|
|
415
|
-
minify ? terser() : null,
|
|
416
|
-
],
|
|
417
|
-
};
|
|
418
|
-
} else {
|
|
419
|
-
return {
|
|
420
|
-
input,
|
|
421
|
-
external: API_SHARED_DEPS,
|
|
422
|
-
plugins: [
|
|
423
|
-
language === 'typescript' ? typescript({ check: false }) : null,
|
|
424
|
-
...plugins,
|
|
425
|
-
nodeResolve(),
|
|
426
|
-
commonjs({ sourceMap: sourcemap }),
|
|
427
|
-
json(),
|
|
428
|
-
replace({
|
|
429
|
-
values: {
|
|
430
|
-
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
431
|
-
},
|
|
432
|
-
preventAssignment: true,
|
|
433
|
-
}),
|
|
434
|
-
minify ? terser() : null,
|
|
435
|
-
],
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function getRollupOutputOptions({
|
|
441
|
-
mode,
|
|
442
|
-
output,
|
|
443
|
-
sourcemap,
|
|
444
|
-
}: {
|
|
445
|
-
mode: RollupMode;
|
|
446
|
-
output: string;
|
|
447
|
-
sourcemap: boolean;
|
|
448
|
-
}): RollupOutputOptions {
|
|
449
|
-
if (mode === 'browser') {
|
|
450
|
-
return {
|
|
451
|
-
file: output,
|
|
452
|
-
format: 'es',
|
|
453
|
-
inlineDynamicImports: true,
|
|
454
|
-
sourcemap,
|
|
455
|
-
};
|
|
456
|
-
} else {
|
|
457
|
-
return {
|
|
458
|
-
file: output,
|
|
459
|
-
format: 'cjs',
|
|
460
|
-
exports: 'default',
|
|
461
|
-
inlineDynamicImports: true,
|
|
462
|
-
sourcemap,
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
function formatRollupError(error: RollupError): string {
|
|
468
|
-
let message = '';
|
|
469
|
-
|
|
470
|
-
message += `${chalk.bold.red(`[${error.name}]`)} ${error.message}${
|
|
471
|
-
error.plugin ? ` (plugin ${error.plugin})` : ''
|
|
472
|
-
}\n`;
|
|
473
|
-
|
|
474
|
-
if (error.url) {
|
|
475
|
-
message += '\n' + chalk.green(error.url);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
if (error.loc) {
|
|
479
|
-
message += '\n' + chalk.green(`${error.loc.file ?? error.id}:${error.loc.line}:${error.loc.column}`);
|
|
480
|
-
} else if (error.id) {
|
|
481
|
-
message += '\n' + chalk.green(error.id);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
if (error.frame) {
|
|
485
|
-
message += '\n' + chalk.dim(error.frame);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
if (error.stack) {
|
|
489
|
-
message += '\n' + chalk.dim(error.stack);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
return message;
|
|
493
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import fse from 'fs-extra';
|
|
4
|
-
import execa from 'execa';
|
|
5
|
-
import ora from 'ora';
|
|
6
|
-
import {
|
|
7
|
-
EXTENSION_TYPES,
|
|
8
|
-
EXTENSION_PKG_KEY,
|
|
9
|
-
EXTENSION_LANGUAGES,
|
|
10
|
-
HYBRID_EXTENSION_TYPES,
|
|
11
|
-
API_OR_HYBRID_EXTENSION_TYPES,
|
|
12
|
-
APP_OR_HYBRID_EXTENSION_TYPES,
|
|
13
|
-
EXTENSION_NAME_REGEX,
|
|
14
|
-
} from '@directus/shared/constants';
|
|
15
|
-
import { isIn } from '@directus/shared/utils';
|
|
16
|
-
import { ExtensionType } from '@directus/shared/types';
|
|
17
|
-
import { log } from '../utils/logger';
|
|
18
|
-
import { isLanguage, languageToShort } from '../utils/languages';
|
|
19
|
-
import renameMap from '../utils/rename-map';
|
|
20
|
-
import { Language } from '../types';
|
|
21
|
-
import getPackageVersion from '../utils/get-package-version';
|
|
22
|
-
|
|
23
|
-
const pkg = require('../../../../package.json');
|
|
24
|
-
|
|
25
|
-
const TEMPLATE_PATH = path.resolve(__dirname, '../../../../templates');
|
|
26
|
-
|
|
27
|
-
type CreateOptions = { language: string };
|
|
28
|
-
|
|
29
|
-
export default async function create(type: string, name: string, options: CreateOptions): Promise<void> {
|
|
30
|
-
const targetDir = name.substring(name.lastIndexOf('/') + 1);
|
|
31
|
-
const targetPath = path.resolve(targetDir);
|
|
32
|
-
|
|
33
|
-
if (!isIn(type, EXTENSION_TYPES)) {
|
|
34
|
-
log(
|
|
35
|
-
`Extension type ${chalk.bold(type)} is not supported. Available extension types: ${EXTENSION_TYPES.map((t) =>
|
|
36
|
-
chalk.bold.magenta(t)
|
|
37
|
-
).join(', ')}.`,
|
|
38
|
-
'error'
|
|
39
|
-
);
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (targetDir.length === 0) {
|
|
44
|
-
log(`Extension name can not be empty.`, 'error');
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (await fse.pathExists(targetPath)) {
|
|
49
|
-
const info = await fse.stat(targetPath);
|
|
50
|
-
|
|
51
|
-
if (!info.isDirectory()) {
|
|
52
|
-
log(`Destination ${chalk.bold(targetDir)} already exists and is not a directory.`, 'error');
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const files = await fse.readdir(targetPath);
|
|
57
|
-
|
|
58
|
-
if (files.length > 0) {
|
|
59
|
-
log(`Destination ${chalk.bold(targetDir)} already exists and is not empty.`, 'error');
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!isLanguage(options.language)) {
|
|
65
|
-
log(
|
|
66
|
-
`Language ${chalk.bold(options.language)} is not supported. Available languages: ${EXTENSION_LANGUAGES.map((t) =>
|
|
67
|
-
chalk.bold.magenta(t)
|
|
68
|
-
).join(', ')}.`,
|
|
69
|
-
'error'
|
|
70
|
-
);
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const spinner = ora(chalk.bold('Scaffolding Directus extension...')).start();
|
|
75
|
-
|
|
76
|
-
await fse.ensureDir(targetPath);
|
|
77
|
-
|
|
78
|
-
await fse.copy(path.join(TEMPLATE_PATH, 'common', options.language), targetPath);
|
|
79
|
-
await fse.copy(path.join(TEMPLATE_PATH, type, options.language), targetPath);
|
|
80
|
-
await renameMap(targetPath, (name) => (name.startsWith('_') ? `.${name.substring(1)}` : null));
|
|
81
|
-
|
|
82
|
-
const entryPath = isIn(type, HYBRID_EXTENSION_TYPES) ? { app: 'dist/app.js', api: 'dist/api.js' } : 'dist/index.js';
|
|
83
|
-
const sourcePath = isIn(type, HYBRID_EXTENSION_TYPES)
|
|
84
|
-
? { app: `src/app.${languageToShort(options.language)}`, api: `src/api.${languageToShort(options.language)}` }
|
|
85
|
-
: `src/index.${languageToShort(options.language)}`;
|
|
86
|
-
|
|
87
|
-
const packageManifest = {
|
|
88
|
-
name: EXTENSION_NAME_REGEX.test(name) ? name : `directus-extension-${name}`,
|
|
89
|
-
version: '1.0.0',
|
|
90
|
-
keywords: ['directus', 'directus-extension', `directus-custom-${type}`],
|
|
91
|
-
[EXTENSION_PKG_KEY]: {
|
|
92
|
-
type,
|
|
93
|
-
path: entryPath,
|
|
94
|
-
source: sourcePath,
|
|
95
|
-
host: `^${pkg.version}`,
|
|
96
|
-
},
|
|
97
|
-
scripts: {
|
|
98
|
-
build: 'directus-extension build',
|
|
99
|
-
dev: 'directus-extension build -w --no-minify',
|
|
100
|
-
},
|
|
101
|
-
devDependencies: await getPackageDeps(type, options.language),
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
await fse.writeJSON(path.join(targetPath, 'package.json'), packageManifest, { spaces: '\t' });
|
|
105
|
-
|
|
106
|
-
await execa('npm', ['install'], { cwd: targetPath });
|
|
107
|
-
|
|
108
|
-
spinner.succeed(chalk.bold('Done'));
|
|
109
|
-
|
|
110
|
-
log(`
|
|
111
|
-
Your ${type} extension has been created at ${chalk.green(targetPath)}
|
|
112
|
-
|
|
113
|
-
To start developing, run:
|
|
114
|
-
${chalk.blue('cd')} ${targetDir}
|
|
115
|
-
${chalk.blue('npm run')} dev
|
|
116
|
-
|
|
117
|
-
and then to build for production, run:
|
|
118
|
-
${chalk.blue('npm run')} build
|
|
119
|
-
`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function getPackageDeps(type: ExtensionType, language: Language) {
|
|
123
|
-
return {
|
|
124
|
-
'@directus/extensions-sdk': pkg.version,
|
|
125
|
-
...(language === 'typescript'
|
|
126
|
-
? {
|
|
127
|
-
...(isIn(type, API_OR_HYBRID_EXTENSION_TYPES)
|
|
128
|
-
? { '@types/node': `^${await getPackageVersion('@types/node')}` }
|
|
129
|
-
: {}),
|
|
130
|
-
typescript: `^${await getPackageVersion('typescript')}`,
|
|
131
|
-
}
|
|
132
|
-
: {}),
|
|
133
|
-
...(isIn(type, APP_OR_HYBRID_EXTENSION_TYPES) ? { vue: `^${await getPackageVersion('vue')}` } : {}),
|
|
134
|
-
};
|
|
135
|
-
}
|
package/src/cli/index.ts
DELETED
package/src/cli/run.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import create from './commands/create';
|
|
3
|
-
import build from './commands/build';
|
|
4
|
-
|
|
5
|
-
const pkg = require('../../../package.json');
|
|
6
|
-
|
|
7
|
-
const program = new Command();
|
|
8
|
-
|
|
9
|
-
program.name('directus-extension').usage('[command] [options]');
|
|
10
|
-
program.version(pkg.version, '-v, --version');
|
|
11
|
-
|
|
12
|
-
program
|
|
13
|
-
.command('create')
|
|
14
|
-
.arguments('<type> <name>')
|
|
15
|
-
.description('Scaffold a new Directus extension')
|
|
16
|
-
.option('-l, --language <language>', 'specify the language to use', 'javascript')
|
|
17
|
-
.action(create);
|
|
18
|
-
|
|
19
|
-
program
|
|
20
|
-
.command('build')
|
|
21
|
-
.description('Bundle a Directus extension to a single entrypoint')
|
|
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
|
-
.option('-w, --watch', 'watch and rebuild on changes')
|
|
28
|
-
.option('--no-minify', 'disable minification')
|
|
29
|
-
.option('--sourcemap', 'include source maps in output')
|
|
30
|
-
.action(build);
|
|
31
|
-
|
|
32
|
-
program.parse(process.argv);
|
package/src/cli/types.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { EXTENSION_LANGUAGES } from '@directus/shared/constants';
|
|
2
|
-
import { Plugin, RollupOptions, OutputOptions as RollupOutputOptions } from 'rollup';
|
|
3
|
-
|
|
4
|
-
export type Language = typeof EXTENSION_LANGUAGES[number];
|
|
5
|
-
export type LanguageShort = 'js' | 'ts';
|
|
6
|
-
|
|
7
|
-
export type Config = {
|
|
8
|
-
plugins?: Plugin[];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type RollupConfig = { rollupOptions: RollupOptions; rollupOutputOptions: RollupOutputOptions };
|
|
12
|
-
export type RollupMode = 'browser' | 'node';
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import execa from 'execa';
|
|
2
|
-
|
|
3
|
-
export default async function getPackageVersion(name: string, tag = 'latest'): Promise<string> {
|
|
4
|
-
const npmView = await execa('npm', ['view', name, '--json']);
|
|
5
|
-
|
|
6
|
-
const packageInfo = JSON.parse(npmView.stdout);
|
|
7
|
-
|
|
8
|
-
return packageInfo['dist-tags'][tag];
|
|
9
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { EXTENSION_LANGUAGES } from '@directus/shared/constants';
|
|
2
|
-
import { Language, LanguageShort } from '../types';
|
|
3
|
-
|
|
4
|
-
export function isLanguage(language: string): language is Language {
|
|
5
|
-
return (EXTENSION_LANGUAGES as readonly string[]).includes(language);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function languageToShort(language: Language): LanguageShort {
|
|
9
|
-
if (language === 'javascript') {
|
|
10
|
-
return 'js';
|
|
11
|
-
} else {
|
|
12
|
-
return 'ts';
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getLanguageFromPath(path: string): string {
|
|
17
|
-
const fileExtension = path.substring(path.lastIndexOf('.') + 1);
|
|
18
|
-
|
|
19
|
-
if (fileExtension === 'js') {
|
|
20
|
-
return 'javascript';
|
|
21
|
-
} else if (fileExtension === 'ts') {
|
|
22
|
-
return 'typescript';
|
|
23
|
-
} else {
|
|
24
|
-
return fileExtension;
|
|
25
|
-
}
|
|
26
|
-
}
|