directus 9.1.2 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/drivers/ldap.js +11 -2
- package/dist/auth/drivers/oauth2.d.ts +1 -1
- package/dist/auth/drivers/oauth2.js +46 -19
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +34 -17
- package/dist/auth.js +5 -3
- package/dist/cli/commands/bootstrap/index.js +3 -2
- package/dist/cli/commands/database/install.js +2 -4
- package/dist/cli/commands/init/index.js +3 -7
- package/dist/cli/commands/schema/apply.js +26 -10
- package/dist/cli/utils/defaults.d.ts +11 -0
- package/dist/cli/utils/defaults.js +14 -0
- package/dist/controllers/assets.js +0 -27
- package/dist/controllers/auth.js +7 -2
- package/dist/controllers/extensions.js +1 -1
- package/dist/database/{functions/types.d.ts → helpers/date/dialects/mssql.d.ts} +2 -1
- package/dist/database/{functions → helpers/date}/dialects/mssql.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/mysql.d.ts +2 -4
- package/dist/database/{functions → helpers/date}/dialects/mysql.js +4 -6
- package/dist/database/{functions/dialects/mssql.d.ts → helpers/date/dialects/oracle.d.ts} +2 -4
- package/dist/database/{functions → helpers/date}/dialects/oracle.js +4 -6
- package/dist/database/helpers/date/dialects/postgres.d.ts +12 -0
- package/dist/database/{functions → helpers/date}/dialects/postgres.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/sqlite.d.ts +3 -4
- package/dist/database/helpers/date/dialects/sqlite.js +35 -0
- package/dist/database/helpers/date/index.d.ts +6 -0
- package/dist/database/helpers/date/index.js +15 -0
- package/dist/database/helpers/date/types.d.ts +13 -0
- package/dist/database/helpers/date/types.js +10 -0
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +14 -0
- package/dist/database/helpers/geometry/dialects/mssql.js +36 -0
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/mysql.js +16 -0
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +15 -0
- package/dist/database/helpers/geometry/dialects/oracle.js +39 -0
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +10 -0
- package/dist/database/helpers/geometry/dialects/postgres.js +23 -0
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/redshift.js +16 -0
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +6 -0
- package/dist/database/helpers/geometry/dialects/sqlite.js +14 -0
- package/dist/database/helpers/geometry/index.d.ts +6 -0
- package/dist/database/helpers/geometry/index.js +15 -0
- package/dist/database/helpers/{geometry.d.ts → geometry/types.d.ts} +3 -7
- package/dist/database/helpers/geometry/types.js +54 -0
- package/dist/database/helpers/index.d.ts +8 -0
- package/dist/database/helpers/index.js +33 -0
- package/dist/database/helpers/types.d.ts +5 -0
- package/dist/database/helpers/types.js +9 -0
- package/dist/database/index.js +6 -6
- package/dist/database/run-ast.js +5 -5
- package/dist/database/seeds/run.js +3 -3
- package/dist/database/system-data/fields/notifications.yaml +1 -0
- package/dist/emitter.d.ts +3 -2
- package/dist/emitter.js +13 -6
- package/dist/env.js +1 -0
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +2 -0
- package/dist/exceptions/invalid-token.d.ts +4 -0
- package/dist/exceptions/invalid-token.js +10 -0
- package/dist/exceptions/unexpected-response.d.ts +4 -0
- package/dist/exceptions/unexpected-response.js +10 -0
- package/dist/extensions.d.ts +1 -0
- package/dist/extensions.js +22 -3
- package/dist/middleware/sanitize-query.js +1 -1
- package/dist/services/activity.js +7 -2
- package/dist/services/assets.js +14 -0
- package/dist/services/fields.d.ts +2 -0
- package/dist/services/fields.js +57 -26
- package/dist/services/files.d.ts +1 -1
- package/dist/services/files.js +27 -19
- package/dist/services/graphql.js +3 -0
- package/dist/services/items.js +18 -29
- package/dist/services/payload.d.ts +2 -0
- package/dist/services/payload.js +3 -3
- package/dist/services/users.js +8 -6
- package/dist/tests/database/migrations/run.test.d.ts +1 -0
- package/dist/tests/database/migrations/run.test.js +29 -0
- package/dist/types/extensions.d.ts +2 -0
- package/dist/utils/apply-query.js +9 -12
- package/dist/utils/apply-snapshot.js +91 -37
- package/dist/utils/get-column.js +2 -2
- package/dist/utils/get-default-index-name.js +2 -2
- package/dist/utils/get-local-type.js +1 -12
- package/dist/utils/get-permissions.d.ts +2 -2
- package/dist/utils/get-permissions.js +103 -66
- package/dist/utils/sanitize-query.js +1 -12
- package/dist/utils/validate-query.js +1 -1
- package/dist/webhooks.js +16 -24
- package/package.json +15 -14
- package/dist/database/functions/dialects/oracle.d.ts +0 -14
- package/dist/database/functions/dialects/postgres.d.ts +0 -14
- package/dist/database/functions/dialects/sqlite.js +0 -33
- package/dist/database/functions/index.d.ts +0 -3
- package/dist/database/functions/index.js +0 -26
- package/dist/database/functions/types.js +0 -2
- package/dist/database/helpers/date.d.ts +0 -8
- package/dist/database/helpers/date.js +0 -44
- package/dist/database/helpers/geometry.js +0 -189
- package/dist/utils/get-simple-hash.d.ts +0 -5
- package/dist/utils/get-simple-hash.js +0 -15
package/dist/services/items.js
CHANGED
|
@@ -213,8 +213,16 @@ class ItemsService {
|
|
|
213
213
|
if (records === null) {
|
|
214
214
|
throw new exceptions_1.ForbiddenException();
|
|
215
215
|
}
|
|
216
|
+
const filteredRecords = await emitter_1.default.emitFilter(`${this.eventScope}.read`, records, {
|
|
217
|
+
query,
|
|
218
|
+
collection: this.collection,
|
|
219
|
+
}, {
|
|
220
|
+
database: this.knex,
|
|
221
|
+
schema: this.schema,
|
|
222
|
+
accountability: this.accountability,
|
|
223
|
+
});
|
|
216
224
|
emitter_1.default.emitAction(`${this.eventScope}.read`, {
|
|
217
|
-
payload:
|
|
225
|
+
payload: filteredRecords,
|
|
218
226
|
query,
|
|
219
227
|
collection: this.collection,
|
|
220
228
|
}, {
|
|
@@ -222,23 +230,15 @@ class ItemsService {
|
|
|
222
230
|
schema: this.schema,
|
|
223
231
|
accountability: this.accountability,
|
|
224
232
|
});
|
|
225
|
-
return
|
|
233
|
+
return filteredRecords;
|
|
226
234
|
}
|
|
227
235
|
/**
|
|
228
236
|
* Get single item by primary key
|
|
229
237
|
*/
|
|
230
|
-
async readOne(key, query, opts) {
|
|
231
|
-
query = query !== null && query !== void 0 ? query : {};
|
|
238
|
+
async readOne(key, query = {}, opts) {
|
|
232
239
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
filter: {
|
|
236
|
-
...(query.filter || {}),
|
|
237
|
-
[primaryKeyField]: {
|
|
238
|
-
_eq: key,
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
};
|
|
240
|
+
const filterWithKey = (0, lodash_1.assign)({}, query.filter, { [primaryKeyField]: { _eq: key } });
|
|
241
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
242
242
|
const results = await this.readByQuery(queryWithKey, opts);
|
|
243
243
|
if (results.length === 0) {
|
|
244
244
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -248,23 +248,12 @@ class ItemsService {
|
|
|
248
248
|
/**
|
|
249
249
|
* Get multiple items by primary keys
|
|
250
250
|
*/
|
|
251
|
-
async readMany(keys, query, opts) {
|
|
252
|
-
|
|
251
|
+
async readMany(keys, query = {}, opts) {
|
|
252
|
+
var _a;
|
|
253
253
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
_and: [
|
|
258
|
-
query.filter || {},
|
|
259
|
-
{
|
|
260
|
-
[primaryKeyField]: {
|
|
261
|
-
_in: keys,
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
],
|
|
265
|
-
},
|
|
266
|
-
};
|
|
267
|
-
const results = await this.readByQuery(queryWithKeys, opts);
|
|
254
|
+
const filterWithKey = { _and: [{ [primaryKeyField]: { _in: keys } }, (_a = query.filter) !== null && _a !== void 0 ? _a : {}] };
|
|
255
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
256
|
+
const results = await this.readByQuery(queryWithKey, opts);
|
|
268
257
|
return results;
|
|
269
258
|
}
|
|
270
259
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { AbstractServiceOptions, Item, PrimaryKey, SchemaOverview } from '../types';
|
|
3
3
|
import { Accountability } from '@directus/shared/types';
|
|
4
|
+
import { Helpers } from '../database/helpers';
|
|
4
5
|
declare type Action = 'create' | 'read' | 'update';
|
|
5
6
|
declare type Transformers = {
|
|
6
7
|
[type: string]: (context: {
|
|
@@ -18,6 +19,7 @@ declare type Transformers = {
|
|
|
18
19
|
export declare class PayloadService {
|
|
19
20
|
accountability: Accountability | null;
|
|
20
21
|
knex: Knex;
|
|
22
|
+
helpers: Helpers;
|
|
21
23
|
collection: string;
|
|
22
24
|
schema: SchemaOverview;
|
|
23
25
|
constructor(collection: string, options: AbstractServiceOptions);
|
package/dist/services/payload.js
CHANGED
|
@@ -13,7 +13,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
13
13
|
const utils_1 = require("@directus/shared/utils");
|
|
14
14
|
const items_1 = require("./items");
|
|
15
15
|
const flat_1 = require("flat");
|
|
16
|
-
const
|
|
16
|
+
const helpers_1 = require("../database/helpers");
|
|
17
17
|
const wellknown_1 = require("wellknown");
|
|
18
18
|
const generate_hash_1 = require("../utils/generate-hash");
|
|
19
19
|
/**
|
|
@@ -111,6 +111,7 @@ class PayloadService {
|
|
|
111
111
|
};
|
|
112
112
|
this.accountability = options.accountability || null;
|
|
113
113
|
this.knex = options.knex || (0, database_1.default)();
|
|
114
|
+
this.helpers = (0, helpers_1.getHelpers)(this.knex);
|
|
114
115
|
this.collection = collection;
|
|
115
116
|
this.schema = options.schema;
|
|
116
117
|
return this;
|
|
@@ -188,10 +189,9 @@ class PayloadService {
|
|
|
188
189
|
* to check if the value is a raw instance before stringifying it in the next step.
|
|
189
190
|
*/
|
|
190
191
|
processGeometries(payloads, action) {
|
|
191
|
-
const helper = (0, geometry_1.getGeometryHelper)();
|
|
192
192
|
const process = action == 'read'
|
|
193
193
|
? (value) => (typeof value === 'string' ? (0, wellknown_1.parse)(value) : value)
|
|
194
|
-
: (value) =>
|
|
194
|
+
: (value) => this.helpers.st.fromGeoJSON(typeof value == 'string' ? JSON.parse(value) : value);
|
|
195
195
|
const fieldsInCollection = Object.entries(this.schema.collections[this.collection].fields);
|
|
196
196
|
const geometryColumns = fieldsInCollection.filter(([_, field]) => field.type.startsWith('geometry'));
|
|
197
197
|
for (const [name] of geometryColumns) {
|
package/dist/services/users.js
CHANGED
|
@@ -19,6 +19,7 @@ const mail_1 = require("./mail");
|
|
|
19
19
|
const settings_1 = require("./settings");
|
|
20
20
|
const stall_1 = require("../utils/stall");
|
|
21
21
|
const perf_hooks_1 = require("perf_hooks");
|
|
22
|
+
const utils_2 = require("@directus/shared/utils");
|
|
22
23
|
class UsersService extends items_1.ItemsService {
|
|
23
24
|
constructor(options) {
|
|
24
25
|
super('directus_users', options);
|
|
@@ -251,7 +252,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
251
252
|
}
|
|
252
253
|
const STALL_TIME = 500;
|
|
253
254
|
const timeStart = perf_hooks_1.performance.now();
|
|
254
|
-
const user = await this.knex.select('status').from('directus_users').where({ email }).first();
|
|
255
|
+
const user = await this.knex.select('status', 'password').from('directus_users').where({ email }).first();
|
|
255
256
|
if ((user === null || user === void 0 ? void 0 : user.status) !== 'active') {
|
|
256
257
|
await (0, stall_1.stall)(STALL_TIME, timeStart);
|
|
257
258
|
throw new exceptions_2.ForbiddenException();
|
|
@@ -261,7 +262,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
261
262
|
knex: this.knex,
|
|
262
263
|
accountability: this.accountability,
|
|
263
264
|
});
|
|
264
|
-
const payload = { email, scope: 'password-reset' };
|
|
265
|
+
const payload = { email, scope: 'password-reset', hash: (0, utils_2.getSimpleHash)('' + user.password) };
|
|
265
266
|
const token = jsonwebtoken_1.default.sign(payload, env_1.default.SECRET, { expiresIn: '1d', issuer: 'directus' });
|
|
266
267
|
const acceptURL = url ? `${url}?token=${token}` : `${env_1.default.PUBLIC_URL}/admin/reset-password?token=${token}`;
|
|
267
268
|
const subjectLine = subject ? subject : 'Password Reset Request';
|
|
@@ -279,11 +280,12 @@ class UsersService extends items_1.ItemsService {
|
|
|
279
280
|
await (0, stall_1.stall)(STALL_TIME, timeStart);
|
|
280
281
|
}
|
|
281
282
|
async resetPassword(token, password) {
|
|
282
|
-
const { email, scope } = jsonwebtoken_1.default.verify(token, env_1.default.SECRET, { issuer: 'directus' });
|
|
283
|
-
if (scope !== 'password-reset')
|
|
283
|
+
const { email, scope, hash } = jsonwebtoken_1.default.verify(token, env_1.default.SECRET, { issuer: 'directus' });
|
|
284
|
+
if (scope !== 'password-reset' || !hash)
|
|
284
285
|
throw new exceptions_2.ForbiddenException();
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
await this.checkPasswordPolicy([password]);
|
|
287
|
+
const user = await this.knex.select('id', 'status', 'password').from('directus_users').where({ email }).first();
|
|
288
|
+
if ((user === null || user === void 0 ? void 0 : user.status) !== 'active' || hash !== (0, utils_2.getSimpleHash)('' + user.password)) {
|
|
287
289
|
throw new exceptions_2.ForbiddenException();
|
|
288
290
|
}
|
|
289
291
|
// Allow unauthenticated update
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
});
|
|
@@ -5,6 +5,7 @@ import { Logger } from 'pino';
|
|
|
5
5
|
import env from '../env';
|
|
6
6
|
import * as exceptions from '../exceptions';
|
|
7
7
|
import * as services from '../services';
|
|
8
|
+
import { Emitter } from '../emitter';
|
|
8
9
|
import { getSchema } from '../utils/get-schema';
|
|
9
10
|
import { SchemaOverview } from './schema';
|
|
10
11
|
export declare type ExtensionContext = {
|
|
@@ -12,6 +13,7 @@ export declare type ExtensionContext = {
|
|
|
12
13
|
exceptions: typeof exceptions;
|
|
13
14
|
database: Knex;
|
|
14
15
|
env: typeof env;
|
|
16
|
+
emitter: Emitter;
|
|
15
17
|
logger: Logger;
|
|
16
18
|
getSchema: typeof getSchema;
|
|
17
19
|
};
|
|
@@ -8,11 +8,9 @@ const lodash_1 = require("lodash");
|
|
|
8
8
|
const nanoid_1 = require("nanoid");
|
|
9
9
|
const uuid_validate_1 = __importDefault(require("uuid-validate"));
|
|
10
10
|
const exceptions_1 = require("../exceptions");
|
|
11
|
-
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
12
11
|
const get_column_1 = require("./get-column");
|
|
13
12
|
const get_relation_type_1 = require("./get-relation-type");
|
|
14
|
-
const
|
|
15
|
-
const date_1 = require("../database/helpers/date");
|
|
13
|
+
const helpers_1 = require("../database/helpers");
|
|
16
14
|
const generateAlias = (0, nanoid_1.customAlphabet)('abcdefghijklmnopqrstuvwxyz', 5);
|
|
17
15
|
/**
|
|
18
16
|
* Apply the Query to a given Knex query builder instance
|
|
@@ -45,7 +43,7 @@ function applyQuery(knex, collection, dbQuery, query, schema, subQuery = false)
|
|
|
45
43
|
applySearch(schema, dbQuery, query.search, collection);
|
|
46
44
|
}
|
|
47
45
|
if (query.group) {
|
|
48
|
-
dbQuery.groupBy(query.group.map(
|
|
46
|
+
dbQuery.groupBy(query.group.map((column) => (0, get_column_1.getColumn)(knex, collection, column, false)));
|
|
49
47
|
}
|
|
50
48
|
if (query.aggregate) {
|
|
51
49
|
applyAggregate(dbQuery, query.aggregate, collection);
|
|
@@ -117,6 +115,7 @@ exports.default = applyQuery;
|
|
|
117
115
|
* ```
|
|
118
116
|
*/
|
|
119
117
|
function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery = false) {
|
|
118
|
+
const helpers = (0, helpers_1.getHelpers)(knex);
|
|
120
119
|
const relations = schema.relations;
|
|
121
120
|
const aliasMap = {};
|
|
122
121
|
addJoins(rootQuery, rootFilter, collection);
|
|
@@ -273,16 +272,15 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
273
272
|
query.where(key, '!=', '');
|
|
274
273
|
});
|
|
275
274
|
}
|
|
276
|
-
const dateHelper = (0, date_1.getDateHelper)();
|
|
277
275
|
const [collection, field] = key.split('.');
|
|
278
276
|
if (collection in schema.collections && field in schema.collections[collection].fields) {
|
|
279
277
|
const type = schema.collections[collection].fields[field].type;
|
|
280
278
|
if (['date', 'dateTime', 'time', 'timestamp'].includes(type)) {
|
|
281
279
|
if (Array.isArray(compareValue)) {
|
|
282
|
-
compareValue = compareValue.map((val) =>
|
|
280
|
+
compareValue = compareValue.map((val) => helpers.date.parse(val));
|
|
283
281
|
}
|
|
284
282
|
else {
|
|
285
|
-
compareValue =
|
|
283
|
+
compareValue = helpers.date.parse(compareValue);
|
|
286
284
|
}
|
|
287
285
|
}
|
|
288
286
|
}
|
|
@@ -361,18 +359,17 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
361
359
|
value = value.split(',');
|
|
362
360
|
dbQuery[logical].whereNotBetween(selectionRaw, value);
|
|
363
361
|
}
|
|
364
|
-
const geometryHelper = (0, geometry_1.getGeometryHelper)();
|
|
365
362
|
if (operator == '_intersects') {
|
|
366
|
-
dbQuery[logical].whereRaw(
|
|
363
|
+
dbQuery[logical].whereRaw(helpers.st.intersects(key, compareValue));
|
|
367
364
|
}
|
|
368
365
|
if (operator == '_nintersects') {
|
|
369
|
-
dbQuery[logical].whereRaw(
|
|
366
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects(key, compareValue));
|
|
370
367
|
}
|
|
371
368
|
if (operator == '_intersects_bbox') {
|
|
372
|
-
dbQuery[logical].whereRaw(
|
|
369
|
+
dbQuery[logical].whereRaw(helpers.st.intersects_bbox(key, compareValue));
|
|
373
370
|
}
|
|
374
371
|
if (operator == '_nintersects_bbox') {
|
|
375
|
-
dbQuery[logical].whereRaw(
|
|
372
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects_bbox(key, compareValue));
|
|
376
373
|
}
|
|
377
374
|
}
|
|
378
375
|
function getWhereColumn(path, collection) {
|
|
@@ -10,6 +10,7 @@ const database_1 = __importDefault(require("../database"));
|
|
|
10
10
|
const get_schema_1 = require("./get-schema");
|
|
11
11
|
const services_1 = require("../services");
|
|
12
12
|
const lodash_1 = require("lodash");
|
|
13
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
13
14
|
async function applySnapshot(snapshot, options) {
|
|
14
15
|
var _a, _b, _c, _d;
|
|
15
16
|
const database = (_a = options === null || options === void 0 ? void 0 : options.database) !== null && _a !== void 0 ? _a : (0, database_1.default)();
|
|
@@ -20,7 +21,13 @@ async function applySnapshot(snapshot, options) {
|
|
|
20
21
|
const collectionsService = new services_1.CollectionsService({ knex: trx, schema });
|
|
21
22
|
for (const { collection, diff } of snapshotDiff.collections) {
|
|
22
23
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
23
|
-
|
|
24
|
+
try {
|
|
25
|
+
await collectionsService.deleteOne(collection);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
logger_1.default.error(`Failed to delete collection "${collection}"`);
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
24
31
|
}
|
|
25
32
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N' && diff[0].rhs) {
|
|
26
33
|
// We'll nest the to-be-created fields in the same collection creation, to prevent
|
|
@@ -28,65 +35,112 @@ async function applySnapshot(snapshot, options) {
|
|
|
28
35
|
const fields = snapshotDiff.fields
|
|
29
36
|
.filter((fieldDiff) => fieldDiff.collection === collection)
|
|
30
37
|
.map((fieldDiff) => fieldDiff.diff[0].rhs);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
try {
|
|
39
|
+
await collectionsService.createOne({
|
|
40
|
+
...diff[0].rhs,
|
|
41
|
+
fields,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
logger_1.default.error(`Failed to create collection "${collection}"`);
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
35
48
|
// Now that the fields are in for this collection, we can strip them from the field
|
|
36
49
|
// edits
|
|
37
50
|
snapshotDiff.fields = snapshotDiff.fields.filter((fieldDiff) => fieldDiff.collection !== collection);
|
|
38
51
|
}
|
|
39
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
53
|
+
const newValues = snapshot.collections.find((field) => {
|
|
54
|
+
return field.collection === collection;
|
|
55
|
+
});
|
|
56
|
+
if (newValues) {
|
|
57
|
+
try {
|
|
58
|
+
await collectionsService.updateOne(collection, newValues);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
logger_1.default.error(`Failed to update collection "${collection}"`);
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
47
65
|
}
|
|
48
66
|
}
|
|
49
67
|
const fieldsService = new services_1.FieldsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
50
68
|
for (const { collection, field, diff } of snapshotDiff.fields) {
|
|
51
69
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
52
|
-
|
|
70
|
+
try {
|
|
71
|
+
await fieldsService.createField(collection, diff[0].rhs);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logger_1.default.error(`Failed to create field "${collection}.${field}"`);
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
53
77
|
}
|
|
54
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
return acc;
|
|
58
|
-
(0, lodash_1.set)(acc, edit.path, edit.rhs);
|
|
59
|
-
return acc;
|
|
60
|
-
}, {});
|
|
61
|
-
await fieldsService.updateField(collection, {
|
|
62
|
-
field,
|
|
63
|
-
type: 'unknown',
|
|
64
|
-
...updates,
|
|
78
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
79
|
+
const newValues = snapshot.fields.find((snapshotField) => {
|
|
80
|
+
return snapshotField.collection === collection && snapshotField.field === field;
|
|
65
81
|
});
|
|
82
|
+
if (newValues) {
|
|
83
|
+
try {
|
|
84
|
+
await fieldsService.updateField(collection, {
|
|
85
|
+
...newValues,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
logger_1.default.error(`Failed to update field "${collection}.${field}"`);
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
66
93
|
}
|
|
67
94
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
68
|
-
|
|
95
|
+
try {
|
|
96
|
+
await fieldsService.deleteField(collection, field);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
logger_1.default.error(`Failed to delete field "${collection}.${field}"`);
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
69
102
|
// Field deletion also cleans up the relationship. We should ignore any relationship
|
|
70
103
|
// changes attached to this now non-existing field
|
|
71
104
|
snapshotDiff.relations = snapshotDiff.relations.filter((relation) => (relation.collection === collection && relation.field === field) === false);
|
|
72
105
|
}
|
|
73
106
|
}
|
|
74
107
|
const relationsService = new services_1.RelationsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
75
|
-
for (const { collection, field, diff
|
|
108
|
+
for (const { collection, field, diff } of snapshotDiff.relations) {
|
|
109
|
+
const structure = {};
|
|
110
|
+
for (const diffEdit of diff) {
|
|
111
|
+
(0, lodash_1.set)(structure, diffEdit.path, undefined);
|
|
112
|
+
}
|
|
76
113
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
77
|
-
|
|
114
|
+
try {
|
|
115
|
+
await relationsService.createOne(diff[0].rhs);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger_1.default.error(`Failed to create relation "${collection}.${field}"`);
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
78
121
|
}
|
|
79
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
122
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
123
|
+
const newValues = snapshot.relations.find((relation) => {
|
|
124
|
+
return relation.collection === collection && relation.field === field;
|
|
125
|
+
});
|
|
126
|
+
if (newValues) {
|
|
127
|
+
try {
|
|
128
|
+
await relationsService.updateOne(collection, field, newValues);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
logger_1.default.error(`Failed to update relation "${collection}.${field}"`);
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
87
135
|
}
|
|
88
136
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
89
|
-
|
|
137
|
+
try {
|
|
138
|
+
await relationsService.deleteOne(collection, field);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
logger_1.default.error(`Failed to delete relation "${collection}.${field}"`);
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
90
144
|
}
|
|
91
145
|
}
|
|
92
146
|
});
|
package/dist/utils/get-column.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getColumn = void 0;
|
|
4
|
-
const
|
|
4
|
+
const helpers_1 = require("../database/helpers");
|
|
5
5
|
const constants_1 = require("@directus/shared/constants");
|
|
6
6
|
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
7
7
|
/**
|
|
@@ -15,7 +15,7 @@ const apply_function_to_column_name_1 = require("./apply-function-to-column-name
|
|
|
15
15
|
* @returns Knex raw instance
|
|
16
16
|
*/
|
|
17
17
|
function getColumn(knex, table, column, alias = (0, apply_function_to_column_name_1.applyFunctionToColumnName)(column)) {
|
|
18
|
-
const fn = (0,
|
|
18
|
+
const { date: fn } = (0, helpers_1.getHelpers)(knex);
|
|
19
19
|
if (column.includes('(') && column.includes(')')) {
|
|
20
20
|
const functionName = column.split('(')[0];
|
|
21
21
|
const columnName = column.match(constants_1.REGEX_BETWEEN_PARENS)[1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getDefaultIndexName = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
/**
|
|
6
6
|
* Generate an index name for a given collection + fields combination.
|
|
7
7
|
*
|
|
@@ -18,7 +18,7 @@ function getDefaultIndexName(type, collection, fields) {
|
|
|
18
18
|
const indexName = (table + '_' + fields.join('_') + '_' + type).toLowerCase();
|
|
19
19
|
if (indexName.length <= 60)
|
|
20
20
|
return indexName;
|
|
21
|
-
const suffix = `__${(0,
|
|
21
|
+
const suffix = `__${(0, utils_1.getSimpleHash)(indexName)}_${type}`;
|
|
22
22
|
const prefix = indexName.substring(0, 60 - suffix.length);
|
|
23
23
|
return `${prefix}${suffix}`;
|
|
24
24
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const database_1 = require("../database");
|
|
7
|
-
const database_2 = __importDefault(require("../database"));
|
|
8
3
|
const localTypeMap = {
|
|
9
4
|
// Shared
|
|
10
5
|
boolean: 'boolean',
|
|
@@ -100,8 +95,6 @@ const localTypeMap = {
|
|
|
100
95
|
integerfirst: 'integer',
|
|
101
96
|
};
|
|
102
97
|
function getLocalType(column, field) {
|
|
103
|
-
const database = (0, database_2.default)();
|
|
104
|
-
const databaseClient = (0, database_1.getDatabaseClient)(database);
|
|
105
98
|
if (!column)
|
|
106
99
|
return 'alias';
|
|
107
100
|
const dataType = column.data_type.toLowerCase();
|
|
@@ -125,13 +118,9 @@ function getLocalType(column, field) {
|
|
|
125
118
|
return 'decimal';
|
|
126
119
|
}
|
|
127
120
|
/** Handle MS SQL varchar(MAX) (eg TEXT) types */
|
|
128
|
-
if (
|
|
121
|
+
if (column.data_type === 'nvarchar' && column.max_length === -1) {
|
|
129
122
|
return 'text';
|
|
130
123
|
}
|
|
131
|
-
/** Handle Boolean as TINYINT and edgecase MySQL where it still is just tinyint */
|
|
132
|
-
if (databaseClient === 'mysql' && dataType === 'tinyint(1)') {
|
|
133
|
-
return 'boolean';
|
|
134
|
-
}
|
|
135
124
|
return type !== null && type !== void 0 ? type : 'unknown';
|
|
136
125
|
}
|
|
137
126
|
exports.default = getLocalType;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Accountability } from '@directus/shared/types';
|
|
1
|
+
import { Permission, Accountability } from '@directus/shared/types';
|
|
2
2
|
import { SchemaOverview } from '../types';
|
|
3
|
-
export declare function getPermissions(accountability: Accountability, schema: SchemaOverview): Promise<
|
|
3
|
+
export declare function getPermissions(accountability: Accountability, schema: SchemaOverview): Promise<Permission[]>;
|