directus 9.4.0 → 9.5.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/README.md +1 -1
- package/dist/app.js +20 -1
- package/dist/auth/auth.d.ts +2 -1
- package/dist/auth/drivers/ldap.js +2 -1
- package/dist/auth/drivers/local.js +2 -1
- package/dist/auth/drivers/oauth2.js +12 -21
- package/dist/auth/drivers/openid.js +14 -3
- package/dist/cache.js +1 -3
- package/dist/cli/commands/init/questions.d.ts +3 -0
- package/dist/cli/commands/init/questions.js +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +11 -1
- package/dist/cli/utils/drivers.d.ts +1 -0
- package/dist/cli/utils/drivers.js +2 -1
- package/dist/controllers/activity.js +2 -1
- package/dist/controllers/auth.js +5 -4
- package/dist/controllers/extensions.js +1 -1
- package/dist/controllers/files.js +1 -1
- package/dist/controllers/shares.js +2 -2
- package/dist/controllers/utils.js +2 -0
- package/dist/database/helpers/date/index.d.ts +1 -0
- package/dist/database/helpers/date/index.js +3 -1
- package/dist/database/helpers/geometry/index.d.ts +1 -0
- package/dist/database/helpers/geometry/index.js +3 -1
- package/dist/database/helpers/index.d.ts +2 -0
- package/dist/database/helpers/index.js +2 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +16 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.js +16 -0
- package/dist/database/helpers/schema/dialects/default.d.ts +3 -0
- package/dist/database/helpers/schema/dialects/default.js +7 -0
- package/dist/database/helpers/schema/dialects/oracle.d.ts +12 -0
- package/dist/database/helpers/schema/dialects/oracle.js +13 -0
- package/dist/database/helpers/schema/index.d.ts +7 -0
- package/dist/database/helpers/schema/index.js +17 -0
- package/dist/database/helpers/schema/types.d.ts +25 -0
- package/dist/database/helpers/schema/types.js +89 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +36 -16
- package/dist/database/migrations/20201105B-change-webhook-url-type.js +6 -25
- package/dist/database/migrations/20210312A-webhooks-collections-text.js +6 -25
- package/dist/database/migrations/20210415A-make-filesize-nullable.js +9 -4
- package/dist/database/migrations/20210506A-rename-interfaces.js +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.js +12 -4
- package/dist/database/migrations/20210525A-add-insights.js +2 -2
- package/dist/database/migrations/20210626A-change-filesize-bigint.js +5 -7
- package/dist/database/migrations/20210903A-add-auth-provider.js +11 -2
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +6 -20
- package/dist/database/migrations/20210920A-webhooks-url-not-null.js +10 -14
- package/dist/database/migrations/20211211A-add-shares.js +5 -4
- package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +3 -0
- package/dist/database/migrations/20211230A-add-project-descriptor.js +15 -0
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.d.ts +1 -1
- package/dist/database/seeds/01-collections.yaml +1 -0
- package/dist/database/seeds/02-roles.yaml +1 -0
- package/dist/database/seeds/03-users.yaml +1 -0
- package/dist/database/system-data/fields/_defaults.yaml +2 -0
- package/dist/database/system-data/fields/settings.yaml +20 -1
- package/dist/database/system-data/fields/shares.yaml +4 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +3 -4
- package/dist/emitter.js +2 -8
- package/dist/env.js +4 -1
- package/dist/exceptions/database/translate.js +1 -0
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +1 -0
- package/dist/exceptions/unsupported-media-type.d.ts +4 -0
- package/dist/exceptions/unsupported-media-type.js +10 -0
- package/dist/extensions.d.ts +14 -8
- package/dist/extensions.js +136 -69
- package/dist/logger.js +22 -1
- package/dist/middleware/authenticate.js +2 -1
- package/dist/middleware/rate-limiter.js +2 -1
- package/dist/services/assets.js +3 -3
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +10 -5
- package/dist/services/authorization.d.ts +2 -3
- package/dist/services/collections.d.ts +2 -2
- package/dist/services/collections.js +10 -6
- package/dist/services/fields.d.ts +2 -3
- package/dist/services/fields.js +8 -4
- package/dist/services/graphql.d.ts +3 -2
- package/dist/services/graphql.js +35 -5
- package/dist/services/import.d.ts +2 -2
- package/dist/services/import.js +2 -1
- package/dist/services/items.d.ts +2 -2
- package/dist/services/items.js +22 -18
- package/dist/services/mail/index.d.ts +2 -2
- package/dist/services/meta.d.ts +2 -2
- package/dist/services/payload.d.ts +2 -2
- package/dist/services/relations.d.ts +2 -2
- package/dist/services/server.d.ts +2 -2
- package/dist/services/server.js +1 -0
- package/dist/services/shares.js +2 -2
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/users.d.ts +2 -3
- package/dist/services/utils.d.ts +2 -2
- package/dist/types/ast.d.ts +1 -2
- package/dist/types/auth.d.ts +1 -3
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.js +0 -3
- package/dist/types/services.d.ts +1 -3
- package/dist/types/snapshot.d.ts +1 -2
- package/dist/utils/apply-query.d.ts +1 -2
- package/dist/utils/apply-query.js +1 -1
- package/dist/utils/apply-snapshot.d.ts +2 -1
- package/dist/utils/get-ast-from-query.d.ts +2 -3
- package/dist/utils/get-default-value.js +3 -1
- package/dist/utils/get-ip-from-req.d.ts +2 -0
- package/dist/utils/get-ip-from-req.js +24 -0
- package/dist/utils/get-local-type.js +1 -1
- package/dist/utils/get-permissions.d.ts +1 -2
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-schema.d.ts +1 -2
- package/dist/utils/get-snapshot.d.ts +2 -1
- package/dist/utils/merge-permissions-for-share.d.ts +1 -2
- package/dist/utils/reduce-schema.d.ts +1 -2
- package/example.env +9 -1
- package/package.json +18 -15
- package/dist/cli/index.test.d.ts +0 -1
- package/dist/cli/index.test.js +0 -58
- package/dist/middleware/cache.test.d.ts +0 -1
- package/dist/middleware/cache.test.js +0 -62
- package/dist/tests/database/migrations/run.test.d.ts +0 -1
- package/dist/tests/database/migrations/run.test.js +0 -29
- package/dist/types/extensions.d.ts +0 -43
- package/dist/types/extensions.js +0 -2
- package/dist/types/relation.d.ts +0 -21
- package/dist/types/relation.js +0 -2
- package/dist/types/schema.d.ts +0 -32
- package/dist/types/schema.js +0 -2
- package/dist/utils/get-cache-key.test.d.ts +0 -1
- package/dist/utils/get-cache-key.test.js +0 -53
package/dist/types/index.js
CHANGED
|
@@ -15,15 +15,12 @@ __exportStar(require("./assets"), exports);
|
|
|
15
15
|
__exportStar(require("./ast"), exports);
|
|
16
16
|
__exportStar(require("./auth"), exports);
|
|
17
17
|
__exportStar(require("./collection"), exports);
|
|
18
|
-
__exportStar(require("./extensions"), exports);
|
|
19
18
|
__exportStar(require("./files"), exports);
|
|
20
19
|
__exportStar(require("./graphql"), exports);
|
|
21
20
|
__exportStar(require("./items"), exports);
|
|
22
21
|
__exportStar(require("./meta"), exports);
|
|
23
22
|
__exportStar(require("./migration"), exports);
|
|
24
|
-
__exportStar(require("./relation"), exports);
|
|
25
23
|
__exportStar(require("./revision"), exports);
|
|
26
|
-
__exportStar(require("./schema"), exports);
|
|
27
24
|
__exportStar(require("./services"), exports);
|
|
28
25
|
__exportStar(require("./snapshot"), exports);
|
|
29
26
|
__exportStar(require("./webhooks"), exports);
|
package/dist/types/services.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
import { Item, PrimaryKey } from './items';
|
|
5
|
-
import { Query } from '@directus/shared/types';
|
|
6
4
|
export declare type AbstractServiceOptions = {
|
|
7
5
|
knex?: Knex;
|
|
8
6
|
accountability?: Accountability | null;
|
package/dist/types/snapshot.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Collection } from './collection';
|
|
2
|
-
import { Relation, RelationMeta } from '
|
|
3
|
-
import { Field, FieldMeta } from '@directus/shared/types';
|
|
2
|
+
import { Relation, RelationMeta, Field, FieldMeta } from '@directus/shared/types';
|
|
4
3
|
import { Diff } from 'deep-diff';
|
|
5
4
|
export declare type Snapshot = {
|
|
6
5
|
version: number;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Aggregate, Filter, Query } from '@directus/shared/types';
|
|
2
|
+
import { Aggregate, Filter, Query, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
/**
|
|
5
4
|
* Apply the Query to a given Knex query builder instance
|
|
6
5
|
*/
|
|
@@ -177,7 +177,7 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
177
177
|
if (relationType === 'o2m' && (subQuery === true || parentAlias !== undefined)) {
|
|
178
178
|
dbQuery.leftJoin({ [alias]: relation.collection }, `${parentAlias || parentCollection}.${schema.collections[relation.related_collection].primary}`, `${alias}.${relation.field}`);
|
|
179
179
|
}
|
|
180
|
-
if (relationType === 'm2o' || subQuery === true) {
|
|
180
|
+
if (relationType === 'm2o' || subQuery === true || (relationType === 'o2m' && parentAlias !== undefined)) {
|
|
181
181
|
let parent;
|
|
182
182
|
if (relationType === 'm2o') {
|
|
183
183
|
parent = relation.related_collection;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Snapshot, SnapshotDiff
|
|
1
|
+
import { Snapshot, SnapshotDiff } from '../types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
3
4
|
export declare function applySnapshot(snapshot: Snapshot, options?: {
|
|
4
5
|
database?: Knex;
|
|
5
6
|
schema?: SchemaOverview;
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Generate an AST based on a given collection and query
|
|
3
3
|
*/
|
|
4
4
|
import { Knex } from 'knex';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { Query, PermissionsAction } from '@directus/shared/types';
|
|
5
|
+
import { AST } from '../types';
|
|
6
|
+
import { Query, PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
8
7
|
declare type GetASTOptions = {
|
|
9
8
|
accountability?: Accountability | null;
|
|
10
9
|
action?: PermissionsAction;
|
|
@@ -16,12 +16,14 @@ function getDefaultValue(column) {
|
|
|
16
16
|
return null;
|
|
17
17
|
if (defaultValue === 'NULL')
|
|
18
18
|
return null;
|
|
19
|
-
// Check if the default is wrapped in an extra pair of quotes, this happens in SQLite
|
|
19
|
+
// Check if the default is wrapped in an extra pair of quotes, this happens in SQLite / MariaDB
|
|
20
20
|
if (typeof defaultValue === 'string' &&
|
|
21
21
|
((defaultValue.startsWith(`'`) && defaultValue.endsWith(`'`)) ||
|
|
22
22
|
(defaultValue.startsWith(`"`) && defaultValue.endsWith(`"`)))) {
|
|
23
23
|
defaultValue = defaultValue.slice(1, -1);
|
|
24
24
|
}
|
|
25
|
+
if (defaultValue === '0000-00-00 00:00:00')
|
|
26
|
+
return null;
|
|
25
27
|
switch (type) {
|
|
26
28
|
case 'bigInteger':
|
|
27
29
|
case 'integer':
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
exports.getIPFromReq = void 0;
|
|
7
|
+
const net_1 = require("net");
|
|
8
|
+
const env_1 = __importDefault(require("../env"));
|
|
9
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
10
|
+
function getIPFromReq(req) {
|
|
11
|
+
let ip = req.ip;
|
|
12
|
+
if (env_1.default.IP_CUSTOM_HEADER) {
|
|
13
|
+
const customIPHeaderValue = req.get(env_1.default.IP_CUSTOM_HEADER);
|
|
14
|
+
if (typeof customIPHeaderValue === 'string' && (0, net_1.isIP)(customIPHeaderValue) !== 0) {
|
|
15
|
+
ip = customIPHeaderValue;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
logger_1.default.warn(`Custom IP header didn't return valid IP address: ${JSON.stringify(customIPHeaderValue)}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// IP addresses starting with ::ffff: are IPv4 addresses in IPv6 format. We can strip the prefix to get back to IPv4
|
|
22
|
+
return ip.startsWith('::ffff:') ? ip.substring(7) : ip;
|
|
23
|
+
}
|
|
24
|
+
exports.getIPFromReq = getIPFromReq;
|
|
@@ -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';
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { Permission, Accountability } from '@directus/shared/types';
|
|
2
|
-
import { SchemaOverview } from '../types';
|
|
1
|
+
import { Permission, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
3
2
|
export declare function getPermissions(accountability: Accountability, schema: SchemaOverview): Promise<Permission[]>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
export declare function getSchema(options?: {
|
|
5
4
|
accountability?: Accountability;
|
|
6
5
|
database?: Knex;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Snapshot } from '../types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
3
4
|
export declare function getSnapshot(options?: {
|
|
4
5
|
database?: Knex;
|
|
5
6
|
schema?: SchemaOverview;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Permission, Accountability, Filter } from '@directus/shared/types';
|
|
2
|
-
import { SchemaOverview } from '../types';
|
|
1
|
+
import { Permission, Accountability, Filter, SchemaOverview } from '@directus/shared/types';
|
|
3
2
|
export declare function mergePermissionsForShare(currentPermissions: Permission[], accountability: Accountability, schema: SchemaOverview): Permission[];
|
|
4
3
|
export declare function traverse(schema: SchemaOverview, rootItemPrimaryKeyField: string, rootItemPrimaryKey: string, currentCollection: string, parentCollections?: string[], path?: string[]): Partial<Permission>[];
|
|
5
4
|
export declare function getFilterForPath(type: 'o2m' | 'm2o' | 'a2o', path: string[], rootPrimaryKeyField: string, rootPrimaryKey: string): Filter;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { SchemaOverview } from '
|
|
2
|
-
import { Permission, PermissionsAction } from '@directus/shared/types';
|
|
1
|
+
import { Permission, PermissionsAction, SchemaOverview } from '@directus/shared/types';
|
|
3
2
|
/**
|
|
4
3
|
* Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
|
|
5
4
|
* the allowed collections/fields/relations included based on the permissions.
|
package/example.env
CHANGED
|
@@ -19,6 +19,14 @@ DB_DATABASE="directus"
|
|
|
19
19
|
DB_USER="postgres"
|
|
20
20
|
DB_PASSWORD="secret"
|
|
21
21
|
|
|
22
|
+
## CockroachDB
|
|
23
|
+
# DB_CLIENT="cockroachdb"
|
|
24
|
+
# DB_HOST="localhost"
|
|
25
|
+
# DB_PORT=5113
|
|
26
|
+
# DB_DATABASE="directus"
|
|
27
|
+
# DB_USER="root"
|
|
28
|
+
# DB_PASSWORD=""
|
|
29
|
+
|
|
22
30
|
## MySQL 8
|
|
23
31
|
# DB_CLIENT="mysql"
|
|
24
32
|
# DB_HOST="localhost"
|
|
@@ -44,7 +52,7 @@ DB_PASSWORD="secret"
|
|
|
44
52
|
# DB_PASSWORD="Test@123"
|
|
45
53
|
|
|
46
54
|
## OracleDB
|
|
47
|
-
# DB_CLIENT="
|
|
55
|
+
# DB_CLIENT="oracledb"
|
|
48
56
|
# DB_CONNECT_STRING="localhost:5104/XE"
|
|
49
57
|
# DB_USER="secretsysuser"
|
|
50
58
|
# DB_PASSWORD="secretpassword"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.5.0",
|
|
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.",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"cms",
|
|
19
19
|
"mysql",
|
|
20
20
|
"postgresql",
|
|
21
|
+
"cockroachdb",
|
|
21
22
|
"sqlite",
|
|
22
23
|
"framework",
|
|
23
24
|
"vue"
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"prebuild": "npm run cleanup",
|
|
61
62
|
"build": "tsc --build && copyfiles \"src/**/*.*\" -e \"src/**/*.ts\" -u 1 dist",
|
|
62
63
|
"cleanup": "rimraf dist",
|
|
63
|
-
"dev": "cross-env NODE_ENV=development SERVE_APP=false ts-node-dev --files --transpile-only --respawn --watch \".env\" --inspect --exit-child -- src/start.ts",
|
|
64
|
+
"dev": "cross-env NODE_ENV=development SERVE_APP=false ts-node-dev --files --transpile-only --respawn --watch \".env\" --inspect=0 --exit-child -- src/start.ts",
|
|
64
65
|
"cli": "cross-env NODE_ENV=development SERVE_APP=false ts-node --script-mode --transpile-only src/cli/run.ts",
|
|
65
66
|
"test": "jest --coverage",
|
|
66
67
|
"test:watch": "jest --watchAll"
|
|
@@ -76,16 +77,16 @@
|
|
|
76
77
|
],
|
|
77
78
|
"dependencies": {
|
|
78
79
|
"@aws-sdk/client-ses": "^3.40.0",
|
|
79
|
-
"@directus/app": "9.
|
|
80
|
-
"@directus/drive": "9.
|
|
81
|
-
"@directus/drive-azure": "9.
|
|
82
|
-
"@directus/drive-gcs": "9.
|
|
83
|
-
"@directus/drive-s3": "9.
|
|
84
|
-
"@directus/extensions-sdk": "9.
|
|
85
|
-
"@directus/format-title": "9.
|
|
86
|
-
"@directus/schema": "9.
|
|
87
|
-
"@directus/shared": "9.
|
|
88
|
-
"@directus/specs": "9.
|
|
80
|
+
"@directus/app": "9.5.0",
|
|
81
|
+
"@directus/drive": "9.5.0",
|
|
82
|
+
"@directus/drive-azure": "9.5.0",
|
|
83
|
+
"@directus/drive-gcs": "9.5.0",
|
|
84
|
+
"@directus/drive-s3": "9.5.0",
|
|
85
|
+
"@directus/extensions-sdk": "9.5.0",
|
|
86
|
+
"@directus/format-title": "9.5.0",
|
|
87
|
+
"@directus/schema": "9.5.0",
|
|
88
|
+
"@directus/shared": "9.5.0",
|
|
89
|
+
"@directus/specs": "9.5.0",
|
|
89
90
|
"@godaddy/terminus": "^4.9.0",
|
|
90
91
|
"@rollup/plugin-alias": "^3.1.2",
|
|
91
92
|
"@rollup/plugin-virtual": "^2.0.3",
|
|
@@ -97,6 +98,7 @@
|
|
|
97
98
|
"busboy": "^0.3.1",
|
|
98
99
|
"camelcase": "^6.2.0",
|
|
99
100
|
"chalk": "^4.1.1",
|
|
101
|
+
"chokidar": "^3.5.2",
|
|
100
102
|
"commander": "^8.0.0",
|
|
101
103
|
"cookie-parser": "^1.4.5",
|
|
102
104
|
"cors": "^2.8.5",
|
|
@@ -114,6 +116,7 @@
|
|
|
114
116
|
"fs-extra": "^10.0.0",
|
|
115
117
|
"graphql": "^15.5.0",
|
|
116
118
|
"graphql-compose": "^9.0.1",
|
|
119
|
+
"helmet": "^4.6.0",
|
|
117
120
|
"inquirer": "^8.1.1",
|
|
118
121
|
"joi": "^17.3.0",
|
|
119
122
|
"js-yaml": "^4.1.0",
|
|
@@ -121,8 +124,8 @@
|
|
|
121
124
|
"json2csv": "^5.0.3",
|
|
122
125
|
"jsonwebtoken": "^8.5.1",
|
|
123
126
|
"keyv": "^4.0.3",
|
|
124
|
-
"knex": "^0.95.
|
|
125
|
-
"knex-schema-inspector": "1.
|
|
127
|
+
"knex": "^0.95.14",
|
|
128
|
+
"knex-schema-inspector": "1.7.2",
|
|
126
129
|
"ldapjs": "^2.3.1",
|
|
127
130
|
"liquidjs": "^9.25.0",
|
|
128
131
|
"lodash": "^4.17.21",
|
|
@@ -169,7 +172,7 @@
|
|
|
169
172
|
"sqlite3": "^5.0.2",
|
|
170
173
|
"tedious": "^13.0.0"
|
|
171
174
|
},
|
|
172
|
-
"gitHead": "
|
|
175
|
+
"gitHead": "78a25fe9538dcd30452dc1a0889e720040c0596c",
|
|
173
176
|
"devDependencies": {
|
|
174
177
|
"@types/async": "3.2.10",
|
|
175
178
|
"@types/atob": "2.1.2",
|
package/dist/cli/index.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/cli/index.test.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const index_1 = require("./index");
|
|
4
|
-
jest.mock('../env', () => ({
|
|
5
|
-
...jest.requireActual('../env').default,
|
|
6
|
-
EXTENSIONS_PATH: '',
|
|
7
|
-
SERVE_APP: false,
|
|
8
|
-
DB_CLIENT: 'pg',
|
|
9
|
-
DB_HOST: 'localhost',
|
|
10
|
-
DB_PORT: 5432,
|
|
11
|
-
DB_DATABASE: 'directus',
|
|
12
|
-
DB_USER: 'postgres',
|
|
13
|
-
DB_PASSWORD: 'psql1234',
|
|
14
|
-
}));
|
|
15
|
-
jest.mock('@directus/shared/utils/node/get-extensions', () => ({
|
|
16
|
-
getPackageExtensions: jest.fn(() => Promise.resolve([])),
|
|
17
|
-
getLocalExtensions: jest.fn(() => Promise.resolve([customCliExtension])),
|
|
18
|
-
}));
|
|
19
|
-
jest.mock(`/hooks/custom-cli/index.js`, () => customCliHook, { virtual: true });
|
|
20
|
-
const customCliExtension = {
|
|
21
|
-
path: `/hooks/custom-cli`,
|
|
22
|
-
name: 'custom-cli',
|
|
23
|
-
type: 'hook',
|
|
24
|
-
entrypoint: 'index.js',
|
|
25
|
-
local: true,
|
|
26
|
-
};
|
|
27
|
-
const beforeHook = jest.fn();
|
|
28
|
-
const afterAction = jest.fn();
|
|
29
|
-
const afterHook = jest.fn(({ program }) => {
|
|
30
|
-
program.command('custom').action(afterAction);
|
|
31
|
-
});
|
|
32
|
-
const customCliHook = ({ init }) => {
|
|
33
|
-
init('cli.before', beforeHook);
|
|
34
|
-
init('cli.after', afterHook);
|
|
35
|
-
};
|
|
36
|
-
const writeOut = jest.fn();
|
|
37
|
-
const writeErr = jest.fn();
|
|
38
|
-
const setup = async () => {
|
|
39
|
-
const program = await (0, index_1.createCli)();
|
|
40
|
-
program.exitOverride();
|
|
41
|
-
program.configureOutput({ writeOut, writeErr });
|
|
42
|
-
return program;
|
|
43
|
-
};
|
|
44
|
-
beforeEach(jest.clearAllMocks);
|
|
45
|
-
describe('cli hooks', () => {
|
|
46
|
-
test('should call hooks before and after creating the cli', async () => {
|
|
47
|
-
const program = await setup();
|
|
48
|
-
expect(beforeHook).toHaveBeenCalledTimes(1);
|
|
49
|
-
expect(beforeHook).toHaveBeenCalledWith({ program });
|
|
50
|
-
expect(afterHook).toHaveBeenCalledTimes(1);
|
|
51
|
-
expect(afterHook).toHaveBeenCalledWith({ program });
|
|
52
|
-
});
|
|
53
|
-
test('should be able to add a custom cli command', async () => {
|
|
54
|
-
const program = await setup();
|
|
55
|
-
program.parseAsync(['custom'], { from: 'user' });
|
|
56
|
-
expect(afterAction).toHaveBeenCalledTimes(1);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,62 +0,0 @@
|
|
|
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 express_1 = __importDefault(require("express"));
|
|
7
|
-
const supertest_1 = __importDefault(require("supertest"));
|
|
8
|
-
const cache_1 = __importDefault(require("./cache"));
|
|
9
|
-
jest.mock('../cache');
|
|
10
|
-
jest.mock('../env', () => ({
|
|
11
|
-
CACHE_ENABLED: true,
|
|
12
|
-
CACHE_NAMESPACE: 'test',
|
|
13
|
-
CACHE_STORE: 'memory',
|
|
14
|
-
CACHE_TTL: '5s',
|
|
15
|
-
CACHE_CONTROL_S_MAXAGE: true,
|
|
16
|
-
}));
|
|
17
|
-
const { cache } = jest.requireMock('../cache');
|
|
18
|
-
const env = jest.requireMock('../env');
|
|
19
|
-
const handler = jest.fn((req, res) => res.json({ data: 'Uncached value' }));
|
|
20
|
-
const setup = () => (0, express_1.default)().use(cache_1.default).all('/items/test', handler);
|
|
21
|
-
beforeEach(jest.clearAllMocks);
|
|
22
|
-
describe('cache middleware', () => {
|
|
23
|
-
test('should return the cached response for a request', async () => {
|
|
24
|
-
cache.get.mockResolvedValueOnce({ data: 'Cached value' });
|
|
25
|
-
cache.get.mockResolvedValueOnce(new Date().getTime() + 1000 * 60);
|
|
26
|
-
const res = await (0, supertest_1.default)(setup()).get('/items/test').send();
|
|
27
|
-
expect(res.body.data).toBe('Cached value');
|
|
28
|
-
expect(res.headers['vary']).toBe('Origin, Cache-Control');
|
|
29
|
-
expect(res.headers['cache-control']).toMatch(/public, max-age=\d+, s-maxage=\d+/);
|
|
30
|
-
expect(handler).not.toHaveBeenCalled();
|
|
31
|
-
});
|
|
32
|
-
test('should call the handler when there is no cached value', async () => {
|
|
33
|
-
cache.get.mockResolvedValueOnce(undefined);
|
|
34
|
-
const res = await (0, supertest_1.default)(setup()).get('/items/test').send();
|
|
35
|
-
expect(res.body.data).toBe('Uncached value');
|
|
36
|
-
expect(cache.get).toHaveBeenCalledTimes(1);
|
|
37
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
38
|
-
});
|
|
39
|
-
test('should not cache requests then the cache is disabled', async () => {
|
|
40
|
-
env.CACHE_ENABLED = false;
|
|
41
|
-
const res = await (0, supertest_1.default)(setup()).get('/items/test').send();
|
|
42
|
-
expect(res.body.data).toBe('Uncached value');
|
|
43
|
-
expect(cache.get).not.toHaveBeenCalled();
|
|
44
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
45
|
-
env.CACHE_ENABLED = true;
|
|
46
|
-
});
|
|
47
|
-
test('should not use cache when the "Cache-Control" header is set to "no-store"', async () => {
|
|
48
|
-
const res = await (0, supertest_1.default)(setup()).get('/items/test').set('Cache-Control', 'no-store').send();
|
|
49
|
-
expect(res.body.data).toBe('Uncached value');
|
|
50
|
-
expect(cache.get).not.toHaveBeenCalled();
|
|
51
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
52
|
-
});
|
|
53
|
-
test('should only cache get requests', async () => {
|
|
54
|
-
const app = setup();
|
|
55
|
-
await (0, supertest_1.default)(app).post('/items/test').send();
|
|
56
|
-
await (0, supertest_1.default)(app).put('/items/test').send();
|
|
57
|
-
await (0, supertest_1.default)(app).patch('/items/test').send();
|
|
58
|
-
await (0, supertest_1.default)(app).delete('/items/test').send();
|
|
59
|
-
expect(cache.get).not.toHaveBeenCalled();
|
|
60
|
-
expect(handler).toHaveBeenCalledTimes(4);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,29 +0,0 @@
|
|
|
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 knex_1 = __importDefault(require("knex"));
|
|
7
|
-
const knex_mock_client_1 = require("knex-mock-client");
|
|
8
|
-
const run_1 = __importDefault(require("../../../database/migrations/run"));
|
|
9
|
-
describe('run', () => {
|
|
10
|
-
let db;
|
|
11
|
-
let tracker;
|
|
12
|
-
beforeAll(() => {
|
|
13
|
-
db = (0, knex_1.default)({ client: knex_mock_client_1.MockClient });
|
|
14
|
-
tracker = (0, knex_mock_client_1.getTracker)();
|
|
15
|
-
});
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
tracker.reset();
|
|
18
|
-
});
|
|
19
|
-
describe('when passed the argument up', () => {
|
|
20
|
-
it('returns "Nothing To Updage" if no directus_migrations', async () => {
|
|
21
|
-
// note the difference between an empty array and ['Empty']
|
|
22
|
-
tracker.on.select('directus_migrations').response(['Empty']);
|
|
23
|
-
await (0, run_1.default)(db, 'up').catch((e) => {
|
|
24
|
-
expect(e).toBeInstanceOf(Error);
|
|
25
|
-
expect(e.message).toBe('Nothing to upgrade');
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
-
import { Router } from 'express';
|
|
3
|
-
import { Knex } from 'knex';
|
|
4
|
-
import { Logger } from 'pino';
|
|
5
|
-
import env from '../env';
|
|
6
|
-
import * as exceptions from '../exceptions';
|
|
7
|
-
import * as services from '../services';
|
|
8
|
-
import { Emitter } from '../emitter';
|
|
9
|
-
import { getSchema } from '../utils/get-schema';
|
|
10
|
-
import { SchemaOverview } from './schema';
|
|
11
|
-
export declare type ExtensionContext = {
|
|
12
|
-
services: typeof services;
|
|
13
|
-
exceptions: typeof exceptions;
|
|
14
|
-
database: Knex;
|
|
15
|
-
env: typeof env;
|
|
16
|
-
emitter: Emitter;
|
|
17
|
-
logger: Logger;
|
|
18
|
-
getSchema: typeof getSchema;
|
|
19
|
-
};
|
|
20
|
-
export declare type HookContext = {
|
|
21
|
-
database: Knex;
|
|
22
|
-
schema: SchemaOverview | null;
|
|
23
|
-
accountability: Accountability | null;
|
|
24
|
-
};
|
|
25
|
-
export declare type FilterHandler = (payload: any, meta: Record<string, any>, context: HookContext) => any | Promise<any>;
|
|
26
|
-
export declare type ActionHandler = (meta: Record<string, any>, context: HookContext) => void | Promise<void>;
|
|
27
|
-
export declare type InitHandler = (meta: Record<string, any>) => void | Promise<void>;
|
|
28
|
-
export declare type ScheduleHandler = () => void | Promise<void>;
|
|
29
|
-
declare type RegisterFunctions = {
|
|
30
|
-
filter: (event: string, handler: FilterHandler) => void;
|
|
31
|
-
action: (event: string, handler: ActionHandler) => void;
|
|
32
|
-
init: (event: string, handler: InitHandler) => void;
|
|
33
|
-
schedule: (cron: string, handler: ScheduleHandler) => void;
|
|
34
|
-
};
|
|
35
|
-
declare type HookHandlerFunction = (register: RegisterFunctions, context: ExtensionContext) => void;
|
|
36
|
-
export declare type HookConfig = HookHandlerFunction;
|
|
37
|
-
declare type EndpointHandlerFunction = (router: Router, context: ExtensionContext) => void;
|
|
38
|
-
interface EndpointAdvancedConfig {
|
|
39
|
-
id: string;
|
|
40
|
-
handler: EndpointHandlerFunction;
|
|
41
|
-
}
|
|
42
|
-
export declare type EndpointConfig = EndpointHandlerFunction | EndpointAdvancedConfig;
|
|
43
|
-
export {};
|
package/dist/types/extensions.js
DELETED
package/dist/types/relation.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ForeignKey } from 'knex-schema-inspector/dist/types/foreign-key';
|
|
2
|
-
export declare type RelationMeta = {
|
|
3
|
-
id: number;
|
|
4
|
-
many_collection: string;
|
|
5
|
-
many_field: string;
|
|
6
|
-
one_collection: string | null;
|
|
7
|
-
one_field: string | null;
|
|
8
|
-
one_collection_field: string | null;
|
|
9
|
-
one_allowed_collections: string[] | null;
|
|
10
|
-
one_deselect_action: 'nullify' | 'delete';
|
|
11
|
-
junction_field: string | null;
|
|
12
|
-
sort_field: string | null;
|
|
13
|
-
system?: boolean;
|
|
14
|
-
};
|
|
15
|
-
export declare type Relation = {
|
|
16
|
-
collection: string;
|
|
17
|
-
field: string;
|
|
18
|
-
related_collection: string | null;
|
|
19
|
-
schema: ForeignKey | null;
|
|
20
|
-
meta: RelationMeta | null;
|
|
21
|
-
};
|
package/dist/types/relation.js
DELETED
package/dist/types/schema.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Type } from '@directus/shared/types';
|
|
2
|
-
import { Relation } from './relation';
|
|
3
|
-
export declare type FieldOverview = {
|
|
4
|
-
field: string;
|
|
5
|
-
defaultValue: any;
|
|
6
|
-
nullable: boolean;
|
|
7
|
-
generated: boolean;
|
|
8
|
-
type: Type | 'unknown' | 'alias';
|
|
9
|
-
dbType: string | null;
|
|
10
|
-
precision: number | null;
|
|
11
|
-
scale: number | null;
|
|
12
|
-
special: string[];
|
|
13
|
-
note: string | null;
|
|
14
|
-
alias: boolean;
|
|
15
|
-
};
|
|
16
|
-
export declare type CollectionsOverview = {
|
|
17
|
-
[name: string]: {
|
|
18
|
-
collection: string;
|
|
19
|
-
primary: string;
|
|
20
|
-
singleton: boolean;
|
|
21
|
-
sortField: string | null;
|
|
22
|
-
note: string | null;
|
|
23
|
-
accountability: 'all' | 'activity' | null;
|
|
24
|
-
fields: {
|
|
25
|
-
[name: string]: FieldOverview;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
export declare type SchemaOverview = {
|
|
30
|
-
collections: CollectionsOverview;
|
|
31
|
-
relations: Relation[];
|
|
32
|
-
};
|
package/dist/types/schema.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const get_cache_key_1 = require("./get-cache-key");
|
|
4
|
-
const restUrl = 'http://localhost/items/example';
|
|
5
|
-
const graphQlUrl = 'http://localhost/graphql';
|
|
6
|
-
const accountability = { user: '00000000-0000-0000-0000-000000000000' };
|
|
7
|
-
const requests = [
|
|
8
|
-
{
|
|
9
|
-
name: 'as unauthenticated request',
|
|
10
|
-
params: { originalUrl: restUrl },
|
|
11
|
-
key: '17da8272c9a0ec6eea38a37d6d78bddeb7c79045',
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
name: 'as authenticated request',
|
|
15
|
-
params: { originalUrl: restUrl, accountability },
|
|
16
|
-
key: '99a6394222a3d7d149ac1662fc2fff506932db58',
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
name: 'a request with a fields query',
|
|
20
|
-
params: { originalUrl: restUrl, sanitizedQuery: { fields: ['id', 'name'] } },
|
|
21
|
-
key: 'aa6e2d8a78de4dfb4af6eaa230d1cd9b7d31ed19',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'a request with a filter query',
|
|
25
|
-
params: { originalUrl: restUrl, sanitizedQuery: { filter: { name: { _eq: 'test' } } } },
|
|
26
|
-
key: 'd7eb8970f0429e1cf85e12eb5bb8669f618b09d3',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'a GraphQL query request',
|
|
30
|
-
params: { originalUrl: graphQlUrl, query: { query: 'query { test { id } }' } },
|
|
31
|
-
key: '201731b75c627c60554512d819b6935b54c73814',
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
const cases = requests.map(({ name, params, key }) => [name, params, key]);
|
|
35
|
-
describe('get cache key', () => {
|
|
36
|
-
test.each(cases)('should create a cache key for %s', (_, params, key) => {
|
|
37
|
-
expect((0, get_cache_key_1.getCacheKey)(params)).toEqual(key);
|
|
38
|
-
});
|
|
39
|
-
test('should create a unique key for each request', () => {
|
|
40
|
-
const keys = requests.map((r) => r.key);
|
|
41
|
-
const hasDuplicate = keys.some((key) => keys.indexOf(key) !== keys.lastIndexOf(key));
|
|
42
|
-
expect(hasDuplicate).toBeFalsy();
|
|
43
|
-
});
|
|
44
|
-
test('should create a unique key for GraphQL requests with different variables', () => {
|
|
45
|
-
const query = 'query Test ($name: String) { test (filter: { name: { _eq: $name } }) { id } }';
|
|
46
|
-
const operationName = 'test';
|
|
47
|
-
const variables1 = JSON.stringify({ name: 'test 1' });
|
|
48
|
-
const variables2 = JSON.stringify({ name: 'test 2' });
|
|
49
|
-
const req1 = { originalUrl: graphQlUrl, query: { query, operationName, variables: variables1 } };
|
|
50
|
-
const req2 = { originalUrl: graphQlUrl, query: { query, operationName, variables: variables2 } };
|
|
51
|
-
expect((0, get_cache_key_1.getCacheKey)(req1)).not.toEqual((0, get_cache_key_1.getCacheKey)(req2));
|
|
52
|
-
});
|
|
53
|
-
});
|