@directus/api 23.1.2 → 23.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/items.js +1 -1
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/cockroachdb.js +3 -3
- package/dist/database/helpers/schema/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mssql.js +3 -3
- package/dist/database/helpers/schema/dialects/oracle.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/oracle.js +8 -3
- package/dist/database/helpers/schema/dialects/postgres.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/postgres.js +3 -3
- package/dist/database/helpers/schema/types.d.ts +2 -1
- package/dist/database/helpers/schema/types.js +4 -1
- package/dist/database/helpers/schema/utils/{preprocess-bindings.d.ts → prep-query-params.d.ts} +2 -2
- package/dist/database/helpers/schema/utils/{preprocess-bindings.js → prep-query-params.js} +1 -1
- package/dist/database/index.js +8 -2
- package/dist/database/run-ast/utils/with-preprocess-bindings.js +4 -3
- package/dist/permissions/modules/validate-access/lib/validate-item-access.js +2 -1
- package/dist/storage/register-locations.js +1 -0
- package/package.json +18 -18
|
@@ -75,7 +75,7 @@ const readHandler = asyncHandler(async (req, res, next) => {
|
|
|
75
75
|
};
|
|
76
76
|
return next();
|
|
77
77
|
});
|
|
78
|
-
router.search('/:collection', collectionExists, validateBatch('read'), readHandler, respond);
|
|
78
|
+
router.search('/:collection', collectionExists, validateBatch('read'), readHandler, mergeContentVersions, respond);
|
|
79
79
|
router.get('/:collection', collectionExists, readHandler, mergeContentVersions, respond);
|
|
80
80
|
router.get('/:collection/:pk', collectionExists, asyncHandler(async (req, res, next) => {
|
|
81
81
|
if (isSystemCollection(req.params['collection']))
|
|
@@ -6,6 +6,6 @@ export declare class SchemaHelperCockroachDb extends SchemaHelper {
|
|
|
6
6
|
changeToType(table: string, column: string, type: (typeof KNEX_TYPES)[number], options?: Options): Promise<void>;
|
|
7
7
|
constraintName(existingName: string): string;
|
|
8
8
|
getDatabaseSize(): Promise<number | null>;
|
|
9
|
-
|
|
9
|
+
prepQueryParams(queryParams: Sql): Sql;
|
|
10
10
|
addInnerSortFieldsToGroupBy(groupByFields: (string | Knex.Raw)[], sortRecords: SortRecord[], hasRelationalSort: boolean): void;
|
|
11
11
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {} from 'knex';
|
|
2
2
|
import { SchemaHelper } from '../types.js';
|
|
3
3
|
import { useEnv } from '@directus/env';
|
|
4
|
-
import {
|
|
4
|
+
import { prepQueryParams } from '../utils/prep-query-params.js';
|
|
5
5
|
const env = useEnv();
|
|
6
6
|
export class SchemaHelperCockroachDb extends SchemaHelper {
|
|
7
7
|
async changeToType(table, column, type, options = {}) {
|
|
@@ -29,8 +29,8 @@ export class SchemaHelperCockroachDb extends SchemaHelper {
|
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
return
|
|
32
|
+
prepQueryParams(queryParams) {
|
|
33
|
+
return prepQueryParams(queryParams, { format: (index) => `$${index + 1}` });
|
|
34
34
|
}
|
|
35
35
|
addInnerSortFieldsToGroupBy(groupByFields, sortRecords, hasRelationalSort) {
|
|
36
36
|
if (hasRelationalSort) {
|
|
@@ -5,6 +5,6 @@ export declare class SchemaHelperMSSQL extends SchemaHelper {
|
|
|
5
5
|
applyOffset(rootQuery: Knex.QueryBuilder, offset: number): void;
|
|
6
6
|
formatUUID(uuid: string): string;
|
|
7
7
|
getDatabaseSize(): Promise<number | null>;
|
|
8
|
-
|
|
8
|
+
prepQueryParams(queryParams: Sql): Sql;
|
|
9
9
|
addInnerSortFieldsToGroupBy(groupByFields: (string | Knex.Raw)[], sortRecords: SortRecord[], _hasRelationalSort: boolean): void;
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SchemaHelper } from '../types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { prepQueryParams } from '../utils/prep-query-params.js';
|
|
3
3
|
export class SchemaHelperMSSQL extends SchemaHelper {
|
|
4
4
|
applyLimit(rootQuery, limit) {
|
|
5
5
|
// The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries,
|
|
@@ -27,8 +27,8 @@ export class SchemaHelperMSSQL extends SchemaHelper {
|
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
return
|
|
30
|
+
prepQueryParams(queryParams) {
|
|
31
|
+
return prepQueryParams(queryParams, { format: (index) => `@p${index}` });
|
|
32
32
|
}
|
|
33
33
|
addInnerSortFieldsToGroupBy(groupByFields, sortRecords, _hasRelationalSort) {
|
|
34
34
|
/*
|
|
@@ -9,6 +9,7 @@ export declare class SchemaHelperOracle extends SchemaHelper {
|
|
|
9
9
|
preRelationChange(relation: Partial<Relation>): void;
|
|
10
10
|
processFieldType(field: Field): Type;
|
|
11
11
|
getDatabaseSize(): Promise<number | null>;
|
|
12
|
-
|
|
12
|
+
prepQueryParams(queryParams: Sql): Sql;
|
|
13
|
+
prepBindings(bindings: Knex.Value[]): any;
|
|
13
14
|
addInnerSortFieldsToGroupBy(groupByFields: (string | Knex.Raw)[], sortRecords: SortRecord[], _hasRelationalSort: boolean): void;
|
|
14
15
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SchemaHelper } from '../types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { prepQueryParams } from '../utils/prep-query-params.js';
|
|
3
3
|
export class SchemaHelperOracle extends SchemaHelper {
|
|
4
4
|
async changeToType(table, column, type, options = {}) {
|
|
5
5
|
await this.changeToTypeByCopy(table, column, type, options);
|
|
@@ -39,8 +39,13 @@ export class SchemaHelperOracle extends SchemaHelper {
|
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
return
|
|
42
|
+
prepQueryParams(queryParams) {
|
|
43
|
+
return prepQueryParams(queryParams, { format: (index) => `:${index + 1}` });
|
|
44
|
+
}
|
|
45
|
+
prepBindings(bindings) {
|
|
46
|
+
// Create an object with keys 1, 2, 3, ... and the bindings as values
|
|
47
|
+
// This will use the "named" binding syntax in the oracledb driver instead of the positional binding
|
|
48
|
+
return Object.fromEntries(bindings.map((binding, index) => [index + 1, binding]));
|
|
44
49
|
}
|
|
45
50
|
addInnerSortFieldsToGroupBy(groupByFields, sortRecords, _hasRelationalSort) {
|
|
46
51
|
/*
|
|
@@ -2,6 +2,6 @@ import type { Knex } from 'knex';
|
|
|
2
2
|
import { SchemaHelper, type SortRecord, type Sql } from '../types.js';
|
|
3
3
|
export declare class SchemaHelperPostgres extends SchemaHelper {
|
|
4
4
|
getDatabaseSize(): Promise<number | null>;
|
|
5
|
-
|
|
5
|
+
prepQueryParams(queryParams: Sql): Sql;
|
|
6
6
|
addInnerSortFieldsToGroupBy(groupByFields: (string | Knex.Raw)[], sortRecords: SortRecord[], hasRelationalSort: boolean): void;
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEnv } from '@directus/env';
|
|
2
2
|
import { SchemaHelper } from '../types.js';
|
|
3
|
-
import {
|
|
3
|
+
import { prepQueryParams } from '../utils/prep-query-params.js';
|
|
4
4
|
const env = useEnv();
|
|
5
5
|
export class SchemaHelperPostgres extends SchemaHelper {
|
|
6
6
|
async getDatabaseSize() {
|
|
@@ -12,8 +12,8 @@ export class SchemaHelperPostgres extends SchemaHelper {
|
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
return
|
|
15
|
+
prepQueryParams(queryParams) {
|
|
16
|
+
return prepQueryParams(queryParams, { format: (index) => `$${index + 1}` });
|
|
17
17
|
}
|
|
18
18
|
addInnerSortFieldsToGroupBy(groupByFields, sortRecords, hasRelationalSort) {
|
|
19
19
|
if (hasRelationalSort) {
|
|
@@ -35,6 +35,7 @@ export declare abstract class SchemaHelper extends DatabaseHelper {
|
|
|
35
35
|
* @returns Size of the database in bytes
|
|
36
36
|
*/
|
|
37
37
|
getDatabaseSize(): Promise<number | null>;
|
|
38
|
-
|
|
38
|
+
prepQueryParams(queryParams: Sql): Sql;
|
|
39
|
+
prepBindings(bindings: Knex.Value[]): any;
|
|
39
40
|
addInnerSortFieldsToGroupBy(_groupByFields: (string | Knex.Raw)[], _sortRecords: SortRecord[], _hasRelationalSort: boolean): void;
|
|
40
41
|
}
|
|
@@ -94,9 +94,12 @@ export class SchemaHelper extends DatabaseHelper {
|
|
|
94
94
|
async getDatabaseSize() {
|
|
95
95
|
return null;
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
prepQueryParams(queryParams) {
|
|
98
98
|
return queryParams;
|
|
99
99
|
}
|
|
100
|
+
prepBindings(bindings) {
|
|
101
|
+
return bindings;
|
|
102
|
+
}
|
|
100
103
|
addInnerSortFieldsToGroupBy(_groupByFields, _sortRecords, _hasRelationalSort) {
|
|
101
104
|
// no-op by default
|
|
102
105
|
}
|
package/dist/database/helpers/schema/utils/{preprocess-bindings.d.ts → prep-query-params.d.ts}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
2
|
import type { Sql } from '../types.js';
|
|
3
|
-
export type
|
|
3
|
+
export type PrepQueryParamsOptions = {
|
|
4
4
|
format(index: number): string;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* Preprocess a SQL query, such that repeated binding values are bound to the same binding index.
|
|
8
8
|
**/
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function prepQueryParams(queryParams: (Partial<Sql> & Pick<Sql, 'sql'>) | string, options: PrepQueryParamsOptions): {
|
|
10
10
|
sql: string;
|
|
11
11
|
bindings: Knex.Value[];
|
|
12
12
|
};
|
|
@@ -2,7 +2,7 @@ import { isString } from 'lodash-es';
|
|
|
2
2
|
/**
|
|
3
3
|
* Preprocess a SQL query, such that repeated binding values are bound to the same binding index.
|
|
4
4
|
**/
|
|
5
|
-
export function
|
|
5
|
+
export function prepQueryParams(queryParams, options) {
|
|
6
6
|
const query = { bindings: [], ...(isString(queryParams) ? { sql: queryParams } : queryParams) };
|
|
7
7
|
// bindingIndices[i] is the index of the first occurrence of query.bindings[i]
|
|
8
8
|
const bindingIndices = new Map();
|
package/dist/database/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createInspector } from '@directus/schema';
|
|
|
3
3
|
import { isObject } from '@directus/utils';
|
|
4
4
|
import fse from 'fs-extra';
|
|
5
5
|
import knex from 'knex';
|
|
6
|
-
import { merge } from 'lodash-es';
|
|
6
|
+
import { isArray, merge } from 'lodash-es';
|
|
7
7
|
import { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import path from 'path';
|
|
@@ -139,7 +139,13 @@ export function getDatabase() {
|
|
|
139
139
|
delta = performance.now() - time;
|
|
140
140
|
times.delete(queryInfo.__knexUid);
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
// eslint-disable-next-line no-nested-ternary
|
|
143
|
+
const bindings = queryInfo.bindings
|
|
144
|
+
? isArray(queryInfo.bindings)
|
|
145
|
+
? queryInfo.bindings
|
|
146
|
+
: Object.values(queryInfo.bindings)
|
|
147
|
+
: [];
|
|
148
|
+
logger.trace(`[${delta ? delta.toFixed(3) : '?'}ms] ${queryInfo.sql} [${bindings.join(', ')}]`);
|
|
143
149
|
})
|
|
144
150
|
.on('query-error', (_, queryInfo) => {
|
|
145
151
|
times.delete(queryInfo.__knexUid);
|
|
@@ -4,9 +4,10 @@ export function withPreprocessBindings(knex, dbQuery) {
|
|
|
4
4
|
dbQuery.client = new Proxy(dbQuery.client, {
|
|
5
5
|
get(target, prop, receiver) {
|
|
6
6
|
if (prop === 'query') {
|
|
7
|
-
return (connection,
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
return (connection, queryParams) => Reflect.get(target, prop, receiver).bind(dbQuery.client)(connection, schemaHelper.prepQueryParams(queryParams));
|
|
8
|
+
}
|
|
9
|
+
if (prop === 'prepBindings') {
|
|
10
|
+
return (bindings) => schemaHelper.prepBindings(Reflect.get(target, prop, receiver).bind(dbQuery.client)(bindings));
|
|
10
11
|
}
|
|
11
12
|
return Reflect.get(target, prop, receiver);
|
|
12
13
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toBoolean } from '@directus/utils';
|
|
1
2
|
import { fetchPermittedAstRootFields } from '../../../../database/run-ast/modules/fetch-permitted-ast-root-fields.js';
|
|
2
3
|
import { processAst } from '../../process-ast/process-ast.js';
|
|
3
4
|
export async function validateItemAccess(options, context) {
|
|
@@ -31,7 +32,7 @@ export async function validateItemAccess(options, context) {
|
|
|
31
32
|
if (items && items.length === options.primaryKeys.length) {
|
|
32
33
|
const { fields } = options;
|
|
33
34
|
if (fields) {
|
|
34
|
-
return items.every((item) => fields.every((field) => item[field]
|
|
35
|
+
return items.every((item) => fields.every((field) => toBoolean(item[field])));
|
|
35
36
|
}
|
|
36
37
|
return true;
|
|
37
38
|
}
|
|
@@ -6,6 +6,7 @@ export const registerLocations = async (storage) => {
|
|
|
6
6
|
const env = useEnv();
|
|
7
7
|
const locations = toArray(env['STORAGE_LOCATIONS']);
|
|
8
8
|
const tus = {
|
|
9
|
+
enabled: RESUMABLE_UPLOADS.ENABLED,
|
|
9
10
|
chunkSize: RESUMABLE_UPLOADS.CHUNK_SIZE,
|
|
10
11
|
};
|
|
11
12
|
locations.forEach((location) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/api",
|
|
3
|
-
"version": "23.1.
|
|
3
|
+
"version": "23.1.3",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -149,29 +149,29 @@
|
|
|
149
149
|
"ws": "8.18.0",
|
|
150
150
|
"zod": "3.23.8",
|
|
151
151
|
"zod-validation-error": "3.4.0",
|
|
152
|
-
"@directus/app": "13.3.
|
|
153
|
-
"@directus/constants": "12.0.
|
|
154
|
-
"@directus/env": "
|
|
152
|
+
"@directus/app": "13.3.3",
|
|
153
|
+
"@directus/constants": "12.0.1",
|
|
154
|
+
"@directus/env": "4.0.0",
|
|
155
155
|
"@directus/errors": "1.0.1",
|
|
156
|
-
"@directus/extensions
|
|
157
|
-
"@directus/extensions": "2.0.
|
|
158
|
-
"@directus/extensions-sdk": "12.1.
|
|
156
|
+
"@directus/extensions": "2.0.5",
|
|
157
|
+
"@directus/extensions-registry": "2.0.5",
|
|
158
|
+
"@directus/extensions-sdk": "12.1.3",
|
|
159
159
|
"@directus/format-title": "11.0.0",
|
|
160
|
-
"@directus/memory": "2.0.
|
|
161
|
-
"@directus/pressure": "2.0.
|
|
160
|
+
"@directus/memory": "2.0.5",
|
|
161
|
+
"@directus/pressure": "2.0.4",
|
|
162
162
|
"@directus/schema": "12.1.1",
|
|
163
163
|
"@directus/specs": "11.1.0",
|
|
164
164
|
"@directus/storage": "11.0.1",
|
|
165
|
-
"@directus/storage-driver-azure": "11.1.
|
|
166
|
-
"@directus/storage-driver-
|
|
167
|
-
"@directus/storage-driver-
|
|
165
|
+
"@directus/storage-driver-azure": "11.1.1",
|
|
166
|
+
"@directus/storage-driver-cloudinary": "11.1.1",
|
|
167
|
+
"@directus/storage-driver-gcs": "11.1.1",
|
|
168
168
|
"@directus/storage-driver-local": "11.0.1",
|
|
169
|
-
"@directus/storage-driver-s3": "11.0.
|
|
170
|
-
"@directus/storage-driver-supabase": "2.1.
|
|
169
|
+
"@directus/storage-driver-s3": "11.0.4",
|
|
170
|
+
"@directus/storage-driver-supabase": "2.1.1",
|
|
171
171
|
"@directus/system-data": "2.1.1",
|
|
172
|
-
"@directus/
|
|
173
|
-
"@directus/
|
|
174
|
-
"directus": "11.2.
|
|
172
|
+
"@directus/utils": "12.0.4",
|
|
173
|
+
"@directus/validation": "1.0.4",
|
|
174
|
+
"directus": "11.2.2"
|
|
175
175
|
},
|
|
176
176
|
"devDependencies": {
|
|
177
177
|
"@ngneat/falso": "7.2.0",
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
"vitest": "2.1.2",
|
|
216
216
|
"@directus/random": "1.0.0",
|
|
217
217
|
"@directus/tsconfig": "2.0.0",
|
|
218
|
-
"@directus/types": "12.2.
|
|
218
|
+
"@directus/types": "12.2.2"
|
|
219
219
|
},
|
|
220
220
|
"optionalDependencies": {
|
|
221
221
|
"@keyv/redis": "3.0.1",
|