directus 9.4.3 → 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/auth/auth.d.ts +2 -1
- package/dist/auth/drivers/oauth2.js +10 -20
- package/dist/auth/drivers/openid.js +12 -2
- package/dist/cli/commands/init/questions.d.ts +3 -0
- package/dist/cli/commands/init/questions.js +2 -0
- 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/files.js +1 -1
- 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 +33 -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 +2 -2
- 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/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +3 -4
- package/dist/emitter.js +2 -8
- 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 +6 -5
- package/dist/extensions.js +56 -42
- package/dist/logger.js +22 -1
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +3 -1
- 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 +2 -1
- 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/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-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 +8 -0
- package/package.json +15 -14
- 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.d.ts
CHANGED
|
@@ -3,15 +3,12 @@ export * from './assets';
|
|
|
3
3
|
export * from './ast';
|
|
4
4
|
export * from './auth';
|
|
5
5
|
export * from './collection';
|
|
6
|
-
export * from './extensions';
|
|
7
6
|
export * from './files';
|
|
8
7
|
export * from './graphql';
|
|
9
8
|
export * from './items';
|
|
10
9
|
export * from './meta';
|
|
11
10
|
export * from './migration';
|
|
12
|
-
export * from './relation';
|
|
13
11
|
export * from './revision';
|
|
14
|
-
export * from './schema';
|
|
15
12
|
export * from './services';
|
|
16
13
|
export * from './snapshot';
|
|
17
14
|
export * from './webhooks';
|
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;
|
|
@@ -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"
|
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"
|
|
@@ -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",
|
|
@@ -123,8 +124,8 @@
|
|
|
123
124
|
"json2csv": "^5.0.3",
|
|
124
125
|
"jsonwebtoken": "^8.5.1",
|
|
125
126
|
"keyv": "^4.0.3",
|
|
126
|
-
"knex": "^0.95.
|
|
127
|
-
"knex-schema-inspector": "1.
|
|
127
|
+
"knex": "^0.95.14",
|
|
128
|
+
"knex-schema-inspector": "1.7.2",
|
|
128
129
|
"ldapjs": "^2.3.1",
|
|
129
130
|
"liquidjs": "^9.25.0",
|
|
130
131
|
"lodash": "^4.17.21",
|
|
@@ -171,7 +172,7 @@
|
|
|
171
172
|
"sqlite3": "^5.0.2",
|
|
172
173
|
"tedious": "^13.0.0"
|
|
173
174
|
},
|
|
174
|
-
"gitHead": "
|
|
175
|
+
"gitHead": "78a25fe9538dcd30452dc1a0889e720040c0596c",
|
|
175
176
|
"devDependencies": {
|
|
176
177
|
"@types/async": "3.2.10",
|
|
177
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
|
-
});
|