@prisma-next/target-mongo 0.5.0-dev.4 → 0.5.0-dev.40
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 +2 -0
- package/dist/control.d.mts +40 -19
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +100 -103
- package/dist/control.mjs.map +1 -1
- package/dist/descriptor-meta-D9_5quQi.mjs +14 -0
- package/dist/descriptor-meta-D9_5quQi.mjs.map +1 -0
- package/dist/{migration-factories-gwi81C8u.mjs → migration-factories-CoNYWrd1.mjs} +3 -1
- package/dist/migration-factories-CoNYWrd1.mjs.map +1 -0
- package/dist/migration.d.mts +7 -1
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +1 -1
- package/dist/{op-factory-call-BjNAcPSF.d.mts → op-factory-call--nK5dk8n.d.mts} +1 -1
- package/dist/{op-factory-call-BjNAcPSF.d.mts.map → op-factory-call--nK5dk8n.d.mts.map} +1 -1
- package/dist/pack.mjs +1 -11
- package/dist/pack.mjs.map +1 -1
- package/dist/runtime.d.mts +20 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +28 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/schema-verify.d.mts +22 -0
- package/dist/schema-verify.d.mts.map +1 -0
- package/dist/schema-verify.mjs +3 -0
- package/dist/verify-mongo-schema-Daa7BMJY.mjs +582 -0
- package/dist/verify-mongo-schema-Daa7BMJY.mjs.map +1 -0
- package/package.json +18 -12
- package/src/core/marker-ledger.ts +90 -20
- package/src/core/migration-factories.ts +8 -0
- package/src/core/mongo-ops-serializer.ts +0 -8
- package/src/core/mongo-planner.ts +8 -2
- package/src/core/mongo-runner.ts +105 -70
- package/src/core/planner-produced-migration.ts +0 -1
- package/src/core/render-typescript.ts +3 -7
- package/src/core/schema-diff.ts +402 -0
- package/src/core/schema-verify/canonicalize-introspection.ts +389 -0
- package/src/core/schema-verify/verify-mongo-schema.ts +60 -0
- package/src/exports/runtime.ts +38 -0
- package/src/exports/schema-verify.ts +2 -0
- package/dist/migration-factories-gwi81C8u.mjs.map +0 -1
|
@@ -3,9 +3,8 @@ import { type ImportRequirement, jsonToTsSource, renderImports } from '@prisma-n
|
|
|
3
3
|
import type { OpFactoryCall } from './op-factory-call';
|
|
4
4
|
|
|
5
5
|
export interface RenderMigrationMeta {
|
|
6
|
-
readonly from: string;
|
|
6
|
+
readonly from: string | null;
|
|
7
7
|
readonly to: string;
|
|
8
|
-
readonly kind?: string;
|
|
9
8
|
readonly labels?: readonly string[];
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -36,8 +35,8 @@ const BASE_IMPORTS: readonly ImportRequirement[] = [
|
|
|
36
35
|
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
37
36
|
* implements the abstract `operations` and `describe` members. `meta` is
|
|
38
37
|
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
39
|
-
* even an empty stub must satisfy it; callers pass
|
|
40
|
-
* migration-new scaffold.
|
|
38
|
+
* even an empty stub must satisfy it; callers pass `from: null` for a
|
|
39
|
+
* baseline `migration-new` scaffold (and a real `to` hash either way).
|
|
41
40
|
*
|
|
42
41
|
* The walk is polymorphic: each call node contributes its own
|
|
43
42
|
* `renderTypeScript()` expression and declares its own
|
|
@@ -89,9 +88,6 @@ function buildDescribeMethod(meta: RenderMigrationMeta): string {
|
|
|
89
88
|
lines.push(' return {');
|
|
90
89
|
lines.push(` from: ${JSON.stringify(meta.from)},`);
|
|
91
90
|
lines.push(` to: ${JSON.stringify(meta.to)},`);
|
|
92
|
-
if (meta.kind) {
|
|
93
|
-
lines.push(` kind: ${JSON.stringify(meta.kind)},`);
|
|
94
|
-
}
|
|
95
91
|
if (meta.labels && meta.labels.length > 0) {
|
|
96
92
|
lines.push(` labels: ${jsonToTsSource(meta.labels)},`);
|
|
97
93
|
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SchemaIssue,
|
|
3
|
+
SchemaVerificationNode,
|
|
4
|
+
} from '@prisma-next/framework-components/control';
|
|
5
|
+
import type {
|
|
6
|
+
MongoSchemaCollection,
|
|
7
|
+
MongoSchemaIndex,
|
|
8
|
+
MongoSchemaIR,
|
|
9
|
+
} from '@prisma-next/mongo-schema-ir';
|
|
10
|
+
import { canonicalize, deepEqual } from '@prisma-next/mongo-schema-ir';
|
|
11
|
+
|
|
12
|
+
export function diffMongoSchemas(
|
|
13
|
+
live: MongoSchemaIR,
|
|
14
|
+
expected: MongoSchemaIR,
|
|
15
|
+
strict: boolean,
|
|
16
|
+
): {
|
|
17
|
+
root: SchemaVerificationNode;
|
|
18
|
+
issues: SchemaIssue[];
|
|
19
|
+
counts: { pass: number; warn: number; fail: number; totalNodes: number };
|
|
20
|
+
} {
|
|
21
|
+
const issues: SchemaIssue[] = [];
|
|
22
|
+
const collectionChildren: SchemaVerificationNode[] = [];
|
|
23
|
+
let pass = 0;
|
|
24
|
+
let warn = 0;
|
|
25
|
+
let fail = 0;
|
|
26
|
+
|
|
27
|
+
const allNames = new Set([...live.collectionNames, ...expected.collectionNames]);
|
|
28
|
+
|
|
29
|
+
for (const name of [...allNames].sort()) {
|
|
30
|
+
const liveColl = live.collection(name);
|
|
31
|
+
const expectedColl = expected.collection(name);
|
|
32
|
+
|
|
33
|
+
if (!liveColl && expectedColl) {
|
|
34
|
+
issues.push({
|
|
35
|
+
kind: 'missing_table',
|
|
36
|
+
table: name,
|
|
37
|
+
message: `Collection "${name}" is missing from the database`,
|
|
38
|
+
});
|
|
39
|
+
collectionChildren.push({
|
|
40
|
+
status: 'fail',
|
|
41
|
+
kind: 'collection',
|
|
42
|
+
name,
|
|
43
|
+
contractPath: `storage.collections.${name}`,
|
|
44
|
+
code: 'MISSING_COLLECTION',
|
|
45
|
+
message: `Collection "${name}" is missing`,
|
|
46
|
+
expected: name,
|
|
47
|
+
actual: null,
|
|
48
|
+
children: [],
|
|
49
|
+
});
|
|
50
|
+
fail++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (liveColl && !expectedColl) {
|
|
55
|
+
const status = strict ? 'fail' : 'warn';
|
|
56
|
+
issues.push({
|
|
57
|
+
kind: 'extra_table',
|
|
58
|
+
table: name,
|
|
59
|
+
message: `Extra collection "${name}" exists in the database but not in the contract`,
|
|
60
|
+
});
|
|
61
|
+
collectionChildren.push({
|
|
62
|
+
status,
|
|
63
|
+
kind: 'collection',
|
|
64
|
+
name,
|
|
65
|
+
contractPath: `storage.collections.${name}`,
|
|
66
|
+
code: 'EXTRA_COLLECTION',
|
|
67
|
+
message: `Extra collection "${name}" found`,
|
|
68
|
+
expected: null,
|
|
69
|
+
actual: name,
|
|
70
|
+
children: [],
|
|
71
|
+
});
|
|
72
|
+
if (status === 'fail') fail++;
|
|
73
|
+
else warn++;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const lc = liveColl as MongoSchemaCollection;
|
|
78
|
+
const ec = expectedColl as MongoSchemaCollection;
|
|
79
|
+
const indexChildren = diffIndexes(name, lc, ec, strict, issues);
|
|
80
|
+
const validatorChildren = diffValidator(name, lc, ec, strict, issues);
|
|
81
|
+
const optionsChildren = diffOptions(name, lc, ec, strict, issues);
|
|
82
|
+
const children = [...indexChildren, ...validatorChildren, ...optionsChildren];
|
|
83
|
+
|
|
84
|
+
const worstStatus = children.reduce<'pass' | 'warn' | 'fail'>(
|
|
85
|
+
(s, c) => (c.status === 'fail' ? 'fail' : c.status === 'warn' && s !== 'fail' ? 'warn' : s),
|
|
86
|
+
'pass',
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
for (const c of children) {
|
|
90
|
+
if (c.status === 'pass') pass++;
|
|
91
|
+
else if (c.status === 'warn') warn++;
|
|
92
|
+
else fail++;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (children.length === 0) {
|
|
96
|
+
pass++;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
collectionChildren.push({
|
|
100
|
+
status: worstStatus,
|
|
101
|
+
kind: 'collection',
|
|
102
|
+
name,
|
|
103
|
+
contractPath: `storage.collections.${name}`,
|
|
104
|
+
code: worstStatus === 'pass' ? 'MATCH' : 'DRIFT',
|
|
105
|
+
message:
|
|
106
|
+
worstStatus === 'pass' ? `Collection "${name}" matches` : `Collection "${name}" has drift`,
|
|
107
|
+
expected: name,
|
|
108
|
+
actual: name,
|
|
109
|
+
children,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const rootStatus = fail > 0 ? 'fail' : warn > 0 ? 'warn' : 'pass';
|
|
114
|
+
const totalNodes = pass + warn + fail + collectionChildren.length;
|
|
115
|
+
|
|
116
|
+
const root: SchemaVerificationNode = {
|
|
117
|
+
status: rootStatus,
|
|
118
|
+
kind: 'root',
|
|
119
|
+
name: 'mongo-schema',
|
|
120
|
+
contractPath: 'storage',
|
|
121
|
+
code: rootStatus === 'pass' ? 'MATCH' : 'DRIFT',
|
|
122
|
+
message: rootStatus === 'pass' ? 'Schema matches' : 'Schema has drift',
|
|
123
|
+
expected: null,
|
|
124
|
+
actual: null,
|
|
125
|
+
children: collectionChildren,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return { root, issues, counts: { pass, warn, fail, totalNodes } };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function buildIndexLookupKey(index: MongoSchemaIndex): string {
|
|
132
|
+
const keys = index.keys.map((k) => `${k.field}:${k.direction}`).join(',');
|
|
133
|
+
const opts = [
|
|
134
|
+
index.unique ? 'unique' : '',
|
|
135
|
+
index.sparse ? 'sparse' : '',
|
|
136
|
+
index.expireAfterSeconds != null ? `ttl:${index.expireAfterSeconds}` : '',
|
|
137
|
+
index.partialFilterExpression ? `pfe:${canonicalize(index.partialFilterExpression)}` : '',
|
|
138
|
+
index.wildcardProjection ? `wp:${canonicalize(index.wildcardProjection)}` : '',
|
|
139
|
+
index.collation ? `col:${canonicalize(index.collation)}` : '',
|
|
140
|
+
index.weights ? `wt:${canonicalize(index.weights)}` : '',
|
|
141
|
+
index.default_language ? `dl:${index.default_language}` : '',
|
|
142
|
+
index.language_override ? `lo:${index.language_override}` : '',
|
|
143
|
+
]
|
|
144
|
+
.filter(Boolean)
|
|
145
|
+
.join(';');
|
|
146
|
+
return opts ? `${keys}|${opts}` : keys;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function formatIndexName(index: MongoSchemaIndex): string {
|
|
150
|
+
return index.keys.map((k) => `${k.field}:${k.direction}`).join(', ');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function diffIndexes(
|
|
154
|
+
collName: string,
|
|
155
|
+
live: MongoSchemaCollection,
|
|
156
|
+
expected: MongoSchemaCollection,
|
|
157
|
+
strict: boolean,
|
|
158
|
+
issues: SchemaIssue[],
|
|
159
|
+
): SchemaVerificationNode[] {
|
|
160
|
+
const nodes: SchemaVerificationNode[] = [];
|
|
161
|
+
const liveLookup = new Map<string, MongoSchemaIndex>();
|
|
162
|
+
for (const idx of live.indexes) liveLookup.set(buildIndexLookupKey(idx), idx);
|
|
163
|
+
|
|
164
|
+
const expectedLookup = new Map<string, MongoSchemaIndex>();
|
|
165
|
+
for (const idx of expected.indexes) expectedLookup.set(buildIndexLookupKey(idx), idx);
|
|
166
|
+
|
|
167
|
+
for (const [key, idx] of expectedLookup) {
|
|
168
|
+
if (liveLookup.has(key)) {
|
|
169
|
+
nodes.push({
|
|
170
|
+
status: 'pass',
|
|
171
|
+
kind: 'index',
|
|
172
|
+
name: formatIndexName(idx),
|
|
173
|
+
contractPath: `storage.collections.${collName}.indexes`,
|
|
174
|
+
code: 'MATCH',
|
|
175
|
+
message: `Index ${formatIndexName(idx)} matches`,
|
|
176
|
+
expected: key,
|
|
177
|
+
actual: key,
|
|
178
|
+
children: [],
|
|
179
|
+
});
|
|
180
|
+
} else {
|
|
181
|
+
issues.push({
|
|
182
|
+
kind: 'index_mismatch',
|
|
183
|
+
table: collName,
|
|
184
|
+
indexOrConstraint: formatIndexName(idx),
|
|
185
|
+
message: `Index ${formatIndexName(idx)} missing on collection "${collName}"`,
|
|
186
|
+
});
|
|
187
|
+
nodes.push({
|
|
188
|
+
status: 'fail',
|
|
189
|
+
kind: 'index',
|
|
190
|
+
name: formatIndexName(idx),
|
|
191
|
+
contractPath: `storage.collections.${collName}.indexes`,
|
|
192
|
+
code: 'MISSING_INDEX',
|
|
193
|
+
message: `Index ${formatIndexName(idx)} missing`,
|
|
194
|
+
expected: key,
|
|
195
|
+
actual: null,
|
|
196
|
+
children: [],
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for (const [key, idx] of liveLookup) {
|
|
202
|
+
if (!expectedLookup.has(key)) {
|
|
203
|
+
const status = strict ? 'fail' : 'warn';
|
|
204
|
+
issues.push({
|
|
205
|
+
kind: 'extra_index',
|
|
206
|
+
table: collName,
|
|
207
|
+
indexOrConstraint: formatIndexName(idx),
|
|
208
|
+
message: `Extra index ${formatIndexName(idx)} on collection "${collName}"`,
|
|
209
|
+
});
|
|
210
|
+
nodes.push({
|
|
211
|
+
status,
|
|
212
|
+
kind: 'index',
|
|
213
|
+
name: formatIndexName(idx),
|
|
214
|
+
contractPath: `storage.collections.${collName}.indexes`,
|
|
215
|
+
code: 'EXTRA_INDEX',
|
|
216
|
+
message: `Extra index ${formatIndexName(idx)}`,
|
|
217
|
+
expected: null,
|
|
218
|
+
actual: key,
|
|
219
|
+
children: [],
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return nodes;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function diffValidator(
|
|
228
|
+
collName: string,
|
|
229
|
+
live: MongoSchemaCollection,
|
|
230
|
+
expected: MongoSchemaCollection,
|
|
231
|
+
strict: boolean,
|
|
232
|
+
issues: SchemaIssue[],
|
|
233
|
+
): SchemaVerificationNode[] {
|
|
234
|
+
if (!live.validator && !expected.validator) return [];
|
|
235
|
+
|
|
236
|
+
if (expected.validator && !live.validator) {
|
|
237
|
+
issues.push({
|
|
238
|
+
kind: 'type_missing',
|
|
239
|
+
table: collName,
|
|
240
|
+
message: `Validator missing on collection "${collName}"`,
|
|
241
|
+
});
|
|
242
|
+
return [
|
|
243
|
+
{
|
|
244
|
+
status: 'fail',
|
|
245
|
+
kind: 'validator',
|
|
246
|
+
name: 'validator',
|
|
247
|
+
contractPath: `storage.collections.${collName}.validator`,
|
|
248
|
+
code: 'MISSING_VALIDATOR',
|
|
249
|
+
message: 'Validator missing',
|
|
250
|
+
expected: canonicalize(expected.validator.jsonSchema),
|
|
251
|
+
actual: null,
|
|
252
|
+
children: [],
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!expected.validator && live.validator) {
|
|
258
|
+
const status = strict ? 'fail' : 'warn';
|
|
259
|
+
issues.push({
|
|
260
|
+
kind: 'extra_validator',
|
|
261
|
+
table: collName,
|
|
262
|
+
message: `Extra validator on collection "${collName}"`,
|
|
263
|
+
});
|
|
264
|
+
return [
|
|
265
|
+
{
|
|
266
|
+
status,
|
|
267
|
+
kind: 'validator',
|
|
268
|
+
name: 'validator',
|
|
269
|
+
contractPath: `storage.collections.${collName}.validator`,
|
|
270
|
+
code: 'EXTRA_VALIDATOR',
|
|
271
|
+
message: 'Extra validator found',
|
|
272
|
+
expected: null,
|
|
273
|
+
actual: canonicalize(live.validator.jsonSchema),
|
|
274
|
+
children: [],
|
|
275
|
+
},
|
|
276
|
+
];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const liveVal = live.validator as NonNullable<typeof live.validator>;
|
|
280
|
+
const expectedVal = expected.validator as NonNullable<typeof expected.validator>;
|
|
281
|
+
const liveSchema = canonicalize(liveVal.jsonSchema);
|
|
282
|
+
const expectedSchema = canonicalize(expectedVal.jsonSchema);
|
|
283
|
+
|
|
284
|
+
if (
|
|
285
|
+
liveSchema !== expectedSchema ||
|
|
286
|
+
liveVal.validationLevel !== expectedVal.validationLevel ||
|
|
287
|
+
liveVal.validationAction !== expectedVal.validationAction
|
|
288
|
+
) {
|
|
289
|
+
issues.push({
|
|
290
|
+
kind: 'type_mismatch',
|
|
291
|
+
table: collName,
|
|
292
|
+
expected: expectedSchema,
|
|
293
|
+
actual: liveSchema,
|
|
294
|
+
message: `Validator mismatch on collection "${collName}"`,
|
|
295
|
+
});
|
|
296
|
+
return [
|
|
297
|
+
{
|
|
298
|
+
status: 'fail',
|
|
299
|
+
kind: 'validator',
|
|
300
|
+
name: 'validator',
|
|
301
|
+
contractPath: `storage.collections.${collName}.validator`,
|
|
302
|
+
code: 'VALIDATOR_MISMATCH',
|
|
303
|
+
message: 'Validator mismatch',
|
|
304
|
+
expected: {
|
|
305
|
+
jsonSchema: expectedVal.jsonSchema,
|
|
306
|
+
validationLevel: expectedVal.validationLevel,
|
|
307
|
+
validationAction: expectedVal.validationAction,
|
|
308
|
+
},
|
|
309
|
+
actual: {
|
|
310
|
+
jsonSchema: liveVal.jsonSchema,
|
|
311
|
+
validationLevel: liveVal.validationLevel,
|
|
312
|
+
validationAction: liveVal.validationAction,
|
|
313
|
+
},
|
|
314
|
+
children: [],
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return [
|
|
320
|
+
{
|
|
321
|
+
status: 'pass',
|
|
322
|
+
kind: 'validator',
|
|
323
|
+
name: 'validator',
|
|
324
|
+
contractPath: `storage.collections.${collName}.validator`,
|
|
325
|
+
code: 'MATCH',
|
|
326
|
+
message: 'Validator matches',
|
|
327
|
+
expected: expectedSchema,
|
|
328
|
+
actual: liveSchema,
|
|
329
|
+
children: [],
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function diffOptions(
|
|
335
|
+
collName: string,
|
|
336
|
+
live: MongoSchemaCollection,
|
|
337
|
+
expected: MongoSchemaCollection,
|
|
338
|
+
strict: boolean,
|
|
339
|
+
issues: SchemaIssue[],
|
|
340
|
+
): SchemaVerificationNode[] {
|
|
341
|
+
if (!live.options && !expected.options) return [];
|
|
342
|
+
|
|
343
|
+
if (!expected.options && live.options) {
|
|
344
|
+
const status = strict ? 'fail' : 'warn';
|
|
345
|
+
issues.push({
|
|
346
|
+
kind: 'type_mismatch',
|
|
347
|
+
table: collName,
|
|
348
|
+
actual: canonicalize(live.options),
|
|
349
|
+
message: `Extra collection options on "${collName}"`,
|
|
350
|
+
});
|
|
351
|
+
return [
|
|
352
|
+
{
|
|
353
|
+
status,
|
|
354
|
+
kind: 'options',
|
|
355
|
+
name: 'options',
|
|
356
|
+
contractPath: `storage.collections.${collName}.options`,
|
|
357
|
+
code: 'EXTRA_OPTIONS',
|
|
358
|
+
message: 'Extra collection options found',
|
|
359
|
+
expected: null,
|
|
360
|
+
actual: live.options,
|
|
361
|
+
children: [],
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (deepEqual(live.options, expected.options)) {
|
|
367
|
+
return [
|
|
368
|
+
{
|
|
369
|
+
status: 'pass',
|
|
370
|
+
kind: 'options',
|
|
371
|
+
name: 'options',
|
|
372
|
+
contractPath: `storage.collections.${collName}.options`,
|
|
373
|
+
code: 'MATCH',
|
|
374
|
+
message: 'Collection options match',
|
|
375
|
+
expected: canonicalize(expected.options),
|
|
376
|
+
actual: canonicalize(live.options),
|
|
377
|
+
children: [],
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
issues.push({
|
|
383
|
+
kind: 'type_mismatch',
|
|
384
|
+
table: collName,
|
|
385
|
+
expected: canonicalize(expected.options),
|
|
386
|
+
actual: canonicalize(live.options),
|
|
387
|
+
message: `Collection options mismatch on "${collName}"`,
|
|
388
|
+
});
|
|
389
|
+
return [
|
|
390
|
+
{
|
|
391
|
+
status: 'fail',
|
|
392
|
+
kind: 'options',
|
|
393
|
+
name: 'options',
|
|
394
|
+
contractPath: `storage.collections.${collName}.options`,
|
|
395
|
+
code: 'OPTIONS_MISMATCH',
|
|
396
|
+
message: 'Collection options mismatch',
|
|
397
|
+
expected: expected.options,
|
|
398
|
+
actual: live.options,
|
|
399
|
+
children: [],
|
|
400
|
+
},
|
|
401
|
+
];
|
|
402
|
+
}
|