@prisma-next/mongo-contract 0.13.0 → 0.14.0-dev.2
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/entity-kinds-C9KNr9IE.mjs +572 -0
- package/dist/entity-kinds-C9KNr9IE.mjs.map +1 -0
- package/dist/entity-kinds.d.mts +16 -0
- package/dist/entity-kinds.d.mts.map +1 -0
- package/dist/entity-kinds.mjs +2 -0
- package/dist/index.d.mts +9 -526
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +18 -563
- package/dist/index.mjs.map +1 -1
- package/dist/mongo-collection-BCi-Bq_a.d.mts +530 -0
- package/dist/mongo-collection-BCi-Bq_a.d.mts.map +1 -0
- package/package.json +11 -8
- package/src/contract-schema.ts +1 -1
- package/src/contract-types.ts +41 -18
- package/src/entity-kinds.ts +34 -0
- package/src/exports/entity-kinds.ts +1 -0
- package/src/exports/index.ts +4 -2
- package/src/ir/build-mongo-namespace.ts +31 -55
- package/src/ir/mongo-index.ts +3 -2
- package/src/ir/mongo-storage.ts +6 -11
- package/src/ir/mongo-unbound-namespace.ts +4 -4
- package/src/validate-storage.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,558 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type } from "arktype";
|
|
1
|
+
import { a as MongoIndex, c as MongoIndexOptionDefaults, d as MongoContractSchema, f as createMongoContractSchema, i as MongoValidator, l as MongoCollationOptions, n as composeMongoEntityKinds, o as MongoCollectionOptions, p as createMongoNamespaceEnvelopeSchema, r as MongoCollection, s as MongoTimeSeriesCollectionOptions, u as MongoChangeStreamPreAndPostImagesOptions } from "./entity-kinds-C9KNr9IE.mjs";
|
|
3
2
|
import { UNBOUND_DOMAIN_NAMESPACE_ID } from "@prisma-next/contract/default-namespace";
|
|
4
|
-
import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
|
|
5
|
-
import { blindCast
|
|
6
|
-
//#region src/contract-schema.ts
|
|
7
|
-
const ControlPolicySchema = type("'managed' | 'tolerated' | 'external' | 'observed'");
|
|
8
|
-
const ScalarFieldTypeSchema = type({
|
|
9
|
-
"+": "reject",
|
|
10
|
-
kind: "'scalar'",
|
|
11
|
-
codecId: "string",
|
|
12
|
-
"typeParams?": "Record<string, unknown>"
|
|
13
|
-
});
|
|
14
|
-
const ValueObjectFieldTypeSchema = type({
|
|
15
|
-
"+": "reject",
|
|
16
|
-
kind: "'valueObject'",
|
|
17
|
-
name: "string"
|
|
18
|
-
});
|
|
19
|
-
const UnionFieldTypeSchema = type({
|
|
20
|
-
"+": "reject",
|
|
21
|
-
kind: "'union'",
|
|
22
|
-
members: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).array()
|
|
23
|
-
});
|
|
24
|
-
const FieldSchema = type({
|
|
25
|
-
"+": "reject",
|
|
26
|
-
type: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).or(UnionFieldTypeSchema),
|
|
27
|
-
"nullable?": "boolean",
|
|
28
|
-
"many?": "boolean",
|
|
29
|
-
"dict?": "boolean"
|
|
30
|
-
}).pipe((field) => ({
|
|
31
|
-
...field,
|
|
32
|
-
nullable: field.nullable ?? false
|
|
33
|
-
}));
|
|
34
|
-
const RelationSchema = type({
|
|
35
|
-
"+": "reject",
|
|
36
|
-
to: CrossReferenceSchema,
|
|
37
|
-
cardinality: "'1:1' | '1:N' | 'N:1'",
|
|
38
|
-
"on?": type({
|
|
39
|
-
"+": "reject",
|
|
40
|
-
localFields: "string[]",
|
|
41
|
-
targetFields: "string[]"
|
|
42
|
-
})
|
|
43
|
-
});
|
|
44
|
-
const StorageRelationEntrySchema = type({
|
|
45
|
-
"+": "reject",
|
|
46
|
-
field: "string"
|
|
47
|
-
});
|
|
48
|
-
const MongoJsonPrimitiveSchema = type.declare().type("string | number | boolean | null");
|
|
49
|
-
function isMongoJsonRecord(value) {
|
|
50
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
51
|
-
const prototype = Object.getPrototypeOf(value);
|
|
52
|
-
return prototype === Object.prototype || prototype === null;
|
|
53
|
-
}
|
|
54
|
-
function withUnseenReference(value, seen, visit) {
|
|
55
|
-
if (seen.has(value)) return false;
|
|
56
|
-
seen.add(value);
|
|
57
|
-
const result = visit();
|
|
58
|
-
seen.delete(value);
|
|
59
|
-
return result;
|
|
60
|
-
}
|
|
61
|
-
function isMongoJsonObject(value, seen) {
|
|
62
|
-
return isMongoJsonRecord(value) && withUnseenReference(value, seen, () => Object.values(value).every((entry) => isMongoJsonValue(entry, seen)));
|
|
63
|
-
}
|
|
64
|
-
function isMongoJsonValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
65
|
-
if (MongoJsonPrimitiveSchema.allows(value)) return true;
|
|
66
|
-
if (Array.isArray(value)) return withUnseenReference(value, seen, () => value.every((entry) => isMongoJsonValue(entry, seen)));
|
|
67
|
-
return isMongoJsonObject(value, seen);
|
|
68
|
-
}
|
|
69
|
-
const MongoJsonValueSchema = type("unknown").narrow((value, ctx) => isMongoJsonValue(value) ? true : ctx.mustBe("a JSON-serializable MongoJsonValue"));
|
|
70
|
-
const MongoJsonObjectSchema = type({ "[string]": "unknown" }).narrow((value, ctx) => isMongoJsonRecord(value) && Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry)) ? true : ctx.mustBe("a JSON object with MongoJsonValue entries"));
|
|
71
|
-
const NumberRecordSchema = type({ "[string]": "number" });
|
|
72
|
-
const IndexFieldsSchema = type({
|
|
73
|
-
"+": "reject",
|
|
74
|
-
"[string]": "1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\""
|
|
75
|
-
}).narrow((fields, ctx) => Object.keys(fields).length > 0 ? true : ctx.mustBe("an index field map with at least one entry"));
|
|
76
|
-
const CollationSchema = type({
|
|
77
|
-
"+": "reject",
|
|
78
|
-
"kind?": "'mongo-collation-options'",
|
|
79
|
-
locale: "string",
|
|
80
|
-
"caseLevel?": "boolean",
|
|
81
|
-
"caseFirst?": "\"off\" | \"upper\" | \"lower\"",
|
|
82
|
-
"strength?": "1 | 2 | 3 | 4 | 5",
|
|
83
|
-
"numericOrdering?": "boolean",
|
|
84
|
-
"alternate?": "\"non-ignorable\" | \"shifted\"",
|
|
85
|
-
"maxVariable?": "\"punct\" | \"space\"",
|
|
86
|
-
"backwards?": "boolean",
|
|
87
|
-
"normalization?": "boolean"
|
|
88
|
-
});
|
|
89
|
-
const IndexOptionDefaultsSchema = type({
|
|
90
|
-
"+": "reject",
|
|
91
|
-
"kind?": "'mongo-index-option-defaults'",
|
|
92
|
-
"storageEngine?": MongoJsonObjectSchema
|
|
93
|
-
});
|
|
94
|
-
const TimeSeriesCollectionOptionsSchema = type({
|
|
95
|
-
"+": "reject",
|
|
96
|
-
"kind?": "'mongo-time-series-collection-options'",
|
|
97
|
-
timeField: "string",
|
|
98
|
-
"metaField?": "string",
|
|
99
|
-
"granularity?": "\"seconds\" | \"minutes\" | \"hours\"",
|
|
100
|
-
"bucketMaxSpanSeconds?": "number",
|
|
101
|
-
"bucketRoundingSeconds?": "number"
|
|
102
|
-
});
|
|
103
|
-
const ClusteredCollectionOptionsSchema = type({
|
|
104
|
-
"+": "reject",
|
|
105
|
-
"kind?": "'mongo-clustered-collection-options'",
|
|
106
|
-
"name?": "string",
|
|
107
|
-
key: type({
|
|
108
|
-
"+": "reject",
|
|
109
|
-
"[string]": "1"
|
|
110
|
-
}).narrow((key, ctx) => Object.keys(key).length > 0 ? true : ctx.mustBe("a clustered index key map with at least one entry")),
|
|
111
|
-
unique: "boolean"
|
|
112
|
-
});
|
|
113
|
-
const ChangeStreamPreAndPostImagesSchema = type({
|
|
114
|
-
"+": "reject",
|
|
115
|
-
"kind?": "'mongo-change-stream-pre-and-post-images-options'",
|
|
116
|
-
enabled: "boolean"
|
|
117
|
-
});
|
|
118
|
-
type({
|
|
119
|
-
"+": "reject",
|
|
120
|
-
"capped?": "boolean",
|
|
121
|
-
"size?": "number",
|
|
122
|
-
"max?": "number",
|
|
123
|
-
"storageEngine?": MongoJsonObjectSchema,
|
|
124
|
-
"indexOptionDefaults?": IndexOptionDefaultsSchema,
|
|
125
|
-
"collation?": CollationSchema,
|
|
126
|
-
"timeseries?": TimeSeriesCollectionOptionsSchema,
|
|
127
|
-
"clusteredIndex?": ClusteredCollectionOptionsSchema,
|
|
128
|
-
"expireAfterSeconds?": "number",
|
|
129
|
-
"changeStreamPreAndPostImages?": ChangeStreamPreAndPostImagesSchema
|
|
130
|
-
});
|
|
131
|
-
const ModelStorageSchema = type({
|
|
132
|
-
"+": "reject",
|
|
133
|
-
"collection?": "string",
|
|
134
|
-
"relations?": type({ "[string]": StorageRelationEntrySchema })
|
|
135
|
-
});
|
|
136
|
-
const DiscriminatorSchema = type({
|
|
137
|
-
"+": "reject",
|
|
138
|
-
field: "string"
|
|
139
|
-
});
|
|
140
|
-
const VariantEntrySchema = type({
|
|
141
|
-
"+": "reject",
|
|
142
|
-
value: "string"
|
|
143
|
-
});
|
|
144
|
-
const ModelDefinitionSchema = type({
|
|
145
|
-
"+": "reject",
|
|
146
|
-
fields: type({ "[string]": FieldSchema }),
|
|
147
|
-
storage: ModelStorageSchema,
|
|
148
|
-
"relations?": type({ "[string]": RelationSchema }),
|
|
149
|
-
"discriminator?": DiscriminatorSchema,
|
|
150
|
-
"variants?": type({ "[string]": VariantEntrySchema }),
|
|
151
|
-
"base?": CrossReferenceSchema,
|
|
152
|
-
"owner?": "string"
|
|
153
|
-
});
|
|
154
|
-
type({
|
|
155
|
-
"+": "reject",
|
|
156
|
-
fields: IndexFieldsSchema,
|
|
157
|
-
"options?": type({
|
|
158
|
-
"+": "reject",
|
|
159
|
-
"kind?": "'mongo-index-options'",
|
|
160
|
-
"unique?": "boolean",
|
|
161
|
-
"name?": "string",
|
|
162
|
-
"partialFilterExpression?": MongoJsonObjectSchema,
|
|
163
|
-
"sparse?": "boolean",
|
|
164
|
-
"expireAfterSeconds?": "number",
|
|
165
|
-
"weights?": NumberRecordSchema,
|
|
166
|
-
"default_language?": "string",
|
|
167
|
-
"language_override?": "string",
|
|
168
|
-
"textIndexVersion?": "number",
|
|
169
|
-
"2dsphereIndexVersion?": "number",
|
|
170
|
-
"bits?": "number",
|
|
171
|
-
"min?": "number",
|
|
172
|
-
"max?": "number",
|
|
173
|
-
"bucketSize?": "number",
|
|
174
|
-
"hidden?": "boolean",
|
|
175
|
-
"collation?": CollationSchema,
|
|
176
|
-
"wildcardProjection?": type({
|
|
177
|
-
"+": "reject",
|
|
178
|
-
"[string]": "0 | 1"
|
|
179
|
-
})
|
|
180
|
-
})
|
|
181
|
-
});
|
|
182
|
-
const MongoStorageIndexSchema = type({
|
|
183
|
-
"+": "reject",
|
|
184
|
-
"kind?": "'mongo-index'",
|
|
185
|
-
keys: type({
|
|
186
|
-
"+": "reject",
|
|
187
|
-
field: "string",
|
|
188
|
-
direction: "1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\""
|
|
189
|
-
}).array().atLeastLength(1),
|
|
190
|
-
"unique?": "boolean",
|
|
191
|
-
"sparse?": "boolean",
|
|
192
|
-
"expireAfterSeconds?": "number",
|
|
193
|
-
"partialFilterExpression?": "Record<string, unknown>",
|
|
194
|
-
"wildcardProjection?": "Record<string, 0 | 1>",
|
|
195
|
-
"collation?": "Record<string, unknown>",
|
|
196
|
-
"weights?": "Record<string, number>",
|
|
197
|
-
"default_language?": "string",
|
|
198
|
-
"language_override?": "string"
|
|
199
|
-
});
|
|
200
|
-
const MongoStorageValidatorSchema = type({
|
|
201
|
-
"+": "reject",
|
|
202
|
-
"kind?": "'mongo-validator'",
|
|
203
|
-
jsonSchema: "Record<string, unknown>",
|
|
204
|
-
validationLevel: "'strict' | 'moderate'",
|
|
205
|
-
validationAction: "'error' | 'warn'"
|
|
206
|
-
});
|
|
207
|
-
const MongoCollectionOptionsSchema = type({
|
|
208
|
-
"+": "reject",
|
|
209
|
-
"kind?": "'mongo-collection-options'",
|
|
210
|
-
"capped?": type({
|
|
211
|
-
"+": "reject",
|
|
212
|
-
size: "number",
|
|
213
|
-
"max?": "number"
|
|
214
|
-
}),
|
|
215
|
-
"storageEngine?": MongoJsonObjectSchema,
|
|
216
|
-
"indexOptionDefaults?": IndexOptionDefaultsSchema,
|
|
217
|
-
"timeseries?": type({
|
|
218
|
-
"+": "reject",
|
|
219
|
-
"kind?": "'mongo-time-series-collection-options'",
|
|
220
|
-
timeField: "string",
|
|
221
|
-
"metaField?": "string",
|
|
222
|
-
"granularity?": "'seconds' | 'minutes' | 'hours'",
|
|
223
|
-
"bucketMaxSpanSeconds?": "number",
|
|
224
|
-
"bucketRoundingSeconds?": "number"
|
|
225
|
-
}),
|
|
226
|
-
"collation?": "Record<string, unknown>",
|
|
227
|
-
"expireAfterSeconds?": "number",
|
|
228
|
-
"changeStreamPreAndPostImages?": ChangeStreamPreAndPostImagesSchema,
|
|
229
|
-
"clusteredIndex?": type({
|
|
230
|
-
"+": "reject",
|
|
231
|
-
"name?": "string"
|
|
232
|
-
})
|
|
233
|
-
});
|
|
234
|
-
const StorageCollectionSchema = type({
|
|
235
|
-
"+": "reject",
|
|
236
|
-
"kind?": "'mongo-collection'",
|
|
237
|
-
"indexes?": MongoStorageIndexSchema.array(),
|
|
238
|
-
"validator?": MongoStorageValidatorSchema,
|
|
239
|
-
"options?": MongoCollectionOptionsSchema,
|
|
240
|
-
"control?": ControlPolicySchema
|
|
241
|
-
});
|
|
242
|
-
function collectionEntrySchema(fragments) {
|
|
243
|
-
if (fragments === void 0 || fragments.size === 0) return StorageCollectionSchema;
|
|
244
|
-
return type("unknown").narrow((entry, ctx) => {
|
|
245
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return ctx.mustBe("an object");
|
|
246
|
-
const kind = entry.kind;
|
|
247
|
-
if (typeof kind === "string") {
|
|
248
|
-
const fragment = fragments.get(kind);
|
|
249
|
-
if (fragment !== void 0) {
|
|
250
|
-
const parsed = fragment(entry);
|
|
251
|
-
if (parsed instanceof type.errors) return ctx.reject({ expected: parsed.summary });
|
|
252
|
-
return true;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
const parsed = StorageCollectionSchema(entry);
|
|
256
|
-
if (parsed instanceof type.errors) return ctx.reject({ expected: parsed.summary });
|
|
257
|
-
return true;
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Builds the per-namespace envelope schema for Mongo storage. Pack
|
|
262
|
-
* contributions are keyed by the descriptor's `discriminator` and
|
|
263
|
-
* validate each entry by matching the entry's `kind` field. Mongo today
|
|
264
|
-
* has no pack contributions; the composition surface exists for symmetry
|
|
265
|
-
* with SQL and as the substrate for future entity kinds.
|
|
266
|
-
*
|
|
267
|
-
* `'kind?': 'string'` because `kind` is non-enumerable on built
|
|
268
|
-
* Mongo namespace IR classes and therefore absent from the wire shape; the
|
|
269
|
-
* type-side narrowing is enforced by the IR class, not by this validator.
|
|
270
|
-
*/
|
|
271
|
-
function createMongoNamespaceEnvelopeSchema(fragments) {
|
|
272
|
-
return type({
|
|
273
|
-
"+": "reject",
|
|
274
|
-
id: "string",
|
|
275
|
-
"kind?": "string",
|
|
276
|
-
entries: type({ "collection?": type({ "[string]": collectionEntrySchema(fragments) }) })
|
|
277
|
-
}).narrow((ns, ctx) => {
|
|
278
|
-
if (typeof ns !== "object" || ns === null || Array.isArray(ns)) return ctx.mustBe("an object");
|
|
279
|
-
if (Object.hasOwn(ns, "collections") || Object.hasOwn(ns, "tables")) return ctx.reject({ expected: "namespace must use `entries: { collection? }`; flat `collections` / `tables` keys are no longer accepted" });
|
|
280
|
-
return true;
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Builds the full Mongo contract schema. The per-namespace entry
|
|
285
|
-
* threading happens through {@link createMongoNamespaceEnvelopeSchema};
|
|
286
|
-
* the rest of the envelope is family-shared.
|
|
287
|
-
*/
|
|
288
|
-
function createMongoContractSchema(fragments) {
|
|
289
|
-
const namespaceEnvelope = createMongoNamespaceEnvelopeSchema(fragments);
|
|
290
|
-
return type({
|
|
291
|
-
"+": "reject",
|
|
292
|
-
targetFamily: "'mongo'",
|
|
293
|
-
"schemaVersion?": "string",
|
|
294
|
-
"target?": "string",
|
|
295
|
-
"storageHash?": "string",
|
|
296
|
-
"profileHash?": "string",
|
|
297
|
-
roots: type({ "[string]": CrossReferenceSchema }),
|
|
298
|
-
"capabilities?": "Record<string, unknown>",
|
|
299
|
-
"extensionPacks?": "Record<string, unknown>",
|
|
300
|
-
"meta?": "Record<string, unknown>",
|
|
301
|
-
"defaultControlPolicy?": ControlPolicySchema,
|
|
302
|
-
"sources?": "Record<string, unknown>",
|
|
303
|
-
"_generated?": "Record<string, unknown>",
|
|
304
|
-
domain: type({ namespaces: type({ "[string]": type({
|
|
305
|
-
models: type({ "[string]": ModelDefinitionSchema }),
|
|
306
|
-
"valueObjects?": type({ "[string]": type({
|
|
307
|
-
"+": "reject",
|
|
308
|
-
fields: type({ "[string]": FieldSchema })
|
|
309
|
-
}) })
|
|
310
|
-
}) }) }),
|
|
311
|
-
storage: type({
|
|
312
|
-
"+": "reject",
|
|
313
|
-
namespaces: type({ "[string]": namespaceEnvelope }),
|
|
314
|
-
"storageHash?": "string"
|
|
315
|
-
})
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
const MongoContractSchema = createMongoContractSchema();
|
|
319
|
-
//#endregion
|
|
3
|
+
import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode, hydrateNamespaceEntities } from "@prisma-next/framework-components/ir";
|
|
4
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
320
5
|
//#region src/default-namespace.ts
|
|
321
6
|
/** Default storage namespace for Mongo-family contracts at runtime. */
|
|
322
7
|
const defaultMongoStorageNamespaceId = UNBOUND_NAMESPACE_ID;
|
|
323
8
|
/** Default domain namespace for Mongo-family contracts at runtime. */
|
|
324
9
|
const defaultMongoDomainNamespaceId = UNBOUND_DOMAIN_NAMESPACE_ID;
|
|
325
10
|
//#endregion
|
|
326
|
-
//#region src/ir/mongo-change-stream-pre-and-post-images-options.ts
|
|
327
|
-
/**
|
|
328
|
-
* Change-stream pre-and-post-images collection option. Lifted from a
|
|
329
|
-
* `type =` data shape to an AST class extending `IRNodeBase` per
|
|
330
|
-
* FR18. Single-field shape; the class exists for AST-pattern
|
|
331
|
-
* consistency (every nested data shape inside `MongoCollectionOptions`
|
|
332
|
-
* is an AST node so the verifier can walk uniformly).
|
|
333
|
-
*/
|
|
334
|
-
var MongoChangeStreamPreAndPostImagesOptions = class extends IRNodeBase {
|
|
335
|
-
kind = "mongo-change-stream-pre-and-post-images-options";
|
|
336
|
-
enabled;
|
|
337
|
-
constructor(options) {
|
|
338
|
-
super();
|
|
339
|
-
this.enabled = options.enabled;
|
|
340
|
-
freezeNode(this);
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
//#endregion
|
|
344
|
-
//#region src/ir/mongo-collation-options.ts
|
|
345
|
-
/**
|
|
346
|
-
* Mongo Contract IR leaf for collection / index collation options.
|
|
347
|
-
*
|
|
348
|
-
* Lifted from a `type =` data shape to an AST class extending
|
|
349
|
-
* `IRNodeBase` per FR18 ("Mongo's Contract IR is fully unified under
|
|
350
|
-
* the AST-class pattern, layered family / target"). Single concrete class
|
|
351
|
-
* (no target subclass): collation options carry no target-specific
|
|
352
|
-
* variation at this layer — both Atlas and self-hosted Mongo consume the
|
|
353
|
-
* same option vocabulary.
|
|
354
|
-
*
|
|
355
|
-
* Undefined optional fields are not assigned, so `JSON.stringify` omits
|
|
356
|
-
* them from the canonical JSON output (matches the pre-lift data shape's
|
|
357
|
-
* round-trip behaviour, modulo the new `kind` discriminator).
|
|
358
|
-
*/
|
|
359
|
-
var MongoCollationOptions = class extends IRNodeBase {
|
|
360
|
-
kind = "mongo-collation-options";
|
|
361
|
-
locale;
|
|
362
|
-
constructor(options) {
|
|
363
|
-
super();
|
|
364
|
-
this.locale = options.locale;
|
|
365
|
-
if (options.caseLevel !== void 0) this.caseLevel = options.caseLevel;
|
|
366
|
-
if (options.caseFirst !== void 0) this.caseFirst = options.caseFirst;
|
|
367
|
-
if (options.strength !== void 0) this.strength = options.strength;
|
|
368
|
-
if (options.numericOrdering !== void 0) this.numericOrdering = options.numericOrdering;
|
|
369
|
-
if (options.alternate !== void 0) this.alternate = options.alternate;
|
|
370
|
-
if (options.maxVariable !== void 0) this.maxVariable = options.maxVariable;
|
|
371
|
-
if (options.backwards !== void 0) this.backwards = options.backwards;
|
|
372
|
-
if (options.normalization !== void 0) this.normalization = options.normalization;
|
|
373
|
-
freezeNode(this);
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
//#endregion
|
|
377
|
-
//#region src/ir/mongo-index-option-defaults.ts
|
|
378
|
-
/**
|
|
379
|
-
* Collection-level default index options (the `indexOptionDefaults`
|
|
380
|
-
* collection-creation field on Mongo's `createCollection`). Lifted from
|
|
381
|
-
* a `type =` data shape to an AST class extending `IRNodeBase` per
|
|
382
|
-
* FR18 (Mongo Contract IR fully unified under the AST-class pattern).
|
|
383
|
-
*
|
|
384
|
-
* Carries `storageEngine` only — the underlying MongoDB option set is
|
|
385
|
-
* intentionally narrow at this layer; per-engine richer option vocabularies
|
|
386
|
-
* are out of scope for this project.
|
|
387
|
-
*/
|
|
388
|
-
var MongoIndexOptionDefaults = class extends IRNodeBase {
|
|
389
|
-
kind = "mongo-index-option-defaults";
|
|
390
|
-
constructor(options = {}) {
|
|
391
|
-
super();
|
|
392
|
-
if (options.storageEngine !== void 0) this.storageEngine = options.storageEngine;
|
|
393
|
-
freezeNode(this);
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
//#endregion
|
|
397
|
-
//#region src/ir/mongo-time-series-collection-options.ts
|
|
398
|
-
/**
|
|
399
|
-
* Time-series collection options. Lifted from a `type =` data shape to
|
|
400
|
-
* an AST class extending `IRNodeBase` per FR18.
|
|
401
|
-
*
|
|
402
|
-
* MongoDB requires `timeField` for any time-series collection; the
|
|
403
|
-
* constructor enforces presence by type signature (`timeField: string`
|
|
404
|
-
* is required on the input).
|
|
405
|
-
*/
|
|
406
|
-
var MongoTimeSeriesCollectionOptions = class extends IRNodeBase {
|
|
407
|
-
kind = "mongo-time-series-collection-options";
|
|
408
|
-
timeField;
|
|
409
|
-
constructor(options) {
|
|
410
|
-
super();
|
|
411
|
-
this.timeField = options.timeField;
|
|
412
|
-
if (options.metaField !== void 0) this.metaField = options.metaField;
|
|
413
|
-
if (options.granularity !== void 0) this.granularity = options.granularity;
|
|
414
|
-
if (options.bucketMaxSpanSeconds !== void 0) this.bucketMaxSpanSeconds = options.bucketMaxSpanSeconds;
|
|
415
|
-
if (options.bucketRoundingSeconds !== void 0) this.bucketRoundingSeconds = options.bucketRoundingSeconds;
|
|
416
|
-
freezeNode(this);
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
//#endregion
|
|
420
|
-
//#region src/ir/mongo-collection-options.ts
|
|
421
|
-
/**
|
|
422
|
-
* Mongo Contract IR node for collection-level creation options (the
|
|
423
|
-
* second argument to `db.createCollection(name, options)`). Lifted from
|
|
424
|
-
* the pre-M2R2 `MongoStorageCollectionOptions` storage interface to a
|
|
425
|
-
* class extending `IRNodeBase` per FR18.
|
|
426
|
-
*
|
|
427
|
-
* Single concrete family-layer class (no target subclass). The
|
|
428
|
-
* constructor accepts the storage JSON envelope shape ({@link
|
|
429
|
-
* MongoCollectionOptionsInput}) so the family-base hydration walker
|
|
430
|
-
* can pass arktype-validated objects directly to `new`. Authoring
|
|
431
|
-
* vocabulary is translated to this shape upstream in the contract-ts
|
|
432
|
-
* builder.
|
|
433
|
-
*
|
|
434
|
-
* Nested IR sub-shapes (collation, timeseries, …) are normalised to
|
|
435
|
-
* their respective IR class instances inside the constructor so
|
|
436
|
-
* downstream walks see a uniform AST regardless of whether the input
|
|
437
|
-
* was a JSON literal or an already-constructed class.
|
|
438
|
-
*/
|
|
439
|
-
var MongoCollectionOptions = class extends IRNodeBase {
|
|
440
|
-
kind = "mongo-collection-options";
|
|
441
|
-
constructor(input = {}) {
|
|
442
|
-
super();
|
|
443
|
-
if (input.capped !== void 0) this.capped = {
|
|
444
|
-
size: input.capped.size,
|
|
445
|
-
...input.capped.max != null && { max: input.capped.max }
|
|
446
|
-
};
|
|
447
|
-
if (input.storageEngine !== void 0) this.storageEngine = input.storageEngine;
|
|
448
|
-
if (input.indexOptionDefaults !== void 0) this.indexOptionDefaults = input.indexOptionDefaults instanceof MongoIndexOptionDefaults ? input.indexOptionDefaults : new MongoIndexOptionDefaults(input.indexOptionDefaults);
|
|
449
|
-
if (input.collation !== void 0) this.collation = input.collation instanceof MongoCollationOptions ? input.collation : new MongoCollationOptions(input.collation);
|
|
450
|
-
if (input.timeseries !== void 0) this.timeseries = input.timeseries instanceof MongoTimeSeriesCollectionOptions ? input.timeseries : new MongoTimeSeriesCollectionOptions(input.timeseries);
|
|
451
|
-
if (input.clusteredIndex !== void 0) this.clusteredIndex = input.clusteredIndex.name !== void 0 ? { name: input.clusteredIndex.name } : {};
|
|
452
|
-
if (input.expireAfterSeconds !== void 0) this.expireAfterSeconds = input.expireAfterSeconds;
|
|
453
|
-
if (input.changeStreamPreAndPostImages !== void 0) this.changeStreamPreAndPostImages = input.changeStreamPreAndPostImages instanceof MongoChangeStreamPreAndPostImagesOptions ? input.changeStreamPreAndPostImages : new MongoChangeStreamPreAndPostImagesOptions(input.changeStreamPreAndPostImages);
|
|
454
|
-
freezeNode(this);
|
|
455
|
-
}
|
|
456
|
-
};
|
|
457
|
-
//#endregion
|
|
458
|
-
//#region src/ir/mongo-index.ts
|
|
459
|
-
/**
|
|
460
|
-
* Mongo Contract IR node for a single collection index entry (one
|
|
461
|
-
* element of `MongoCollection.indexes`). Lifted from the
|
|
462
|
-
* pre-M2R2 `MongoStorageIndex` storage interface to a class extending
|
|
463
|
-
* `IRNodeBase` per FR18.
|
|
464
|
-
*
|
|
465
|
-
* Single concrete family-layer class (no target subclass). The spec's
|
|
466
|
-
* `MongoTargetIndex extends MongoIndex` pattern remains additive — a
|
|
467
|
-
* future Mongo target with target-specific index extensions is free to
|
|
468
|
-
* subclass; for the single Mongo target shipped today a concrete
|
|
469
|
-
* family-layer class is enough and avoids a target-import layering
|
|
470
|
-
* violation from the contract-ts builder.
|
|
471
|
-
*/
|
|
472
|
-
var MongoIndex = class extends IRNodeBase {
|
|
473
|
-
kind = "mongo-index";
|
|
474
|
-
keys;
|
|
475
|
-
constructor(input) {
|
|
476
|
-
super();
|
|
477
|
-
this.keys = input.keys;
|
|
478
|
-
if (input.unique !== void 0) this.unique = input.unique;
|
|
479
|
-
if (input.sparse !== void 0) this.sparse = input.sparse;
|
|
480
|
-
if (input.expireAfterSeconds !== void 0) this.expireAfterSeconds = input.expireAfterSeconds;
|
|
481
|
-
if (input.partialFilterExpression !== void 0) this.partialFilterExpression = input.partialFilterExpression;
|
|
482
|
-
if (input.wildcardProjection !== void 0) this.wildcardProjection = input.wildcardProjection;
|
|
483
|
-
if (input.collation !== void 0) this.collation = input.collation;
|
|
484
|
-
if (input.weights !== void 0) this.weights = input.weights;
|
|
485
|
-
if (input.default_language !== void 0) this.default_language = input.default_language;
|
|
486
|
-
if (input.language_override !== void 0) this.language_override = input.language_override;
|
|
487
|
-
freezeNode(this);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
//#endregion
|
|
491
|
-
//#region src/ir/mongo-validator.ts
|
|
492
|
-
/**
|
|
493
|
-
* Mongo Contract IR node for collection-level document validators (the
|
|
494
|
-
* `validator` field on Mongo's `createCollection`). Lifted from the
|
|
495
|
-
* pre-M2R2 `MongoStorageValidator` storage interface to a class extending
|
|
496
|
-
* `IRNodeBase` per FR18.
|
|
497
|
-
*
|
|
498
|
-
* Concrete at the family layer (no target subclass). The spec's
|
|
499
|
-
* abstract-family + target-concrete pattern (`MongoTargetValidator
|
|
500
|
-
* extends MongoValidator`) becomes meaningful when a second Mongo target
|
|
501
|
-
* introduces target-specific validator extensions (Atlas search rules,
|
|
502
|
-
* DocumentDB-specific levels, …); for the single Mongo target shipped
|
|
503
|
-
* today, a concrete family-layer class lets the PSL JSON-Schema deriver
|
|
504
|
-
* and the contract-ts builder construct instances directly without a
|
|
505
|
-
* target-import layering violation. Target subclassing remains additive
|
|
506
|
-
* — a future `MongoTargetValidator extends MongoValidator` is an
|
|
507
|
-
* additive change, not a breaking one.
|
|
508
|
-
*/
|
|
509
|
-
var MongoValidator = class extends IRNodeBase {
|
|
510
|
-
kind = "mongo-validator";
|
|
511
|
-
jsonSchema;
|
|
512
|
-
validationLevel;
|
|
513
|
-
validationAction;
|
|
514
|
-
constructor(input) {
|
|
515
|
-
super();
|
|
516
|
-
this.jsonSchema = input.jsonSchema;
|
|
517
|
-
this.validationLevel = input.validationLevel;
|
|
518
|
-
this.validationAction = input.validationAction;
|
|
519
|
-
freezeNode(this);
|
|
520
|
-
}
|
|
521
|
-
};
|
|
522
|
-
//#endregion
|
|
523
|
-
//#region src/ir/mongo-collection.ts
|
|
524
|
-
/**
|
|
525
|
-
* Mongo Contract IR node for a single collection entry in a namespace's
|
|
526
|
-
* `collections` map. Lifted from the pre-M2R2
|
|
527
|
-
* `MongoStorageCollection` storage interface to a class extending
|
|
528
|
-
* `IRNodeBase` per FR18.
|
|
529
|
-
*
|
|
530
|
-
* Concrete at the family layer (no target subclass). The spec's
|
|
531
|
-
* `MongoTargetCollection extends MongoCollection` pattern remains
|
|
532
|
-
* additive: a future Mongo target with target-specific extensions is
|
|
533
|
-
* free to subclass without breaking the family-layer construction
|
|
534
|
-
* sites.
|
|
535
|
-
*
|
|
536
|
-
* The unprefixed name `MongoCollection` is now the contract IR class.
|
|
537
|
-
* Note that `@prisma-next/mongo-orm` also exports a (different)
|
|
538
|
-
* `MongoCollection<TContract, ModelName>` generic for the user-facing
|
|
539
|
-
* ORM query builder; the two live in separate packages and are
|
|
540
|
-
* resolved by import path. A source file that needs both should alias
|
|
541
|
-
* one (e.g. `import { MongoCollection as MongoContractCollection }
|
|
542
|
-
* from '@prisma-next/mongo-contract'`).
|
|
543
|
-
*/
|
|
544
|
-
var MongoCollection = class extends IRNodeBase {
|
|
545
|
-
kind = "mongo-collection";
|
|
546
|
-
constructor(input = {}) {
|
|
547
|
-
super();
|
|
548
|
-
if (input.indexes !== void 0) this.indexes = input.indexes.map((idx) => idx instanceof MongoIndex ? idx : new MongoIndex(idx));
|
|
549
|
-
if (input.validator !== void 0) this.validator = input.validator instanceof MongoValidator ? input.validator : new MongoValidator(input.validator);
|
|
550
|
-
if (input.options !== void 0) this.options = input.options instanceof MongoCollectionOptions ? input.options : new MongoCollectionOptions(input.options);
|
|
551
|
-
if (input.control !== void 0) this.control = input.control;
|
|
552
|
-
freezeNode(this);
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
//#endregion
|
|
556
11
|
//#region src/ir/mongo-unbound-namespace.ts
|
|
557
12
|
var MongoUnboundNamespace = class MongoUnboundNamespace extends NamespaceBase {
|
|
558
13
|
static instance = new MongoUnboundNamespace();
|
|
@@ -572,24 +27,24 @@ var MongoUnboundNamespace = class MongoUnboundNamespace extends NamespaceBase {
|
|
|
572
27
|
//#endregion
|
|
573
28
|
//#region src/ir/build-mongo-namespace.ts
|
|
574
29
|
const MONGO_NAMESPACE_KIND = "mongo-namespace";
|
|
575
|
-
function isMaterializedMongoNamespace(ns) {
|
|
576
|
-
if (typeof ns !== "object" || ns === null) return false;
|
|
577
|
-
const proto = Object.getPrototypeOf(ns);
|
|
578
|
-
if (proto === Object.prototype || proto === null) return false;
|
|
579
|
-
return ns.kind === MONGO_NAMESPACE_KIND;
|
|
580
|
-
}
|
|
581
30
|
var MongoBoundNamespace = class MongoBoundNamespace extends NamespaceBase {
|
|
582
31
|
id;
|
|
583
32
|
entries;
|
|
584
33
|
static fromCollectionsInput(input) {
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
34
|
+
const collectionMap = input.entries["collection"];
|
|
35
|
+
const collectionCount = collectionMap !== void 0 ? Object.keys(collectionMap).length : 0;
|
|
36
|
+
const hasUnknownKinds = Object.keys(input.entries).some((kind) => kind !== "collection");
|
|
37
|
+
if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0 && !hasUnknownKinds) return MongoUnboundNamespace.instance;
|
|
38
|
+
return new MongoBoundNamespace(input);
|
|
588
39
|
}
|
|
589
40
|
constructor(input) {
|
|
590
41
|
super();
|
|
591
42
|
this.id = input.id;
|
|
592
|
-
|
|
43
|
+
const rawEntries = {
|
|
44
|
+
collection: {},
|
|
45
|
+
...input.entries
|
|
46
|
+
};
|
|
47
|
+
this.entries = Object.freeze(blindCast(hydrateNamespaceEntities(rawEntries, composeMongoEntityKinds(), "carry")));
|
|
593
48
|
Object.defineProperty(this, "kind", {
|
|
594
49
|
value: MONGO_NAMESPACE_KIND,
|
|
595
50
|
writable: false,
|
|
@@ -598,13 +53,13 @@ var MongoBoundNamespace = class MongoBoundNamespace extends NamespaceBase {
|
|
|
598
53
|
});
|
|
599
54
|
freezeNode(this);
|
|
600
55
|
}
|
|
56
|
+
get collection() {
|
|
57
|
+
return this.entries.collection ?? Object.freeze({});
|
|
58
|
+
}
|
|
601
59
|
};
|
|
602
60
|
function buildMongoNamespace(input) {
|
|
603
61
|
return MongoBoundNamespace.fromCollectionsInput(input);
|
|
604
62
|
}
|
|
605
|
-
function buildMongoNamespaceMap(namespaces) {
|
|
606
|
-
return Object.fromEntries(Object.entries(namespaces).map(([nsKey, ns]) => [nsKey, isMaterializedMongoNamespace(ns) ? blindCast(ns) : MongoBoundNamespace.fromCollectionsInput(blindCast(ns))]));
|
|
607
|
-
}
|
|
608
63
|
//#endregion
|
|
609
64
|
//#region src/ir/mongo-clustered-collection-options.ts
|
|
610
65
|
/**
|
|
@@ -737,7 +192,7 @@ function formatCrossRef(crossRef) {
|
|
|
737
192
|
return `${crossRef.namespace}.${crossRef.model}`;
|
|
738
193
|
}
|
|
739
194
|
function storageDeclaresCollection(storage, collectionName) {
|
|
740
|
-
for (const ns of Object.values(storage.namespaces)) if (Object.hasOwn(ns.entries
|
|
195
|
+
for (const ns of Object.values(storage.namespaces)) if (Object.hasOwn(ns.entries["collection"] ?? {}, collectionName)) return true;
|
|
741
196
|
return false;
|
|
742
197
|
}
|
|
743
198
|
function validateMongoStorage(contract) {
|
|
@@ -773,6 +228,6 @@ function validateMongoStorage(contract) {
|
|
|
773
228
|
if (errors.length > 0) throw new Error(`Contract storage validation failed:\n- ${errors.join("\n- ")}`);
|
|
774
229
|
}
|
|
775
230
|
//#endregion
|
|
776
|
-
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace,
|
|
231
|
+
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, defaultMongoDomainNamespaceId, defaultMongoStorageNamespaceId, validateMongoStorage };
|
|
777
232
|
|
|
778
233
|
//# sourceMappingURL=index.mjs.map
|