@directus/api 30.0.0 → 32.0.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/app.js +7 -0
- package/dist/auth/auth.d.ts +2 -1
- package/dist/auth/auth.js +7 -2
- package/dist/auth/drivers/ldap.d.ts +0 -2
- package/dist/auth/drivers/ldap.js +9 -7
- package/dist/auth/drivers/oauth2.d.ts +0 -2
- package/dist/auth/drivers/oauth2.js +28 -11
- package/dist/auth/drivers/openid.d.ts +0 -2
- package/dist/auth/drivers/openid.js +28 -11
- package/dist/auth/drivers/saml.d.ts +0 -2
- package/dist/auth/drivers/saml.js +5 -5
- package/dist/auth.js +1 -2
- package/dist/cli/commands/bootstrap/index.js +12 -33
- package/dist/cli/commands/init/index.js +1 -1
- package/dist/cli/commands/schema/apply.d.ts +4 -0
- package/dist/cli/commands/schema/apply.js +26 -3
- package/dist/controllers/collections.js +7 -2
- package/dist/controllers/fields.js +31 -8
- package/dist/controllers/mcp.d.ts +2 -0
- package/dist/controllers/mcp.js +33 -0
- package/dist/controllers/server.js +26 -1
- package/dist/controllers/settings.js +9 -2
- package/dist/controllers/users.js +17 -7
- package/dist/controllers/versions.js +3 -2
- package/dist/database/errors/dialects/mssql.d.ts +1 -1
- package/dist/database/errors/dialects/mssql.js +18 -10
- package/dist/database/helpers/fn/types.js +3 -3
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/cockroachdb.js +13 -0
- package/dist/database/helpers/schema/dialects/mssql.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/mssql.js +23 -0
- package/dist/database/helpers/schema/dialects/mysql.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/mysql.js +25 -0
- package/dist/database/helpers/schema/dialects/oracle.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/oracle.js +13 -0
- package/dist/database/helpers/schema/dialects/postgres.d.ts +2 -1
- package/dist/database/helpers/schema/dialects/postgres.js +13 -0
- package/dist/database/helpers/schema/types.d.ts +5 -0
- package/dist/database/helpers/schema/types.js +6 -0
- package/dist/database/migrations/20250813A-add-mcp.d.ts +3 -0
- package/dist/database/migrations/20250813A-add-mcp.js +18 -0
- package/dist/database/migrations/20251012A-add-field-searchable.d.ts +3 -0
- package/dist/database/migrations/20251012A-add-field-searchable.js +10 -0
- package/dist/database/migrations/20251014A-add-project-owner.d.ts +3 -0
- package/dist/database/migrations/20251014A-add-project-owner.js +37 -0
- package/dist/database/migrations/20251028A-add-retention-indexes.d.ts +3 -0
- package/dist/database/migrations/20251028A-add-retention-indexes.js +42 -0
- package/dist/database/run-ast/README.md +46 -0
- package/dist/database/run-ast/lib/apply-query/add-join.js +2 -2
- package/dist/database/run-ast/lib/apply-query/filter/get-filter-type.d.ts +2 -2
- package/dist/database/run-ast/lib/apply-query/index.d.ts +0 -1
- package/dist/database/run-ast/lib/apply-query/index.js +4 -6
- package/dist/database/run-ast/lib/apply-query/search.js +2 -0
- package/dist/database/run-ast/lib/get-db-query.js +7 -6
- package/dist/database/run-ast/utils/generate-alias.d.ts +6 -0
- package/dist/database/run-ast/utils/generate-alias.js +57 -0
- package/dist/flows.js +1 -0
- package/dist/mcp/define.d.ts +2 -0
- package/dist/mcp/define.js +3 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/schema.d.ts +485 -0
- package/dist/mcp/schema.js +219 -0
- package/dist/mcp/server.d.ts +103 -0
- package/dist/mcp/server.js +310 -0
- package/dist/mcp/tools/assets.d.ts +3 -0
- package/dist/mcp/tools/assets.js +54 -0
- package/dist/mcp/tools/collections.d.ts +84 -0
- package/dist/mcp/tools/collections.js +90 -0
- package/dist/mcp/tools/fields.d.ts +101 -0
- package/dist/mcp/tools/fields.js +157 -0
- package/dist/mcp/tools/files.d.ts +235 -0
- package/dist/mcp/tools/files.js +103 -0
- package/dist/mcp/tools/flows.d.ts +323 -0
- package/dist/mcp/tools/flows.js +85 -0
- package/dist/mcp/tools/folders.d.ts +95 -0
- package/dist/mcp/tools/folders.js +96 -0
- package/dist/mcp/tools/index.d.ts +15 -0
- package/dist/mcp/tools/index.js +29 -0
- package/dist/mcp/tools/items.d.ts +87 -0
- package/dist/mcp/tools/items.js +141 -0
- package/dist/mcp/tools/operations.d.ts +171 -0
- package/dist/mcp/tools/operations.js +77 -0
- package/dist/mcp/tools/prompts/assets.md +8 -0
- package/dist/mcp/tools/prompts/collections.md +336 -0
- package/dist/mcp/tools/prompts/fields.md +521 -0
- package/dist/mcp/tools/prompts/files.md +180 -0
- package/dist/mcp/tools/prompts/flows.md +495 -0
- package/dist/mcp/tools/prompts/folders.md +34 -0
- package/dist/mcp/tools/prompts/index.d.ts +16 -0
- package/dist/mcp/tools/prompts/index.js +19 -0
- package/dist/mcp/tools/prompts/items.md +317 -0
- package/dist/mcp/tools/prompts/operations.md +721 -0
- package/dist/mcp/tools/prompts/relations.md +386 -0
- package/dist/mcp/tools/prompts/schema.md +130 -0
- package/dist/mcp/tools/prompts/system-prompt-description.md +1 -0
- package/dist/mcp/tools/prompts/system-prompt.md +44 -0
- package/dist/mcp/tools/prompts/trigger-flow.md +214 -0
- package/dist/mcp/tools/relations.d.ts +73 -0
- package/dist/mcp/tools/relations.js +93 -0
- package/dist/mcp/tools/schema.d.ts +54 -0
- package/dist/mcp/tools/schema.js +317 -0
- package/dist/mcp/tools/system.d.ts +3 -0
- package/dist/mcp/tools/system.js +22 -0
- package/dist/mcp/tools/trigger-flow.d.ts +8 -0
- package/dist/mcp/tools/trigger-flow.js +48 -0
- package/dist/mcp/transport.d.ts +13 -0
- package/dist/mcp/transport.js +18 -0
- package/dist/mcp/types.d.ts +56 -0
- package/dist/mcp/types.js +1 -0
- package/dist/metrics/lib/create-metrics.js +16 -25
- package/dist/middleware/collection-exists.js +2 -2
- package/dist/operations/mail/index.js +3 -1
- package/dist/operations/mail/rate-limiter.d.ts +1 -0
- package/dist/operations/mail/rate-limiter.js +29 -0
- package/dist/permissions/modules/process-payload/process-payload.js +3 -10
- package/dist/permissions/modules/validate-access/validate-access.js +2 -3
- package/dist/schedules/metrics.js +6 -2
- package/dist/schedules/project.d.ts +4 -0
- package/dist/schedules/project.js +27 -0
- package/dist/services/authentication.js +36 -0
- package/dist/services/collections.d.ts +3 -3
- package/dist/services/collections.js +16 -1
- package/dist/services/fields.d.ts +21 -5
- package/dist/services/fields.js +109 -32
- package/dist/services/graphql/resolvers/query.js +1 -1
- package/dist/services/graphql/resolvers/system-admin.js +49 -5
- package/dist/services/graphql/schema/parse-query.js +8 -8
- package/dist/services/graphql/utils/aggregate-query.d.ts +1 -1
- package/dist/services/graphql/utils/aggregate-query.js +5 -1
- package/dist/services/graphql/utils/filter-replace-m2a.js +2 -1
- package/dist/services/import-export.d.ts +9 -1
- package/dist/services/import-export.js +287 -101
- package/dist/services/items.d.ts +1 -1
- package/dist/services/items.js +50 -24
- package/dist/services/mail/index.js +2 -0
- package/dist/services/mail/rate-limiter.d.ts +1 -0
- package/dist/services/mail/rate-limiter.js +29 -0
- package/dist/services/meta.js +28 -24
- package/dist/services/payload.d.ts +7 -3
- package/dist/services/payload.js +26 -12
- package/dist/services/schema.js +4 -1
- package/dist/services/server.d.ts +1 -0
- package/dist/services/server.js +15 -18
- package/dist/services/settings.d.ts +2 -1
- package/dist/services/settings.js +15 -0
- package/dist/services/tfa.d.ts +1 -1
- package/dist/services/tfa.js +20 -5
- package/dist/services/tus/server.js +14 -9
- package/dist/services/versions.d.ts +6 -4
- package/dist/services/versions.js +84 -25
- package/dist/telemetry/lib/get-report.js +4 -4
- package/dist/telemetry/lib/send-report.d.ts +6 -1
- package/dist/telemetry/lib/send-report.js +3 -1
- package/dist/telemetry/types/report.d.ts +17 -1
- package/dist/telemetry/utils/get-settings.d.ts +9 -0
- package/dist/telemetry/utils/get-settings.js +14 -0
- package/dist/test-utils/README.md +760 -0
- package/dist/test-utils/cache.d.ts +51 -0
- package/dist/test-utils/cache.js +59 -0
- package/dist/test-utils/database.d.ts +48 -0
- package/dist/test-utils/database.js +52 -0
- package/dist/test-utils/emitter.d.ts +35 -0
- package/dist/test-utils/emitter.js +38 -0
- package/dist/test-utils/fields-service.d.ts +28 -0
- package/dist/test-utils/fields-service.js +36 -0
- package/dist/test-utils/items-service.d.ts +23 -0
- package/dist/test-utils/items-service.js +37 -0
- package/dist/test-utils/knex.d.ts +164 -0
- package/dist/test-utils/knex.js +268 -0
- package/dist/test-utils/schema.d.ts +26 -0
- package/dist/test-utils/schema.js +35 -0
- package/dist/types/auth.d.ts +2 -3
- package/dist/utils/apply-diff.js +15 -0
- package/dist/utils/create-admin.d.ts +11 -0
- package/dist/utils/create-admin.js +50 -0
- package/dist/utils/get-schema.js +5 -3
- package/dist/utils/get-snapshot-diff.js +49 -5
- package/dist/utils/get-snapshot.js +13 -7
- package/dist/utils/sanitize-schema.d.ts +11 -4
- package/dist/utils/sanitize-schema.js +9 -6
- package/dist/utils/schedule.js +15 -19
- package/dist/utils/validate-diff.js +31 -0
- package/dist/utils/validate-snapshot.js +7 -0
- package/dist/utils/versioning/deep-map-with-schema.d.ts +23 -0
- package/dist/utils/versioning/deep-map-with-schema.js +81 -0
- package/dist/utils/versioning/handle-version.d.ts +2 -2
- package/dist/utils/versioning/handle-version.js +47 -43
- package/dist/utils/versioning/split-recursive.d.ts +4 -0
- package/dist/utils/versioning/split-recursive.js +27 -0
- package/dist/websocket/controllers/hooks.js +12 -20
- package/dist/websocket/messages.d.ts +3 -3
- package/package.json +65 -66
- package/dist/cli/utils/defaults.d.ts +0 -4
- package/dist/cli/utils/defaults.js +0 -17
- package/dist/telemetry/utils/get-project-id.d.ts +0 -2
- package/dist/telemetry/utils/get-project-id.js +0 -4
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knex mocking utilities for service tests
|
|
3
|
+
* Provides mock knex instances, table builders, and tracker utilities
|
|
4
|
+
*/
|
|
5
|
+
import { systemCollectionNames } from '@directus/system-data';
|
|
6
|
+
import knex from 'knex';
|
|
7
|
+
import { MockClient, createTracker } from 'knex-mock-client';
|
|
8
|
+
import { vi } from 'vitest';
|
|
9
|
+
/**
|
|
10
|
+
* Creates a mocked knex instance with tracker and schema builder support
|
|
11
|
+
*
|
|
12
|
+
* @returns Object containing the mocked db instance, tracker, and mockSchema
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const { db, tracker, mockSchema } = createMockKnex();
|
|
17
|
+
*
|
|
18
|
+
* // Use tracker to mock query responses
|
|
19
|
+
* tracker.on.select('users').response([{ id: 1, name: 'John' }]);
|
|
20
|
+
*
|
|
21
|
+
* // Verify schema operations
|
|
22
|
+
* expect(mockSchema.createTable).toHaveBeenCalled();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function createMockKnex() {
|
|
26
|
+
const db = vi.mocked(knex.default({ client: MockClient }));
|
|
27
|
+
const tracker = createTracker(db);
|
|
28
|
+
// Mock schema builder methods with functional callbacks
|
|
29
|
+
const mockSchemaBuilder = {
|
|
30
|
+
createTable: vi.fn((_tableName, callback) => {
|
|
31
|
+
callback(createMockTableBuilder());
|
|
32
|
+
return Promise.resolve();
|
|
33
|
+
}),
|
|
34
|
+
dropTable: vi.fn().mockResolvedValue(undefined),
|
|
35
|
+
hasTable: vi.fn().mockResolvedValue(false),
|
|
36
|
+
table: vi.fn((_tableName, callback) => {
|
|
37
|
+
callback(createMockTableBuilder());
|
|
38
|
+
return Promise.resolve();
|
|
39
|
+
}),
|
|
40
|
+
alterTable: vi.fn((_tableName, callback) => {
|
|
41
|
+
callback(createMockTableBuilder());
|
|
42
|
+
return Promise.resolve();
|
|
43
|
+
}),
|
|
44
|
+
dropTableIfExists: vi.fn().mockResolvedValue(undefined),
|
|
45
|
+
renameTable: vi.fn().mockResolvedValue(undefined),
|
|
46
|
+
raw: vi.fn().mockResolvedValue(undefined),
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(db, 'schema', {
|
|
49
|
+
get: () => mockSchemaBuilder,
|
|
50
|
+
configurable: true,
|
|
51
|
+
});
|
|
52
|
+
// Note: We do NOT override the query builder methods (select, where, from, etc.)
|
|
53
|
+
// because knex-mock-client already provides them and connects them to the tracker.
|
|
54
|
+
// Overriding them would break the tracker connection and cause queries to not return
|
|
55
|
+
// the mocked responses.
|
|
56
|
+
return { db, tracker, mockSchemaBuilder };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Creates a mock table builder for schema operations
|
|
60
|
+
* Used for testing column creation and alteration
|
|
61
|
+
*
|
|
62
|
+
* @returns Mock table builder with chainable methods
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const table = createMockTableBuilder();
|
|
67
|
+
* table.string('name', 255).notNullable().index();
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function createMockTableBuilder() {
|
|
71
|
+
return {
|
|
72
|
+
// Column types - actively used
|
|
73
|
+
string: vi.fn().mockReturnThis(),
|
|
74
|
+
text: vi.fn().mockReturnThis(),
|
|
75
|
+
integer: vi.fn().mockReturnThis(),
|
|
76
|
+
bigInteger: vi.fn().mockReturnThis(),
|
|
77
|
+
float: vi.fn().mockReturnThis(),
|
|
78
|
+
decimal: vi.fn().mockReturnThis(),
|
|
79
|
+
boolean: vi.fn().mockReturnThis(),
|
|
80
|
+
date: vi.fn().mockReturnThis(),
|
|
81
|
+
dateTime: vi.fn().mockReturnThis(),
|
|
82
|
+
timestamp: vi.fn().mockReturnThis(),
|
|
83
|
+
json: vi.fn().mockReturnThis(),
|
|
84
|
+
jsonb: vi.fn().mockReturnThis(),
|
|
85
|
+
uuid: vi.fn().mockReturnThis(),
|
|
86
|
+
// Column types - unused
|
|
87
|
+
// tinyint: vi.fn().mockReturnThis(),
|
|
88
|
+
// smallint: vi.fn().mockReturnThis(),
|
|
89
|
+
// mediumint: vi.fn().mockReturnThis(),
|
|
90
|
+
// bigint: vi.fn().mockReturnThis(),
|
|
91
|
+
// double: vi.fn().mockReturnThis(),
|
|
92
|
+
// datetime: vi.fn().mockReturnThis(),
|
|
93
|
+
// time: vi.fn().mockReturnThis(),
|
|
94
|
+
// timestamps: vi.fn().mockReturnThis(),
|
|
95
|
+
// binary: vi.fn().mockReturnThis(),
|
|
96
|
+
// enum: vi.fn().mockReturnThis(),
|
|
97
|
+
// enu: vi.fn().mockReturnThis(),
|
|
98
|
+
// geometry: vi.fn().mockReturnThis(),
|
|
99
|
+
// geography: vi.fn().mockReturnThis(),
|
|
100
|
+
// point: vi.fn().mockReturnThis(),
|
|
101
|
+
// linestring: vi.fn().mockReturnThis(),
|
|
102
|
+
// polygon: vi.fn().mockReturnThis(),
|
|
103
|
+
// multipoint: vi.fn().mockReturnThis(),
|
|
104
|
+
// multilinestring: vi.fn().mockReturnThis(),
|
|
105
|
+
// multipolygon: vi.fn().mockReturnThis(),
|
|
106
|
+
// geometrycollection: vi.fn().mockReturnThis(),
|
|
107
|
+
// specificType: vi.fn().mockReturnThis(),
|
|
108
|
+
// Auto-increment columns
|
|
109
|
+
increments: vi.fn().mockReturnThis(),
|
|
110
|
+
bigIncrements: vi.fn().mockReturnThis(),
|
|
111
|
+
// Column modifiers - actively used
|
|
112
|
+
defaultTo: vi.fn().mockReturnThis(),
|
|
113
|
+
notNullable: vi.fn().mockReturnThis(),
|
|
114
|
+
nullable: vi.fn().mockReturnThis(),
|
|
115
|
+
primary: vi.fn().mockReturnThis(),
|
|
116
|
+
unique: vi.fn().mockReturnThis(),
|
|
117
|
+
index: vi.fn().mockReturnThis(),
|
|
118
|
+
alter: vi.fn().mockReturnThis(),
|
|
119
|
+
// Column modifiers - unused
|
|
120
|
+
// unsigned: vi.fn().mockReturnThis(),
|
|
121
|
+
// comment: vi.fn().mockReturnThis(),
|
|
122
|
+
// collate: vi.fn().mockReturnThis(),
|
|
123
|
+
// charset: vi.fn().mockReturnThis(),
|
|
124
|
+
// first: vi.fn().mockReturnThis(),
|
|
125
|
+
// after: vi.fn().mockReturnThis(),
|
|
126
|
+
// references: vi.fn().mockReturnThis(),
|
|
127
|
+
// inTable: vi.fn().mockReturnThis(),
|
|
128
|
+
// onDelete: vi.fn().mockReturnThis(),
|
|
129
|
+
// onUpdate: vi.fn().mockReturnThis(),
|
|
130
|
+
// foreign: vi.fn().mockReturnThis(),
|
|
131
|
+
// Schema alterations - actively used
|
|
132
|
+
dropColumn: vi.fn().mockReturnThis(),
|
|
133
|
+
dropUnique: vi.fn().mockReturnThis(),
|
|
134
|
+
dropIndex: vi.fn().mockReturnThis(),
|
|
135
|
+
// Schema alterations - unused
|
|
136
|
+
// dropColumns: vi.fn().mockReturnThis(),
|
|
137
|
+
// renameColumn: vi.fn().mockReturnThis(),
|
|
138
|
+
// dropPrimary: vi.fn().mockReturnThis(),
|
|
139
|
+
// dropForeign: vi.fn().mockReturnThis(),
|
|
140
|
+
// dropTimestamps: vi.fn().mockReturnThis(),
|
|
141
|
+
// Table options - unused
|
|
142
|
+
// engine: vi.fn().mockReturnThis(),
|
|
143
|
+
// inherits: vi.fn().mockReturnThis(),
|
|
144
|
+
// queryContext: vi.fn().mockReturnThis(),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Sets up common database operation mock handlers for all system collections
|
|
149
|
+
* Automatically mocks CRUD operations (select, insert, update, delete) for all Directus system collections
|
|
150
|
+
*
|
|
151
|
+
* @param tracker The knex-mock-client tracker instance
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const { db, tracker, mockSchema } = createMockKnex();
|
|
156
|
+
* setupSystemCollectionMocks(tracker);
|
|
157
|
+
* // Now all CRUD operations on system collections are mocked
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export function setupSystemCollectionMocks(tracker) {
|
|
161
|
+
// Mock all CRUD operations for all system collections
|
|
162
|
+
for (const collection of systemCollectionNames) {
|
|
163
|
+
tracker.on.select(collection).response([]);
|
|
164
|
+
tracker.on.insert(collection).response([]);
|
|
165
|
+
tracker.on.update(collection).response([]);
|
|
166
|
+
tracker.on.delete(collection).response([]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Resets all mock states
|
|
171
|
+
* Should be called in afterEach hooks to clean up between tests
|
|
172
|
+
*
|
|
173
|
+
* @param tracker The knex-mock-client tracker instance
|
|
174
|
+
* @param mockSchema The mock schema object from createMockKnex
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const { db, tracker, mockSchema } = createMockKnex();
|
|
179
|
+
*
|
|
180
|
+
* afterEach(() => {
|
|
181
|
+
* resetMocks(tracker, mockSchema);
|
|
182
|
+
* });
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export function resetKnexMocks(tracker, mockSchema) {
|
|
186
|
+
tracker.reset();
|
|
187
|
+
vi.clearAllMocks();
|
|
188
|
+
mockSchema.createTable.mockClear();
|
|
189
|
+
mockSchema.dropTable.mockClear();
|
|
190
|
+
mockSchema.hasTable.mockClear();
|
|
191
|
+
mockSchema.table.mockClear();
|
|
192
|
+
if (mockSchema.alterTable) {
|
|
193
|
+
mockSchema.alterTable.mockClear();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Creates a mock createTable function for testing table creation
|
|
198
|
+
* Returns a vi.fn() that calls the callback with a mock table builder
|
|
199
|
+
*
|
|
200
|
+
* @returns Mock function for db.schema.createTable
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* const { db } = createMockKnex();
|
|
205
|
+
* const createTableSpy = mockCreateTable();
|
|
206
|
+
* db.schema.createTable = createTableSpy as any;
|
|
207
|
+
*
|
|
208
|
+
* // Now when createTable is called, it will invoke the callback with a mock table builder
|
|
209
|
+
* await db.schema.createTable('users', (table) => {
|
|
210
|
+
* table.increments('id');
|
|
211
|
+
* table.string('name');
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export function mockCreateTable() {
|
|
216
|
+
return vi.fn((_tableName, callback) => {
|
|
217
|
+
callback(createMockTableBuilder());
|
|
218
|
+
return Promise.resolve();
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Creates a mock alterTable function for testing schema alterations
|
|
223
|
+
* Returns a vi.fn() that calls the callback with a mock table builder
|
|
224
|
+
*
|
|
225
|
+
* @returns Mock function for db.schema.alterTable
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* const { db } = createMockKnex();
|
|
230
|
+
* const alterTableSpy = mockAlterTable();
|
|
231
|
+
* db.schema.alterTable = alterTableSpy as any;
|
|
232
|
+
*
|
|
233
|
+
* // Now when alterTable is called, it will invoke the callback with a mock table builder
|
|
234
|
+
* await db.schema.alterTable('users', (table) => {
|
|
235
|
+
* table.string('name');
|
|
236
|
+
* });
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export function mockAlterTable() {
|
|
240
|
+
return vi.fn((_tableName, callback) => {
|
|
241
|
+
callback(createMockTableBuilder());
|
|
242
|
+
return Promise.resolve();
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Creates a mock schema.table function for testing schema operations
|
|
247
|
+
* Returns a vi.fn() that calls the callback with a mock table builder
|
|
248
|
+
*
|
|
249
|
+
* @returns Mock function for db.schema.table
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```typescript
|
|
253
|
+
* const { db } = createMockKnex();
|
|
254
|
+
* const schemaTableSpy = mockSchemaTable();
|
|
255
|
+
* db.schema.table = schemaTableSpy as any;
|
|
256
|
+
*
|
|
257
|
+
* // Now when schema.table is called, it will invoke the callback with a mock table builder
|
|
258
|
+
* await db.schema.table('users', (table) => {
|
|
259
|
+
* table.dropColumn('name');
|
|
260
|
+
* });
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export function mockSchemaTable() {
|
|
264
|
+
return vi.fn((_tableName, callback) => {
|
|
265
|
+
callback(createMockTableBuilder());
|
|
266
|
+
return Promise.resolve();
|
|
267
|
+
});
|
|
268
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema mocking utilities for service tests
|
|
3
|
+
* Provides simplified mocks for @directus/schema module used in service testing
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a standard schema inspector mock for service tests
|
|
7
|
+
* This matches the pattern used across all service test files
|
|
8
|
+
*
|
|
9
|
+
* @returns Mock module object for vi.mock()
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Standard usage
|
|
14
|
+
* vi.mock('@directus/schema', () => mockSchema());
|
|
15
|
+
*
|
|
16
|
+
* // To dynamically change inspector behavior during tests, import and mock directly:
|
|
17
|
+
* import { createInspector } from '@directus/schema';
|
|
18
|
+
* vi.mocked(createInspector).mockReturnValue({
|
|
19
|
+
* tableInfo: vi.fn().mockResolvedValue([{ name: 'custom_table' }]),
|
|
20
|
+
* // ... other custom behaviors
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function mockSchema(): {
|
|
25
|
+
createInspector: import("vitest").Mock<(...args: any[]) => any>;
|
|
26
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema mocking utilities for service tests
|
|
3
|
+
* Provides simplified mocks for @directus/schema module used in service testing
|
|
4
|
+
*/
|
|
5
|
+
import { vi } from 'vitest';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a standard schema inspector mock for service tests
|
|
8
|
+
* This matches the pattern used across all service test files
|
|
9
|
+
*
|
|
10
|
+
* @returns Mock module object for vi.mock()
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Standard usage
|
|
15
|
+
* vi.mock('@directus/schema', () => mockSchema());
|
|
16
|
+
*
|
|
17
|
+
* // To dynamically change inspector behavior during tests, import and mock directly:
|
|
18
|
+
* import { createInspector } from '@directus/schema';
|
|
19
|
+
* vi.mocked(createInspector).mockReturnValue({
|
|
20
|
+
* tableInfo: vi.fn().mockResolvedValue([{ name: 'custom_table' }]),
|
|
21
|
+
* // ... other custom behaviors
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function mockSchema() {
|
|
26
|
+
return {
|
|
27
|
+
createInspector: vi.fn().mockReturnValue({
|
|
28
|
+
tableInfo: vi.fn().mockResolvedValue([]),
|
|
29
|
+
columnInfo: vi.fn().mockResolvedValue([]),
|
|
30
|
+
primary: vi.fn().mockResolvedValue('id'),
|
|
31
|
+
foreignKeys: vi.fn().mockResolvedValue([]),
|
|
32
|
+
withSchema: vi.fn().mockReturnThis(),
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
}
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { SchemaOverview } from '@directus/types';
|
|
2
1
|
import type { Knex } from 'knex';
|
|
3
2
|
export interface AuthDriverOptions {
|
|
4
3
|
knex: Knex;
|
|
5
|
-
schema: SchemaOverview;
|
|
6
4
|
}
|
|
7
5
|
export interface User {
|
|
8
6
|
id: string;
|
|
@@ -27,10 +25,11 @@ export interface Session {
|
|
|
27
25
|
export type DirectusTokenPayload = {
|
|
28
26
|
id?: string;
|
|
29
27
|
role: string | null;
|
|
30
|
-
session?: string;
|
|
31
28
|
app_access: boolean | number;
|
|
32
29
|
admin_access: boolean | number;
|
|
33
30
|
share?: string;
|
|
31
|
+
session?: string;
|
|
32
|
+
enforce_tfa?: boolean;
|
|
34
33
|
};
|
|
35
34
|
export type ShareData = {
|
|
36
35
|
share_id: string;
|
package/dist/utils/apply-diff.js
CHANGED
|
@@ -205,6 +205,21 @@ export async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
205
205
|
!relation.diff.some((diff) => diff.kind === DiffKind.NEW)) === false);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
+
for (const { collection, field, diff } of snapshotDiff.systemFields) {
|
|
209
|
+
if (diff?.[0]?.kind === DiffKind.EDIT) {
|
|
210
|
+
try {
|
|
211
|
+
const newValues = diff.reduce((acc, currentDiff) => {
|
|
212
|
+
deepDiff.applyChange(acc, undefined, currentDiff);
|
|
213
|
+
return acc;
|
|
214
|
+
}, { collection, field });
|
|
215
|
+
await fieldsService.updateField(collection, newValues, mutationOptions);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
logger.error(`Failed to update field "${collection}.${field}"`);
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
208
223
|
const relationsService = new RelationsService({
|
|
209
224
|
knex: trx,
|
|
210
225
|
schema: await getSchema({ database: trx, bypassCache: true }),
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SchemaOverview } from '@directus/types';
|
|
2
|
+
import type { Policy, Role, User } from '@directus/types';
|
|
3
|
+
export declare const defaultAdminRole: Partial<Role>;
|
|
4
|
+
export declare const defaultAdminUser: Partial<User>;
|
|
5
|
+
export declare const defaultAdminPolicy: Partial<Policy>;
|
|
6
|
+
export declare function createAdmin(schema: SchemaOverview, admin?: {
|
|
7
|
+
email?: string;
|
|
8
|
+
password?: string;
|
|
9
|
+
first_name?: string;
|
|
10
|
+
last_name?: string;
|
|
11
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { useLogger } from '../logger/index.js';
|
|
3
|
+
import { AccessService } from '../services/access.js';
|
|
4
|
+
import { UsersService } from '../services/index.js';
|
|
5
|
+
import { PoliciesService } from '../services/policies.js';
|
|
6
|
+
import { RolesService } from '../services/roles.js';
|
|
7
|
+
export const defaultAdminRole = {
|
|
8
|
+
name: 'Administrator',
|
|
9
|
+
icon: 'verified',
|
|
10
|
+
description: '$t:admin_description',
|
|
11
|
+
};
|
|
12
|
+
export const defaultAdminUser = {
|
|
13
|
+
status: 'active',
|
|
14
|
+
first_name: 'Admin',
|
|
15
|
+
last_name: 'User',
|
|
16
|
+
};
|
|
17
|
+
export const defaultAdminPolicy = {
|
|
18
|
+
name: 'Administrator',
|
|
19
|
+
icon: 'verified',
|
|
20
|
+
admin_access: true,
|
|
21
|
+
app_access: true,
|
|
22
|
+
description: '$t:admin_description',
|
|
23
|
+
};
|
|
24
|
+
export async function createAdmin(schema, admin) {
|
|
25
|
+
const logger = useLogger();
|
|
26
|
+
const env = useEnv();
|
|
27
|
+
logger.info('Setting up first admin role...');
|
|
28
|
+
const accessService = new AccessService({ schema });
|
|
29
|
+
const policiesService = new PoliciesService({ schema });
|
|
30
|
+
const rolesService = new RolesService({ schema });
|
|
31
|
+
const role = await rolesService.createOne(defaultAdminRole);
|
|
32
|
+
const policy = await policiesService.createOne(defaultAdminPolicy);
|
|
33
|
+
await accessService.createOne({ policy, role });
|
|
34
|
+
const usersService = new UsersService({ schema });
|
|
35
|
+
const adminEmail = admin?.email ?? env['ADMIN_EMAIL'];
|
|
36
|
+
const adminPassword = admin?.password ?? env['ADMIN_PASSWORD'];
|
|
37
|
+
if (!adminEmail || !adminPassword)
|
|
38
|
+
return;
|
|
39
|
+
const token = env['ADMIN_TOKEN'] ?? null;
|
|
40
|
+
logger.info('Adding first admin user...');
|
|
41
|
+
await usersService.createOne({
|
|
42
|
+
...defaultAdminUser,
|
|
43
|
+
first_name: admin?.first_name ?? defaultAdminUser.first_name,
|
|
44
|
+
last_name: admin?.last_name ?? defaultAdminUser.last_name,
|
|
45
|
+
email: adminEmail,
|
|
46
|
+
password: adminPassword,
|
|
47
|
+
token,
|
|
48
|
+
role,
|
|
49
|
+
});
|
|
50
|
+
}
|
package/dist/utils/get-schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEnv } from '@directus/env';
|
|
2
2
|
import { createInspector } from '@directus/schema';
|
|
3
3
|
import { systemCollectionRows } from '@directus/system-data';
|
|
4
|
-
import { parseJSON, toArray } from '@directus/utils';
|
|
4
|
+
import { parseJSON, toArray, toBoolean } from '@directus/utils';
|
|
5
5
|
import { mapValues } from 'lodash-es';
|
|
6
6
|
import { useBus } from '../bus/index.js';
|
|
7
7
|
import { getMemorySchemaCache, setMemorySchemaCache } from '../cache.js';
|
|
@@ -106,7 +106,7 @@ async function getDatabaseSchema(database, schemaInspector) {
|
|
|
106
106
|
result.collections[collection] = {
|
|
107
107
|
collection,
|
|
108
108
|
primary: info.primary,
|
|
109
|
-
singleton: collectionMeta?.singleton
|
|
109
|
+
singleton: toBoolean(collectionMeta?.singleton),
|
|
110
110
|
note: collectionMeta?.note || null,
|
|
111
111
|
sortField: collectionMeta?.sort_field || null,
|
|
112
112
|
accountability: collectionMeta ? collectionMeta.accountability : 'all',
|
|
@@ -124,13 +124,14 @@ async function getDatabaseSchema(database, schemaInspector) {
|
|
|
124
124
|
note: null,
|
|
125
125
|
validation: null,
|
|
126
126
|
alias: false,
|
|
127
|
+
searchable: true,
|
|
127
128
|
};
|
|
128
129
|
}),
|
|
129
130
|
};
|
|
130
131
|
}
|
|
131
132
|
const fields = [
|
|
132
133
|
...(await database
|
|
133
|
-
.select('id', 'collection', 'field', 'special', 'note', 'validation')
|
|
134
|
+
.select('id', 'collection', 'field', 'special', 'note', 'validation', 'searchable')
|
|
134
135
|
.from('directus_fields')),
|
|
135
136
|
...systemFieldRows,
|
|
136
137
|
].filter((field) => (field.special ? toArray(field.special) : []).includes('no-data') === false);
|
|
@@ -159,6 +160,7 @@ async function getDatabaseSchema(database, schemaInspector) {
|
|
|
159
160
|
note: field.note,
|
|
160
161
|
alias: existing?.alias ?? true,
|
|
161
162
|
validation: validation ?? null,
|
|
163
|
+
searchable: toBoolean(field.searchable) ?? true,
|
|
162
164
|
};
|
|
163
165
|
}
|
|
164
166
|
const relationsService = new RelationsService({ knex: database, schema: result });
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import deepDiff from 'deep-diff';
|
|
2
2
|
import { DiffKind } from '@directus/types';
|
|
3
|
-
import { sanitizeCollection, sanitizeField, sanitizeRelation } from './sanitize-schema.js';
|
|
3
|
+
import { sanitizeCollection, sanitizeField, sanitizeRelation, sanitizeSystemField } from './sanitize-schema.js';
|
|
4
4
|
export function getSnapshotDiff(current, after) {
|
|
5
5
|
const diffedSnapshot = {
|
|
6
6
|
collections: [
|
|
7
7
|
...current.collections.map((currentCollection) => {
|
|
8
8
|
const afterCollection = after.collections.find((afterCollection) => afterCollection.collection === currentCollection.collection);
|
|
9
|
+
const afterCollectionSanitized = afterCollection ? sanitizeCollection(afterCollection) : undefined;
|
|
9
10
|
return {
|
|
10
11
|
collection: currentCollection.collection,
|
|
11
|
-
diff: deepDiff.diff(sanitizeCollection(currentCollection),
|
|
12
|
+
diff: deepDiff.diff(sanitizeCollection(currentCollection), afterCollectionSanitized),
|
|
12
13
|
};
|
|
13
14
|
}),
|
|
14
15
|
...after.collections
|
|
@@ -32,13 +33,14 @@ export function getSnapshotDiff(current, after) {
|
|
|
32
33
|
return {
|
|
33
34
|
collection: currentField.collection,
|
|
34
35
|
field: currentField.field,
|
|
35
|
-
diff: deepDiff.diff(sanitizeField(currentField, isAutoIncrementPrimaryKey),
|
|
36
|
+
diff: deepDiff.diff(sanitizeField(currentField, isAutoIncrementPrimaryKey), undefined),
|
|
36
37
|
};
|
|
37
38
|
}
|
|
39
|
+
const afterFieldSanitized = afterField ? sanitizeField(afterField, isAutoIncrementPrimaryKey) : undefined;
|
|
38
40
|
return {
|
|
39
41
|
collection: currentField.collection,
|
|
40
42
|
field: currentField.field,
|
|
41
|
-
diff: deepDiff.diff(sanitizeField(currentField, isAutoIncrementPrimaryKey),
|
|
43
|
+
diff: deepDiff.diff(sanitizeField(currentField, isAutoIncrementPrimaryKey), afterFieldSanitized),
|
|
42
44
|
};
|
|
43
45
|
}),
|
|
44
46
|
...after.fields
|
|
@@ -58,14 +60,49 @@ export function getSnapshotDiff(current, after) {
|
|
|
58
60
|
diff: deepDiff.diff(undefined, sanitizeField(afterField)),
|
|
59
61
|
})),
|
|
60
62
|
].filter((obj) => Array.isArray(obj.diff)),
|
|
63
|
+
systemFields: [
|
|
64
|
+
...(current.systemFields ?? []).map((currentSystemField) => {
|
|
65
|
+
const afterSystemField = (after.systemFields ?? []).find((afterSystemField) => afterSystemField.collection === currentSystemField.collection &&
|
|
66
|
+
afterSystemField.field === currentSystemField.field);
|
|
67
|
+
const afterSystemFieldSanitized = afterSystemField
|
|
68
|
+
? sanitizeSystemField(afterSystemField)
|
|
69
|
+
: invertIndexed(currentSystemField);
|
|
70
|
+
return {
|
|
71
|
+
collection: currentSystemField.collection,
|
|
72
|
+
field: currentSystemField.field,
|
|
73
|
+
diff: deepDiff.diff(sanitizeSystemField(currentSystemField), afterSystemFieldSanitized),
|
|
74
|
+
};
|
|
75
|
+
}),
|
|
76
|
+
...(after.systemFields ?? [])
|
|
77
|
+
.filter((afterSystemField) => {
|
|
78
|
+
if (!afterSystemField.schema.is_indexed)
|
|
79
|
+
return false;
|
|
80
|
+
const currentSystemField = (current.systemFields ?? []).find((currentSystemField) => currentSystemField.collection === afterSystemField.collection &&
|
|
81
|
+
afterSystemField.field === currentSystemField.field);
|
|
82
|
+
return Boolean(currentSystemField) === false;
|
|
83
|
+
})
|
|
84
|
+
.map((afterSystemField) => {
|
|
85
|
+
const currentSystemField = (current.systemFields ?? []).find((currentSystemField) => currentSystemField.collection === afterSystemField.collection &&
|
|
86
|
+
currentSystemField.field === afterSystemField.field);
|
|
87
|
+
const currentSystemFieldSanitized = currentSystemField
|
|
88
|
+
? sanitizeSystemField(currentSystemField)
|
|
89
|
+
: invertIndexed(afterSystemField);
|
|
90
|
+
return {
|
|
91
|
+
collection: afterSystemField.collection,
|
|
92
|
+
field: afterSystemField.field,
|
|
93
|
+
diff: deepDiff.diff(currentSystemFieldSanitized, sanitizeSystemField(afterSystemField)),
|
|
94
|
+
};
|
|
95
|
+
}),
|
|
96
|
+
].filter((obj) => Array.isArray(obj.diff)),
|
|
61
97
|
relations: [
|
|
62
98
|
...current.relations.map((currentRelation) => {
|
|
63
99
|
const afterRelation = after.relations.find((afterRelation) => afterRelation.collection === currentRelation.collection && afterRelation.field === currentRelation.field);
|
|
100
|
+
const afterRelationSanitized = afterRelation ? sanitizeRelation(afterRelation) : undefined;
|
|
64
101
|
return {
|
|
65
102
|
collection: currentRelation.collection,
|
|
66
103
|
field: currentRelation.field,
|
|
67
104
|
related_collection: currentRelation.related_collection,
|
|
68
|
-
diff: deepDiff.diff(sanitizeRelation(currentRelation),
|
|
105
|
+
diff: deepDiff.diff(sanitizeRelation(currentRelation), afterRelationSanitized),
|
|
69
106
|
};
|
|
70
107
|
}),
|
|
71
108
|
...after.relations
|
|
@@ -91,3 +128,10 @@ export function getSnapshotDiff(current, after) {
|
|
|
91
128
|
diffedSnapshot.relations = diffedSnapshot.relations.filter((relation) => deletedCollections.includes(relation.collection) === false);
|
|
92
129
|
return diffedSnapshot;
|
|
93
130
|
}
|
|
131
|
+
function invertIndexed(field) {
|
|
132
|
+
const newSchema = { ...field.schema };
|
|
133
|
+
if ('is_indexed' in field.schema) {
|
|
134
|
+
newSchema.is_indexed = !field.schema.is_indexed;
|
|
135
|
+
}
|
|
136
|
+
return { ...field, schema: newSchema };
|
|
137
|
+
}
|
|
@@ -5,7 +5,7 @@ import { CollectionsService } from '../services/collections.js';
|
|
|
5
5
|
import { FieldsService } from '../services/fields.js';
|
|
6
6
|
import { RelationsService } from '../services/relations.js';
|
|
7
7
|
import { getSchema } from './get-schema.js';
|
|
8
|
-
import { sanitizeCollection, sanitizeField, sanitizeRelation } from './sanitize-schema.js';
|
|
8
|
+
import { sanitizeCollection, sanitizeField, sanitizeRelation, sanitizeSystemField } from './sanitize-schema.js';
|
|
9
9
|
export async function getSnapshot(options) {
|
|
10
10
|
const database = options?.database ?? getDatabase();
|
|
11
11
|
const vendor = getDatabaseClient(database);
|
|
@@ -21,16 +21,19 @@ export async function getSnapshot(options) {
|
|
|
21
21
|
const collectionsFiltered = collectionsRaw.filter((item) => excludeSystem(item) && excludeUntracked(item));
|
|
22
22
|
const fieldsFiltered = fieldsRaw.filter((item) => excludeSystem(item) && excludeUntracked(item));
|
|
23
23
|
const relationsFiltered = relationsRaw.filter((item) => excludeSystem(item) && excludeUntracked(item));
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
24
|
+
const systemFieldsFiltered = fieldsRaw.filter((item) => systemFieldWithIndex(item));
|
|
25
|
+
const collectionsSorted = sortBy(mapValues(collectionsFiltered, sortDeep), ['collection']).map((collection) => sanitizeCollection(collection));
|
|
26
|
+
const fieldsSorted = sortBy(mapValues(fieldsFiltered, sortDeep), ['collection', 'meta.id']).map((field) => sanitizeField(omitID(field)));
|
|
27
|
+
const systemFieldsSorted = sortBy(systemFieldsFiltered, ['collection', 'field']).map((field) => sanitizeSystemField(field));
|
|
28
|
+
const relationsSorted = sortBy(mapValues(relationsFiltered, sortDeep), ['collection', 'meta.id']).map((relation) => sanitizeRelation(omitID(relation)));
|
|
27
29
|
return {
|
|
28
30
|
version: 1,
|
|
29
31
|
directus: version,
|
|
30
32
|
vendor,
|
|
31
|
-
collections: collectionsSorted
|
|
32
|
-
fields: fieldsSorted
|
|
33
|
-
|
|
33
|
+
collections: collectionsSorted,
|
|
34
|
+
fields: fieldsSorted,
|
|
35
|
+
systemFields: systemFieldsSorted,
|
|
36
|
+
relations: relationsSorted,
|
|
34
37
|
};
|
|
35
38
|
}
|
|
36
39
|
function excludeSystem(item) {
|
|
@@ -38,6 +41,9 @@ function excludeSystem(item) {
|
|
|
38
41
|
return false;
|
|
39
42
|
return true;
|
|
40
43
|
}
|
|
44
|
+
function systemFieldWithIndex(item) {
|
|
45
|
+
return item.meta?.system === true && item.schema?.is_indexed;
|
|
46
|
+
}
|
|
41
47
|
function excludeUntracked(item) {
|
|
42
48
|
if (item?.meta === null)
|
|
43
49
|
return false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Column } from '@directus/schema';
|
|
2
|
-
import type { Field, Relation } from '@directus/types';
|
|
2
|
+
import type { Field, Relation, SnapshotCollection, SnapshotField, SnapshotRelation, SnapshotSystemField } from '@directus/types';
|
|
3
3
|
import type { Collection } from '../types/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Pick certain database vendor specific collection properties that should be compared when performing diff
|
|
@@ -7,7 +7,7 @@ import type { Collection } from '../types/index.js';
|
|
|
7
7
|
* @param collection collection to sanitize
|
|
8
8
|
* @returns sanitized collection
|
|
9
9
|
*/
|
|
10
|
-
export declare function sanitizeCollection(collection: Collection
|
|
10
|
+
export declare function sanitizeCollection(collection: Collection): SnapshotCollection;
|
|
11
11
|
/**
|
|
12
12
|
* Pick certain database vendor specific field properties that should be compared when performing diff
|
|
13
13
|
*
|
|
@@ -15,7 +15,7 @@ export declare function sanitizeCollection(collection: Collection | undefined):
|
|
|
15
15
|
* @param sanitizeAllSchema Whether or not the whole field schema should be sanitized. Mainly used to prevent modifying autoincrement fields
|
|
16
16
|
* @returns sanitized field
|
|
17
17
|
*/
|
|
18
|
-
export declare function sanitizeField(field: Field
|
|
18
|
+
export declare function sanitizeField(field: Field, sanitizeAllSchema?: boolean): SnapshotField;
|
|
19
19
|
export declare function sanitizeColumn(column: Column): Pick<Column, "table" | "foreign_key_table" | "foreign_key_column" | "name" | "data_type" | "default_value" | "max_length" | "numeric_precision" | "numeric_scale" | "is_nullable" | "is_unique" | "is_indexed" | "is_primary_key" | "is_generated" | "generation_expression" | "has_auto_increment">;
|
|
20
20
|
/**
|
|
21
21
|
* Pick certain database vendor specific relation properties that should be compared when performing diff
|
|
@@ -23,4 +23,11 @@ export declare function sanitizeColumn(column: Column): Pick<Column, "table" | "
|
|
|
23
23
|
* @param relation relation to sanitize
|
|
24
24
|
* @returns sanitized relation
|
|
25
25
|
*/
|
|
26
|
-
export declare function sanitizeRelation(relation: Relation
|
|
26
|
+
export declare function sanitizeRelation(relation: Relation): SnapshotRelation;
|
|
27
|
+
/**
|
|
28
|
+
* Pick certain specific system field properties that should be compared when performing diff
|
|
29
|
+
*
|
|
30
|
+
* @param field field to sanitize
|
|
31
|
+
* @returns sanitized system field
|
|
32
|
+
*/
|
|
33
|
+
export declare function sanitizeSystemField(field: Field | SnapshotSystemField): SnapshotSystemField;
|