@directus/extensions-sdk 10.2.0 → 10.3.1
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/cli/commands/add.d.ts +5 -1
- package/dist/cli/commands/add.js +45 -12
- package/dist/cli/commands/build.js +24 -6
- package/dist/cli/commands/create.d.ts +1 -0
- package/dist/cli/commands/create.js +23 -12
- package/dist/cli/run.js +6 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +26 -25
- package/templates/theme/javascript/source/index.js +1 -0
- package/templates/theme/typescript/source/index.ts +1 -0
package/dist/cli/commands/add.js
CHANGED
|
@@ -13,24 +13,34 @@ import { getLanguageFromPath, isLanguage, languageToShort } from '../utils/langu
|
|
|
13
13
|
import { log } from '../utils/logger.js';
|
|
14
14
|
import copyTemplate from './helpers/copy-template.js';
|
|
15
15
|
import getExtensionDevDeps from './helpers/get-extension-dev-deps.js';
|
|
16
|
-
export default async function add() {
|
|
16
|
+
export default async function add(options) {
|
|
17
|
+
const install = options.install ?? true;
|
|
17
18
|
const extensionPath = process.cwd();
|
|
18
19
|
const packagePath = path.resolve('package.json');
|
|
19
20
|
if (!(await fse.pathExists(packagePath))) {
|
|
20
|
-
log(`Current directory is not a valid
|
|
21
|
+
log(`Current directory is not a valid Directus extension:`, 'error');
|
|
22
|
+
log(`Missing "package.json" file.`, 'error');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
let extensionManifestFile;
|
|
26
|
+
try {
|
|
27
|
+
extensionManifestFile = await fse.readFile(packagePath, 'utf8');
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
log(`Failed to read "package.json" file from current directory.`, 'error');
|
|
21
31
|
process.exit(1);
|
|
22
32
|
}
|
|
23
33
|
let extensionManifest;
|
|
24
|
-
let indent = null;
|
|
25
34
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
indent = detectJsonIndent(extensionManifestFile);
|
|
35
|
+
extensionManifest = JSON.parse(extensionManifestFile);
|
|
36
|
+
ExtensionManifest.parse(extensionManifest);
|
|
29
37
|
}
|
|
30
|
-
catch
|
|
31
|
-
log(`Current directory is not a valid Directus extension
|
|
38
|
+
catch {
|
|
39
|
+
log(`Current directory is not a valid Directus extension:`, 'error');
|
|
40
|
+
log(`Invalid "package.json" file.`, 'error');
|
|
32
41
|
process.exit(1);
|
|
33
42
|
}
|
|
43
|
+
const indent = detectJsonIndent(extensionManifestFile);
|
|
34
44
|
const extensionOptions = extensionManifest[EXTENSION_PKG_KEY];
|
|
35
45
|
const sourceExists = await fse.pathExists(path.resolve('src'));
|
|
36
46
|
if (extensionOptions.type === 'bundle') {
|
|
@@ -60,6 +70,11 @@ export default async function add() {
|
|
|
60
70
|
when: !sourceExists && extensionOptions.entries.length > 0,
|
|
61
71
|
},
|
|
62
72
|
]);
|
|
73
|
+
const bundleEntryNames = new Set(extensionOptions.entries.map((entry) => entry.name));
|
|
74
|
+
if (bundleEntryNames.has(name)) {
|
|
75
|
+
log(`Extension ${chalk.bold(name)} already exists for this bundle.`, 'error');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
63
78
|
const spinner = ora(chalk.bold('Modifying Directus extension...')).start();
|
|
64
79
|
const source = alternativeSource ?? 'src';
|
|
65
80
|
const sourcePath = path.resolve(source, name);
|
|
@@ -86,12 +101,21 @@ export default async function add() {
|
|
|
86
101
|
const newExtensionManifest = {
|
|
87
102
|
...extensionManifest,
|
|
88
103
|
[EXTENSION_PKG_KEY]: newExtensionOptions,
|
|
89
|
-
devDependencies:
|
|
104
|
+
devDependencies: {
|
|
105
|
+
...extensionManifest.devDependencies,
|
|
106
|
+
...(await getExtensionDevDeps(newEntries.map((entry) => entry.type), getLanguageFromEntries(newEntries))),
|
|
107
|
+
},
|
|
90
108
|
};
|
|
91
109
|
await fse.writeJSON(packagePath, newExtensionManifest, { spaces: indent ?? '\t' });
|
|
92
110
|
const packageManager = getPackageManager();
|
|
93
|
-
|
|
111
|
+
if (install) {
|
|
112
|
+
await execa(packageManager, ['install'], { cwd: extensionPath });
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
spinner.info(`Dependency installation skipped, to install run: ${chalk.blue(`${packageManager}`)} install`);
|
|
116
|
+
}
|
|
94
117
|
spinner.succeed(chalk.bold('Done'));
|
|
118
|
+
log(`Your ${type} extension has been added.`);
|
|
95
119
|
}
|
|
96
120
|
else {
|
|
97
121
|
const { proceed } = await inquirer.prompt([
|
|
@@ -197,12 +221,21 @@ export default async function add() {
|
|
|
197
221
|
name: EXTENSION_NAME_REGEX.test(extensionName) ? extensionName : `directus-extension-${extensionName}`,
|
|
198
222
|
keywords: ['directus', 'directus-extension', `directus-custom-bundle`],
|
|
199
223
|
[EXTENSION_PKG_KEY]: newExtensionOptions,
|
|
200
|
-
devDependencies:
|
|
224
|
+
devDependencies: {
|
|
225
|
+
...extensionManifest.devDependencies,
|
|
226
|
+
...(await getExtensionDevDeps(entries.map((entry) => entry.type), getLanguageFromEntries(entries))),
|
|
227
|
+
},
|
|
201
228
|
};
|
|
202
229
|
await fse.writeJSON(packagePath, newExtensionManifest, { spaces: indent ?? '\t' });
|
|
203
230
|
const packageManager = getPackageManager();
|
|
204
|
-
|
|
231
|
+
if (install) {
|
|
232
|
+
await execa(packageManager, ['install'], { cwd: extensionPath });
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
spinner.info(`Dependency installation skipped, to install run: ${chalk.blue(`${packageManager}`)} install`);
|
|
236
|
+
}
|
|
205
237
|
spinner.succeed(chalk.bold('Done'));
|
|
238
|
+
log(`Your ${type} extension has been added.`);
|
|
206
239
|
}
|
|
207
240
|
}
|
|
208
241
|
function getLanguageFromEntries(entries) {
|
|
@@ -6,7 +6,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
|
6
6
|
import replaceDefault from '@rollup/plugin-replace';
|
|
7
7
|
import terserDefault from '@rollup/plugin-terser';
|
|
8
8
|
import virtualDefault from '@rollup/plugin-virtual';
|
|
9
|
-
import
|
|
9
|
+
import vue from '@vitejs/plugin-vue';
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import fse from 'fs-extra';
|
|
12
12
|
import ora from 'ora';
|
|
@@ -22,7 +22,6 @@ import loadConfig from './helpers/load-config.js';
|
|
|
22
22
|
import { validateSplitEntrypointOption } from './helpers/validate-cli-options.js';
|
|
23
23
|
// Workaround for https://github.com/rollup/plugins/issues/1329
|
|
24
24
|
const virtual = virtualDefault;
|
|
25
|
-
const vue = vueDefault;
|
|
26
25
|
const esbuild = esbuildDefault;
|
|
27
26
|
const styles = stylesDefault;
|
|
28
27
|
const commonjs = commonjsDefault;
|
|
@@ -36,15 +35,26 @@ export default async function build(options) {
|
|
|
36
35
|
if (!options.type && !options.input && !options.output) {
|
|
37
36
|
const packagePath = path.resolve('package.json');
|
|
38
37
|
if (!(await fse.pathExists(packagePath))) {
|
|
39
|
-
log(`Current directory is not a valid
|
|
38
|
+
log(`Current directory is not a valid Directus extension:`, 'error');
|
|
39
|
+
log(`Missing "package.json" file.`, 'error');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
let extensionManifestFile;
|
|
43
|
+
try {
|
|
44
|
+
extensionManifestFile = await fse.readFile(packagePath, 'utf8');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
log(`Failed to read "package.json" file from current directory.`, 'error');
|
|
40
48
|
process.exit(1);
|
|
41
49
|
}
|
|
42
50
|
let extensionManifest;
|
|
43
51
|
try {
|
|
44
|
-
extensionManifest =
|
|
52
|
+
extensionManifest = JSON.parse(extensionManifestFile);
|
|
53
|
+
ExtensionManifest.parse(extensionManifest);
|
|
45
54
|
}
|
|
46
|
-
catch
|
|
47
|
-
log(`Current directory is not a valid Directus extension
|
|
55
|
+
catch {
|
|
56
|
+
log(`Current directory is not a valid Directus extension:`, 'error');
|
|
57
|
+
log(`Invalid "package.json" file.`, 'error');
|
|
48
58
|
process.exit(1);
|
|
49
59
|
}
|
|
50
60
|
const extensionOptions = extensionManifest[EXTENSION_PKG_KEY];
|
|
@@ -236,6 +246,14 @@ async function buildBundleExtension({ entries, outputApp, outputApi, format, wat
|
|
|
236
246
|
log(`API output file can not be empty.`, 'error');
|
|
237
247
|
process.exit(1);
|
|
238
248
|
}
|
|
249
|
+
const bundleEntryNames = new Set();
|
|
250
|
+
for (const { name } of entries) {
|
|
251
|
+
if (bundleEntryNames.has(name)) {
|
|
252
|
+
log(`Duplicate extension found in bundle for ${chalk.bold(name)}.`, 'error');
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
bundleEntryNames.add(name);
|
|
256
|
+
}
|
|
239
257
|
const config = await loadConfig();
|
|
240
258
|
const plugins = config.plugins ?? [];
|
|
241
259
|
const entrypointApp = generateBundleEntrypoint('app', entries);
|
|
@@ -12,6 +12,7 @@ import { log } from '../utils/logger.js';
|
|
|
12
12
|
import copyTemplate from './helpers/copy-template.js';
|
|
13
13
|
import getExtensionDevDeps from './helpers/get-extension-dev-deps.js';
|
|
14
14
|
export default async function create(type, name, options) {
|
|
15
|
+
const install = options.install ?? true;
|
|
15
16
|
const targetDir = name.substring(name.lastIndexOf('/') + 1);
|
|
16
17
|
const targetPath = path.resolve(targetDir);
|
|
17
18
|
if (!isIn(type, EXTENSION_TYPES)) {
|
|
@@ -35,14 +36,14 @@ export default async function create(type, name, options) {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
if (isIn(type, BUNDLE_EXTENSION_TYPES)) {
|
|
38
|
-
await createPackageExtension({ type, name, targetDir, targetPath });
|
|
39
|
+
await createPackageExtension({ type, name, targetDir, targetPath, install });
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
42
|
const language = options.language ?? 'javascript';
|
|
42
|
-
await createLocalExtension({ type, name, targetDir, targetPath, language });
|
|
43
|
+
await createLocalExtension({ type, name, targetDir, targetPath, language, install });
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
async function createPackageExtension({ type, name, targetDir, targetPath, }) {
|
|
46
|
+
async function createPackageExtension({ type, name, targetDir, targetPath, install, }) {
|
|
46
47
|
const spinner = ora(chalk.bold('Scaffolding Directus extension...')).start();
|
|
47
48
|
await fse.ensureDir(targetPath);
|
|
48
49
|
await copyTemplate(type, targetPath);
|
|
@@ -51,11 +52,13 @@ async function createPackageExtension({ type, name, targetDir, targetPath, }) {
|
|
|
51
52
|
const packageManifest = getPackageManifest(name, options, await getExtensionDevDeps(type));
|
|
52
53
|
await fse.writeJSON(path.join(targetPath, 'package.json'), packageManifest, { spaces: '\t' });
|
|
53
54
|
const packageManager = getPackageManager();
|
|
54
|
-
|
|
55
|
+
if (install) {
|
|
56
|
+
await execa(packageManager, ['install'], { cwd: targetPath });
|
|
57
|
+
}
|
|
55
58
|
spinner.succeed(chalk.bold('Done'));
|
|
56
|
-
log(getDoneMessage(type, targetDir, targetPath, packageManager));
|
|
59
|
+
log(getDoneMessage(type, targetDir, targetPath, packageManager, install));
|
|
57
60
|
}
|
|
58
|
-
async function createLocalExtension({ type, name, targetDir, targetPath, language, }) {
|
|
61
|
+
async function createLocalExtension({ type, name, targetDir, targetPath, language, install, }) {
|
|
59
62
|
if (!isLanguage(language)) {
|
|
60
63
|
log(`Language ${chalk.bold(language)} is not supported. Available languages: ${EXTENSION_LANGUAGES.map((t) => chalk.bold.magenta(t)).join(', ')}.`, 'error');
|
|
61
64
|
process.exit(1);
|
|
@@ -80,9 +83,11 @@ async function createLocalExtension({ type, name, targetDir, targetPath, languag
|
|
|
80
83
|
const packageManifest = getPackageManifest(name, options, await getExtensionDevDeps(type, language));
|
|
81
84
|
await fse.writeJSON(path.join(targetPath, 'package.json'), packageManifest, { spaces: '\t' });
|
|
82
85
|
const packageManager = getPackageManager();
|
|
83
|
-
|
|
86
|
+
if (install) {
|
|
87
|
+
await execa(packageManager, ['install'], { cwd: targetPath });
|
|
88
|
+
}
|
|
84
89
|
spinner.succeed(chalk.bold('Done'));
|
|
85
|
-
log(getDoneMessage(type, targetDir, targetPath, packageManager));
|
|
90
|
+
log(getDoneMessage(type, targetDir, targetPath, packageManager, install));
|
|
86
91
|
}
|
|
87
92
|
function getPackageManifest(name, options, deps) {
|
|
88
93
|
const packageManifest = {
|
|
@@ -105,15 +110,21 @@ function getPackageManifest(name, options, deps) {
|
|
|
105
110
|
}
|
|
106
111
|
return packageManifest;
|
|
107
112
|
}
|
|
108
|
-
function getDoneMessage(type, targetDir, targetPath, packageManager) {
|
|
109
|
-
|
|
113
|
+
function getDoneMessage(type, targetDir, targetPath, packageManager, install) {
|
|
114
|
+
let message = `
|
|
110
115
|
Your ${type} extension has been created at ${chalk.green(targetPath)}
|
|
111
116
|
|
|
112
117
|
To start developing, run:
|
|
113
|
-
${chalk.blue('cd')} ${targetDir}
|
|
118
|
+
${chalk.blue('cd')} ${targetDir}`;
|
|
119
|
+
if (!install) {
|
|
120
|
+
message += `
|
|
121
|
+
${chalk.blue(`${packageManager}`)} install`;
|
|
122
|
+
}
|
|
123
|
+
message += `
|
|
114
124
|
${chalk.blue(`${packageManager} run`)} dev
|
|
115
125
|
|
|
116
|
-
|
|
126
|
+
To build for production, run:
|
|
117
127
|
${chalk.blue(`${packageManager} run`)} build
|
|
118
128
|
`;
|
|
129
|
+
return message;
|
|
119
130
|
}
|
package/dist/cli/run.js
CHANGED
|
@@ -11,9 +11,14 @@ program
|
|
|
11
11
|
.command('create')
|
|
12
12
|
.arguments('<type> <name>')
|
|
13
13
|
.description('Scaffold a new Directus extension')
|
|
14
|
+
.option('--no-install', 'skip dependency installation after creating extension')
|
|
14
15
|
.option('-l, --language <language>', 'specify the language to use')
|
|
15
16
|
.action(create);
|
|
16
|
-
program
|
|
17
|
+
program
|
|
18
|
+
.command('add')
|
|
19
|
+
.description('Add entries to an existing Directus extension')
|
|
20
|
+
.option('--no-install', 'skip dependency (re)installation after adding extension')
|
|
21
|
+
.action(add);
|
|
17
22
|
program
|
|
18
23
|
.command('build')
|
|
19
24
|
.description('Bundle a Directus extension to a single entrypoint')
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { useApi, useCollection, useExtensions, useFilterFields, useItems, useLayout, useStores, useSync, } from '@directus/composables';
|
|
1
|
+
export { useApi, useSdk, useCollection, useExtensions, useFilterFields, useItems, useLayout, useStores, useSync, } from '@directus/composables';
|
|
2
2
|
export { defineDisplay, defineEndpoint, defineHook, defineInterface, defineLayout, defineModule, defineOperationApi, defineOperationApp, definePanel, } from '@directus/extensions';
|
|
3
|
+
export { defineTheme } from '@directus/themes';
|
|
3
4
|
export { getFieldsFromTemplate, getRelationType } from '@directus/utils';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { useApi, useCollection, useExtensions, useFilterFields, useItems, useLayout, useStores, useSync, } from '@directus/composables';
|
|
1
|
+
export { useApi, useSdk, useCollection, useExtensions, useFilterFields, useItems, useLayout, useStores, useSync, } from '@directus/composables';
|
|
2
2
|
export { defineDisplay, defineEndpoint, defineHook, defineInterface, defineLayout, defineModule, defineOperationApi, defineOperationApp, definePanel, } from '@directus/extensions';
|
|
3
|
+
export { defineTheme } from '@directus/themes';
|
|
3
4
|
export { getFieldsFromTemplate, getRelationType } from '@directus/utils';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/extensions-sdk",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.3.1",
|
|
4
4
|
"description": "A toolkit to develop extensions to extend Directus",
|
|
5
5
|
"homepage": "https://directus.io",
|
|
6
6
|
"repository": {
|
|
@@ -26,37 +26,38 @@
|
|
|
26
26
|
"templates"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@rollup/plugin-commonjs": "25.0.
|
|
30
|
-
"@rollup/plugin-json": "6.
|
|
31
|
-
"@rollup/plugin-node-resolve": "15.
|
|
32
|
-
"@rollup/plugin-replace": "5.0.
|
|
33
|
-
"@rollup/plugin-terser": "0.4.
|
|
34
|
-
"@rollup/plugin-virtual": "3.0.
|
|
35
|
-
"@vitejs/plugin-vue": "4.2
|
|
36
|
-
"chalk": "5.
|
|
29
|
+
"@rollup/plugin-commonjs": "25.0.7",
|
|
30
|
+
"@rollup/plugin-json": "6.1.0",
|
|
31
|
+
"@rollup/plugin-node-resolve": "15.2.3",
|
|
32
|
+
"@rollup/plugin-replace": "5.0.5",
|
|
33
|
+
"@rollup/plugin-terser": "0.4.4",
|
|
34
|
+
"@rollup/plugin-virtual": "3.0.2",
|
|
35
|
+
"@vitejs/plugin-vue": "4.6.2",
|
|
36
|
+
"chalk": "5.3.0",
|
|
37
37
|
"commander": "10.0.1",
|
|
38
38
|
"esbuild": "0.17.19",
|
|
39
|
-
"execa": "7.
|
|
40
|
-
"fs-extra": "11.
|
|
41
|
-
"inquirer": "9.2.
|
|
39
|
+
"execa": "7.2.0",
|
|
40
|
+
"fs-extra": "11.2.0",
|
|
41
|
+
"inquirer": "9.2.14",
|
|
42
42
|
"ora": "6.3.1",
|
|
43
|
-
"rollup": "3.
|
|
43
|
+
"rollup": "3.29.4",
|
|
44
44
|
"rollup-plugin-esbuild": "5.0.0",
|
|
45
45
|
"rollup-plugin-styles": "4.0.0",
|
|
46
|
-
"vite": "4.
|
|
47
|
-
"vue": "3.
|
|
48
|
-
"@directus/composables": "10.1.
|
|
49
|
-
"@directus/constants": "11.0.
|
|
50
|
-
"@directus/extensions": "0.
|
|
51
|
-
"@directus/
|
|
52
|
-
"@directus/types": "11.0.
|
|
46
|
+
"vite": "4.5.2",
|
|
47
|
+
"vue": "3.4.15",
|
|
48
|
+
"@directus/composables": "10.1.8",
|
|
49
|
+
"@directus/constants": "11.0.3",
|
|
50
|
+
"@directus/extensions": "0.3.0",
|
|
51
|
+
"@directus/themes": "0.3.3",
|
|
52
|
+
"@directus/types": "11.0.4",
|
|
53
|
+
"@directus/utils": "11.0.4"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
|
-
"@types/fs-extra": "11.0.
|
|
56
|
-
"@types/inquirer": "9.0.
|
|
57
|
-
"@vitest/coverage-
|
|
58
|
-
"typescript": "5.
|
|
59
|
-
"vitest": "
|
|
56
|
+
"@types/fs-extra": "11.0.4",
|
|
57
|
+
"@types/inquirer": "9.0.7",
|
|
58
|
+
"@vitest/coverage-v8": "1.2.2",
|
|
59
|
+
"typescript": "5.3.3",
|
|
60
|
+
"vitest": "1.2.2",
|
|
60
61
|
"@directus/tsconfig": "1.0.1"
|
|
61
62
|
},
|
|
62
63
|
"engines": {
|