@prisma-next/mongo-contract 0.11.0-dev.5 → 0.11.0-dev.51
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/canonicalization-hooks.d.mts +9 -0
- package/dist/canonicalization-hooks.d.mts.map +1 -0
- package/dist/canonicalization-hooks.mjs +17 -0
- package/dist/canonicalization-hooks.mjs.map +1 -0
- package/dist/index.d.mts +15 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +95 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
- package/src/canonicalization-hooks.ts +19 -0
- package/src/contract-schema.ts +6 -5
- package/src/contract-types.ts +7 -0
- package/src/exports/canonicalization-hooks.ts +1 -0
- package/src/exports/index.ts +2 -0
- package/src/ir/build-mongo-namespace.ts +80 -0
- package/src/ir/mongo-storage.ts +7 -67
- package/src/validate-storage.ts +10 -7
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PreserveEmptyPredicate } from "@prisma-next/contract/hashing";
|
|
2
|
+
|
|
3
|
+
//#region src/canonicalization-hooks.d.ts
|
|
4
|
+
declare const mongoContractCanonicalizationHooks: {
|
|
5
|
+
readonly shouldPreserveEmpty: PreserveEmptyPredicate;
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { mongoContractCanonicalizationHooks };
|
|
9
|
+
//# sourceMappingURL=canonicalization-hooks.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonicalization-hooks.d.mts","names":[],"sources":["../src/canonicalization-hooks.ts"],"mappings":";;;cAca,kCAAA;EAAA,SACF,mBAAA,EAAqB,sBAAsB;AAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createPreserveEmptyPredicate } from "@prisma-next/contract/hashing-utils";
|
|
2
|
+
const mongoContractCanonicalizationHooks = { shouldPreserveEmpty: createPreserveEmptyPredicate([[
|
|
3
|
+
"storage",
|
|
4
|
+
"namespaces",
|
|
5
|
+
"*",
|
|
6
|
+
"collections"
|
|
7
|
+
], [
|
|
8
|
+
"storage",
|
|
9
|
+
"namespaces",
|
|
10
|
+
"*",
|
|
11
|
+
"collections",
|
|
12
|
+
"*"
|
|
13
|
+
]]) };
|
|
14
|
+
//#endregion
|
|
15
|
+
export { mongoContractCanonicalizationHooks };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=canonicalization-hooks.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonicalization-hooks.mjs","names":[],"sources":["../src/canonicalization-hooks.ts"],"sourcesContent":["import type { PreserveEmptyPredicate } from '@prisma-next/contract/hashing';\nimport {\n createPreserveEmptyPredicate,\n type PathPattern,\n} from '@prisma-next/contract/hashing-utils';\n\nconst preserveEmptyPatterns = [\n ['storage', 'namespaces', '*', 'collections'],\n ['storage', 'namespaces', '*', 'collections', '*'],\n] as const satisfies readonly PathPattern[];\n\nconst shouldPreserveEmpty: PreserveEmptyPredicate =\n createPreserveEmptyPredicate(preserveEmptyPatterns);\n\nexport const mongoContractCanonicalizationHooks: {\n readonly shouldPreserveEmpty: PreserveEmptyPredicate;\n} = {\n shouldPreserveEmpty,\n};\n"],"mappings":";AAcA,MAAa,qCAET,EACF,qBALA,6BAA6B,CAL7B;CAAC;CAAW;CAAc;CAAK;AAAa,GAC5C;CAAC;CAAW;CAAc;CAAK;CAAe;AAAG,CAIA,CAKjD,EACF"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { Contract, ContractField, ContractModel, ContractValueObject, StorageBase, StorageHashBase } from "@prisma-next/contract/types";
|
|
1
2
|
import * as _$arktype from "arktype";
|
|
2
3
|
import { Type } from "arktype";
|
|
3
4
|
import { IRNodeBase, Namespace, NamespaceBase, Storage } from "@prisma-next/framework-components/ir";
|
|
4
|
-
import { Contract, ContractField, ContractModel, ContractValueObject, StorageBase, StorageHashBase } from "@prisma-next/contract/types";
|
|
5
|
-
|
|
6
5
|
//#region src/contract-schema.d.ts
|
|
7
6
|
/**
|
|
8
7
|
* Builds the per-namespace envelope schema for Mongo storage. Pack
|
|
@@ -11,8 +10,8 @@ import { Contract, ContractField, ContractModel, ContractValueObject, StorageBas
|
|
|
11
10
|
* has no pack contributions; the composition surface exists for symmetry
|
|
12
11
|
* with SQL and as the substrate for future entity kinds.
|
|
13
12
|
*
|
|
14
|
-
* `'kind?': 'string'` because `kind` is non-enumerable on
|
|
15
|
-
*
|
|
13
|
+
* `'kind?': 'string'` because `kind` is non-enumerable on built
|
|
14
|
+
* Mongo namespace IR classes and therefore absent from the wire shape; the
|
|
16
15
|
* type-side narrowing is enforced by the IR class, not by this validator.
|
|
17
16
|
*/
|
|
18
17
|
declare function createMongoNamespaceEnvelopeSchema(fragments?: ReadonlyMap<string, Type<unknown>>): Type<unknown>;
|
|
@@ -482,6 +481,9 @@ type MongoStorageShape<THash extends string = string> = StorageBase<THash> & {
|
|
|
482
481
|
}>;
|
|
483
482
|
};
|
|
484
483
|
type MongoContract<S extends MongoStorageShape = MongoStorageShape, M extends Record<string, MongoModelDefinition> = Record<string, MongoModelDefinition>> = Contract<S, M>;
|
|
484
|
+
type RootModelName<TContract extends MongoContract, RootName extends keyof TContract['roots'] & string> = TContract['roots'][RootName] extends {
|
|
485
|
+
readonly model: infer M extends string;
|
|
486
|
+
} ? M & keyof TContract['models'] : never;
|
|
485
487
|
type MongoTypeMaps<TCodecTypes extends Record<string, {
|
|
486
488
|
output: unknown;
|
|
487
489
|
}> = Record<string, {
|
|
@@ -536,13 +538,13 @@ interface MongoNamespaceCollectionsInput {
|
|
|
536
538
|
readonly id: string;
|
|
537
539
|
readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;
|
|
538
540
|
}
|
|
539
|
-
interface MongoStorageInput<THash extends string = string> {
|
|
540
|
-
readonly storageHash: StorageHashBase<THash>;
|
|
541
|
-
readonly namespaces?: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>;
|
|
542
|
-
}
|
|
543
541
|
type MongoNamespace = Namespace & {
|
|
544
542
|
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
545
543
|
};
|
|
544
|
+
interface MongoStorageInput<THash extends string = string> {
|
|
545
|
+
readonly storageHash: StorageHashBase<THash>;
|
|
546
|
+
readonly namespaces: Readonly<Record<string, MongoNamespace>>;
|
|
547
|
+
}
|
|
546
548
|
declare class MongoStorage<THash extends string = string> extends IRNodeBase implements Storage {
|
|
547
549
|
readonly kind: 'mongo-storage';
|
|
548
550
|
readonly storageHash: StorageHashBase<THash>;
|
|
@@ -550,6 +552,10 @@ declare class MongoStorage<THash extends string = string> extends IRNodeBase imp
|
|
|
550
552
|
constructor(input: MongoStorageInput<THash>);
|
|
551
553
|
}
|
|
552
554
|
//#endregion
|
|
555
|
+
//#region src/ir/build-mongo-namespace.d.ts
|
|
556
|
+
declare function buildMongoNamespace(input: MongoNamespaceCollectionsInput): MongoNamespace;
|
|
557
|
+
declare function buildMongoNamespaceMap(namespaces: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>): Readonly<Record<string, MongoNamespace>>;
|
|
558
|
+
//#endregion
|
|
553
559
|
//#region src/ir/mongo-unbound-namespace.d.ts
|
|
554
560
|
declare class MongoUnboundNamespace extends NamespaceBase {
|
|
555
561
|
static readonly instance: MongoUnboundNamespace;
|
|
@@ -576,5 +582,5 @@ declare function applyPolymorphicScopeToMongoIndex(index: MongoIndex, scope: Pol
|
|
|
576
582
|
//#region src/validate-storage.d.ts
|
|
577
583
|
declare function validateMongoStorage(contract: MongoContract): void;
|
|
578
584
|
//#endregion
|
|
579
|
-
export { type ApplyScopeResult, type ExtractMongoCodecTypes, type ExtractMongoFieldInputTypes, type ExtractMongoFieldOutputTypes, type ExtractMongoTypeMaps, type InferModelRow, MongoChangeStreamPreAndPostImagesOptions, type MongoChangeStreamPreAndPostImagesOptionsInput, type MongoClusteredCollectionKey, MongoClusteredCollectionOptions, type MongoClusteredCollectionOptionsInput, type MongoCollationAlternate, type MongoCollationCaseFirst, type MongoCollationMaxVariable, MongoCollationOptions, type MongoCollationOptionsInput, type MongoCollationStrength, MongoCollection, type MongoCollectionInput, MongoCollectionOptions, type MongoCollectionOptionsAuthoringInput, type MongoCollectionOptionsInput, type MongoContract, MongoContractSchema, type MongoContractWithTypeMaps, MongoIndex, type MongoIndexAuthoringInput, type MongoIndexFieldValue, type MongoIndexFields, type MongoIndexInput, type MongoIndexKey, type MongoIndexKeyDirection, MongoIndexOptionDefaults, type MongoIndexOptionDefaultsInput, MongoIndexOptions, type MongoIndexOptionsInput, type MongoJsonObject, type MongoJsonPrimitive, type MongoJsonValue, type MongoModelDefinition, type MongoModelStorage, MongoStorage, type MongoStorageCappedShape, type MongoStorageClusteredIndexShape, type MongoStorageInput, type MongoStorageShape, MongoTimeSeriesCollectionOptions, type MongoTimeSeriesCollectionOptionsInput, type MongoTimeSeriesGranularity, type MongoTypeMaps, type MongoTypeMapsPhantomKey, MongoUnboundNamespace, MongoValidator, type MongoValidatorInput, type MongoValidatorValidationAction, type MongoValidatorValidationLevel, type MongoWildcardProjection, type PolymorphicIndexScope, applyPolymorphicScopeToMongoIndex, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, validateMongoStorage };
|
|
585
|
+
export { type ApplyScopeResult, type ExtractMongoCodecTypes, type ExtractMongoFieldInputTypes, type ExtractMongoFieldOutputTypes, type ExtractMongoTypeMaps, type InferModelRow, MongoChangeStreamPreAndPostImagesOptions, type MongoChangeStreamPreAndPostImagesOptionsInput, type MongoClusteredCollectionKey, MongoClusteredCollectionOptions, type MongoClusteredCollectionOptionsInput, type MongoCollationAlternate, type MongoCollationCaseFirst, type MongoCollationMaxVariable, MongoCollationOptions, type MongoCollationOptionsInput, type MongoCollationStrength, MongoCollection, type MongoCollectionInput, MongoCollectionOptions, type MongoCollectionOptionsAuthoringInput, type MongoCollectionOptionsInput, type MongoContract, MongoContractSchema, type MongoContractWithTypeMaps, MongoIndex, type MongoIndexAuthoringInput, type MongoIndexFieldValue, type MongoIndexFields, type MongoIndexInput, type MongoIndexKey, type MongoIndexKeyDirection, MongoIndexOptionDefaults, type MongoIndexOptionDefaultsInput, MongoIndexOptions, type MongoIndexOptionsInput, type MongoJsonObject, type MongoJsonPrimitive, type MongoJsonValue, type MongoModelDefinition, type MongoModelStorage, MongoStorage, type MongoStorageCappedShape, type MongoStorageClusteredIndexShape, type MongoStorageInput, type MongoStorageShape, MongoTimeSeriesCollectionOptions, type MongoTimeSeriesCollectionOptionsInput, type MongoTimeSeriesGranularity, type MongoTypeMaps, type MongoTypeMapsPhantomKey, MongoUnboundNamespace, MongoValidator, type MongoValidatorInput, type MongoValidatorValidationAction, type MongoValidatorValidationLevel, type MongoWildcardProjection, type PolymorphicIndexScope, type RootModelName, applyPolymorphicScopeToMongoIndex, buildMongoNamespace, buildMongoNamespaceMap, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, validateMongoStorage };
|
|
580
586
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/contract-schema.ts","../src/ir/mongo-change-stream-pre-and-post-images-options.ts","../src/ir/mongo-clustered-collection-options.ts","../src/ir/mongo-collation-options.ts","../src/ir/mongo-index-option-defaults.ts","../src/ir/mongo-time-series-collection-options.ts","../src/ir/mongo-collection-options.ts","../src/ir/mongo-index.ts","../src/ir/mongo-validator.ts","../src/ir/mongo-collection.ts","../src/ir/mongo-index-options.ts","../src/contract-types.ts","../src/ir/mongo-storage.ts","../src/ir/mongo-unbound-namespace.ts","../src/polymorphic-index-scope.ts","../src/validate-storage.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/contract-schema.ts","../src/ir/mongo-change-stream-pre-and-post-images-options.ts","../src/ir/mongo-clustered-collection-options.ts","../src/ir/mongo-collation-options.ts","../src/ir/mongo-index-option-defaults.ts","../src/ir/mongo-time-series-collection-options.ts","../src/ir/mongo-collection-options.ts","../src/ir/mongo-index.ts","../src/ir/mongo-validator.ts","../src/ir/mongo-collection.ts","../src/ir/mongo-index-options.ts","../src/contract-types.ts","../src/ir/mongo-storage.ts","../src/ir/build-mongo-namespace.ts","../src/ir/mongo-unbound-namespace.ts","../src/polymorphic-index-scope.ts","../src/validate-storage.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { CrossReferenceSchema } from "@prisma-next/contract/types";
|
|
1
2
|
import { type } from "arktype";
|
|
2
3
|
import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
|
|
4
|
+
import { blindCast, castAs } from "@prisma-next/utils/casts";
|
|
3
5
|
//#region src/contract-schema.ts
|
|
4
6
|
const ScalarFieldTypeSchema = type({
|
|
5
7
|
"+": "reject",
|
|
@@ -29,7 +31,7 @@ const FieldSchema = type({
|
|
|
29
31
|
}));
|
|
30
32
|
const RelationSchema = type({
|
|
31
33
|
"+": "reject",
|
|
32
|
-
to:
|
|
34
|
+
to: CrossReferenceSchema,
|
|
33
35
|
cardinality: "'1:1' | '1:N' | 'N:1'",
|
|
34
36
|
"on?": type({
|
|
35
37
|
"+": "reject",
|
|
@@ -144,7 +146,7 @@ const ModelDefinitionSchema = type({
|
|
|
144
146
|
"relations?": type({ "[string]": RelationSchema }),
|
|
145
147
|
"discriminator?": DiscriminatorSchema,
|
|
146
148
|
"variants?": type({ "[string]": VariantEntrySchema }),
|
|
147
|
-
"base?":
|
|
149
|
+
"base?": CrossReferenceSchema,
|
|
148
150
|
"owner?": "string"
|
|
149
151
|
});
|
|
150
152
|
type({
|
|
@@ -259,8 +261,8 @@ function collectionEntrySchema(fragments) {
|
|
|
259
261
|
* has no pack contributions; the composition surface exists for symmetry
|
|
260
262
|
* with SQL and as the substrate for future entity kinds.
|
|
261
263
|
*
|
|
262
|
-
* `'kind?': 'string'` because `kind` is non-enumerable on
|
|
263
|
-
*
|
|
264
|
+
* `'kind?': 'string'` because `kind` is non-enumerable on built
|
|
265
|
+
* Mongo namespace IR classes and therefore absent from the wire shape; the
|
|
264
266
|
* type-side narrowing is enforced by the IR class, not by this validator.
|
|
265
267
|
*/
|
|
266
268
|
function createMongoNamespaceEnvelopeSchema(fragments) {
|
|
@@ -277,6 +279,7 @@ function createMongoNamespaceEnvelopeSchema(fragments) {
|
|
|
277
279
|
* the rest of the envelope is family-shared.
|
|
278
280
|
*/
|
|
279
281
|
function createMongoContractSchema(fragments) {
|
|
282
|
+
const namespaceEnvelope = createMongoNamespaceEnvelopeSchema(fragments);
|
|
280
283
|
return type({
|
|
281
284
|
"+": "reject",
|
|
282
285
|
targetFamily: "'mongo'",
|
|
@@ -284,7 +287,7 @@ function createMongoContractSchema(fragments) {
|
|
|
284
287
|
"target?": "string",
|
|
285
288
|
"storageHash?": "string",
|
|
286
289
|
"profileHash?": "string",
|
|
287
|
-
roots: "
|
|
290
|
+
roots: type({ "[string]": CrossReferenceSchema }),
|
|
288
291
|
"capabilities?": "Record<string, unknown>",
|
|
289
292
|
"extensionPacks?": "Record<string, unknown>",
|
|
290
293
|
"meta?": "Record<string, unknown>",
|
|
@@ -293,7 +296,7 @@ function createMongoContractSchema(fragments) {
|
|
|
293
296
|
"domain?": "unknown",
|
|
294
297
|
storage: type({
|
|
295
298
|
"+": "reject",
|
|
296
|
-
namespaces: type({ "[string]":
|
|
299
|
+
namespaces: type({ "[string]": namespaceEnvelope }),
|
|
297
300
|
"storageHash?": "string"
|
|
298
301
|
}),
|
|
299
302
|
models: type({ "[string]": ModelDefinitionSchema }),
|
|
@@ -323,28 +326,6 @@ var MongoChangeStreamPreAndPostImagesOptions = class extends IRNodeBase {
|
|
|
323
326
|
}
|
|
324
327
|
};
|
|
325
328
|
//#endregion
|
|
326
|
-
//#region src/ir/mongo-clustered-collection-options.ts
|
|
327
|
-
/**
|
|
328
|
-
* Clustered-collection options (the `clusteredIndex` collection-creation
|
|
329
|
-
* field). Lifted from a `type =` data shape to an AST class extending
|
|
330
|
-
* `IRNodeBase` per FR18.
|
|
331
|
-
*
|
|
332
|
-
* MongoDB requires `key` and `unique` for any clustered collection; the
|
|
333
|
-
* constructor enforces presence by type signature.
|
|
334
|
-
*/
|
|
335
|
-
var MongoClusteredCollectionOptions = class extends IRNodeBase {
|
|
336
|
-
kind = "mongo-clustered-collection-options";
|
|
337
|
-
key;
|
|
338
|
-
unique;
|
|
339
|
-
constructor(options) {
|
|
340
|
-
super();
|
|
341
|
-
if (options.name !== void 0) this.name = options.name;
|
|
342
|
-
this.key = options.key;
|
|
343
|
-
this.unique = options.unique;
|
|
344
|
-
freezeNode(this);
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
//#endregion
|
|
348
329
|
//#region src/ir/mongo-collation-options.ts
|
|
349
330
|
/**
|
|
350
331
|
* Mongo Contract IR leaf for collection / index collation options.
|
|
@@ -556,6 +537,81 @@ var MongoCollection = class extends IRNodeBase {
|
|
|
556
537
|
}
|
|
557
538
|
};
|
|
558
539
|
//#endregion
|
|
540
|
+
//#region src/ir/mongo-unbound-namespace.ts
|
|
541
|
+
var MongoUnboundNamespace = class MongoUnboundNamespace extends NamespaceBase {
|
|
542
|
+
static instance = new MongoUnboundNamespace();
|
|
543
|
+
id = UNBOUND_NAMESPACE_ID;
|
|
544
|
+
collections = Object.freeze({});
|
|
545
|
+
constructor() {
|
|
546
|
+
super();
|
|
547
|
+
Object.defineProperty(this, "kind", {
|
|
548
|
+
value: "mongo-namespace",
|
|
549
|
+
writable: false,
|
|
550
|
+
enumerable: false,
|
|
551
|
+
configurable: true
|
|
552
|
+
});
|
|
553
|
+
freezeNode(this);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/ir/build-mongo-namespace.ts
|
|
558
|
+
const MONGO_NAMESPACE_KIND = "mongo-namespace";
|
|
559
|
+
function isMaterializedMongoNamespace(ns) {
|
|
560
|
+
if (typeof ns !== "object" || ns === null) return false;
|
|
561
|
+
const proto = Object.getPrototypeOf(ns);
|
|
562
|
+
if (proto === Object.prototype || proto === null) return false;
|
|
563
|
+
return ns.kind === MONGO_NAMESPACE_KIND;
|
|
564
|
+
}
|
|
565
|
+
var MongoBoundNamespace = class MongoBoundNamespace extends NamespaceBase {
|
|
566
|
+
id;
|
|
567
|
+
collections;
|
|
568
|
+
static fromCollectionsInput(input) {
|
|
569
|
+
const collectionCount = Object.keys(input.collections ?? {}).length;
|
|
570
|
+
if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0) return castAs(MongoUnboundNamespace.instance);
|
|
571
|
+
return castAs(new MongoBoundNamespace(input));
|
|
572
|
+
}
|
|
573
|
+
constructor(input) {
|
|
574
|
+
super();
|
|
575
|
+
this.id = input.id;
|
|
576
|
+
this.collections = Object.freeze(Object.fromEntries(Object.entries(input.collections ?? {}).map(([name, c]) => [name, c instanceof MongoCollection ? c : new MongoCollection(c)])));
|
|
577
|
+
Object.defineProperty(this, "kind", {
|
|
578
|
+
value: MONGO_NAMESPACE_KIND,
|
|
579
|
+
writable: false,
|
|
580
|
+
enumerable: false,
|
|
581
|
+
configurable: true
|
|
582
|
+
});
|
|
583
|
+
freezeNode(this);
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
function buildMongoNamespace(input) {
|
|
587
|
+
return MongoBoundNamespace.fromCollectionsInput(input);
|
|
588
|
+
}
|
|
589
|
+
function buildMongoNamespaceMap(namespaces) {
|
|
590
|
+
return Object.fromEntries(Object.entries(namespaces).map(([nsKey, ns]) => [nsKey, isMaterializedMongoNamespace(ns) ? blindCast(ns) : MongoBoundNamespace.fromCollectionsInput(ns)]));
|
|
591
|
+
}
|
|
592
|
+
//#endregion
|
|
593
|
+
//#region src/ir/mongo-clustered-collection-options.ts
|
|
594
|
+
/**
|
|
595
|
+
* Clustered-collection options (the `clusteredIndex` collection-creation
|
|
596
|
+
* field). Lifted from a `type =` data shape to an AST class extending
|
|
597
|
+
* `IRNodeBase` per FR18.
|
|
598
|
+
*
|
|
599
|
+
* MongoDB requires `key` and `unique` for any clustered collection; the
|
|
600
|
+
* constructor enforces presence by type signature.
|
|
601
|
+
*/
|
|
602
|
+
var MongoClusteredCollectionOptions = class extends IRNodeBase {
|
|
603
|
+
kind = "mongo-clustered-collection-options";
|
|
604
|
+
key;
|
|
605
|
+
unique;
|
|
606
|
+
constructor(options) {
|
|
607
|
+
super();
|
|
608
|
+
if (options.name !== void 0) this.name = options.name;
|
|
609
|
+
this.key = options.key;
|
|
610
|
+
this.unique = options.unique;
|
|
611
|
+
freezeNode(this);
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
//#endregion
|
|
559
615
|
//#region src/ir/mongo-index-options.ts
|
|
560
616
|
/**
|
|
561
617
|
* Mongo Contract IR node for the per-index option vocabulary (the second
|
|
@@ -592,48 +648,7 @@ var MongoIndexOptions = class extends IRNodeBase {
|
|
|
592
648
|
}
|
|
593
649
|
};
|
|
594
650
|
//#endregion
|
|
595
|
-
//#region src/ir/mongo-unbound-namespace.ts
|
|
596
|
-
var MongoUnboundNamespace = class MongoUnboundNamespace extends NamespaceBase {
|
|
597
|
-
static instance = new MongoUnboundNamespace();
|
|
598
|
-
id = UNBOUND_NAMESPACE_ID;
|
|
599
|
-
collections = Object.freeze({});
|
|
600
|
-
constructor() {
|
|
601
|
-
super();
|
|
602
|
-
Object.defineProperty(this, "kind", {
|
|
603
|
-
value: "mongo-namespace",
|
|
604
|
-
writable: false,
|
|
605
|
-
enumerable: false,
|
|
606
|
-
configurable: true
|
|
607
|
-
});
|
|
608
|
-
freezeNode(this);
|
|
609
|
-
}
|
|
610
|
-
};
|
|
611
|
-
//#endregion
|
|
612
651
|
//#region src/ir/mongo-storage.ts
|
|
613
|
-
const DEFAULT_NAMESPACES = Object.freeze({ [UNBOUND_NAMESPACE_ID]: MongoUnboundNamespace.instance });
|
|
614
|
-
var MongoNamespacePayload = class extends NamespaceBase {
|
|
615
|
-
id;
|
|
616
|
-
collections;
|
|
617
|
-
constructor(input) {
|
|
618
|
-
super();
|
|
619
|
-
this.id = input.id;
|
|
620
|
-
this.collections = Object.freeze(Object.fromEntries(Object.entries(input.collections ?? {}).map(([name, c]) => [name, c instanceof MongoCollection ? c : new MongoCollection(c)])));
|
|
621
|
-
Object.defineProperty(this, "kind", {
|
|
622
|
-
value: "mongo-namespace",
|
|
623
|
-
writable: false,
|
|
624
|
-
enumerable: false,
|
|
625
|
-
configurable: true
|
|
626
|
-
});
|
|
627
|
-
freezeNode(this);
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
function normaliseNamespaceEntry(nsKey, ns) {
|
|
631
|
-
if (ns instanceof NamespaceBase) return ns;
|
|
632
|
-
const input = ns;
|
|
633
|
-
const collectionCount = Object.keys(input.collections ?? {}).length;
|
|
634
|
-
if (nsKey === UNBOUND_NAMESPACE_ID && collectionCount === 0) return MongoUnboundNamespace.instance;
|
|
635
|
-
return new MongoNamespacePayload(input);
|
|
636
|
-
}
|
|
637
652
|
var MongoStorage = class extends IRNodeBase {
|
|
638
653
|
storageHash;
|
|
639
654
|
namespaces;
|
|
@@ -646,7 +661,7 @@ var MongoStorage = class extends IRNodeBase {
|
|
|
646
661
|
configurable: true
|
|
647
662
|
});
|
|
648
663
|
this.storageHash = input.storageHash;
|
|
649
|
-
this.namespaces = Object.freeze(
|
|
664
|
+
this.namespaces = Object.freeze(input.namespaces);
|
|
650
665
|
freezeNode(this);
|
|
651
666
|
}
|
|
652
667
|
};
|
|
@@ -702,6 +717,9 @@ function applyPolymorphicScopeToMongoIndex(index, scope) {
|
|
|
702
717
|
}
|
|
703
718
|
//#endregion
|
|
704
719
|
//#region src/validate-storage.ts
|
|
720
|
+
function formatCrossRef(crossRef) {
|
|
721
|
+
return `${crossRef.namespace}.${crossRef.model}`;
|
|
722
|
+
}
|
|
705
723
|
function storageDeclaresCollection(storage, collectionName) {
|
|
706
724
|
for (const ns of Object.values(storage.namespaces)) if (Object.hasOwn(ns.collections, collectionName)) return true;
|
|
707
725
|
return false;
|
|
@@ -711,7 +729,7 @@ function validateMongoStorage(contract) {
|
|
|
711
729
|
for (const [modelName, model] of Object.entries(contract.models)) {
|
|
712
730
|
if (model.storage.collection && !storageDeclaresCollection(contract.storage, model.storage.collection)) errors.push(`Model "${modelName}" references collection "${model.storage.collection}" which is not declared under any namespace's collections map`);
|
|
713
731
|
if (model.base) {
|
|
714
|
-
const baseModel = contract.models[model.base];
|
|
732
|
+
const baseModel = contract.models[model.base.model];
|
|
715
733
|
if (baseModel) {
|
|
716
734
|
const variantCollection = model.storage.collection;
|
|
717
735
|
const baseCollection = baseModel.storage.collection;
|
|
@@ -719,14 +737,15 @@ function validateMongoStorage(contract) {
|
|
|
719
737
|
}
|
|
720
738
|
}
|
|
721
739
|
for (const [relName, relation] of Object.entries(model.relations ?? {})) {
|
|
722
|
-
const targetModel = contract.models[relation.to];
|
|
740
|
+
const targetModel = contract.models[relation.to.model];
|
|
741
|
+
const targetLabel = formatCrossRef(relation.to);
|
|
723
742
|
if (targetModel?.owner) {
|
|
724
|
-
if (targetModel.owner !== modelName) errors.push(`Embed relation "${relName}" targets "${
|
|
725
|
-
if (targetModel.storage.collection) errors.push(`Embed relation "${relName}" targets "${
|
|
743
|
+
if (targetModel.owner !== modelName) errors.push(`Embed relation "${relName}" targets "${targetLabel}" which is owned by "${targetModel.owner}", not "${modelName}"`);
|
|
744
|
+
if (targetModel.storage.collection) errors.push(`Embed relation "${relName}" targets "${targetLabel}" which must not have a collection`);
|
|
726
745
|
} else if ("on" in relation && relation.on) {
|
|
727
746
|
for (const localField of relation.on.localFields) if (!(localField in model.fields)) errors.push(`Reference relation "${relName}": localField "${localField}" is not a field on model "${modelName}"`);
|
|
728
747
|
if (targetModel) {
|
|
729
|
-
for (const targetField of relation.on.targetFields) if (!(targetField in targetModel.fields)) errors.push(`Reference relation "${relName}": targetField "${targetField}" is not a field on model "${
|
|
748
|
+
for (const targetField of relation.on.targetFields) if (!(targetField in targetModel.fields)) errors.push(`Reference relation "${relName}": targetField "${targetField}" is not a field on model "${targetLabel}"`);
|
|
730
749
|
}
|
|
731
750
|
}
|
|
732
751
|
}
|
|
@@ -734,6 +753,6 @@ function validateMongoStorage(contract) {
|
|
|
734
753
|
if (errors.length > 0) throw new Error(`Contract storage validation failed:\n- ${errors.join("\n- ")}`);
|
|
735
754
|
}
|
|
736
755
|
//#endregion
|
|
737
|
-
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, validateMongoStorage };
|
|
756
|
+
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace, buildMongoNamespaceMap, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, validateMongoStorage };
|
|
738
757
|
|
|
739
758
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/contract-schema.ts","../src/ir/mongo-change-stream-pre-and-post-images-options.ts","../src/ir/mongo-clustered-collection-options.ts","../src/ir/mongo-collation-options.ts","../src/ir/mongo-index-option-defaults.ts","../src/ir/mongo-time-series-collection-options.ts","../src/ir/mongo-collection-options.ts","../src/ir/mongo-index.ts","../src/ir/mongo-validator.ts","../src/ir/mongo-collection.ts","../src/ir/mongo-index-options.ts","../src/ir/mongo-unbound-namespace.ts","../src/ir/mongo-storage.ts","../src/polymorphic-index-scope.ts","../src/validate-storage.ts"],"sourcesContent":["import { type Type, type } from 'arktype';\nimport type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';\n\nconst ScalarFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'scalar'\",\n codecId: 'string',\n 'typeParams?': 'Record<string, unknown>',\n});\n\nconst ValueObjectFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'valueObject'\",\n name: 'string',\n});\n\nconst UnionFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'union'\",\n members: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).array(),\n});\n\nconst FieldTypeSchema = ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).or(\n UnionFieldTypeSchema,\n);\n\nconst RawFieldSchema = type({\n '+': 'reject',\n type: FieldTypeSchema,\n 'nullable?': 'boolean',\n 'many?': 'boolean',\n 'dict?': 'boolean',\n});\n\nconst FieldSchema = RawFieldSchema.pipe((field) => ({\n ...field,\n nullable: field.nullable ?? false,\n}));\n\nconst RelationOnSchema = type({\n '+': 'reject',\n localFields: 'string[]',\n targetFields: 'string[]',\n});\n\nconst RelationSchema = type({\n '+': 'reject',\n to: 'string',\n cardinality: \"'1:1' | '1:N' | 'N:1'\",\n 'on?': RelationOnSchema,\n});\n\nconst StorageRelationEntrySchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst MongoJsonPrimitiveSchema = type\n .declare<MongoJsonPrimitive>()\n .type('string | number | boolean | null');\n\nfunction isMongoJsonRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction withUnseenReference(value: object, seen: WeakSet<object>, visit: () => boolean): boolean {\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n const result = visit();\n seen.delete(value);\n return result;\n}\n\nfunction isMongoJsonObject(value: unknown, seen: WeakSet<object>): value is MongoJsonObject {\n return (\n isMongoJsonRecord(value) &&\n withUnseenReference(value, seen, () =>\n Object.values(value).every((entry) => isMongoJsonValue(entry, seen)),\n )\n );\n}\n\nfunction isMongoJsonValue(value: unknown, seen = new WeakSet<object>()): value is MongoJsonValue {\n if (MongoJsonPrimitiveSchema.allows(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return withUnseenReference(value, seen, () =>\n value.every((entry) => isMongoJsonValue(entry, seen)),\n );\n }\n return isMongoJsonObject(value, seen);\n}\n\nconst MongoJsonValueSchema = type('unknown').narrow((value, ctx) =>\n isMongoJsonValue(value) ? true : ctx.mustBe('a JSON-serializable MongoJsonValue'),\n);\n\nconst MongoJsonObjectSchema = type({ '[string]': 'unknown' }).narrow((value, ctx) =>\n isMongoJsonRecord(value) &&\n Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry))\n ? true\n : ctx.mustBe('a JSON object with MongoJsonValue entries'),\n);\n\nconst NumberRecordSchema = type({ '[string]': 'number' });\n\nconst IndexFieldsSchema = type({\n '+': 'reject',\n '[string]': '1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"',\n}).narrow((fields, ctx) =>\n Object.keys(fields).length > 0 ? true : ctx.mustBe('an index field map with at least one entry'),\n);\n\nconst CollationSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collation-options'\",\n locale: 'string',\n 'caseLevel?': 'boolean',\n 'caseFirst?': '\"off\" | \"upper\" | \"lower\"',\n 'strength?': '1 | 2 | 3 | 4 | 5',\n 'numericOrdering?': 'boolean',\n 'alternate?': '\"non-ignorable\" | \"shifted\"',\n 'maxVariable?': '\"punct\" | \"space\"',\n 'backwards?': 'boolean',\n 'normalization?': 'boolean',\n});\n\nconst IndexOptionDefaultsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index-option-defaults'\",\n 'storageEngine?': MongoJsonObjectSchema,\n});\n\nconst TimeSeriesCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-time-series-collection-options'\",\n timeField: 'string',\n 'metaField?': 'string',\n 'granularity?': '\"seconds\" | \"minutes\" | \"hours\"',\n 'bucketMaxSpanSeconds?': 'number',\n 'bucketRoundingSeconds?': 'number',\n});\n\nconst ClusteredCollectionKeySchema = type({\n '+': 'reject',\n '[string]': '1',\n}).narrow((key, ctx) =>\n Object.keys(key).length > 0\n ? true\n : ctx.mustBe('a clustered index key map with at least one entry'),\n);\n\nconst ClusteredCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-clustered-collection-options'\",\n 'name?': 'string',\n key: ClusteredCollectionKeySchema,\n unique: 'boolean',\n});\n\nconst ChangeStreamPreAndPostImagesSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-change-stream-pre-and-post-images-options'\",\n enabled: 'boolean',\n});\n\nconst CollectionOptionsSchema = type({\n '+': 'reject',\n 'capped?': 'boolean',\n 'size?': 'number',\n 'max?': 'number',\n 'storageEngine?': MongoJsonObjectSchema,\n 'indexOptionDefaults?': IndexOptionDefaultsSchema,\n 'collation?': CollationSchema,\n 'timeseries?': TimeSeriesCollectionOptionsSchema,\n 'clusteredIndex?': ClusteredCollectionOptionsSchema,\n 'expireAfterSeconds?': 'number',\n 'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,\n});\n\nconst ModelStorageSchema = type({\n '+': 'reject',\n 'collection?': 'string',\n 'relations?': type({ '[string]': StorageRelationEntrySchema }),\n});\n\nconst DiscriminatorSchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst VariantEntrySchema = type({\n '+': 'reject',\n value: 'string',\n});\n\nconst ModelDefinitionSchema = type({\n '+': 'reject',\n fields: type({ '[string]': FieldSchema }),\n storage: ModelStorageSchema,\n 'relations?': type({ '[string]': RelationSchema }),\n 'discriminator?': DiscriminatorSchema,\n 'variants?': type({ '[string]': VariantEntrySchema }),\n 'base?': 'string',\n 'owner?': 'string',\n});\n\nconst WildcardProjectionSchema = type({\n '+': 'reject',\n '[string]': '0 | 1',\n});\n\nconst IndexOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index-options'\",\n 'unique?': 'boolean',\n 'name?': 'string',\n 'partialFilterExpression?': MongoJsonObjectSchema,\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'weights?': NumberRecordSchema,\n 'default_language?': 'string',\n 'language_override?': 'string',\n 'textIndexVersion?': 'number',\n '2dsphereIndexVersion?': 'number',\n 'bits?': 'number',\n 'min?': 'number',\n 'max?': 'number',\n 'bucketSize?': 'number',\n 'hidden?': 'boolean',\n 'collation?': CollationSchema,\n 'wildcardProjection?': WildcardProjectionSchema,\n});\n\nconst IndexSchema = type({\n '+': 'reject',\n fields: IndexFieldsSchema,\n 'options?': IndexOptionsSchema,\n});\n\nconst MongoIndexKeySchema = type({\n '+': 'reject',\n field: 'string',\n direction: '1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"',\n});\n\nconst MongoStorageIndexSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index'\",\n keys: MongoIndexKeySchema.array().atLeastLength(1),\n 'unique?': 'boolean',\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'partialFilterExpression?': 'Record<string, unknown>',\n 'wildcardProjection?': 'Record<string, 0 | 1>',\n 'collation?': 'Record<string, unknown>',\n 'weights?': 'Record<string, number>',\n 'default_language?': 'string',\n 'language_override?': 'string',\n});\n\nconst MongoStorageValidatorSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-validator'\",\n jsonSchema: 'Record<string, unknown>',\n validationLevel: \"'strict' | 'moderate'\",\n validationAction: \"'error' | 'warn'\",\n});\n\nconst CappedOptionsSchema = type({\n '+': 'reject',\n size: 'number',\n 'max?': 'number',\n});\n\nconst TimeseriesOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-time-series-collection-options'\",\n timeField: 'string',\n 'metaField?': 'string',\n 'granularity?': \"'seconds' | 'minutes' | 'hours'\",\n 'bucketMaxSpanSeconds?': 'number',\n 'bucketRoundingSeconds?': 'number',\n});\n\nconst ClusteredIndexSchema = type({\n '+': 'reject',\n 'name?': 'string',\n});\n\nconst MongoCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collection-options'\",\n 'capped?': CappedOptionsSchema,\n 'storageEngine?': MongoJsonObjectSchema,\n 'indexOptionDefaults?': IndexOptionDefaultsSchema,\n 'timeseries?': TimeseriesOptionsSchema,\n 'collation?': 'Record<string, unknown>',\n 'expireAfterSeconds?': 'number',\n 'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,\n 'clusteredIndex?': ClusteredIndexSchema,\n});\n\nconst StorageCollectionSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collection'\",\n 'indexes?': MongoStorageIndexSchema.array(),\n 'validator?': MongoStorageValidatorSchema,\n 'options?': MongoCollectionOptionsSchema,\n});\n\nfunction collectionEntrySchema(fragments?: ReadonlyMap<string, Type<unknown>>): Type<unknown> {\n if (fragments === undefined || fragments.size === 0) {\n return StorageCollectionSchema;\n }\n return type('unknown').narrow((entry, ctx) => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return ctx.mustBe('an object');\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const fragment = fragments.get(kind);\n if (fragment !== undefined) {\n const parsed = fragment(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n }\n }\n const parsed = StorageCollectionSchema(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n });\n}\n\n/**\n * Builds the per-namespace envelope schema for Mongo storage. Pack\n * contributions are keyed by the descriptor's `discriminator` and\n * validate each entry by matching the entry's `kind` field. Mongo today\n * has no pack contributions; the composition surface exists for symmetry\n * with SQL and as the substrate for future entity kinds.\n *\n * `'kind?': 'string'` because `kind` is non-enumerable on\n * `MongoNamespacePayload` and therefore absent from the wire shape; the\n * type-side narrowing is enforced by the IR class, not by this validator.\n */\nexport function createMongoNamespaceEnvelopeSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n return type({\n '+': 'reject',\n id: 'string',\n 'kind?': 'string',\n 'collections?': type({ '[string]': collectionEntrySchema(fragments) }),\n }) as Type<unknown>;\n}\n\n/**\n * Builds the full Mongo contract schema. The per-namespace entry\n * threading happens through {@link createMongoNamespaceEnvelopeSchema};\n * the rest of the envelope is family-shared.\n */\nexport function createMongoContractSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const namespaceEnvelope = createMongoNamespaceEnvelopeSchema(fragments);\n return type({\n '+': 'reject',\n targetFamily: \"'mongo'\",\n 'schemaVersion?': 'string',\n 'target?': 'string',\n 'storageHash?': 'string',\n 'profileHash?': 'string',\n roots: 'Record<string, string>',\n 'capabilities?': 'Record<string, unknown>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': 'Record<string, unknown>',\n 'sources?': 'Record<string, unknown>',\n '_generated?': 'Record<string, unknown>',\n 'domain?': 'unknown',\n storage: type({\n '+': 'reject',\n namespaces: type({ '[string]': namespaceEnvelope }),\n 'storageHash?': 'string',\n }),\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n }) as Type<unknown>;\n}\n\nexport const MongoContractSchema = createMongoContractSchema();\n\nexport {\n CollationSchema,\n CollectionOptionsSchema,\n IndexFieldsSchema,\n IndexOptionsSchema,\n IndexSchema,\n MongoIndexKeySchema,\n MongoStorageIndexSchema,\n NumberRecordSchema,\n WildcardProjectionSchema,\n};\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport interface MongoChangeStreamPreAndPostImagesOptionsInput {\n readonly enabled: boolean;\n}\n\n/**\n * Change-stream pre-and-post-images collection option. Lifted from a\n * `type =` data shape to an AST class extending `IRNodeBase` per\n * FR18. Single-field shape; the class exists for AST-pattern\n * consistency (every nested data shape inside `MongoCollectionOptions`\n * is an AST node so the verifier can walk uniformly).\n */\nexport class MongoChangeStreamPreAndPostImagesOptions extends IRNodeBase {\n readonly kind = 'mongo-change-stream-pre-and-post-images-options' as const;\n readonly enabled: boolean;\n\n constructor(options: MongoChangeStreamPreAndPostImagesOptionsInput) {\n super();\n this.enabled = options.enabled;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoClusteredCollectionKey = Readonly<Record<string, 1>>;\n\nexport interface MongoClusteredCollectionOptionsInput {\n readonly name?: string;\n readonly key: MongoClusteredCollectionKey;\n readonly unique: boolean;\n}\n\n/**\n * Clustered-collection options (the `clusteredIndex` collection-creation\n * field). Lifted from a `type =` data shape to an AST class extending\n * `IRNodeBase` per FR18.\n *\n * MongoDB requires `key` and `unique` for any clustered collection; the\n * constructor enforces presence by type signature.\n */\nexport class MongoClusteredCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-clustered-collection-options' as const;\n declare readonly name?: string;\n readonly key: MongoClusteredCollectionKey;\n readonly unique: boolean;\n\n constructor(options: MongoClusteredCollectionOptionsInput) {\n super();\n if (options.name !== undefined) this.name = options.name;\n this.key = options.key;\n this.unique = options.unique;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoCollationCaseFirst = 'off' | 'upper' | 'lower';\nexport type MongoCollationStrength = 1 | 2 | 3 | 4 | 5;\nexport type MongoCollationAlternate = 'non-ignorable' | 'shifted';\nexport type MongoCollationMaxVariable = 'punct' | 'space';\n\n/**\n * Authoring / hydration input shape for {@link MongoCollationOptions}. Carries\n * the canonical data without the IR-class `kind` discriminator; the class\n * fabricates `kind` so the authoring DSL and the SPI hydration walker can\n * pass plain data literals through the constructor without forcing every\n * call site to spell out `kind: 'mongo-collation-options'`.\n */\nexport interface MongoCollationOptionsInput {\n readonly locale: string;\n readonly caseLevel?: boolean;\n readonly caseFirst?: MongoCollationCaseFirst;\n readonly strength?: MongoCollationStrength;\n readonly numericOrdering?: boolean;\n readonly alternate?: MongoCollationAlternate;\n readonly maxVariable?: MongoCollationMaxVariable;\n readonly backwards?: boolean;\n readonly normalization?: boolean;\n}\n\n/**\n * Mongo Contract IR leaf for collection / index collation options.\n *\n * Lifted from a `type =` data shape to an AST class extending\n * `IRNodeBase` per FR18 (\"Mongo's Contract IR is fully unified under\n * the AST-class pattern, layered family / target\"). Single concrete class\n * (no target subclass): collation options carry no target-specific\n * variation at this layer — both Atlas and self-hosted Mongo consume the\n * same option vocabulary.\n *\n * Undefined optional fields are not assigned, so `JSON.stringify` omits\n * them from the canonical JSON output (matches the pre-lift data shape's\n * round-trip behaviour, modulo the new `kind` discriminator).\n */\nexport class MongoCollationOptions extends IRNodeBase {\n readonly kind = 'mongo-collation-options' as const;\n readonly locale: string;\n declare readonly caseLevel?: boolean;\n declare readonly caseFirst?: MongoCollationCaseFirst;\n declare readonly strength?: MongoCollationStrength;\n declare readonly numericOrdering?: boolean;\n declare readonly alternate?: MongoCollationAlternate;\n declare readonly maxVariable?: MongoCollationMaxVariable;\n declare readonly backwards?: boolean;\n declare readonly normalization?: boolean;\n\n constructor(options: MongoCollationOptionsInput) {\n super();\n this.locale = options.locale;\n if (options.caseLevel !== undefined) this.caseLevel = options.caseLevel;\n if (options.caseFirst !== undefined) this.caseFirst = options.caseFirst;\n if (options.strength !== undefined) this.strength = options.strength;\n if (options.numericOrdering !== undefined) this.numericOrdering = options.numericOrdering;\n if (options.alternate !== undefined) this.alternate = options.alternate;\n if (options.maxVariable !== undefined) this.maxVariable = options.maxVariable;\n if (options.backwards !== undefined) this.backwards = options.backwards;\n if (options.normalization !== undefined) this.normalization = options.normalization;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject } from '../contract-types';\n\nexport interface MongoIndexOptionDefaultsInput {\n readonly storageEngine?: MongoJsonObject;\n}\n\n/**\n * Collection-level default index options (the `indexOptionDefaults`\n * collection-creation field on Mongo's `createCollection`). Lifted from\n * a `type =` data shape to an AST class extending `IRNodeBase` per\n * FR18 (Mongo Contract IR fully unified under the AST-class pattern).\n *\n * Carries `storageEngine` only — the underlying MongoDB option set is\n * intentionally narrow at this layer; per-engine richer option vocabularies\n * are out of scope for this project.\n */\nexport class MongoIndexOptionDefaults extends IRNodeBase {\n readonly kind = 'mongo-index-option-defaults' as const;\n declare readonly storageEngine?: MongoJsonObject;\n\n constructor(options: MongoIndexOptionDefaultsInput = {}) {\n super();\n if (options.storageEngine !== undefined) this.storageEngine = options.storageEngine;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoTimeSeriesGranularity = 'seconds' | 'minutes' | 'hours';\n\nexport interface MongoTimeSeriesCollectionOptionsInput {\n readonly timeField: string;\n readonly metaField?: string;\n readonly granularity?: MongoTimeSeriesGranularity;\n readonly bucketMaxSpanSeconds?: number;\n readonly bucketRoundingSeconds?: number;\n}\n\n/**\n * Time-series collection options. Lifted from a `type =` data shape to\n * an AST class extending `IRNodeBase` per FR18.\n *\n * MongoDB requires `timeField` for any time-series collection; the\n * constructor enforces presence by type signature (`timeField: string`\n * is required on the input).\n */\nexport class MongoTimeSeriesCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-time-series-collection-options' as const;\n readonly timeField: string;\n declare readonly metaField?: string;\n declare readonly granularity?: MongoTimeSeriesGranularity;\n declare readonly bucketMaxSpanSeconds?: number;\n declare readonly bucketRoundingSeconds?: number;\n\n constructor(options: MongoTimeSeriesCollectionOptionsInput) {\n super();\n this.timeField = options.timeField;\n if (options.metaField !== undefined) this.metaField = options.metaField;\n if (options.granularity !== undefined) this.granularity = options.granularity;\n if (options.bucketMaxSpanSeconds !== undefined)\n this.bucketMaxSpanSeconds = options.bucketMaxSpanSeconds;\n if (options.bucketRoundingSeconds !== undefined)\n this.bucketRoundingSeconds = options.bucketRoundingSeconds;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject } from '../contract-types';\nimport {\n MongoChangeStreamPreAndPostImagesOptions,\n type MongoChangeStreamPreAndPostImagesOptionsInput,\n} from './mongo-change-stream-pre-and-post-images-options';\nimport type {\n MongoClusteredCollectionOptions,\n MongoClusteredCollectionOptionsInput,\n} from './mongo-clustered-collection-options';\nimport { MongoCollationOptions, type MongoCollationOptionsInput } from './mongo-collation-options';\nimport {\n MongoIndexOptionDefaults,\n type MongoIndexOptionDefaultsInput,\n} from './mongo-index-option-defaults';\nimport {\n MongoTimeSeriesCollectionOptions,\n type MongoTimeSeriesCollectionOptionsInput,\n} from './mongo-time-series-collection-options';\n\n/**\n * Storage-shape sub-shape: only `name` is persisted on the storage\n * `clusteredIndex` field. The richer authoring vocabulary\n * (`MongoClusteredCollectionOptions.key`, `…unique`) is intentionally\n * not round-tripped through the on-disk JSON envelope — those fields\n * are application-side configuration that informs collection creation\n * but does not survive into the persisted collection options.\n */\nexport interface MongoStorageClusteredIndexShape {\n readonly name?: string;\n}\n\n/**\n * Storage-shape sub-shape: `capped` collections persist `size` (required)\n * and optionally `max` document count. The authoring DSL surface uses a\n * flat `capped: boolean` + separate `size` / `max` fields; builders\n * translate that authoring vocabulary into this nested storage form\n * before constructing {@link MongoCollectionOptions}.\n */\nexport interface MongoStorageCappedShape {\n readonly size: number;\n readonly max?: number;\n}\n\n/**\n * Hydration / construction input shape for {@link MongoCollectionOptions}.\n * Mirrors the on-disk storage JSON envelope exactly (nested `capped`,\n * `clusteredIndex`, …) so the family-base serializer's hydration walker\n * can hand an arktype-validated object literal straight to `new`.\n * Nested IR-class fields may be supplied as either plain data literals\n * (typical for JSON-derived input) or already-constructed class\n * instances (typical when re-wrapping during a partial walk).\n */\nexport interface MongoCollectionOptionsInput {\n readonly capped?: MongoStorageCappedShape;\n readonly storageEngine?: MongoJsonObject;\n readonly indexOptionDefaults?: MongoIndexOptionDefaults | MongoIndexOptionDefaultsInput;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly timeseries?: MongoTimeSeriesCollectionOptions | MongoTimeSeriesCollectionOptionsInput;\n readonly clusteredIndex?: MongoStorageClusteredIndexShape;\n readonly expireAfterSeconds?: number;\n readonly changeStreamPreAndPostImages?:\n | MongoChangeStreamPreAndPostImagesOptions\n | MongoChangeStreamPreAndPostImagesOptionsInput;\n}\n\n/**\n * Authoring-side flat vocabulary accepted by the contract-ts builder\n * DSL (e.g. `capped: boolean` + separate `size` / `max` scalars). The\n * builder translates this surface into a {@link MongoCollectionOptionsInput}\n * before constructing {@link MongoCollectionOptions}. Kept as a\n * standalone type so authoring DSL ergonomics do not leak into the\n * storage IR construction contract.\n */\nexport interface MongoCollectionOptionsAuthoringInput {\n readonly capped?: boolean;\n readonly size?: number;\n readonly max?: number;\n readonly storageEngine?: MongoJsonObject;\n readonly indexOptionDefaults?: MongoIndexOptionDefaults | MongoIndexOptionDefaultsInput;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly timeseries?: MongoTimeSeriesCollectionOptions | MongoTimeSeriesCollectionOptionsInput;\n readonly clusteredIndex?: MongoClusteredCollectionOptions | MongoClusteredCollectionOptionsInput;\n readonly expireAfterSeconds?: number;\n readonly changeStreamPreAndPostImages?:\n | MongoChangeStreamPreAndPostImagesOptions\n | MongoChangeStreamPreAndPostImagesOptionsInput;\n}\n\n/**\n * Mongo Contract IR node for collection-level creation options (the\n * second argument to `db.createCollection(name, options)`). Lifted from\n * the pre-M2R2 `MongoStorageCollectionOptions` storage interface to a\n * class extending `IRNodeBase` per FR18.\n *\n * Single concrete family-layer class (no target subclass). The\n * constructor accepts the storage JSON envelope shape ({@link\n * MongoCollectionOptionsInput}) so the family-base hydration walker\n * can pass arktype-validated objects directly to `new`. Authoring\n * vocabulary is translated to this shape upstream in the contract-ts\n * builder.\n *\n * Nested IR sub-shapes (collation, timeseries, …) are normalised to\n * their respective IR class instances inside the constructor so\n * downstream walks see a uniform AST regardless of whether the input\n * was a JSON literal or an already-constructed class.\n */\nexport class MongoCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-collection-options' as const;\n declare readonly capped?: MongoStorageCappedShape;\n declare readonly storageEngine?: MongoJsonObject;\n declare readonly indexOptionDefaults?: MongoIndexOptionDefaults;\n declare readonly collation?: MongoCollationOptions;\n declare readonly timeseries?: MongoTimeSeriesCollectionOptions;\n declare readonly clusteredIndex?: MongoStorageClusteredIndexShape;\n declare readonly expireAfterSeconds?: number;\n declare readonly changeStreamPreAndPostImages?: MongoChangeStreamPreAndPostImagesOptions;\n\n constructor(input: MongoCollectionOptionsInput = {}) {\n super();\n if (input.capped !== undefined) {\n this.capped = {\n size: input.capped.size,\n ...(input.capped.max != null && { max: input.capped.max }),\n };\n }\n if (input.storageEngine !== undefined) this.storageEngine = input.storageEngine;\n if (input.indexOptionDefaults !== undefined) {\n this.indexOptionDefaults =\n input.indexOptionDefaults instanceof MongoIndexOptionDefaults\n ? input.indexOptionDefaults\n : new MongoIndexOptionDefaults(input.indexOptionDefaults);\n }\n if (input.collation !== undefined) {\n this.collation =\n input.collation instanceof MongoCollationOptions\n ? input.collation\n : new MongoCollationOptions(input.collation);\n }\n if (input.timeseries !== undefined) {\n this.timeseries =\n input.timeseries instanceof MongoTimeSeriesCollectionOptions\n ? input.timeseries\n : new MongoTimeSeriesCollectionOptions(input.timeseries);\n }\n if (input.clusteredIndex !== undefined) {\n this.clusteredIndex =\n input.clusteredIndex.name !== undefined ? { name: input.clusteredIndex.name } : {};\n }\n if (input.expireAfterSeconds !== undefined) this.expireAfterSeconds = input.expireAfterSeconds;\n if (input.changeStreamPreAndPostImages !== undefined) {\n this.changeStreamPreAndPostImages =\n input.changeStreamPreAndPostImages instanceof MongoChangeStreamPreAndPostImagesOptions\n ? input.changeStreamPreAndPostImages\n : new MongoChangeStreamPreAndPostImagesOptions(input.changeStreamPreAndPostImages);\n }\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoIndexKey } from '../contract-types';\n\n/**\n * Hydration / construction input shape for {@link MongoIndex}. Mirrors\n * the on-disk storage JSON envelope exactly so the family-base\n * serializer's hydration walker can hand an arktype-validated literal\n * straight to `new`.\n */\nexport interface MongoIndexInput {\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly unique?: boolean;\n readonly sparse?: boolean;\n readonly expireAfterSeconds?: number;\n readonly partialFilterExpression?: Record<string, unknown>;\n readonly wildcardProjection?: Record<string, 0 | 1>;\n readonly collation?: Record<string, unknown>;\n readonly weights?: Record<string, number>;\n readonly default_language?: string;\n readonly language_override?: string;\n}\n\n/**\n * Mongo Contract IR node for a single collection index entry (one\n * element of `MongoCollection.indexes`). Lifted from the\n * pre-M2R2 `MongoStorageIndex` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Single concrete family-layer class (no target subclass). The spec's\n * `MongoTargetIndex extends MongoIndex` pattern remains additive — a\n * future Mongo target with target-specific index extensions is free to\n * subclass; for the single Mongo target shipped today a concrete\n * family-layer class is enough and avoids a target-import layering\n * violation from the contract-ts builder.\n */\nexport class MongoIndex extends IRNodeBase {\n readonly kind = 'mongo-index' as const;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n declare readonly unique?: boolean;\n declare readonly sparse?: boolean;\n declare readonly expireAfterSeconds?: number;\n declare readonly partialFilterExpression?: Record<string, unknown>;\n declare readonly wildcardProjection?: Record<string, 0 | 1>;\n declare readonly collation?: Record<string, unknown>;\n declare readonly weights?: Record<string, number>;\n declare readonly default_language?: string;\n declare readonly language_override?: string;\n\n constructor(input: MongoIndexInput) {\n super();\n this.keys = input.keys;\n if (input.unique !== undefined) this.unique = input.unique;\n if (input.sparse !== undefined) this.sparse = input.sparse;\n if (input.expireAfterSeconds !== undefined) this.expireAfterSeconds = input.expireAfterSeconds;\n if (input.partialFilterExpression !== undefined)\n this.partialFilterExpression = input.partialFilterExpression;\n if (input.wildcardProjection !== undefined) this.wildcardProjection = input.wildcardProjection;\n if (input.collation !== undefined) this.collation = input.collation;\n if (input.weights !== undefined) this.weights = input.weights;\n if (input.default_language !== undefined) this.default_language = input.default_language;\n if (input.language_override !== undefined) this.language_override = input.language_override;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoValidatorValidationLevel = 'strict' | 'moderate';\nexport type MongoValidatorValidationAction = 'error' | 'warn';\n\nexport interface MongoValidatorInput {\n readonly jsonSchema: Record<string, unknown>;\n readonly validationLevel: MongoValidatorValidationLevel;\n readonly validationAction: MongoValidatorValidationAction;\n}\n\n/**\n * Mongo Contract IR node for collection-level document validators (the\n * `validator` field on Mongo's `createCollection`). Lifted from the\n * pre-M2R2 `MongoStorageValidator` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Concrete at the family layer (no target subclass). The spec's\n * abstract-family + target-concrete pattern (`MongoTargetValidator\n * extends MongoValidator`) becomes meaningful when a second Mongo target\n * introduces target-specific validator extensions (Atlas search rules,\n * DocumentDB-specific levels, …); for the single Mongo target shipped\n * today, a concrete family-layer class lets the PSL JSON-Schema deriver\n * and the contract-ts builder construct instances directly without a\n * target-import layering violation. Target subclassing remains additive\n * — a future `MongoTargetValidator extends MongoValidator` is an\n * additive change, not a breaking one.\n */\nexport class MongoValidator extends IRNodeBase {\n readonly kind = 'mongo-validator' as const;\n readonly jsonSchema: Record<string, unknown>;\n readonly validationLevel: MongoValidatorValidationLevel;\n readonly validationAction: MongoValidatorValidationAction;\n\n constructor(input: MongoValidatorInput) {\n super();\n this.jsonSchema = input.jsonSchema;\n this.validationLevel = input.validationLevel;\n this.validationAction = input.validationAction;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport {\n MongoCollectionOptions,\n type MongoCollectionOptionsInput,\n} from './mongo-collection-options';\nimport { MongoIndex, type MongoIndexInput } from './mongo-index';\nimport { MongoValidator, type MongoValidatorInput } from './mongo-validator';\n\n/**\n * Hydration / construction input shape for {@link MongoCollection}.\n * Mirrors the on-disk storage JSON envelope exactly (the value held at\n * `contract.storage.namespaces[<namespaceId>].collections[<name>]`) so the family-base\n * serializer's hydration walker can hand an arktype-validated literal\n * straight to `new`. Nested IR-class fields may be supplied as either\n * plain data literals (typical for JSON-derived input) or\n * already-constructed class instances.\n */\nexport interface MongoCollectionInput {\n readonly indexes?: ReadonlyArray<MongoIndex | MongoIndexInput>;\n readonly validator?: MongoValidator | MongoValidatorInput;\n readonly options?: MongoCollectionOptions | MongoCollectionOptionsInput;\n}\n\n/**\n * Mongo Contract IR node for a single collection entry in a namespace's\n * `collections` map. Lifted from the pre-M2R2\n * `MongoStorageCollection` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Concrete at the family layer (no target subclass). The spec's\n * `MongoTargetCollection extends MongoCollection` pattern remains\n * additive: a future Mongo target with target-specific extensions is\n * free to subclass without breaking the family-layer construction\n * sites.\n *\n * The unprefixed name `MongoCollection` is now the contract IR class.\n * Note that `@prisma-next/mongo-orm` also exports a (different)\n * `MongoCollection<TContract, ModelName>` generic for the user-facing\n * ORM query builder; the two live in separate packages and are\n * resolved by import path. A source file that needs both should alias\n * one (e.g. `import { MongoCollection as MongoContractCollection }\n * from '@prisma-next/mongo-contract'`).\n */\nexport class MongoCollection extends IRNodeBase {\n readonly kind = 'mongo-collection' as const;\n declare readonly indexes?: ReadonlyArray<MongoIndex>;\n declare readonly validator?: MongoValidator;\n declare readonly options?: MongoCollectionOptions;\n\n constructor(input: MongoCollectionInput = {}) {\n super();\n if (input.indexes !== undefined) {\n this.indexes = input.indexes.map((idx) =>\n idx instanceof MongoIndex ? idx : new MongoIndex(idx),\n );\n }\n if (input.validator !== undefined) {\n this.validator =\n input.validator instanceof MongoValidator\n ? input.validator\n : new MongoValidator(input.validator);\n }\n if (input.options !== undefined) {\n this.options =\n input.options instanceof MongoCollectionOptions\n ? input.options\n : new MongoCollectionOptions(input.options);\n }\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject, MongoWildcardProjection } from '../contract-types';\nimport { MongoCollationOptions, type MongoCollationOptionsInput } from './mongo-collation-options';\n\n/**\n * Authoring / hydration input shape for {@link MongoIndexOptions}. Carries\n * the index option vocabulary as plain data without the IR-class `kind`\n * discriminator. `collation` accepts either a class instance or its own\n * input shape — the constructor normalises to the class form internally.\n */\nexport interface MongoIndexOptionsInput {\n readonly unique?: boolean;\n readonly name?: string;\n readonly partialFilterExpression?: MongoJsonObject;\n readonly sparse?: boolean;\n readonly expireAfterSeconds?: number;\n readonly weights?: Readonly<Record<string, number>>;\n readonly default_language?: string;\n readonly language_override?: string;\n readonly textIndexVersion?: number;\n readonly '2dsphereIndexVersion'?: number;\n readonly bits?: number;\n readonly min?: number;\n readonly max?: number;\n readonly bucketSize?: number;\n readonly hidden?: boolean;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly wildcardProjection?: MongoWildcardProjection;\n}\n\n/**\n * Mongo Contract IR node for the per-index option vocabulary (the second\n * argument to `db.collection.createIndex(keys, options)` minus the keys\n * themselves). Lifted from a `type =` data shape to an AST class\n * extending `IRNodeBase` per FR18.\n *\n * Nested `collation` is itself an IR class (`MongoCollationOptions`); the\n * constructor accepts either a class instance or a data literal and\n * normalises to the class form so downstream walks see a uniform IR tree.\n */\nexport class MongoIndexOptions extends IRNodeBase {\n readonly kind = 'mongo-index-options' as const;\n declare readonly unique?: boolean;\n declare readonly name?: string;\n declare readonly partialFilterExpression?: MongoJsonObject;\n declare readonly sparse?: boolean;\n declare readonly expireAfterSeconds?: number;\n declare readonly weights?: Readonly<Record<string, number>>;\n declare readonly default_language?: string;\n declare readonly language_override?: string;\n declare readonly textIndexVersion?: number;\n declare readonly '2dsphereIndexVersion'?: number;\n declare readonly bits?: number;\n declare readonly min?: number;\n declare readonly max?: number;\n declare readonly bucketSize?: number;\n declare readonly hidden?: boolean;\n declare readonly collation?: MongoCollationOptions;\n declare readonly wildcardProjection?: MongoWildcardProjection;\n\n constructor(options: MongoIndexOptionsInput = {}) {\n super();\n if (options.unique !== undefined) this.unique = options.unique;\n if (options.name !== undefined) this.name = options.name;\n if (options.partialFilterExpression !== undefined)\n this.partialFilterExpression = options.partialFilterExpression;\n if (options.sparse !== undefined) this.sparse = options.sparse;\n if (options.expireAfterSeconds !== undefined)\n this.expireAfterSeconds = options.expireAfterSeconds;\n if (options.weights !== undefined) this.weights = options.weights;\n if (options.default_language !== undefined) this.default_language = options.default_language;\n if (options.language_override !== undefined) this.language_override = options.language_override;\n if (options.textIndexVersion !== undefined) this.textIndexVersion = options.textIndexVersion;\n if (options['2dsphereIndexVersion'] !== undefined)\n this['2dsphereIndexVersion'] = options['2dsphereIndexVersion'];\n if (options.bits !== undefined) this.bits = options.bits;\n if (options.min !== undefined) this.min = options.min;\n if (options.max !== undefined) this.max = options.max;\n if (options.bucketSize !== undefined) this.bucketSize = options.bucketSize;\n if (options.hidden !== undefined) this.hidden = options.hidden;\n if (options.collation !== undefined) {\n this.collation =\n options.collation instanceof MongoCollationOptions\n ? options.collation\n : new MongoCollationOptions(options.collation);\n }\n if (options.wildcardProjection !== undefined)\n this.wildcardProjection = options.wildcardProjection;\n freezeNode(this);\n }\n}\n","import {\n freezeNode,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport type { MongoCollection } from './mongo-collection';\n\nexport class MongoUnboundNamespace extends NamespaceBase {\n static readonly instance: MongoUnboundNamespace = new MongoUnboundNamespace();\n\n readonly id = UNBOUND_NAMESPACE_ID;\n readonly collections: Readonly<Record<string, MongoCollection>> = Object.freeze({});\n declare readonly kind: string;\n\n private constructor() {\n super();\n Object.defineProperty(this, 'kind', {\n value: 'mongo-namespace',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n}\n","import type { StorageHashBase } from '@prisma-next/contract/types';\nimport {\n freezeNode,\n IRNodeBase,\n type Namespace,\n NamespaceBase,\n type Storage,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { MongoCollection, type MongoCollectionInput } from './mongo-collection';\nimport { MongoUnboundNamespace } from './mongo-unbound-namespace';\n\nexport interface MongoNamespaceCollectionsInput {\n readonly id: string;\n readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;\n}\n\nexport interface MongoStorageInput<THash extends string = string> {\n readonly storageHash: StorageHashBase<THash>;\n readonly namespaces?: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>;\n}\n\nconst DEFAULT_NAMESPACES: Readonly<Record<string, Namespace>> = Object.freeze({\n [UNBOUND_NAMESPACE_ID]: MongoUnboundNamespace.instance,\n});\n\nclass MongoNamespacePayload extends NamespaceBase {\n declare readonly kind: string;\n\n readonly id: string;\n readonly collections: Readonly<Record<string, MongoCollection>>;\n\n constructor(input: MongoNamespaceCollectionsInput) {\n super();\n this.id = input.id;\n this.collections = Object.freeze(\n Object.fromEntries(\n Object.entries(input.collections ?? {}).map(([name, c]) => [\n name,\n c instanceof MongoCollection ? c : new MongoCollection(c),\n ]),\n ),\n );\n Object.defineProperty(this, 'kind', {\n value: 'mongo-namespace',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n}\n\nfunction normaliseNamespaceEntry(\n nsKey: string,\n ns: Namespace | MongoNamespaceCollectionsInput,\n): Namespace {\n if (ns instanceof NamespaceBase) {\n return ns;\n }\n // The framework `Namespace` interface only promises `id`; the remaining\n // arm of this union — plain-object inputs accepted by `MongoStorageInput`\n // — is `MongoNamespaceCollectionsInput`. The `instanceof` guard above\n // discriminates the two; TypeScript can't narrow further without a hint.\n const input = ns as MongoNamespaceCollectionsInput;\n const collectionCount = Object.keys(input.collections ?? {}).length;\n if (nsKey === UNBOUND_NAMESPACE_ID && collectionCount === 0) {\n return MongoUnboundNamespace.instance;\n }\n return new MongoNamespacePayload(input);\n}\n\n// Mongo concretions always store `MongoCollection` instances in\n// `collections` (Mongo idiom — distinct from the SQL family's `tables`).\n// Narrowing the namespace map here lets target/family-level consumers\n// iterate `namespaces[*].collections[*]` and recover the concrete\n// collection type without the framework's wider `Namespace` tripping\n// them up.\nexport type MongoNamespace = Namespace & {\n readonly collections: Readonly<Record<string, MongoCollection>>;\n};\n\nexport class MongoStorage<THash extends string = string> extends IRNodeBase implements Storage {\n declare readonly kind: 'mongo-storage';\n readonly storageHash: StorageHashBase<THash>;\n readonly namespaces: Readonly<Record<string, MongoNamespace>>;\n\n constructor(input: MongoStorageInput<THash>) {\n super();\n Object.defineProperty(this, 'kind', {\n value: 'mongo-storage',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n this.storageHash = input.storageHash;\n this.namespaces = Object.freeze(\n Object.fromEntries(\n Object.entries(input.namespaces ?? DEFAULT_NAMESPACES).map(([nsKey, ns]) => [\n nsKey,\n normaliseNamespaceEntry(nsKey, ns) as MongoNamespace,\n ]),\n ),\n );\n freezeNode(this);\n }\n}\n","import { MongoIndex, type MongoIndexInput } from './ir/mongo-index';\n\nexport type PolymorphicIndexScope = {\n readonly discriminatorField: string;\n readonly discriminatorValue: string | number | boolean;\n};\n\nexport type ApplyScopeResult =\n | { readonly kind: 'ok'; readonly index: MongoIndex }\n | { readonly kind: 'conflict'; readonly reason: string };\n\nfunction isScalarDiscriminatorValue(value: unknown): value is string | number | boolean {\n const t = typeof value;\n return t === 'string' || t === 'number' || t === 'boolean';\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return JSON.stringify(value);\n if (value === null) return 'null';\n if (Array.isArray(value)) return JSON.stringify(value);\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\nexport function applyPolymorphicScopeToMongoIndex(\n index: MongoIndex,\n scope: PolymorphicIndexScope,\n): ApplyScopeResult {\n if (!isScalarDiscriminatorValue(scope.discriminatorValue)) {\n return {\n kind: 'conflict',\n reason: `Variant-scoped indexes require a scalar (string, number, or boolean) discriminator value for field \"${scope.discriminatorField}\", but received ${formatValue(scope.discriminatorValue)}.`,\n };\n }\n\n const existing = index.partialFilterExpression;\n if (existing && Object.hasOwn(existing, scope.discriminatorField)) {\n const existingValue = existing[scope.discriminatorField];\n if (existingValue === scope.discriminatorValue) {\n return { kind: 'ok', index };\n }\n return {\n kind: 'conflict',\n reason: `Index partialFilterExpression sets \"${scope.discriminatorField}\" to ${formatValue(existingValue)}, which conflicts with the variant's discriminator value ${formatValue(scope.discriminatorValue)}.`,\n };\n }\n\n const merged: Record<string, unknown> = {\n ...(existing ?? {}),\n [scope.discriminatorField]: scope.discriminatorValue,\n };\n\n const cloned: MongoIndexInput = {\n keys: index.keys,\n ...(index.unique !== undefined && { unique: index.unique }),\n ...(index.sparse !== undefined && { sparse: index.sparse }),\n ...(index.expireAfterSeconds !== undefined && { expireAfterSeconds: index.expireAfterSeconds }),\n partialFilterExpression: merged,\n ...(index.wildcardProjection !== undefined && { wildcardProjection: index.wildcardProjection }),\n ...(index.collation !== undefined && { collation: index.collation }),\n ...(index.weights !== undefined && { weights: index.weights }),\n ...(index.default_language !== undefined && { default_language: index.default_language }),\n ...(index.language_override !== undefined && { language_override: index.language_override }),\n };\n\n return { kind: 'ok', index: new MongoIndex(cloned) };\n}\n","import type { MongoContract } from './contract-types';\n\nfunction storageDeclaresCollection(\n storage: MongoContract['storage'],\n collectionName: string,\n): boolean {\n for (const ns of Object.values(storage.namespaces)) {\n if (Object.hasOwn(ns.collections, collectionName)) {\n return true;\n }\n }\n return false;\n}\n\nexport function validateMongoStorage(contract: MongoContract): void {\n const errors: string[] = [];\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (\n model.storage.collection &&\n !storageDeclaresCollection(contract.storage, model.storage.collection)\n ) {\n errors.push(\n `Model \"${modelName}\" references collection \"${model.storage.collection}\" which is not declared under any namespace's collections map`,\n );\n }\n\n // Mongo does not support multi-table inheritance (ADR 2): all variants of a base\n // must share the same collection (single-table inheritance only).\n if (model.base) {\n const baseModel = contract.models[model.base];\n if (baseModel) {\n const variantCollection = model.storage.collection;\n const baseCollection = baseModel.storage.collection;\n if (variantCollection !== baseCollection) {\n errors.push(\n `Mongo does not support multi-table inheritance; variant \"${modelName}\" must share its base's collection (\"${baseCollection ?? '(none)'}\"), but has \"${variantCollection ?? '(none)'}\"`,\n );\n }\n }\n }\n\n for (const [relName, relation] of Object.entries(model.relations ?? {})) {\n const targetModel = contract.models[relation.to];\n\n if (targetModel?.owner) {\n if (targetModel.owner !== modelName) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which is owned by \"${targetModel.owner}\", not \"${modelName}\"`,\n );\n }\n if (targetModel.storage.collection) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which must not have a collection`,\n );\n }\n } else if ('on' in relation && relation.on) {\n for (const localField of relation.on.localFields) {\n if (!(localField in model.fields)) {\n errors.push(\n `Reference relation \"${relName}\": localField \"${localField}\" is not a field on model \"${modelName}\"`,\n );\n }\n }\n\n if (targetModel) {\n for (const targetField of relation.on.targetFields) {\n if (!(targetField in targetModel.fields)) {\n errors.push(\n `Reference relation \"${relName}\": targetField \"${targetField}\" is not a field on model \"${relation.to}\"`,\n );\n }\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(`Contract storage validation failed:\\n- ${errors.join('\\n- ')}`);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/contract-schema.ts","../src/ir/mongo-change-stream-pre-and-post-images-options.ts","../src/ir/mongo-collation-options.ts","../src/ir/mongo-index-option-defaults.ts","../src/ir/mongo-time-series-collection-options.ts","../src/ir/mongo-collection-options.ts","../src/ir/mongo-index.ts","../src/ir/mongo-validator.ts","../src/ir/mongo-collection.ts","../src/ir/mongo-unbound-namespace.ts","../src/ir/build-mongo-namespace.ts","../src/ir/mongo-clustered-collection-options.ts","../src/ir/mongo-index-options.ts","../src/ir/mongo-storage.ts","../src/polymorphic-index-scope.ts","../src/validate-storage.ts"],"sourcesContent":["import { CrossReferenceSchema } from '@prisma-next/contract/types';\nimport { type Type, type } from 'arktype';\nimport type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';\n\nconst ScalarFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'scalar'\",\n codecId: 'string',\n 'typeParams?': 'Record<string, unknown>',\n});\n\nconst ValueObjectFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'valueObject'\",\n name: 'string',\n});\n\nconst UnionFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'union'\",\n members: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).array(),\n});\n\nconst FieldTypeSchema = ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).or(\n UnionFieldTypeSchema,\n);\n\nconst RawFieldSchema = type({\n '+': 'reject',\n type: FieldTypeSchema,\n 'nullable?': 'boolean',\n 'many?': 'boolean',\n 'dict?': 'boolean',\n});\n\nconst FieldSchema = RawFieldSchema.pipe((field) => ({\n ...field,\n nullable: field.nullable ?? false,\n}));\n\nconst RelationOnSchema = type({\n '+': 'reject',\n localFields: 'string[]',\n targetFields: 'string[]',\n});\n\nconst RelationSchema = type({\n '+': 'reject',\n to: CrossReferenceSchema,\n cardinality: \"'1:1' | '1:N' | 'N:1'\",\n 'on?': RelationOnSchema,\n});\n\nconst StorageRelationEntrySchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst MongoJsonPrimitiveSchema = type\n .declare<MongoJsonPrimitive>()\n .type('string | number | boolean | null');\n\nfunction isMongoJsonRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction withUnseenReference(value: object, seen: WeakSet<object>, visit: () => boolean): boolean {\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n const result = visit();\n seen.delete(value);\n return result;\n}\n\nfunction isMongoJsonObject(value: unknown, seen: WeakSet<object>): value is MongoJsonObject {\n return (\n isMongoJsonRecord(value) &&\n withUnseenReference(value, seen, () =>\n Object.values(value).every((entry) => isMongoJsonValue(entry, seen)),\n )\n );\n}\n\nfunction isMongoJsonValue(value: unknown, seen = new WeakSet<object>()): value is MongoJsonValue {\n if (MongoJsonPrimitiveSchema.allows(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return withUnseenReference(value, seen, () =>\n value.every((entry) => isMongoJsonValue(entry, seen)),\n );\n }\n return isMongoJsonObject(value, seen);\n}\n\nconst MongoJsonValueSchema = type('unknown').narrow((value, ctx) =>\n isMongoJsonValue(value) ? true : ctx.mustBe('a JSON-serializable MongoJsonValue'),\n);\n\nconst MongoJsonObjectSchema = type({ '[string]': 'unknown' }).narrow((value, ctx) =>\n isMongoJsonRecord(value) &&\n Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry))\n ? true\n : ctx.mustBe('a JSON object with MongoJsonValue entries'),\n);\n\nconst NumberRecordSchema = type({ '[string]': 'number' });\n\nconst IndexFieldsSchema = type({\n '+': 'reject',\n '[string]': '1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"',\n}).narrow((fields, ctx) =>\n Object.keys(fields).length > 0 ? true : ctx.mustBe('an index field map with at least one entry'),\n);\n\nconst CollationSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collation-options'\",\n locale: 'string',\n 'caseLevel?': 'boolean',\n 'caseFirst?': '\"off\" | \"upper\" | \"lower\"',\n 'strength?': '1 | 2 | 3 | 4 | 5',\n 'numericOrdering?': 'boolean',\n 'alternate?': '\"non-ignorable\" | \"shifted\"',\n 'maxVariable?': '\"punct\" | \"space\"',\n 'backwards?': 'boolean',\n 'normalization?': 'boolean',\n});\n\nconst IndexOptionDefaultsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index-option-defaults'\",\n 'storageEngine?': MongoJsonObjectSchema,\n});\n\nconst TimeSeriesCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-time-series-collection-options'\",\n timeField: 'string',\n 'metaField?': 'string',\n 'granularity?': '\"seconds\" | \"minutes\" | \"hours\"',\n 'bucketMaxSpanSeconds?': 'number',\n 'bucketRoundingSeconds?': 'number',\n});\n\nconst ClusteredCollectionKeySchema = type({\n '+': 'reject',\n '[string]': '1',\n}).narrow((key, ctx) =>\n Object.keys(key).length > 0\n ? true\n : ctx.mustBe('a clustered index key map with at least one entry'),\n);\n\nconst ClusteredCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-clustered-collection-options'\",\n 'name?': 'string',\n key: ClusteredCollectionKeySchema,\n unique: 'boolean',\n});\n\nconst ChangeStreamPreAndPostImagesSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-change-stream-pre-and-post-images-options'\",\n enabled: 'boolean',\n});\n\nconst CollectionOptionsSchema = type({\n '+': 'reject',\n 'capped?': 'boolean',\n 'size?': 'number',\n 'max?': 'number',\n 'storageEngine?': MongoJsonObjectSchema,\n 'indexOptionDefaults?': IndexOptionDefaultsSchema,\n 'collation?': CollationSchema,\n 'timeseries?': TimeSeriesCollectionOptionsSchema,\n 'clusteredIndex?': ClusteredCollectionOptionsSchema,\n 'expireAfterSeconds?': 'number',\n 'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,\n});\n\nconst ModelStorageSchema = type({\n '+': 'reject',\n 'collection?': 'string',\n 'relations?': type({ '[string]': StorageRelationEntrySchema }),\n});\n\nconst DiscriminatorSchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst VariantEntrySchema = type({\n '+': 'reject',\n value: 'string',\n});\n\nconst ModelDefinitionSchema = type({\n '+': 'reject',\n fields: type({ '[string]': FieldSchema }),\n storage: ModelStorageSchema,\n 'relations?': type({ '[string]': RelationSchema }),\n 'discriminator?': DiscriminatorSchema,\n 'variants?': type({ '[string]': VariantEntrySchema }),\n 'base?': CrossReferenceSchema,\n 'owner?': 'string',\n});\n\nconst WildcardProjectionSchema = type({\n '+': 'reject',\n '[string]': '0 | 1',\n});\n\nconst IndexOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index-options'\",\n 'unique?': 'boolean',\n 'name?': 'string',\n 'partialFilterExpression?': MongoJsonObjectSchema,\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'weights?': NumberRecordSchema,\n 'default_language?': 'string',\n 'language_override?': 'string',\n 'textIndexVersion?': 'number',\n '2dsphereIndexVersion?': 'number',\n 'bits?': 'number',\n 'min?': 'number',\n 'max?': 'number',\n 'bucketSize?': 'number',\n 'hidden?': 'boolean',\n 'collation?': CollationSchema,\n 'wildcardProjection?': WildcardProjectionSchema,\n});\n\nconst IndexSchema = type({\n '+': 'reject',\n fields: IndexFieldsSchema,\n 'options?': IndexOptionsSchema,\n});\n\nconst MongoIndexKeySchema = type({\n '+': 'reject',\n field: 'string',\n direction: '1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"',\n});\n\nconst MongoStorageIndexSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-index'\",\n keys: MongoIndexKeySchema.array().atLeastLength(1),\n 'unique?': 'boolean',\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'partialFilterExpression?': 'Record<string, unknown>',\n 'wildcardProjection?': 'Record<string, 0 | 1>',\n 'collation?': 'Record<string, unknown>',\n 'weights?': 'Record<string, number>',\n 'default_language?': 'string',\n 'language_override?': 'string',\n});\n\nconst MongoStorageValidatorSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-validator'\",\n jsonSchema: 'Record<string, unknown>',\n validationLevel: \"'strict' | 'moderate'\",\n validationAction: \"'error' | 'warn'\",\n});\n\nconst CappedOptionsSchema = type({\n '+': 'reject',\n size: 'number',\n 'max?': 'number',\n});\n\nconst TimeseriesOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-time-series-collection-options'\",\n timeField: 'string',\n 'metaField?': 'string',\n 'granularity?': \"'seconds' | 'minutes' | 'hours'\",\n 'bucketMaxSpanSeconds?': 'number',\n 'bucketRoundingSeconds?': 'number',\n});\n\nconst ClusteredIndexSchema = type({\n '+': 'reject',\n 'name?': 'string',\n});\n\nconst MongoCollectionOptionsSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collection-options'\",\n 'capped?': CappedOptionsSchema,\n 'storageEngine?': MongoJsonObjectSchema,\n 'indexOptionDefaults?': IndexOptionDefaultsSchema,\n 'timeseries?': TimeseriesOptionsSchema,\n 'collation?': 'Record<string, unknown>',\n 'expireAfterSeconds?': 'number',\n 'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,\n 'clusteredIndex?': ClusteredIndexSchema,\n});\n\nconst StorageCollectionSchema = type({\n '+': 'reject',\n 'kind?': \"'mongo-collection'\",\n 'indexes?': MongoStorageIndexSchema.array(),\n 'validator?': MongoStorageValidatorSchema,\n 'options?': MongoCollectionOptionsSchema,\n});\n\nfunction collectionEntrySchema(fragments?: ReadonlyMap<string, Type<unknown>>): Type<unknown> {\n if (fragments === undefined || fragments.size === 0) {\n return StorageCollectionSchema;\n }\n return type('unknown').narrow((entry, ctx) => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return ctx.mustBe('an object');\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const fragment = fragments.get(kind);\n if (fragment !== undefined) {\n const parsed = fragment(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n }\n }\n const parsed = StorageCollectionSchema(entry);\n if (parsed instanceof type.errors) {\n return ctx.reject({ expected: parsed.summary });\n }\n return true;\n });\n}\n\n/**\n * Builds the per-namespace envelope schema for Mongo storage. Pack\n * contributions are keyed by the descriptor's `discriminator` and\n * validate each entry by matching the entry's `kind` field. Mongo today\n * has no pack contributions; the composition surface exists for symmetry\n * with SQL and as the substrate for future entity kinds.\n *\n * `'kind?': 'string'` because `kind` is non-enumerable on built\n * Mongo namespace IR classes and therefore absent from the wire shape; the\n * type-side narrowing is enforced by the IR class, not by this validator.\n */\nexport function createMongoNamespaceEnvelopeSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n return type({\n '+': 'reject',\n id: 'string',\n 'kind?': 'string',\n 'collections?': type({ '[string]': collectionEntrySchema(fragments) }),\n }) as Type<unknown>;\n}\n\n/**\n * Builds the full Mongo contract schema. The per-namespace entry\n * threading happens through {@link createMongoNamespaceEnvelopeSchema};\n * the rest of the envelope is family-shared.\n */\nexport function createMongoContractSchema(\n fragments?: ReadonlyMap<string, Type<unknown>>,\n): Type<unknown> {\n const namespaceEnvelope = createMongoNamespaceEnvelopeSchema(fragments);\n return type({\n '+': 'reject',\n targetFamily: \"'mongo'\",\n 'schemaVersion?': 'string',\n 'target?': 'string',\n 'storageHash?': 'string',\n 'profileHash?': 'string',\n roots: type({ '[string]': CrossReferenceSchema }),\n 'capabilities?': 'Record<string, unknown>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': 'Record<string, unknown>',\n 'sources?': 'Record<string, unknown>',\n '_generated?': 'Record<string, unknown>',\n 'domain?': 'unknown',\n storage: type({\n '+': 'reject',\n namespaces: type({ '[string]': namespaceEnvelope }),\n 'storageHash?': 'string',\n }),\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n }) as Type<unknown>;\n}\n\nexport const MongoContractSchema = createMongoContractSchema();\n\nexport {\n CollationSchema,\n CollectionOptionsSchema,\n IndexFieldsSchema,\n IndexOptionsSchema,\n IndexSchema,\n MongoIndexKeySchema,\n MongoStorageIndexSchema,\n NumberRecordSchema,\n WildcardProjectionSchema,\n};\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport interface MongoChangeStreamPreAndPostImagesOptionsInput {\n readonly enabled: boolean;\n}\n\n/**\n * Change-stream pre-and-post-images collection option. Lifted from a\n * `type =` data shape to an AST class extending `IRNodeBase` per\n * FR18. Single-field shape; the class exists for AST-pattern\n * consistency (every nested data shape inside `MongoCollectionOptions`\n * is an AST node so the verifier can walk uniformly).\n */\nexport class MongoChangeStreamPreAndPostImagesOptions extends IRNodeBase {\n readonly kind = 'mongo-change-stream-pre-and-post-images-options' as const;\n readonly enabled: boolean;\n\n constructor(options: MongoChangeStreamPreAndPostImagesOptionsInput) {\n super();\n this.enabled = options.enabled;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoCollationCaseFirst = 'off' | 'upper' | 'lower';\nexport type MongoCollationStrength = 1 | 2 | 3 | 4 | 5;\nexport type MongoCollationAlternate = 'non-ignorable' | 'shifted';\nexport type MongoCollationMaxVariable = 'punct' | 'space';\n\n/**\n * Authoring / hydration input shape for {@link MongoCollationOptions}. Carries\n * the canonical data without the IR-class `kind` discriminator; the class\n * fabricates `kind` so the authoring DSL and the SPI hydration walker can\n * pass plain data literals through the constructor without forcing every\n * call site to spell out `kind: 'mongo-collation-options'`.\n */\nexport interface MongoCollationOptionsInput {\n readonly locale: string;\n readonly caseLevel?: boolean;\n readonly caseFirst?: MongoCollationCaseFirst;\n readonly strength?: MongoCollationStrength;\n readonly numericOrdering?: boolean;\n readonly alternate?: MongoCollationAlternate;\n readonly maxVariable?: MongoCollationMaxVariable;\n readonly backwards?: boolean;\n readonly normalization?: boolean;\n}\n\n/**\n * Mongo Contract IR leaf for collection / index collation options.\n *\n * Lifted from a `type =` data shape to an AST class extending\n * `IRNodeBase` per FR18 (\"Mongo's Contract IR is fully unified under\n * the AST-class pattern, layered family / target\"). Single concrete class\n * (no target subclass): collation options carry no target-specific\n * variation at this layer — both Atlas and self-hosted Mongo consume the\n * same option vocabulary.\n *\n * Undefined optional fields are not assigned, so `JSON.stringify` omits\n * them from the canonical JSON output (matches the pre-lift data shape's\n * round-trip behaviour, modulo the new `kind` discriminator).\n */\nexport class MongoCollationOptions extends IRNodeBase {\n readonly kind = 'mongo-collation-options' as const;\n readonly locale: string;\n declare readonly caseLevel?: boolean;\n declare readonly caseFirst?: MongoCollationCaseFirst;\n declare readonly strength?: MongoCollationStrength;\n declare readonly numericOrdering?: boolean;\n declare readonly alternate?: MongoCollationAlternate;\n declare readonly maxVariable?: MongoCollationMaxVariable;\n declare readonly backwards?: boolean;\n declare readonly normalization?: boolean;\n\n constructor(options: MongoCollationOptionsInput) {\n super();\n this.locale = options.locale;\n if (options.caseLevel !== undefined) this.caseLevel = options.caseLevel;\n if (options.caseFirst !== undefined) this.caseFirst = options.caseFirst;\n if (options.strength !== undefined) this.strength = options.strength;\n if (options.numericOrdering !== undefined) this.numericOrdering = options.numericOrdering;\n if (options.alternate !== undefined) this.alternate = options.alternate;\n if (options.maxVariable !== undefined) this.maxVariable = options.maxVariable;\n if (options.backwards !== undefined) this.backwards = options.backwards;\n if (options.normalization !== undefined) this.normalization = options.normalization;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject } from '../contract-types';\n\nexport interface MongoIndexOptionDefaultsInput {\n readonly storageEngine?: MongoJsonObject;\n}\n\n/**\n * Collection-level default index options (the `indexOptionDefaults`\n * collection-creation field on Mongo's `createCollection`). Lifted from\n * a `type =` data shape to an AST class extending `IRNodeBase` per\n * FR18 (Mongo Contract IR fully unified under the AST-class pattern).\n *\n * Carries `storageEngine` only — the underlying MongoDB option set is\n * intentionally narrow at this layer; per-engine richer option vocabularies\n * are out of scope for this project.\n */\nexport class MongoIndexOptionDefaults extends IRNodeBase {\n readonly kind = 'mongo-index-option-defaults' as const;\n declare readonly storageEngine?: MongoJsonObject;\n\n constructor(options: MongoIndexOptionDefaultsInput = {}) {\n super();\n if (options.storageEngine !== undefined) this.storageEngine = options.storageEngine;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoTimeSeriesGranularity = 'seconds' | 'minutes' | 'hours';\n\nexport interface MongoTimeSeriesCollectionOptionsInput {\n readonly timeField: string;\n readonly metaField?: string;\n readonly granularity?: MongoTimeSeriesGranularity;\n readonly bucketMaxSpanSeconds?: number;\n readonly bucketRoundingSeconds?: number;\n}\n\n/**\n * Time-series collection options. Lifted from a `type =` data shape to\n * an AST class extending `IRNodeBase` per FR18.\n *\n * MongoDB requires `timeField` for any time-series collection; the\n * constructor enforces presence by type signature (`timeField: string`\n * is required on the input).\n */\nexport class MongoTimeSeriesCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-time-series-collection-options' as const;\n readonly timeField: string;\n declare readonly metaField?: string;\n declare readonly granularity?: MongoTimeSeriesGranularity;\n declare readonly bucketMaxSpanSeconds?: number;\n declare readonly bucketRoundingSeconds?: number;\n\n constructor(options: MongoTimeSeriesCollectionOptionsInput) {\n super();\n this.timeField = options.timeField;\n if (options.metaField !== undefined) this.metaField = options.metaField;\n if (options.granularity !== undefined) this.granularity = options.granularity;\n if (options.bucketMaxSpanSeconds !== undefined)\n this.bucketMaxSpanSeconds = options.bucketMaxSpanSeconds;\n if (options.bucketRoundingSeconds !== undefined)\n this.bucketRoundingSeconds = options.bucketRoundingSeconds;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject } from '../contract-types';\nimport {\n MongoChangeStreamPreAndPostImagesOptions,\n type MongoChangeStreamPreAndPostImagesOptionsInput,\n} from './mongo-change-stream-pre-and-post-images-options';\nimport type {\n MongoClusteredCollectionOptions,\n MongoClusteredCollectionOptionsInput,\n} from './mongo-clustered-collection-options';\nimport { MongoCollationOptions, type MongoCollationOptionsInput } from './mongo-collation-options';\nimport {\n MongoIndexOptionDefaults,\n type MongoIndexOptionDefaultsInput,\n} from './mongo-index-option-defaults';\nimport {\n MongoTimeSeriesCollectionOptions,\n type MongoTimeSeriesCollectionOptionsInput,\n} from './mongo-time-series-collection-options';\n\n/**\n * Storage-shape sub-shape: only `name` is persisted on the storage\n * `clusteredIndex` field. The richer authoring vocabulary\n * (`MongoClusteredCollectionOptions.key`, `…unique`) is intentionally\n * not round-tripped through the on-disk JSON envelope — those fields\n * are application-side configuration that informs collection creation\n * but does not survive into the persisted collection options.\n */\nexport interface MongoStorageClusteredIndexShape {\n readonly name?: string;\n}\n\n/**\n * Storage-shape sub-shape: `capped` collections persist `size` (required)\n * and optionally `max` document count. The authoring DSL surface uses a\n * flat `capped: boolean` + separate `size` / `max` fields; builders\n * translate that authoring vocabulary into this nested storage form\n * before constructing {@link MongoCollectionOptions}.\n */\nexport interface MongoStorageCappedShape {\n readonly size: number;\n readonly max?: number;\n}\n\n/**\n * Hydration / construction input shape for {@link MongoCollectionOptions}.\n * Mirrors the on-disk storage JSON envelope exactly (nested `capped`,\n * `clusteredIndex`, …) so the family-base serializer's hydration walker\n * can hand an arktype-validated object literal straight to `new`.\n * Nested IR-class fields may be supplied as either plain data literals\n * (typical for JSON-derived input) or already-constructed class\n * instances (typical when re-wrapping during a partial walk).\n */\nexport interface MongoCollectionOptionsInput {\n readonly capped?: MongoStorageCappedShape;\n readonly storageEngine?: MongoJsonObject;\n readonly indexOptionDefaults?: MongoIndexOptionDefaults | MongoIndexOptionDefaultsInput;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly timeseries?: MongoTimeSeriesCollectionOptions | MongoTimeSeriesCollectionOptionsInput;\n readonly clusteredIndex?: MongoStorageClusteredIndexShape;\n readonly expireAfterSeconds?: number;\n readonly changeStreamPreAndPostImages?:\n | MongoChangeStreamPreAndPostImagesOptions\n | MongoChangeStreamPreAndPostImagesOptionsInput;\n}\n\n/**\n * Authoring-side flat vocabulary accepted by the contract-ts builder\n * DSL (e.g. `capped: boolean` + separate `size` / `max` scalars). The\n * builder translates this surface into a {@link MongoCollectionOptionsInput}\n * before constructing {@link MongoCollectionOptions}. Kept as a\n * standalone type so authoring DSL ergonomics do not leak into the\n * storage IR construction contract.\n */\nexport interface MongoCollectionOptionsAuthoringInput {\n readonly capped?: boolean;\n readonly size?: number;\n readonly max?: number;\n readonly storageEngine?: MongoJsonObject;\n readonly indexOptionDefaults?: MongoIndexOptionDefaults | MongoIndexOptionDefaultsInput;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly timeseries?: MongoTimeSeriesCollectionOptions | MongoTimeSeriesCollectionOptionsInput;\n readonly clusteredIndex?: MongoClusteredCollectionOptions | MongoClusteredCollectionOptionsInput;\n readonly expireAfterSeconds?: number;\n readonly changeStreamPreAndPostImages?:\n | MongoChangeStreamPreAndPostImagesOptions\n | MongoChangeStreamPreAndPostImagesOptionsInput;\n}\n\n/**\n * Mongo Contract IR node for collection-level creation options (the\n * second argument to `db.createCollection(name, options)`). Lifted from\n * the pre-M2R2 `MongoStorageCollectionOptions` storage interface to a\n * class extending `IRNodeBase` per FR18.\n *\n * Single concrete family-layer class (no target subclass). The\n * constructor accepts the storage JSON envelope shape ({@link\n * MongoCollectionOptionsInput}) so the family-base hydration walker\n * can pass arktype-validated objects directly to `new`. Authoring\n * vocabulary is translated to this shape upstream in the contract-ts\n * builder.\n *\n * Nested IR sub-shapes (collation, timeseries, …) are normalised to\n * their respective IR class instances inside the constructor so\n * downstream walks see a uniform AST regardless of whether the input\n * was a JSON literal or an already-constructed class.\n */\nexport class MongoCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-collection-options' as const;\n declare readonly capped?: MongoStorageCappedShape;\n declare readonly storageEngine?: MongoJsonObject;\n declare readonly indexOptionDefaults?: MongoIndexOptionDefaults;\n declare readonly collation?: MongoCollationOptions;\n declare readonly timeseries?: MongoTimeSeriesCollectionOptions;\n declare readonly clusteredIndex?: MongoStorageClusteredIndexShape;\n declare readonly expireAfterSeconds?: number;\n declare readonly changeStreamPreAndPostImages?: MongoChangeStreamPreAndPostImagesOptions;\n\n constructor(input: MongoCollectionOptionsInput = {}) {\n super();\n if (input.capped !== undefined) {\n this.capped = {\n size: input.capped.size,\n ...(input.capped.max != null && { max: input.capped.max }),\n };\n }\n if (input.storageEngine !== undefined) this.storageEngine = input.storageEngine;\n if (input.indexOptionDefaults !== undefined) {\n this.indexOptionDefaults =\n input.indexOptionDefaults instanceof MongoIndexOptionDefaults\n ? input.indexOptionDefaults\n : new MongoIndexOptionDefaults(input.indexOptionDefaults);\n }\n if (input.collation !== undefined) {\n this.collation =\n input.collation instanceof MongoCollationOptions\n ? input.collation\n : new MongoCollationOptions(input.collation);\n }\n if (input.timeseries !== undefined) {\n this.timeseries =\n input.timeseries instanceof MongoTimeSeriesCollectionOptions\n ? input.timeseries\n : new MongoTimeSeriesCollectionOptions(input.timeseries);\n }\n if (input.clusteredIndex !== undefined) {\n this.clusteredIndex =\n input.clusteredIndex.name !== undefined ? { name: input.clusteredIndex.name } : {};\n }\n if (input.expireAfterSeconds !== undefined) this.expireAfterSeconds = input.expireAfterSeconds;\n if (input.changeStreamPreAndPostImages !== undefined) {\n this.changeStreamPreAndPostImages =\n input.changeStreamPreAndPostImages instanceof MongoChangeStreamPreAndPostImagesOptions\n ? input.changeStreamPreAndPostImages\n : new MongoChangeStreamPreAndPostImagesOptions(input.changeStreamPreAndPostImages);\n }\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoIndexKey } from '../contract-types';\n\n/**\n * Hydration / construction input shape for {@link MongoIndex}. Mirrors\n * the on-disk storage JSON envelope exactly so the family-base\n * serializer's hydration walker can hand an arktype-validated literal\n * straight to `new`.\n */\nexport interface MongoIndexInput {\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly unique?: boolean;\n readonly sparse?: boolean;\n readonly expireAfterSeconds?: number;\n readonly partialFilterExpression?: Record<string, unknown>;\n readonly wildcardProjection?: Record<string, 0 | 1>;\n readonly collation?: Record<string, unknown>;\n readonly weights?: Record<string, number>;\n readonly default_language?: string;\n readonly language_override?: string;\n}\n\n/**\n * Mongo Contract IR node for a single collection index entry (one\n * element of `MongoCollection.indexes`). Lifted from the\n * pre-M2R2 `MongoStorageIndex` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Single concrete family-layer class (no target subclass). The spec's\n * `MongoTargetIndex extends MongoIndex` pattern remains additive — a\n * future Mongo target with target-specific index extensions is free to\n * subclass; for the single Mongo target shipped today a concrete\n * family-layer class is enough and avoids a target-import layering\n * violation from the contract-ts builder.\n */\nexport class MongoIndex extends IRNodeBase {\n readonly kind = 'mongo-index' as const;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n declare readonly unique?: boolean;\n declare readonly sparse?: boolean;\n declare readonly expireAfterSeconds?: number;\n declare readonly partialFilterExpression?: Record<string, unknown>;\n declare readonly wildcardProjection?: Record<string, 0 | 1>;\n declare readonly collation?: Record<string, unknown>;\n declare readonly weights?: Record<string, number>;\n declare readonly default_language?: string;\n declare readonly language_override?: string;\n\n constructor(input: MongoIndexInput) {\n super();\n this.keys = input.keys;\n if (input.unique !== undefined) this.unique = input.unique;\n if (input.sparse !== undefined) this.sparse = input.sparse;\n if (input.expireAfterSeconds !== undefined) this.expireAfterSeconds = input.expireAfterSeconds;\n if (input.partialFilterExpression !== undefined)\n this.partialFilterExpression = input.partialFilterExpression;\n if (input.wildcardProjection !== undefined) this.wildcardProjection = input.wildcardProjection;\n if (input.collation !== undefined) this.collation = input.collation;\n if (input.weights !== undefined) this.weights = input.weights;\n if (input.default_language !== undefined) this.default_language = input.default_language;\n if (input.language_override !== undefined) this.language_override = input.language_override;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoValidatorValidationLevel = 'strict' | 'moderate';\nexport type MongoValidatorValidationAction = 'error' | 'warn';\n\nexport interface MongoValidatorInput {\n readonly jsonSchema: Record<string, unknown>;\n readonly validationLevel: MongoValidatorValidationLevel;\n readonly validationAction: MongoValidatorValidationAction;\n}\n\n/**\n * Mongo Contract IR node for collection-level document validators (the\n * `validator` field on Mongo's `createCollection`). Lifted from the\n * pre-M2R2 `MongoStorageValidator` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Concrete at the family layer (no target subclass). The spec's\n * abstract-family + target-concrete pattern (`MongoTargetValidator\n * extends MongoValidator`) becomes meaningful when a second Mongo target\n * introduces target-specific validator extensions (Atlas search rules,\n * DocumentDB-specific levels, …); for the single Mongo target shipped\n * today, a concrete family-layer class lets the PSL JSON-Schema deriver\n * and the contract-ts builder construct instances directly without a\n * target-import layering violation. Target subclassing remains additive\n * — a future `MongoTargetValidator extends MongoValidator` is an\n * additive change, not a breaking one.\n */\nexport class MongoValidator extends IRNodeBase {\n readonly kind = 'mongo-validator' as const;\n readonly jsonSchema: Record<string, unknown>;\n readonly validationLevel: MongoValidatorValidationLevel;\n readonly validationAction: MongoValidatorValidationAction;\n\n constructor(input: MongoValidatorInput) {\n super();\n this.jsonSchema = input.jsonSchema;\n this.validationLevel = input.validationLevel;\n this.validationAction = input.validationAction;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport {\n MongoCollectionOptions,\n type MongoCollectionOptionsInput,\n} from './mongo-collection-options';\nimport { MongoIndex, type MongoIndexInput } from './mongo-index';\nimport { MongoValidator, type MongoValidatorInput } from './mongo-validator';\n\n/**\n * Hydration / construction input shape for {@link MongoCollection}.\n * Mirrors the on-disk storage JSON envelope exactly (the value held at\n * `contract.storage.namespaces[<namespaceId>].collections[<name>]`) so the family-base\n * serializer's hydration walker can hand an arktype-validated literal\n * straight to `new`. Nested IR-class fields may be supplied as either\n * plain data literals (typical for JSON-derived input) or\n * already-constructed class instances.\n */\nexport interface MongoCollectionInput {\n readonly indexes?: ReadonlyArray<MongoIndex | MongoIndexInput>;\n readonly validator?: MongoValidator | MongoValidatorInput;\n readonly options?: MongoCollectionOptions | MongoCollectionOptionsInput;\n}\n\n/**\n * Mongo Contract IR node for a single collection entry in a namespace's\n * `collections` map. Lifted from the pre-M2R2\n * `MongoStorageCollection` storage interface to a class extending\n * `IRNodeBase` per FR18.\n *\n * Concrete at the family layer (no target subclass). The spec's\n * `MongoTargetCollection extends MongoCollection` pattern remains\n * additive: a future Mongo target with target-specific extensions is\n * free to subclass without breaking the family-layer construction\n * sites.\n *\n * The unprefixed name `MongoCollection` is now the contract IR class.\n * Note that `@prisma-next/mongo-orm` also exports a (different)\n * `MongoCollection<TContract, ModelName>` generic for the user-facing\n * ORM query builder; the two live in separate packages and are\n * resolved by import path. A source file that needs both should alias\n * one (e.g. `import { MongoCollection as MongoContractCollection }\n * from '@prisma-next/mongo-contract'`).\n */\nexport class MongoCollection extends IRNodeBase {\n readonly kind = 'mongo-collection' as const;\n declare readonly indexes?: ReadonlyArray<MongoIndex>;\n declare readonly validator?: MongoValidator;\n declare readonly options?: MongoCollectionOptions;\n\n constructor(input: MongoCollectionInput = {}) {\n super();\n if (input.indexes !== undefined) {\n this.indexes = input.indexes.map((idx) =>\n idx instanceof MongoIndex ? idx : new MongoIndex(idx),\n );\n }\n if (input.validator !== undefined) {\n this.validator =\n input.validator instanceof MongoValidator\n ? input.validator\n : new MongoValidator(input.validator);\n }\n if (input.options !== undefined) {\n this.options =\n input.options instanceof MongoCollectionOptions\n ? input.options\n : new MongoCollectionOptions(input.options);\n }\n freezeNode(this);\n }\n}\n","import {\n freezeNode,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport type { MongoCollection } from './mongo-collection';\n\nexport class MongoUnboundNamespace extends NamespaceBase {\n static readonly instance: MongoUnboundNamespace = new MongoUnboundNamespace();\n\n readonly id = UNBOUND_NAMESPACE_ID;\n readonly collections: Readonly<Record<string, MongoCollection>> = Object.freeze({});\n declare readonly kind: string;\n\n private constructor() {\n super();\n Object.defineProperty(this, 'kind', {\n value: 'mongo-namespace',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n}\n","import {\n freezeNode,\n type Namespace,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { blindCast, castAs } from '@prisma-next/utils/casts';\nimport { MongoCollection } from './mongo-collection';\nimport type { MongoNamespace, MongoNamespaceCollectionsInput } from './mongo-storage';\nimport { MongoUnboundNamespace } from './mongo-unbound-namespace';\n\nconst MONGO_NAMESPACE_KIND = 'mongo-namespace' as const;\n\nfunction isMaterializedMongoNamespace(\n ns: Namespace | MongoNamespaceCollectionsInput,\n): ns is MongoNamespace {\n if (typeof ns !== 'object' || ns === null) {\n return false;\n }\n const proto = Object.getPrototypeOf(ns);\n if (proto === Object.prototype || proto === null) {\n return false;\n }\n return (ns as Namespace).kind === MONGO_NAMESPACE_KIND;\n}\n\nclass MongoBoundNamespace extends NamespaceBase {\n declare readonly kind: string;\n\n readonly id: string;\n readonly collections: Readonly<Record<string, MongoCollection>>;\n\n static fromCollectionsInput(input: MongoNamespaceCollectionsInput): MongoNamespace {\n const collectionCount = Object.keys(input.collections ?? {}).length;\n if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0) {\n return castAs<MongoNamespace>(MongoUnboundNamespace.instance);\n }\n return castAs<MongoNamespace>(new MongoBoundNamespace(input));\n }\n\n private constructor(input: MongoNamespaceCollectionsInput) {\n super();\n this.id = input.id;\n this.collections = Object.freeze(\n Object.fromEntries(\n Object.entries(input.collections ?? {}).map(([name, c]) => [\n name,\n c instanceof MongoCollection ? c : new MongoCollection(c),\n ]),\n ),\n );\n Object.defineProperty(this, 'kind', {\n value: MONGO_NAMESPACE_KIND,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n}\n\nexport function buildMongoNamespace(input: MongoNamespaceCollectionsInput): MongoNamespace {\n return MongoBoundNamespace.fromCollectionsInput(input);\n}\n\nexport function buildMongoNamespaceMap(\n namespaces: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>,\n): Readonly<Record<string, MongoNamespace>> {\n return Object.fromEntries(\n Object.entries(namespaces).map(([nsKey, ns]) => [\n nsKey,\n isMaterializedMongoNamespace(ns)\n ? blindCast<\n MongoNamespace,\n 'a materialised Mongo-family namespace entry in a namespace map is a MongoNamespace'\n >(ns)\n : MongoBoundNamespace.fromCollectionsInput(ns),\n ]),\n );\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\n\nexport type MongoClusteredCollectionKey = Readonly<Record<string, 1>>;\n\nexport interface MongoClusteredCollectionOptionsInput {\n readonly name?: string;\n readonly key: MongoClusteredCollectionKey;\n readonly unique: boolean;\n}\n\n/**\n * Clustered-collection options (the `clusteredIndex` collection-creation\n * field). Lifted from a `type =` data shape to an AST class extending\n * `IRNodeBase` per FR18.\n *\n * MongoDB requires `key` and `unique` for any clustered collection; the\n * constructor enforces presence by type signature.\n */\nexport class MongoClusteredCollectionOptions extends IRNodeBase {\n readonly kind = 'mongo-clustered-collection-options' as const;\n declare readonly name?: string;\n readonly key: MongoClusteredCollectionKey;\n readonly unique: boolean;\n\n constructor(options: MongoClusteredCollectionOptionsInput) {\n super();\n if (options.name !== undefined) this.name = options.name;\n this.key = options.key;\n this.unique = options.unique;\n freezeNode(this);\n }\n}\n","import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';\nimport type { MongoJsonObject, MongoWildcardProjection } from '../contract-types';\nimport { MongoCollationOptions, type MongoCollationOptionsInput } from './mongo-collation-options';\n\n/**\n * Authoring / hydration input shape for {@link MongoIndexOptions}. Carries\n * the index option vocabulary as plain data without the IR-class `kind`\n * discriminator. `collation` accepts either a class instance or its own\n * input shape — the constructor normalises to the class form internally.\n */\nexport interface MongoIndexOptionsInput {\n readonly unique?: boolean;\n readonly name?: string;\n readonly partialFilterExpression?: MongoJsonObject;\n readonly sparse?: boolean;\n readonly expireAfterSeconds?: number;\n readonly weights?: Readonly<Record<string, number>>;\n readonly default_language?: string;\n readonly language_override?: string;\n readonly textIndexVersion?: number;\n readonly '2dsphereIndexVersion'?: number;\n readonly bits?: number;\n readonly min?: number;\n readonly max?: number;\n readonly bucketSize?: number;\n readonly hidden?: boolean;\n readonly collation?: MongoCollationOptions | MongoCollationOptionsInput;\n readonly wildcardProjection?: MongoWildcardProjection;\n}\n\n/**\n * Mongo Contract IR node for the per-index option vocabulary (the second\n * argument to `db.collection.createIndex(keys, options)` minus the keys\n * themselves). Lifted from a `type =` data shape to an AST class\n * extending `IRNodeBase` per FR18.\n *\n * Nested `collation` is itself an IR class (`MongoCollationOptions`); the\n * constructor accepts either a class instance or a data literal and\n * normalises to the class form so downstream walks see a uniform IR tree.\n */\nexport class MongoIndexOptions extends IRNodeBase {\n readonly kind = 'mongo-index-options' as const;\n declare readonly unique?: boolean;\n declare readonly name?: string;\n declare readonly partialFilterExpression?: MongoJsonObject;\n declare readonly sparse?: boolean;\n declare readonly expireAfterSeconds?: number;\n declare readonly weights?: Readonly<Record<string, number>>;\n declare readonly default_language?: string;\n declare readonly language_override?: string;\n declare readonly textIndexVersion?: number;\n declare readonly '2dsphereIndexVersion'?: number;\n declare readonly bits?: number;\n declare readonly min?: number;\n declare readonly max?: number;\n declare readonly bucketSize?: number;\n declare readonly hidden?: boolean;\n declare readonly collation?: MongoCollationOptions;\n declare readonly wildcardProjection?: MongoWildcardProjection;\n\n constructor(options: MongoIndexOptionsInput = {}) {\n super();\n if (options.unique !== undefined) this.unique = options.unique;\n if (options.name !== undefined) this.name = options.name;\n if (options.partialFilterExpression !== undefined)\n this.partialFilterExpression = options.partialFilterExpression;\n if (options.sparse !== undefined) this.sparse = options.sparse;\n if (options.expireAfterSeconds !== undefined)\n this.expireAfterSeconds = options.expireAfterSeconds;\n if (options.weights !== undefined) this.weights = options.weights;\n if (options.default_language !== undefined) this.default_language = options.default_language;\n if (options.language_override !== undefined) this.language_override = options.language_override;\n if (options.textIndexVersion !== undefined) this.textIndexVersion = options.textIndexVersion;\n if (options['2dsphereIndexVersion'] !== undefined)\n this['2dsphereIndexVersion'] = options['2dsphereIndexVersion'];\n if (options.bits !== undefined) this.bits = options.bits;\n if (options.min !== undefined) this.min = options.min;\n if (options.max !== undefined) this.max = options.max;\n if (options.bucketSize !== undefined) this.bucketSize = options.bucketSize;\n if (options.hidden !== undefined) this.hidden = options.hidden;\n if (options.collation !== undefined) {\n this.collation =\n options.collation instanceof MongoCollationOptions\n ? options.collation\n : new MongoCollationOptions(options.collation);\n }\n if (options.wildcardProjection !== undefined)\n this.wildcardProjection = options.wildcardProjection;\n freezeNode(this);\n }\n}\n","import type { StorageHashBase } from '@prisma-next/contract/types';\nimport {\n freezeNode,\n IRNodeBase,\n type Namespace,\n type Storage,\n} from '@prisma-next/framework-components/ir';\nimport type { MongoCollection, MongoCollectionInput } from './mongo-collection';\n\nexport interface MongoNamespaceCollectionsInput {\n readonly id: string;\n readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;\n}\n\n// Mongo concretions always store `MongoCollection` instances in\n// `collections` (Mongo idiom — distinct from the SQL family's `tables`).\n// Narrowing the namespace map here lets target/family-level consumers\n// iterate `namespaces[*].collections[*]` and recover the concrete\n// collection type without the framework's wider `Namespace` tripping\n// them up.\nexport type MongoNamespace = Namespace & {\n readonly collections: Readonly<Record<string, MongoCollection>>;\n};\n\nexport interface MongoStorageInput<THash extends string = string> {\n readonly storageHash: StorageHashBase<THash>;\n readonly namespaces: Readonly<Record<string, MongoNamespace>>;\n}\n\nexport class MongoStorage<THash extends string = string> extends IRNodeBase implements Storage {\n declare readonly kind: 'mongo-storage';\n readonly storageHash: StorageHashBase<THash>;\n readonly namespaces: Readonly<Record<string, MongoNamespace>>;\n\n constructor(input: MongoStorageInput<THash>) {\n super();\n Object.defineProperty(this, 'kind', {\n value: 'mongo-storage',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n this.storageHash = input.storageHash;\n this.namespaces = Object.freeze(input.namespaces);\n freezeNode(this);\n }\n}\n","import { MongoIndex, type MongoIndexInput } from './ir/mongo-index';\n\nexport type PolymorphicIndexScope = {\n readonly discriminatorField: string;\n readonly discriminatorValue: string | number | boolean;\n};\n\nexport type ApplyScopeResult =\n | { readonly kind: 'ok'; readonly index: MongoIndex }\n | { readonly kind: 'conflict'; readonly reason: string };\n\nfunction isScalarDiscriminatorValue(value: unknown): value is string | number | boolean {\n const t = typeof value;\n return t === 'string' || t === 'number' || t === 'boolean';\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return JSON.stringify(value);\n if (value === null) return 'null';\n if (Array.isArray(value)) return JSON.stringify(value);\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n}\n\nexport function applyPolymorphicScopeToMongoIndex(\n index: MongoIndex,\n scope: PolymorphicIndexScope,\n): ApplyScopeResult {\n if (!isScalarDiscriminatorValue(scope.discriminatorValue)) {\n return {\n kind: 'conflict',\n reason: `Variant-scoped indexes require a scalar (string, number, or boolean) discriminator value for field \"${scope.discriminatorField}\", but received ${formatValue(scope.discriminatorValue)}.`,\n };\n }\n\n const existing = index.partialFilterExpression;\n if (existing && Object.hasOwn(existing, scope.discriminatorField)) {\n const existingValue = existing[scope.discriminatorField];\n if (existingValue === scope.discriminatorValue) {\n return { kind: 'ok', index };\n }\n return {\n kind: 'conflict',\n reason: `Index partialFilterExpression sets \"${scope.discriminatorField}\" to ${formatValue(existingValue)}, which conflicts with the variant's discriminator value ${formatValue(scope.discriminatorValue)}.`,\n };\n }\n\n const merged: Record<string, unknown> = {\n ...(existing ?? {}),\n [scope.discriminatorField]: scope.discriminatorValue,\n };\n\n const cloned: MongoIndexInput = {\n keys: index.keys,\n ...(index.unique !== undefined && { unique: index.unique }),\n ...(index.sparse !== undefined && { sparse: index.sparse }),\n ...(index.expireAfterSeconds !== undefined && { expireAfterSeconds: index.expireAfterSeconds }),\n partialFilterExpression: merged,\n ...(index.wildcardProjection !== undefined && { wildcardProjection: index.wildcardProjection }),\n ...(index.collation !== undefined && { collation: index.collation }),\n ...(index.weights !== undefined && { weights: index.weights }),\n ...(index.default_language !== undefined && { default_language: index.default_language }),\n ...(index.language_override !== undefined && { language_override: index.language_override }),\n };\n\n return { kind: 'ok', index: new MongoIndex(cloned) };\n}\n","import type { MongoContract } from './contract-types';\n\nfunction formatCrossRef(crossRef: { readonly namespace: string; readonly model: string }): string {\n return `${crossRef.namespace}.${crossRef.model}`;\n}\n\nfunction storageDeclaresCollection(\n storage: MongoContract['storage'],\n collectionName: string,\n): boolean {\n for (const ns of Object.values(storage.namespaces)) {\n if (Object.hasOwn(ns.collections, collectionName)) {\n return true;\n }\n }\n return false;\n}\n\nexport function validateMongoStorage(contract: MongoContract): void {\n const errors: string[] = [];\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (\n model.storage.collection &&\n !storageDeclaresCollection(contract.storage, model.storage.collection)\n ) {\n errors.push(\n `Model \"${modelName}\" references collection \"${model.storage.collection}\" which is not declared under any namespace's collections map`,\n );\n }\n\n if (model.base) {\n const baseModel = contract.models[model.base.model];\n if (baseModel) {\n const variantCollection = model.storage.collection;\n const baseCollection = baseModel.storage.collection;\n if (variantCollection !== baseCollection) {\n errors.push(\n `Mongo does not support multi-table inheritance; variant \"${modelName}\" must share its base's collection (\"${baseCollection ?? '(none)'}\"), but has \"${variantCollection ?? '(none)'}\"`,\n );\n }\n }\n }\n\n for (const [relName, relation] of Object.entries(model.relations ?? {})) {\n const targetModel = contract.models[relation.to.model];\n const targetLabel = formatCrossRef(relation.to);\n\n if (targetModel?.owner) {\n if (targetModel.owner !== modelName) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${targetLabel}\" which is owned by \"${targetModel.owner}\", not \"${modelName}\"`,\n );\n }\n if (targetModel.storage.collection) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${targetLabel}\" which must not have a collection`,\n );\n }\n } else if ('on' in relation && relation.on) {\n for (const localField of relation.on.localFields) {\n if (!(localField in model.fields)) {\n errors.push(\n `Reference relation \"${relName}\": localField \"${localField}\" is not a field on model \"${modelName}\"`,\n );\n }\n }\n\n if (targetModel) {\n for (const targetField of relation.on.targetFields) {\n if (!(targetField in targetModel.fields)) {\n errors.push(\n `Reference relation \"${relName}\": targetField \"${targetField}\" is not a field on model \"${targetLabel}\"`,\n );\n }\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(`Contract storage validation failed:\\n- ${errors.join('\\n- ')}`);\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/mongo-contract",
|
|
3
|
-
"version": "0.11.0-dev.
|
|
3
|
+
"version": "0.11.0-dev.51",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Contract types and validation for Prisma Next MongoDB support",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/contract": "0.11.0-dev.
|
|
10
|
-
"@prisma-next/framework-components": "0.11.0-dev.
|
|
11
|
-
"@prisma-next/utils": "0.11.0-dev.
|
|
9
|
+
"@prisma-next/contract": "0.11.0-dev.51",
|
|
10
|
+
"@prisma-next/framework-components": "0.11.0-dev.51",
|
|
11
|
+
"@prisma-next/utils": "0.11.0-dev.51",
|
|
12
12
|
"arktype": "^2.2.0"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@prisma-next/test-utils": "0.11.0-dev.
|
|
16
|
-
"@prisma-next/tsconfig": "0.11.0-dev.
|
|
17
|
-
"@prisma-next/tsdown": "0.11.0-dev.
|
|
15
|
+
"@prisma-next/test-utils": "0.11.0-dev.51",
|
|
16
|
+
"@prisma-next/tsconfig": "0.11.0-dev.51",
|
|
17
|
+
"@prisma-next/tsdown": "0.11.0-dev.51",
|
|
18
18
|
"tsdown": "0.22.0",
|
|
19
19
|
"typescript": "5.9.3",
|
|
20
20
|
"vitest": "4.1.6"
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"exports": {
|
|
27
27
|
".": "./dist/index.mjs",
|
|
28
|
+
"./canonicalization-hooks": "./dist/canonicalization-hooks.mjs",
|
|
28
29
|
"./package.json": "./package.json"
|
|
29
30
|
},
|
|
30
31
|
"types": "./dist/index.d.mts",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PreserveEmptyPredicate } from '@prisma-next/contract/hashing';
|
|
2
|
+
import {
|
|
3
|
+
createPreserveEmptyPredicate,
|
|
4
|
+
type PathPattern,
|
|
5
|
+
} from '@prisma-next/contract/hashing-utils';
|
|
6
|
+
|
|
7
|
+
const preserveEmptyPatterns = [
|
|
8
|
+
['storage', 'namespaces', '*', 'collections'],
|
|
9
|
+
['storage', 'namespaces', '*', 'collections', '*'],
|
|
10
|
+
] as const satisfies readonly PathPattern[];
|
|
11
|
+
|
|
12
|
+
const shouldPreserveEmpty: PreserveEmptyPredicate =
|
|
13
|
+
createPreserveEmptyPredicate(preserveEmptyPatterns);
|
|
14
|
+
|
|
15
|
+
export const mongoContractCanonicalizationHooks: {
|
|
16
|
+
readonly shouldPreserveEmpty: PreserveEmptyPredicate;
|
|
17
|
+
} = {
|
|
18
|
+
shouldPreserveEmpty,
|
|
19
|
+
};
|
package/src/contract-schema.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CrossReferenceSchema } from '@prisma-next/contract/types';
|
|
1
2
|
import { type Type, type } from 'arktype';
|
|
2
3
|
import type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';
|
|
3
4
|
|
|
@@ -45,7 +46,7 @@ const RelationOnSchema = type({
|
|
|
45
46
|
|
|
46
47
|
const RelationSchema = type({
|
|
47
48
|
'+': 'reject',
|
|
48
|
-
to:
|
|
49
|
+
to: CrossReferenceSchema,
|
|
49
50
|
cardinality: "'1:1' | '1:N' | 'N:1'",
|
|
50
51
|
'on?': RelationOnSchema,
|
|
51
52
|
});
|
|
@@ -209,7 +210,7 @@ const ModelDefinitionSchema = type({
|
|
|
209
210
|
'relations?': type({ '[string]': RelationSchema }),
|
|
210
211
|
'discriminator?': DiscriminatorSchema,
|
|
211
212
|
'variants?': type({ '[string]': VariantEntrySchema }),
|
|
212
|
-
'base?':
|
|
213
|
+
'base?': CrossReferenceSchema,
|
|
213
214
|
'owner?': 'string',
|
|
214
215
|
});
|
|
215
216
|
|
|
@@ -351,8 +352,8 @@ function collectionEntrySchema(fragments?: ReadonlyMap<string, Type<unknown>>):
|
|
|
351
352
|
* has no pack contributions; the composition surface exists for symmetry
|
|
352
353
|
* with SQL and as the substrate for future entity kinds.
|
|
353
354
|
*
|
|
354
|
-
* `'kind?': 'string'` because `kind` is non-enumerable on
|
|
355
|
-
*
|
|
355
|
+
* `'kind?': 'string'` because `kind` is non-enumerable on built
|
|
356
|
+
* Mongo namespace IR classes and therefore absent from the wire shape; the
|
|
356
357
|
* type-side narrowing is enforced by the IR class, not by this validator.
|
|
357
358
|
*/
|
|
358
359
|
export function createMongoNamespaceEnvelopeSchema(
|
|
@@ -382,7 +383,7 @@ export function createMongoContractSchema(
|
|
|
382
383
|
'target?': 'string',
|
|
383
384
|
'storageHash?': 'string',
|
|
384
385
|
'profileHash?': 'string',
|
|
385
|
-
roots: '
|
|
386
|
+
roots: type({ '[string]': CrossReferenceSchema }),
|
|
386
387
|
'capabilities?': 'Record<string, unknown>',
|
|
387
388
|
'extensionPacks?': 'Record<string, unknown>',
|
|
388
389
|
'meta?': 'Record<string, unknown>',
|
package/src/contract-types.ts
CHANGED
|
@@ -71,6 +71,13 @@ export type MongoContract<
|
|
|
71
71
|
M extends Record<string, MongoModelDefinition> = Record<string, MongoModelDefinition>,
|
|
72
72
|
> = Contract<S, M>;
|
|
73
73
|
|
|
74
|
+
export type RootModelName<
|
|
75
|
+
TContract extends MongoContract,
|
|
76
|
+
RootName extends keyof TContract['roots'] & string,
|
|
77
|
+
> = TContract['roots'][RootName] extends { readonly model: infer M extends string }
|
|
78
|
+
? M & keyof TContract['models']
|
|
79
|
+
: never;
|
|
80
|
+
|
|
74
81
|
export type MongoTypeMaps<
|
|
75
82
|
TCodecTypes extends Record<string, { output: unknown }> = Record<string, { output: unknown }>,
|
|
76
83
|
TFieldOutputTypes extends Record<string, Record<string, unknown>> = Record<
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { mongoContractCanonicalizationHooks } from '../canonicalization-hooks';
|
package/src/exports/index.ts
CHANGED
|
@@ -25,7 +25,9 @@ export type {
|
|
|
25
25
|
MongoTypeMaps,
|
|
26
26
|
MongoTypeMapsPhantomKey,
|
|
27
27
|
MongoWildcardProjection,
|
|
28
|
+
RootModelName,
|
|
28
29
|
} from '../contract-types';
|
|
30
|
+
export { buildMongoNamespace, buildMongoNamespaceMap } from '../ir/build-mongo-namespace';
|
|
29
31
|
export type { MongoChangeStreamPreAndPostImagesOptionsInput } from '../ir/mongo-change-stream-pre-and-post-images-options';
|
|
30
32
|
export { MongoChangeStreamPreAndPostImagesOptions } from '../ir/mongo-change-stream-pre-and-post-images-options';
|
|
31
33
|
export type {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
freezeNode,
|
|
3
|
+
type Namespace,
|
|
4
|
+
NamespaceBase,
|
|
5
|
+
UNBOUND_NAMESPACE_ID,
|
|
6
|
+
} from '@prisma-next/framework-components/ir';
|
|
7
|
+
import { blindCast, castAs } from '@prisma-next/utils/casts';
|
|
8
|
+
import { MongoCollection } from './mongo-collection';
|
|
9
|
+
import type { MongoNamespace, MongoNamespaceCollectionsInput } from './mongo-storage';
|
|
10
|
+
import { MongoUnboundNamespace } from './mongo-unbound-namespace';
|
|
11
|
+
|
|
12
|
+
const MONGO_NAMESPACE_KIND = 'mongo-namespace' as const;
|
|
13
|
+
|
|
14
|
+
function isMaterializedMongoNamespace(
|
|
15
|
+
ns: Namespace | MongoNamespaceCollectionsInput,
|
|
16
|
+
): ns is MongoNamespace {
|
|
17
|
+
if (typeof ns !== 'object' || ns === null) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const proto = Object.getPrototypeOf(ns);
|
|
21
|
+
if (proto === Object.prototype || proto === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return (ns as Namespace).kind === MONGO_NAMESPACE_KIND;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class MongoBoundNamespace extends NamespaceBase {
|
|
28
|
+
declare readonly kind: string;
|
|
29
|
+
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
32
|
+
|
|
33
|
+
static fromCollectionsInput(input: MongoNamespaceCollectionsInput): MongoNamespace {
|
|
34
|
+
const collectionCount = Object.keys(input.collections ?? {}).length;
|
|
35
|
+
if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0) {
|
|
36
|
+
return castAs<MongoNamespace>(MongoUnboundNamespace.instance);
|
|
37
|
+
}
|
|
38
|
+
return castAs<MongoNamespace>(new MongoBoundNamespace(input));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private constructor(input: MongoNamespaceCollectionsInput) {
|
|
42
|
+
super();
|
|
43
|
+
this.id = input.id;
|
|
44
|
+
this.collections = Object.freeze(
|
|
45
|
+
Object.fromEntries(
|
|
46
|
+
Object.entries(input.collections ?? {}).map(([name, c]) => [
|
|
47
|
+
name,
|
|
48
|
+
c instanceof MongoCollection ? c : new MongoCollection(c),
|
|
49
|
+
]),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
Object.defineProperty(this, 'kind', {
|
|
53
|
+
value: MONGO_NAMESPACE_KIND,
|
|
54
|
+
writable: false,
|
|
55
|
+
enumerable: false,
|
|
56
|
+
configurable: true,
|
|
57
|
+
});
|
|
58
|
+
freezeNode(this);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function buildMongoNamespace(input: MongoNamespaceCollectionsInput): MongoNamespace {
|
|
63
|
+
return MongoBoundNamespace.fromCollectionsInput(input);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function buildMongoNamespaceMap(
|
|
67
|
+
namespaces: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>,
|
|
68
|
+
): Readonly<Record<string, MongoNamespace>> {
|
|
69
|
+
return Object.fromEntries(
|
|
70
|
+
Object.entries(namespaces).map(([nsKey, ns]) => [
|
|
71
|
+
nsKey,
|
|
72
|
+
isMaterializedMongoNamespace(ns)
|
|
73
|
+
? blindCast<
|
|
74
|
+
MongoNamespace,
|
|
75
|
+
'a materialised Mongo-family namespace entry in a namespace map is a MongoNamespace'
|
|
76
|
+
>(ns)
|
|
77
|
+
: MongoBoundNamespace.fromCollectionsInput(ns),
|
|
78
|
+
]),
|
|
79
|
+
);
|
|
80
|
+
}
|
package/src/ir/mongo-storage.ts
CHANGED
|
@@ -3,73 +3,15 @@ import {
|
|
|
3
3
|
freezeNode,
|
|
4
4
|
IRNodeBase,
|
|
5
5
|
type Namespace,
|
|
6
|
-
NamespaceBase,
|
|
7
6
|
type Storage,
|
|
8
|
-
UNBOUND_NAMESPACE_ID,
|
|
9
7
|
} from '@prisma-next/framework-components/ir';
|
|
10
|
-
import { MongoCollection,
|
|
11
|
-
import { MongoUnboundNamespace } from './mongo-unbound-namespace';
|
|
8
|
+
import type { MongoCollection, MongoCollectionInput } from './mongo-collection';
|
|
12
9
|
|
|
13
10
|
export interface MongoNamespaceCollectionsInput {
|
|
14
11
|
readonly id: string;
|
|
15
12
|
readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;
|
|
16
13
|
}
|
|
17
14
|
|
|
18
|
-
export interface MongoStorageInput<THash extends string = string> {
|
|
19
|
-
readonly storageHash: StorageHashBase<THash>;
|
|
20
|
-
readonly namespaces?: Readonly<Record<string, Namespace | MongoNamespaceCollectionsInput>>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const DEFAULT_NAMESPACES: Readonly<Record<string, Namespace>> = Object.freeze({
|
|
24
|
-
[UNBOUND_NAMESPACE_ID]: MongoUnboundNamespace.instance,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
class MongoNamespacePayload extends NamespaceBase {
|
|
28
|
-
declare readonly kind: string;
|
|
29
|
-
|
|
30
|
-
readonly id: string;
|
|
31
|
-
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
32
|
-
|
|
33
|
-
constructor(input: MongoNamespaceCollectionsInput) {
|
|
34
|
-
super();
|
|
35
|
-
this.id = input.id;
|
|
36
|
-
this.collections = Object.freeze(
|
|
37
|
-
Object.fromEntries(
|
|
38
|
-
Object.entries(input.collections ?? {}).map(([name, c]) => [
|
|
39
|
-
name,
|
|
40
|
-
c instanceof MongoCollection ? c : new MongoCollection(c),
|
|
41
|
-
]),
|
|
42
|
-
),
|
|
43
|
-
);
|
|
44
|
-
Object.defineProperty(this, 'kind', {
|
|
45
|
-
value: 'mongo-namespace',
|
|
46
|
-
writable: false,
|
|
47
|
-
enumerable: false,
|
|
48
|
-
configurable: true,
|
|
49
|
-
});
|
|
50
|
-
freezeNode(this);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function normaliseNamespaceEntry(
|
|
55
|
-
nsKey: string,
|
|
56
|
-
ns: Namespace | MongoNamespaceCollectionsInput,
|
|
57
|
-
): Namespace {
|
|
58
|
-
if (ns instanceof NamespaceBase) {
|
|
59
|
-
return ns;
|
|
60
|
-
}
|
|
61
|
-
// The framework `Namespace` interface only promises `id`; the remaining
|
|
62
|
-
// arm of this union — plain-object inputs accepted by `MongoStorageInput`
|
|
63
|
-
// — is `MongoNamespaceCollectionsInput`. The `instanceof` guard above
|
|
64
|
-
// discriminates the two; TypeScript can't narrow further without a hint.
|
|
65
|
-
const input = ns as MongoNamespaceCollectionsInput;
|
|
66
|
-
const collectionCount = Object.keys(input.collections ?? {}).length;
|
|
67
|
-
if (nsKey === UNBOUND_NAMESPACE_ID && collectionCount === 0) {
|
|
68
|
-
return MongoUnboundNamespace.instance;
|
|
69
|
-
}
|
|
70
|
-
return new MongoNamespacePayload(input);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
15
|
// Mongo concretions always store `MongoCollection` instances in
|
|
74
16
|
// `collections` (Mongo idiom — distinct from the SQL family's `tables`).
|
|
75
17
|
// Narrowing the namespace map here lets target/family-level consumers
|
|
@@ -80,6 +22,11 @@ export type MongoNamespace = Namespace & {
|
|
|
80
22
|
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
81
23
|
};
|
|
82
24
|
|
|
25
|
+
export interface MongoStorageInput<THash extends string = string> {
|
|
26
|
+
readonly storageHash: StorageHashBase<THash>;
|
|
27
|
+
readonly namespaces: Readonly<Record<string, MongoNamespace>>;
|
|
28
|
+
}
|
|
29
|
+
|
|
83
30
|
export class MongoStorage<THash extends string = string> extends IRNodeBase implements Storage {
|
|
84
31
|
declare readonly kind: 'mongo-storage';
|
|
85
32
|
readonly storageHash: StorageHashBase<THash>;
|
|
@@ -94,14 +41,7 @@ export class MongoStorage<THash extends string = string> extends IRNodeBase impl
|
|
|
94
41
|
configurable: true,
|
|
95
42
|
});
|
|
96
43
|
this.storageHash = input.storageHash;
|
|
97
|
-
this.namespaces = Object.freeze(
|
|
98
|
-
Object.fromEntries(
|
|
99
|
-
Object.entries(input.namespaces ?? DEFAULT_NAMESPACES).map(([nsKey, ns]) => [
|
|
100
|
-
nsKey,
|
|
101
|
-
normaliseNamespaceEntry(nsKey, ns) as MongoNamespace,
|
|
102
|
-
]),
|
|
103
|
-
),
|
|
104
|
-
);
|
|
44
|
+
this.namespaces = Object.freeze(input.namespaces);
|
|
105
45
|
freezeNode(this);
|
|
106
46
|
}
|
|
107
47
|
}
|
package/src/validate-storage.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { MongoContract } from './contract-types';
|
|
2
2
|
|
|
3
|
+
function formatCrossRef(crossRef: { readonly namespace: string; readonly model: string }): string {
|
|
4
|
+
return `${crossRef.namespace}.${crossRef.model}`;
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
function storageDeclaresCollection(
|
|
4
8
|
storage: MongoContract['storage'],
|
|
5
9
|
collectionName: string,
|
|
@@ -25,10 +29,8 @@ export function validateMongoStorage(contract: MongoContract): void {
|
|
|
25
29
|
);
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
// Mongo does not support multi-table inheritance (ADR 2): all variants of a base
|
|
29
|
-
// must share the same collection (single-table inheritance only).
|
|
30
32
|
if (model.base) {
|
|
31
|
-
const baseModel = contract.models[model.base];
|
|
33
|
+
const baseModel = contract.models[model.base.model];
|
|
32
34
|
if (baseModel) {
|
|
33
35
|
const variantCollection = model.storage.collection;
|
|
34
36
|
const baseCollection = baseModel.storage.collection;
|
|
@@ -41,17 +43,18 @@ export function validateMongoStorage(contract: MongoContract): void {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
for (const [relName, relation] of Object.entries(model.relations ?? {})) {
|
|
44
|
-
const targetModel = contract.models[relation.to];
|
|
46
|
+
const targetModel = contract.models[relation.to.model];
|
|
47
|
+
const targetLabel = formatCrossRef(relation.to);
|
|
45
48
|
|
|
46
49
|
if (targetModel?.owner) {
|
|
47
50
|
if (targetModel.owner !== modelName) {
|
|
48
51
|
errors.push(
|
|
49
|
-
`Embed relation "${relName}" targets "${
|
|
52
|
+
`Embed relation "${relName}" targets "${targetLabel}" which is owned by "${targetModel.owner}", not "${modelName}"`,
|
|
50
53
|
);
|
|
51
54
|
}
|
|
52
55
|
if (targetModel.storage.collection) {
|
|
53
56
|
errors.push(
|
|
54
|
-
`Embed relation "${relName}" targets "${
|
|
57
|
+
`Embed relation "${relName}" targets "${targetLabel}" which must not have a collection`,
|
|
55
58
|
);
|
|
56
59
|
}
|
|
57
60
|
} else if ('on' in relation && relation.on) {
|
|
@@ -67,7 +70,7 @@ export function validateMongoStorage(contract: MongoContract): void {
|
|
|
67
70
|
for (const targetField of relation.on.targetFields) {
|
|
68
71
|
if (!(targetField in targetModel.fields)) {
|
|
69
72
|
errors.push(
|
|
70
|
-
`Reference relation "${relName}": targetField "${targetField}" is not a field on model "${
|
|
73
|
+
`Reference relation "${relName}": targetField "${targetField}" is not a field on model "${targetLabel}"`,
|
|
71
74
|
);
|
|
72
75
|
}
|
|
73
76
|
}
|