directus 9.4.2 → 9.4.3
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/app.js +9 -0
- package/dist/cli/index.js +1 -1
- package/dist/controllers/extensions.js +1 -1
- package/dist/database/migrations/run.js +1 -1
- package/dist/env.js +1 -0
- package/dist/extensions.d.ts +11 -6
- package/dist/extensions.js +92 -39
- package/dist/services/assets.js +3 -3
- package/dist/services/authentication.js +4 -1
- package/dist/services/graphql.js +4 -4
- package/dist/utils/get-local-type.js +1 -1
- package/package.json +13 -12
package/dist/app.js
CHANGED
|
@@ -106,6 +106,15 @@ async function createApp() {
|
|
|
106
106
|
directives: {
|
|
107
107
|
// Unsafe-eval is required for vue3 / vue-i18n / app extensions
|
|
108
108
|
scriptSrc: ["'self'", "'unsafe-eval'"],
|
|
109
|
+
// Even though this is recommended to have enabled, it breaks most local
|
|
110
|
+
// installations. Making this opt-in rather than opt-out is a little more
|
|
111
|
+
// friendly. Ref #10806
|
|
112
|
+
upgradeInsecureRequests: null,
|
|
113
|
+
// These are required for MapLibre
|
|
114
|
+
workerSrc: ["'self'", 'blob:'],
|
|
115
|
+
childSrc: ["'self'", 'blob:'],
|
|
116
|
+
imgSrc: ["'self'", 'data:', 'blob:'],
|
|
117
|
+
connectSrc: ["'self'", 'https://*'],
|
|
109
118
|
},
|
|
110
119
|
}, (0, get_config_from_env_1.getConfigFromEnv)('CONTENT_SECURITY_POLICY_'))));
|
|
111
120
|
await emitter_1.default.emitInit('app.before', { app });
|
package/dist/cli/index.js
CHANGED
|
@@ -22,7 +22,7 @@ const pkg = require('../../package.json');
|
|
|
22
22
|
async function createCli() {
|
|
23
23
|
const program = new commander_1.Command();
|
|
24
24
|
const extensionManager = (0, extensions_1.getExtensionManager)();
|
|
25
|
-
await extensionManager.initialize({ schedule: false });
|
|
25
|
+
await extensionManager.initialize({ schedule: false, watch: false });
|
|
26
26
|
await emitter_1.default.emitInit('cli.before', { program });
|
|
27
27
|
program.name('directus').usage('[command] [options]');
|
|
28
28
|
program.version(pkg.version, '-v, --version');
|
|
@@ -16,7 +16,7 @@ router.get('/:type', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
16
16
|
throw new exceptions_1.RouteNotFoundException(req.path);
|
|
17
17
|
}
|
|
18
18
|
const extensionManager = (0, extensions_1.getExtensionManager)();
|
|
19
|
-
const extensions = extensionManager.
|
|
19
|
+
const extensions = extensionManager.getExtensionsList(type);
|
|
20
20
|
res.locals.payload = {
|
|
21
21
|
data: extensions,
|
|
22
22
|
};
|
|
@@ -13,7 +13,7 @@ async function run(database, direction, log = true) {
|
|
|
13
13
|
let migrationFiles = await fs_extra_1.default.readdir(__dirname);
|
|
14
14
|
const customMigrationsPath = path_1.default.resolve(env_1.default.EXTENSIONS_PATH, 'migrations');
|
|
15
15
|
let customMigrationFiles = ((await fs_extra_1.default.pathExists(customMigrationsPath)) && (await fs_extra_1.default.readdir(customMigrationsPath))) || [];
|
|
16
|
-
migrationFiles = migrationFiles.filter((file) =>
|
|
16
|
+
migrationFiles = migrationFiles.filter((file) => /^[0-9]+[A-Z]-[^.]+\.(?:js|ts)$/.test(file));
|
|
17
17
|
customMigrationFiles = customMigrationFiles.filter((file) => file.endsWith('.js'));
|
|
18
18
|
const completedMigrations = await database.select('*').from('directus_migrations').orderBy('version');
|
|
19
19
|
const migrations = [
|
package/dist/env.js
CHANGED
package/dist/extensions.d.ts
CHANGED
|
@@ -2,22 +2,27 @@ import { Router } from 'express';
|
|
|
2
2
|
import { AppExtensionType, ExtensionType } from '@directus/shared/types';
|
|
3
3
|
export declare function getExtensionManager(): ExtensionManager;
|
|
4
4
|
declare class ExtensionManager {
|
|
5
|
-
private
|
|
5
|
+
private isLoaded;
|
|
6
|
+
private isScheduleHookEnabled;
|
|
6
7
|
private extensions;
|
|
7
8
|
private appExtensions;
|
|
8
|
-
private
|
|
9
|
-
private apiEndpoints;
|
|
9
|
+
private apiExtensions;
|
|
10
10
|
private apiEmitter;
|
|
11
11
|
private endpointRouter;
|
|
12
|
-
private
|
|
12
|
+
private watcher;
|
|
13
13
|
constructor();
|
|
14
|
-
initialize({ schedule }?: {
|
|
14
|
+
initialize({ schedule, watch }?: {
|
|
15
15
|
schedule: boolean;
|
|
16
|
+
watch: boolean;
|
|
16
17
|
}): Promise<void>;
|
|
17
18
|
reload(): Promise<void>;
|
|
18
|
-
|
|
19
|
+
getExtensionsList(type?: ExtensionType): string[];
|
|
19
20
|
getAppExtensions(type: AppExtensionType): string | undefined;
|
|
20
21
|
getEndpointRouter(): Router;
|
|
22
|
+
private load;
|
|
23
|
+
private unload;
|
|
24
|
+
private initializeWatcher;
|
|
25
|
+
private updateWatchedExtensions;
|
|
21
26
|
private getExtensions;
|
|
22
27
|
private generateExtensionBundles;
|
|
23
28
|
private getSharedDepsMapping;
|
package/dist/extensions.js
CHANGED
|
@@ -45,6 +45,8 @@ const plugin_alias_1 = __importDefault(require("@rollup/plugin-alias"));
|
|
|
45
45
|
const url_1 = require("./utils/url");
|
|
46
46
|
const get_module_default_1 = __importDefault(require("./utils/get-module-default"));
|
|
47
47
|
const lodash_1 = require("lodash");
|
|
48
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
49
|
+
const utils_1 = require("@directus/shared/utils");
|
|
48
50
|
let extensionManager;
|
|
49
51
|
function getExtensionManager() {
|
|
50
52
|
if (extensionManager) {
|
|
@@ -56,19 +58,66 @@ function getExtensionManager() {
|
|
|
56
58
|
exports.getExtensionManager = getExtensionManager;
|
|
57
59
|
class ExtensionManager {
|
|
58
60
|
constructor() {
|
|
59
|
-
this.
|
|
61
|
+
this.isLoaded = false;
|
|
62
|
+
this.isScheduleHookEnabled = true;
|
|
60
63
|
this.extensions = [];
|
|
61
64
|
this.appExtensions = {};
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
64
|
-
this.isScheduleHookEnabled = true;
|
|
65
|
+
this.apiExtensions = { hooks: [], endpoints: [] };
|
|
66
|
+
this.watcher = null;
|
|
65
67
|
this.apiEmitter = new emitter_1.Emitter();
|
|
66
68
|
this.endpointRouter = (0, express_1.Router)();
|
|
67
69
|
}
|
|
68
|
-
async initialize({ schedule } = { schedule: true }) {
|
|
70
|
+
async initialize({ schedule, watch } = { schedule: true, watch: true }) {
|
|
69
71
|
this.isScheduleHookEnabled = schedule;
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
+
if (watch) {
|
|
73
|
+
this.initializeWatcher();
|
|
74
|
+
}
|
|
75
|
+
if (!this.isLoaded) {
|
|
76
|
+
await this.load();
|
|
77
|
+
this.updateWatchedExtensions(this.extensions);
|
|
78
|
+
const loadedExtensions = this.getExtensionsList();
|
|
79
|
+
if (loadedExtensions.length > 0) {
|
|
80
|
+
logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async reload() {
|
|
85
|
+
if (this.isLoaded) {
|
|
86
|
+
logger_1.default.info('Reloading extensions');
|
|
87
|
+
const prevExtensions = (0, lodash_1.clone)(this.extensions);
|
|
88
|
+
await this.unload();
|
|
89
|
+
await this.load();
|
|
90
|
+
const added = this.extensions.filter((extension) => !prevExtensions.some((prevExtension) => extension.path === prevExtension.path));
|
|
91
|
+
const removed = prevExtensions.filter((prevExtension) => !this.extensions.some((extension) => prevExtension.path === extension.path));
|
|
92
|
+
this.updateWatchedExtensions(added, removed);
|
|
93
|
+
const addedExtensions = added.map((extension) => extension.name);
|
|
94
|
+
const removedExtensions = removed.map((extension) => extension.name);
|
|
95
|
+
if (addedExtensions.length > 0) {
|
|
96
|
+
logger_1.default.info(`Added extensions: ${addedExtensions.join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
if (removedExtensions.length > 0) {
|
|
99
|
+
logger_1.default.info(`Removed extensions: ${removedExtensions.join(', ')}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
logger_1.default.warn('Extensions have to be loaded before they can be reloaded');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
getExtensionsList(type) {
|
|
107
|
+
if (type === undefined) {
|
|
108
|
+
return this.extensions.map((extension) => extension.name);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
return this.extensions.filter((extension) => extension.type === type).map((extension) => extension.name);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
getAppExtensions(type) {
|
|
115
|
+
return this.appExtensions[type];
|
|
116
|
+
}
|
|
117
|
+
getEndpointRouter() {
|
|
118
|
+
return this.endpointRouter;
|
|
119
|
+
}
|
|
120
|
+
async load() {
|
|
72
121
|
try {
|
|
73
122
|
await (0, node_1.ensureExtensionDirs)(env_1.default.EXTENSIONS_PATH, env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES);
|
|
74
123
|
this.extensions = await this.getExtensions();
|
|
@@ -82,38 +131,42 @@ class ExtensionManager {
|
|
|
82
131
|
if (env_1.default.SERVE_APP) {
|
|
83
132
|
this.appExtensions = await this.generateExtensionBundles();
|
|
84
133
|
}
|
|
85
|
-
|
|
86
|
-
if (loadedExtensions.length > 0) {
|
|
87
|
-
logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
|
|
88
|
-
}
|
|
89
|
-
this.isInitialized = true;
|
|
134
|
+
this.isLoaded = true;
|
|
90
135
|
}
|
|
91
|
-
async
|
|
92
|
-
if (!this.isInitialized)
|
|
93
|
-
return;
|
|
94
|
-
logger_1.default.info('Reloading extensions');
|
|
136
|
+
async unload() {
|
|
95
137
|
this.unregisterHooks();
|
|
96
138
|
this.unregisterEndpoints();
|
|
97
139
|
this.apiEmitter.offAll();
|
|
98
140
|
if (env_1.default.SERVE_APP) {
|
|
99
141
|
this.appExtensions = {};
|
|
100
142
|
}
|
|
101
|
-
this.
|
|
102
|
-
await this.initialize();
|
|
143
|
+
this.isLoaded = false;
|
|
103
144
|
}
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
145
|
+
initializeWatcher() {
|
|
146
|
+
if (env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development' && !this.watcher) {
|
|
147
|
+
logger_1.default.info('Watching extensions for changes...');
|
|
148
|
+
const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.resolve(env_1.default.EXTENSIONS_PATH, (0, utils_1.pluralize)(type)));
|
|
149
|
+
this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
|
|
150
|
+
ignoreInitial: true,
|
|
151
|
+
});
|
|
152
|
+
this.watcher
|
|
153
|
+
.on('add', () => this.reload())
|
|
154
|
+
.on('change', () => this.reload())
|
|
155
|
+
.on('unlink', () => this.reload());
|
|
110
156
|
}
|
|
111
157
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
158
|
+
updateWatchedExtensions(added, removed = []) {
|
|
159
|
+
if (this.watcher) {
|
|
160
|
+
const toPackageExtensionPaths = (extensions) => extensions
|
|
161
|
+
.filter((extension) => !extension.local)
|
|
162
|
+
.map((extension) => extension.type !== 'pack'
|
|
163
|
+
? path_1.default.resolve(extension.path, extension.entrypoint || '')
|
|
164
|
+
: path_1.default.resolve(extension.path, 'package.json'));
|
|
165
|
+
const addedPackageExtensionPaths = toPackageExtensionPaths(added);
|
|
166
|
+
const removedPackageExtensionPaths = toPackageExtensionPaths(removed);
|
|
167
|
+
this.watcher.add(addedPackageExtensionPaths);
|
|
168
|
+
this.watcher.unwatch(removedPackageExtensionPaths);
|
|
169
|
+
}
|
|
117
170
|
}
|
|
118
171
|
async getExtensions() {
|
|
119
172
|
const packageExtensions = await (0, node_1.getPackageExtensions)('.', env_1.default.SERVE_APP ? constants_1.EXTENSION_PACKAGE_TYPES : constants_1.API_EXTENSION_PACKAGE_TYPES);
|
|
@@ -188,7 +241,7 @@ class ExtensionManager {
|
|
|
188
241
|
const registerFunctions = {
|
|
189
242
|
filter: (event, handler) => {
|
|
190
243
|
emitter_1.default.onFilter(event, handler);
|
|
191
|
-
this.
|
|
244
|
+
this.apiExtensions.hooks.push({
|
|
192
245
|
type: 'filter',
|
|
193
246
|
path: hookPath,
|
|
194
247
|
event,
|
|
@@ -197,7 +250,7 @@ class ExtensionManager {
|
|
|
197
250
|
},
|
|
198
251
|
action: (event, handler) => {
|
|
199
252
|
emitter_1.default.onAction(event, handler);
|
|
200
|
-
this.
|
|
253
|
+
this.apiExtensions.hooks.push({
|
|
201
254
|
type: 'action',
|
|
202
255
|
path: hookPath,
|
|
203
256
|
event,
|
|
@@ -206,7 +259,7 @@ class ExtensionManager {
|
|
|
206
259
|
},
|
|
207
260
|
init: (event, handler) => {
|
|
208
261
|
emitter_1.default.onInit(event, handler);
|
|
209
|
-
this.
|
|
262
|
+
this.apiExtensions.hooks.push({
|
|
210
263
|
type: 'init',
|
|
211
264
|
path: hookPath,
|
|
212
265
|
event,
|
|
@@ -225,7 +278,7 @@ class ExtensionManager {
|
|
|
225
278
|
}
|
|
226
279
|
}
|
|
227
280
|
});
|
|
228
|
-
this.
|
|
281
|
+
this.apiExtensions.hooks.push({
|
|
229
282
|
type: 'schedule',
|
|
230
283
|
path: hookPath,
|
|
231
284
|
task,
|
|
@@ -263,12 +316,12 @@ class ExtensionManager {
|
|
|
263
316
|
logger: logger_1.default,
|
|
264
317
|
getSchema: get_schema_1.getSchema,
|
|
265
318
|
});
|
|
266
|
-
this.
|
|
319
|
+
this.apiExtensions.endpoints.push({
|
|
267
320
|
path: endpointPath,
|
|
268
321
|
});
|
|
269
322
|
}
|
|
270
323
|
unregisterHooks() {
|
|
271
|
-
for (const hook of this.
|
|
324
|
+
for (const hook of this.apiExtensions.hooks) {
|
|
272
325
|
switch (hook.type) {
|
|
273
326
|
case 'filter':
|
|
274
327
|
emitter_1.default.offFilter(hook.event, hook.handler);
|
|
@@ -280,18 +333,18 @@ class ExtensionManager {
|
|
|
280
333
|
emitter_1.default.offInit(hook.event, hook.handler);
|
|
281
334
|
break;
|
|
282
335
|
case 'schedule':
|
|
283
|
-
hook.task.
|
|
336
|
+
hook.task.stop();
|
|
284
337
|
break;
|
|
285
338
|
}
|
|
286
339
|
delete require.cache[require.resolve(hook.path)];
|
|
287
340
|
}
|
|
288
|
-
this.
|
|
341
|
+
this.apiExtensions.hooks = [];
|
|
289
342
|
}
|
|
290
343
|
unregisterEndpoints() {
|
|
291
|
-
for (const endpoint of this.
|
|
344
|
+
for (const endpoint of this.apiExtensions.endpoints) {
|
|
292
345
|
delete require.cache[require.resolve(endpoint.path)];
|
|
293
346
|
}
|
|
294
347
|
this.endpointRouter.stack = [];
|
|
295
|
-
this.
|
|
348
|
+
this.apiExtensions.endpoints = [];
|
|
296
349
|
}
|
|
297
350
|
}
|
package/dist/services/assets.js
CHANGED
|
@@ -52,9 +52,6 @@ class AssetsService {
|
|
|
52
52
|
.from('directus_settings')
|
|
53
53
|
.first();
|
|
54
54
|
const systemPublicKeys = Object.values(publicSettings || {});
|
|
55
|
-
if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
56
|
-
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
|
57
|
-
}
|
|
58
55
|
/**
|
|
59
56
|
* This is a little annoying. Postgres will error out if you're trying to search in `where`
|
|
60
57
|
* with a wrong type. In case of directus_files where id is a uuid, we'll have to verify the
|
|
@@ -63,6 +60,9 @@ class AssetsService {
|
|
|
63
60
|
const isValidUUID = (0, uuid_validate_1.default)(id, 4);
|
|
64
61
|
if (isValidUUID === false)
|
|
65
62
|
throw new exceptions_1.ForbiddenException();
|
|
63
|
+
if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
64
|
+
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
|
65
|
+
}
|
|
66
66
|
const file = (await this.knex.select('*').from('directus_files').where({ id }).first());
|
|
67
67
|
if (!file)
|
|
68
68
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -43,7 +43,7 @@ class AuthenticationService {
|
|
|
43
43
|
const user = await this.knex
|
|
44
44
|
.select('u.id', 'u.first_name', 'u.last_name', 'u.email', 'u.password', 'u.status', 'u.role', 'r.admin_access', 'r.app_access', 'u.tfa_secret', 'u.provider', 'u.external_identifier', 'u.auth_data')
|
|
45
45
|
.from('directus_users as u')
|
|
46
|
-
.
|
|
46
|
+
.leftJoin('directus_roles as r', 'u.role', 'r.id')
|
|
47
47
|
.where('u.id', await provider.getUserID((0, lodash_1.cloneDeep)(payload)))
|
|
48
48
|
.andWhere('u.provider', providerName)
|
|
49
49
|
.first();
|
|
@@ -247,6 +247,9 @@ class AuthenticationService {
|
|
|
247
247
|
collection: record.share_collection,
|
|
248
248
|
item: record.share_item,
|
|
249
249
|
};
|
|
250
|
+
tokenPayload.app_access = false;
|
|
251
|
+
tokenPayload.admin_access = false;
|
|
252
|
+
delete tokenPayload.id;
|
|
250
253
|
}
|
|
251
254
|
const customClaims = await emitter_1.default.emitFilter('auth.jwt', tokenPayload, {
|
|
252
255
|
status: 'pending',
|
package/dist/services/graphql.js
CHANGED
|
@@ -1397,10 +1397,10 @@ class GraphQLService {
|
|
|
1397
1397
|
resolve: async () => {
|
|
1398
1398
|
const extensionManager = (0, extensions_1.getExtensionManager)();
|
|
1399
1399
|
return {
|
|
1400
|
-
interfaces: extensionManager.
|
|
1401
|
-
displays: extensionManager.
|
|
1402
|
-
layouts: extensionManager.
|
|
1403
|
-
modules: extensionManager.
|
|
1400
|
+
interfaces: extensionManager.getExtensionsList('interface'),
|
|
1401
|
+
displays: extensionManager.getExtensionsList('display'),
|
|
1402
|
+
layouts: extensionManager.getExtensionsList('layout'),
|
|
1403
|
+
modules: extensionManager.getExtensionsList('module'),
|
|
1404
1404
|
};
|
|
1405
1405
|
},
|
|
1406
1406
|
},
|
|
@@ -107,7 +107,7 @@ function getLocalType(column, field) {
|
|
|
107
107
|
return 'hash';
|
|
108
108
|
if (special.includes('csv'))
|
|
109
109
|
return 'csv';
|
|
110
|
-
if (special.includes('uuid'))
|
|
110
|
+
if (special.includes('uuid') || special.includes('file'))
|
|
111
111
|
return 'uuid';
|
|
112
112
|
if (type === null || type === void 0 ? void 0 : type.startsWith('geometry')) {
|
|
113
113
|
return special[0] || 'geometry';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.4.
|
|
3
|
+
"version": "9.4.3",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"homepage": "https://github.com/directus/directus#readme",
|
|
6
6
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content.",
|
|
@@ -76,16 +76,16 @@
|
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@aws-sdk/client-ses": "^3.40.0",
|
|
79
|
-
"@directus/app": "9.4.
|
|
80
|
-
"@directus/drive": "9.4.
|
|
81
|
-
"@directus/drive-azure": "9.4.
|
|
82
|
-
"@directus/drive-gcs": "9.4.
|
|
83
|
-
"@directus/drive-s3": "9.4.
|
|
84
|
-
"@directus/extensions-sdk": "9.4.
|
|
85
|
-
"@directus/format-title": "9.4.
|
|
86
|
-
"@directus/schema": "9.4.
|
|
87
|
-
"@directus/shared": "9.4.
|
|
88
|
-
"@directus/specs": "9.4.
|
|
79
|
+
"@directus/app": "9.4.3",
|
|
80
|
+
"@directus/drive": "9.4.3",
|
|
81
|
+
"@directus/drive-azure": "9.4.3",
|
|
82
|
+
"@directus/drive-gcs": "9.4.3",
|
|
83
|
+
"@directus/drive-s3": "9.4.3",
|
|
84
|
+
"@directus/extensions-sdk": "9.4.3",
|
|
85
|
+
"@directus/format-title": "9.4.3",
|
|
86
|
+
"@directus/schema": "9.4.3",
|
|
87
|
+
"@directus/shared": "9.4.3",
|
|
88
|
+
"@directus/specs": "9.4.3",
|
|
89
89
|
"@godaddy/terminus": "^4.9.0",
|
|
90
90
|
"@rollup/plugin-alias": "^3.1.2",
|
|
91
91
|
"@rollup/plugin-virtual": "^2.0.3",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"busboy": "^0.3.1",
|
|
98
98
|
"camelcase": "^6.2.0",
|
|
99
99
|
"chalk": "^4.1.1",
|
|
100
|
+
"chokidar": "^3.5.2",
|
|
100
101
|
"commander": "^8.0.0",
|
|
101
102
|
"cookie-parser": "^1.4.5",
|
|
102
103
|
"cors": "^2.8.5",
|
|
@@ -170,7 +171,7 @@
|
|
|
170
171
|
"sqlite3": "^5.0.2",
|
|
171
172
|
"tedious": "^13.0.0"
|
|
172
173
|
},
|
|
173
|
-
"gitHead": "
|
|
174
|
+
"gitHead": "65bfe68b0c7993a1bd5b0daac0855265911313d0",
|
|
174
175
|
"devDependencies": {
|
|
175
176
|
"@types/async": "3.2.10",
|
|
176
177
|
"@types/atob": "2.1.2",
|