@prisma-next/mongo-contract 0.12.0 → 0.13.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canonicalization-hooks.mjs +4 -2
- package/dist/canonicalization-hooks.mjs.map +1 -1
- package/dist/index.d.mts +29 -14
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +24 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
- package/src/canonicalization-hooks.ts +2 -2
- package/src/contract-schema.ts +18 -1
- package/src/contract-types.ts +13 -8
- package/src/default-namespace.ts +8 -0
- package/src/exports/index.ts +4 -0
- package/src/ir/build-mongo-namespace.ts +19 -10
- package/src/ir/mongo-collection.ts +5 -1
- package/src/ir/mongo-storage.ts +11 -8
- package/src/ir/mongo-unbound-namespace.ts +3 -1
- package/src/validate-storage.ts +1 -1
|
@@ -4,12 +4,14 @@ const matchesPreserveEmptyPattern = createPreserveEmptyPredicate([[
|
|
|
4
4
|
"storage",
|
|
5
5
|
"namespaces",
|
|
6
6
|
"*",
|
|
7
|
-
"
|
|
7
|
+
"entries",
|
|
8
|
+
"collection"
|
|
8
9
|
], [
|
|
9
10
|
"storage",
|
|
10
11
|
"namespaces",
|
|
11
12
|
"*",
|
|
12
|
-
"
|
|
13
|
+
"entries",
|
|
14
|
+
"collection",
|
|
13
15
|
"*"
|
|
14
16
|
]]);
|
|
15
17
|
const shouldPreserveEmpty = (path) => path[path.length - 1] === "additionalProperties" || matchesPreserveEmptyPattern(path);
|
|
@@ -1 +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', '*', '
|
|
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', '*', 'entries', 'collection'],\n ['storage', 'namespaces', '*', 'entries', 'collection', '*'],\n] as const satisfies readonly PathPattern[];\n\nconst matchesPreserveEmptyPattern = createPreserveEmptyPredicate(preserveEmptyPatterns);\n\n// `additionalProperties: false` is the closed-schema marker on a Mongo\n// `$jsonSchema` validator. It is injected at every object level — top-level\n// collections, nested embedded value objects, and each polymorphic `oneOf`\n// branch — so it appears at an unbounded set of paths that fixed-length path\n// patterns cannot enumerate. It is a meaningful constraint rather than an\n// omittable default, so preserve it wherever it occurs in a Mongo contract.\nconst shouldPreserveEmpty: PreserveEmptyPredicate = (path) =>\n path[path.length - 1] === 'additionalProperties' || matchesPreserveEmptyPattern(path);\n\nexport const mongoContractCanonicalizationHooks: {\n readonly shouldPreserveEmpty: PreserveEmptyPredicate;\n} = {\n shouldPreserveEmpty,\n};\n"],"mappings":";;AAWA,MAAM,8BAA8B,6BAA6B,CAJ/D;CAAC;CAAW;CAAc;CAAK;CAAW;AAAY,GACtD;CAAC;CAAW;CAAc;CAAK;CAAW;CAAc;AAAG,CAGwB,CAAC;AAQtF,MAAM,uBAA+C,SACnD,KAAK,KAAK,SAAS,OAAO,0BAA0B,4BAA4B,IAAI;AAEtF,MAAa,qCAET,EACF,oBACF"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Contract, ContractField, ContractModel, ContractModelsMap, ContractValueObject, ContractValueObjectsMap, StorageBase, StorageHashBase } from "@prisma-next/contract/types";
|
|
3
|
-
import * as _$arktype from "arktype";
|
|
1
|
+
import { Contract, ContractField, ContractModel, ContractModelDefinitions, ContractValueObject, ContractValueObjectDefinitions, ControlPolicy, StorageBase, StorageHashBase } from "@prisma-next/contract/types";
|
|
4
2
|
import { Type } from "arktype";
|
|
5
3
|
import { IRNodeBase, Namespace, NamespaceBase, Storage } from "@prisma-next/framework-components/ir";
|
|
4
|
+
|
|
6
5
|
//#region src/contract-schema.d.ts
|
|
7
6
|
/**
|
|
8
7
|
* Builds the per-namespace envelope schema for Mongo storage. Pack
|
|
@@ -22,7 +21,7 @@ declare function createMongoNamespaceEnvelopeSchema(fragments?: ReadonlyMap<stri
|
|
|
22
21
|
* the rest of the envelope is family-shared.
|
|
23
22
|
*/
|
|
24
23
|
declare function createMongoContractSchema(fragments?: ReadonlyMap<string, Type<unknown>>): Type<unknown>;
|
|
25
|
-
declare const MongoContractSchema:
|
|
24
|
+
declare const MongoContractSchema: import("arktype").BaseType<unknown, {}>;
|
|
26
25
|
//#endregion
|
|
27
26
|
//#region src/ir/mongo-change-stream-pre-and-post-images-options.d.ts
|
|
28
27
|
interface MongoChangeStreamPreAndPostImagesOptionsInput {
|
|
@@ -339,7 +338,7 @@ declare class MongoValidator extends IRNodeBase {
|
|
|
339
338
|
/**
|
|
340
339
|
* Hydration / construction input shape for {@link MongoCollection}.
|
|
341
340
|
* Mirrors the on-disk storage JSON envelope exactly (the value held at
|
|
342
|
-
* `contract.storage.namespaces[<namespaceId>].
|
|
341
|
+
* `contract.storage.namespaces[<namespaceId>].entries.collection[<name>]`) so the family-base
|
|
343
342
|
* serializer's hydration walker can hand an arktype-validated literal
|
|
344
343
|
* straight to `new`. Nested IR-class fields may be supplied as either
|
|
345
344
|
* plain data literals (typical for JSON-derived input) or
|
|
@@ -349,6 +348,7 @@ interface MongoCollectionInput {
|
|
|
349
348
|
readonly indexes?: ReadonlyArray<MongoIndex | MongoIndexInput>;
|
|
350
349
|
readonly validator?: MongoValidator | MongoValidatorInput;
|
|
351
350
|
readonly options?: MongoCollectionOptions | MongoCollectionOptionsInput;
|
|
351
|
+
readonly control?: ControlPolicy;
|
|
352
352
|
}
|
|
353
353
|
/**
|
|
354
354
|
* Mongo Contract IR node for a single collection entry in a namespace's
|
|
@@ -375,6 +375,7 @@ declare class MongoCollection extends IRNodeBase {
|
|
|
375
375
|
readonly indexes?: ReadonlyArray<MongoIndex>;
|
|
376
376
|
readonly validator?: MongoValidator;
|
|
377
377
|
readonly options?: MongoCollectionOptions;
|
|
378
|
+
readonly control?: ControlPolicy;
|
|
378
379
|
constructor(input?: MongoCollectionInput);
|
|
379
380
|
}
|
|
380
381
|
//#endregion
|
|
@@ -478,15 +479,17 @@ type MongoModelDefinition = ContractModel<MongoModelStorage>;
|
|
|
478
479
|
*/
|
|
479
480
|
type MongoStorageShape<THash extends string = string> = StorageBase<THash> & {
|
|
480
481
|
readonly namespaces: Record<string, Namespace & {
|
|
481
|
-
readonly
|
|
482
|
+
readonly entries: Readonly<{
|
|
483
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
484
|
+
}>;
|
|
482
485
|
}>;
|
|
483
486
|
};
|
|
484
487
|
type MongoContract<S extends MongoStorageShape = MongoStorageShape, M extends Record<string, MongoModelDefinition> = Record<string, MongoModelDefinition>> = Contract<S, M>;
|
|
485
488
|
/** Model map inferred from a {@link MongoContract} (domain.namespaces union). */
|
|
486
|
-
type MongoModelsMap<TContract extends MongoContract> =
|
|
489
|
+
type MongoModelsMap<TContract extends MongoContract> = ContractModelDefinitions<TContract>;
|
|
487
490
|
type RootModelName<TContract extends MongoContract, RootName extends keyof TContract['roots'] & string> = TContract['roots'][RootName] extends {
|
|
488
491
|
readonly model: infer M extends string;
|
|
489
|
-
} ? M & keyof
|
|
492
|
+
} ? M & keyof import('@prisma-next/contract/types').ContractModelDefinitions<TContract> : never;
|
|
490
493
|
type MongoTypeMaps<TCodecTypes extends Record<string, {
|
|
491
494
|
output: unknown;
|
|
492
495
|
}> = Record<string, {
|
|
@@ -510,7 +513,7 @@ type ExtractMongoFieldOutputTypes<T> = ExtractMongoTypeMaps<T> extends {
|
|
|
510
513
|
type ExtractMongoFieldInputTypes<T> = ExtractMongoTypeMaps<T> extends {
|
|
511
514
|
fieldInputTypes: infer F;
|
|
512
515
|
} ? F extends Record<string, Record<string, unknown>> ? F : Record<string, never> : Record<string, never>;
|
|
513
|
-
type ExtractValueObjects<TContract extends Contract> =
|
|
516
|
+
type ExtractValueObjects<TContract extends Contract> = ContractValueObjectDefinitions<TContract>;
|
|
514
517
|
type NormalizeContractFields<TFields> = { [K in keyof TFields]: TFields[K] extends ContractField ? TFields[K] : never };
|
|
515
518
|
type ExtractValueObjectFields<TValueObjects extends Record<string, ContractValueObject>, VOName extends keyof TValueObjects> = NormalizeContractFields<TValueObjects[VOName]['fields']>;
|
|
516
519
|
type InferFieldBaseType<TFieldType, TValueObjects extends Record<string, ContractValueObject>, TCodecTypes extends Record<string, {
|
|
@@ -530,17 +533,27 @@ type InferFieldType<TField, TValueObjects extends Record<string, ContractValueOb
|
|
|
530
533
|
}>> = TField extends ContractField ? TField extends {
|
|
531
534
|
many: true;
|
|
532
535
|
} ? TField['nullable'] extends true ? InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes>[] | null : InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes>[] : TField['nullable'] extends true ? InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes> | null : InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes> : never;
|
|
533
|
-
type InferModelRow<TContract extends MongoContractWithTypeMaps<MongoContract, MongoTypeMaps>, ModelName extends string & keyof
|
|
536
|
+
type InferModelRow<TContract extends MongoContractWithTypeMaps<MongoContract, MongoTypeMaps>, ModelName extends string & keyof ContractModelDefinitions<TContract>, TFields extends Record<string, ContractField> = ContractModelDefinitions<TContract>[ModelName]['fields'], TCodecTypes extends Record<string, {
|
|
534
537
|
output: unknown;
|
|
535
538
|
}> = ExtractMongoCodecTypes<TContract>, TValueObjects extends Record<string, ContractValueObject> = ExtractValueObjects<TContract>> = { -readonly [FieldName in keyof TFields]: InferFieldType<TFields[FieldName], TValueObjects, TCodecTypes> };
|
|
536
539
|
//#endregion
|
|
540
|
+
//#region src/default-namespace.d.ts
|
|
541
|
+
/** Default storage namespace for Mongo-family contracts at runtime. */
|
|
542
|
+
declare const defaultMongoStorageNamespaceId: "__unbound__";
|
|
543
|
+
/** Default domain namespace for Mongo-family contracts at runtime. */
|
|
544
|
+
declare const defaultMongoDomainNamespaceId: "__unbound__";
|
|
545
|
+
//#endregion
|
|
537
546
|
//#region src/ir/mongo-storage.d.ts
|
|
538
547
|
interface MongoNamespaceCollectionsInput {
|
|
539
548
|
readonly id: string;
|
|
540
|
-
readonly
|
|
549
|
+
readonly entries: {
|
|
550
|
+
readonly collection: Record<string, MongoCollection | MongoCollectionInput>;
|
|
551
|
+
};
|
|
541
552
|
}
|
|
542
553
|
type MongoNamespace = Namespace & {
|
|
543
|
-
readonly
|
|
554
|
+
readonly entries: Readonly<{
|
|
555
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
556
|
+
}>;
|
|
544
557
|
};
|
|
545
558
|
interface MongoStorageInput<THash extends string = string> {
|
|
546
559
|
readonly storageHash: StorageHashBase<THash>;
|
|
@@ -561,7 +574,9 @@ declare function buildMongoNamespaceMap(namespaces: Readonly<Record<string, Name
|
|
|
561
574
|
declare class MongoUnboundNamespace extends NamespaceBase {
|
|
562
575
|
static readonly instance: MongoUnboundNamespace;
|
|
563
576
|
readonly id: "__unbound__";
|
|
564
|
-
readonly
|
|
577
|
+
readonly entries: Readonly<{
|
|
578
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
579
|
+
}>;
|
|
565
580
|
readonly kind: string;
|
|
566
581
|
private constructor();
|
|
567
582
|
}
|
|
@@ -583,5 +598,5 @@ declare function applyPolymorphicScopeToMongoIndex(index: MongoIndex, scope: Pol
|
|
|
583
598
|
//#region src/validate-storage.d.ts
|
|
584
599
|
declare function validateMongoStorage(contract: MongoContract): void;
|
|
585
600
|
//#endregion
|
|
586
|
-
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, type MongoModelsMap, 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 };
|
|
601
|
+
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, type MongoModelsMap, 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, defaultMongoDomainNamespaceId, defaultMongoStorageNamespaceId, validateMongoStorage };
|
|
587
602
|
//# 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/build-mongo-namespace.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/default-namespace.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,8 +1,10 @@
|
|
|
1
1
|
import { CrossReferenceSchema } from "@prisma-next/contract/types";
|
|
2
2
|
import { type } from "arktype";
|
|
3
|
+
import { UNBOUND_DOMAIN_NAMESPACE_ID } from "@prisma-next/contract/default-namespace";
|
|
3
4
|
import { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
|
|
4
5
|
import { blindCast, castAs } from "@prisma-next/utils/casts";
|
|
5
6
|
//#region src/contract-schema.ts
|
|
7
|
+
const ControlPolicySchema = type("'managed' | 'tolerated' | 'external' | 'observed'");
|
|
6
8
|
const ScalarFieldTypeSchema = type({
|
|
7
9
|
"+": "reject",
|
|
8
10
|
kind: "'scalar'",
|
|
@@ -234,7 +236,8 @@ const StorageCollectionSchema = type({
|
|
|
234
236
|
"kind?": "'mongo-collection'",
|
|
235
237
|
"indexes?": MongoStorageIndexSchema.array(),
|
|
236
238
|
"validator?": MongoStorageValidatorSchema,
|
|
237
|
-
"options?": MongoCollectionOptionsSchema
|
|
239
|
+
"options?": MongoCollectionOptionsSchema,
|
|
240
|
+
"control?": ControlPolicySchema
|
|
238
241
|
});
|
|
239
242
|
function collectionEntrySchema(fragments) {
|
|
240
243
|
if (fragments === void 0 || fragments.size === 0) return StorageCollectionSchema;
|
|
@@ -270,7 +273,11 @@ function createMongoNamespaceEnvelopeSchema(fragments) {
|
|
|
270
273
|
"+": "reject",
|
|
271
274
|
id: "string",
|
|
272
275
|
"kind?": "string",
|
|
273
|
-
"
|
|
276
|
+
entries: type({ "collection?": type({ "[string]": collectionEntrySchema(fragments) }) })
|
|
277
|
+
}).narrow((ns, ctx) => {
|
|
278
|
+
if (typeof ns !== "object" || ns === null || Array.isArray(ns)) return ctx.mustBe("an object");
|
|
279
|
+
if (Object.hasOwn(ns, "collections") || Object.hasOwn(ns, "tables")) return ctx.reject({ expected: "namespace must use `entries: { collection? }`; flat `collections` / `tables` keys are no longer accepted" });
|
|
280
|
+
return true;
|
|
274
281
|
});
|
|
275
282
|
}
|
|
276
283
|
/**
|
|
@@ -291,6 +298,7 @@ function createMongoContractSchema(fragments) {
|
|
|
291
298
|
"capabilities?": "Record<string, unknown>",
|
|
292
299
|
"extensionPacks?": "Record<string, unknown>",
|
|
293
300
|
"meta?": "Record<string, unknown>",
|
|
301
|
+
"defaultControlPolicy?": ControlPolicySchema,
|
|
294
302
|
"sources?": "Record<string, unknown>",
|
|
295
303
|
"_generated?": "Record<string, unknown>",
|
|
296
304
|
domain: type({ namespaces: type({ "[string]": type({
|
|
@@ -309,6 +317,12 @@ function createMongoContractSchema(fragments) {
|
|
|
309
317
|
}
|
|
310
318
|
const MongoContractSchema = createMongoContractSchema();
|
|
311
319
|
//#endregion
|
|
320
|
+
//#region src/default-namespace.ts
|
|
321
|
+
/** Default storage namespace for Mongo-family contracts at runtime. */
|
|
322
|
+
const defaultMongoStorageNamespaceId = UNBOUND_NAMESPACE_ID;
|
|
323
|
+
/** Default domain namespace for Mongo-family contracts at runtime. */
|
|
324
|
+
const defaultMongoDomainNamespaceId = UNBOUND_DOMAIN_NAMESPACE_ID;
|
|
325
|
+
//#endregion
|
|
312
326
|
//#region src/ir/mongo-change-stream-pre-and-post-images-options.ts
|
|
313
327
|
/**
|
|
314
328
|
* Change-stream pre-and-post-images collection option. Lifted from a
|
|
@@ -534,6 +548,7 @@ var MongoCollection = class extends IRNodeBase {
|
|
|
534
548
|
if (input.indexes !== void 0) this.indexes = input.indexes.map((idx) => idx instanceof MongoIndex ? idx : new MongoIndex(idx));
|
|
535
549
|
if (input.validator !== void 0) this.validator = input.validator instanceof MongoValidator ? input.validator : new MongoValidator(input.validator);
|
|
536
550
|
if (input.options !== void 0) this.options = input.options instanceof MongoCollectionOptions ? input.options : new MongoCollectionOptions(input.options);
|
|
551
|
+
if (input.control !== void 0) this.control = input.control;
|
|
537
552
|
freezeNode(this);
|
|
538
553
|
}
|
|
539
554
|
};
|
|
@@ -542,7 +557,7 @@ var MongoCollection = class extends IRNodeBase {
|
|
|
542
557
|
var MongoUnboundNamespace = class MongoUnboundNamespace extends NamespaceBase {
|
|
543
558
|
static instance = new MongoUnboundNamespace();
|
|
544
559
|
id = UNBOUND_NAMESPACE_ID;
|
|
545
|
-
|
|
560
|
+
entries = Object.freeze({ collection: Object.freeze({}) });
|
|
546
561
|
constructor() {
|
|
547
562
|
super();
|
|
548
563
|
Object.defineProperty(this, "kind", {
|
|
@@ -565,16 +580,16 @@ function isMaterializedMongoNamespace(ns) {
|
|
|
565
580
|
}
|
|
566
581
|
var MongoBoundNamespace = class MongoBoundNamespace extends NamespaceBase {
|
|
567
582
|
id;
|
|
568
|
-
|
|
583
|
+
entries;
|
|
569
584
|
static fromCollectionsInput(input) {
|
|
570
|
-
const collectionCount = Object.keys(input.
|
|
585
|
+
const collectionCount = Object.keys(input.entries.collection).length;
|
|
571
586
|
if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0) return castAs(MongoUnboundNamespace.instance);
|
|
572
587
|
return castAs(new MongoBoundNamespace(input));
|
|
573
588
|
}
|
|
574
589
|
constructor(input) {
|
|
575
590
|
super();
|
|
576
591
|
this.id = input.id;
|
|
577
|
-
this.
|
|
592
|
+
this.entries = Object.freeze({ collection: Object.freeze(Object.fromEntries(Object.entries(input.entries.collection).map(([name, c]) => [name, c instanceof MongoCollection ? c : new MongoCollection(c)]))) });
|
|
578
593
|
Object.defineProperty(this, "kind", {
|
|
579
594
|
value: MONGO_NAMESPACE_KIND,
|
|
580
595
|
writable: false,
|
|
@@ -588,7 +603,7 @@ function buildMongoNamespace(input) {
|
|
|
588
603
|
return MongoBoundNamespace.fromCollectionsInput(input);
|
|
589
604
|
}
|
|
590
605
|
function buildMongoNamespaceMap(namespaces) {
|
|
591
|
-
return Object.fromEntries(Object.entries(namespaces).map(([nsKey, ns]) => [nsKey, isMaterializedMongoNamespace(ns) ? blindCast(ns) : MongoBoundNamespace.fromCollectionsInput(ns)]));
|
|
606
|
+
return Object.fromEntries(Object.entries(namespaces).map(([nsKey, ns]) => [nsKey, isMaterializedMongoNamespace(ns) ? blindCast(ns) : MongoBoundNamespace.fromCollectionsInput(blindCast(ns))]));
|
|
592
607
|
}
|
|
593
608
|
//#endregion
|
|
594
609
|
//#region src/ir/mongo-clustered-collection-options.ts
|
|
@@ -722,7 +737,7 @@ function formatCrossRef(crossRef) {
|
|
|
722
737
|
return `${crossRef.namespace}.${crossRef.model}`;
|
|
723
738
|
}
|
|
724
739
|
function storageDeclaresCollection(storage, collectionName) {
|
|
725
|
-
for (const ns of Object.values(storage.namespaces)) if (Object.hasOwn(ns.
|
|
740
|
+
for (const ns of Object.values(storage.namespaces)) if (Object.hasOwn(ns.entries.collection, collectionName)) return true;
|
|
726
741
|
return false;
|
|
727
742
|
}
|
|
728
743
|
function validateMongoStorage(contract) {
|
|
@@ -758,6 +773,6 @@ function validateMongoStorage(contract) {
|
|
|
758
773
|
if (errors.length > 0) throw new Error(`Contract storage validation failed:\n- ${errors.join("\n- ")}`);
|
|
759
774
|
}
|
|
760
775
|
//#endregion
|
|
761
|
-
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace, buildMongoNamespaceMap, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, validateMongoStorage };
|
|
776
|
+
export { MongoChangeStreamPreAndPostImagesOptions, MongoClusteredCollectionOptions, MongoCollationOptions, MongoCollection, MongoCollectionOptions, MongoContractSchema, MongoIndex, MongoIndexOptionDefaults, MongoIndexOptions, MongoStorage, MongoTimeSeriesCollectionOptions, MongoUnboundNamespace, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace, buildMongoNamespaceMap, createMongoContractSchema, createMongoNamespaceEnvelopeSchema, defaultMongoDomainNamespaceId, defaultMongoStorageNamespaceId, validateMongoStorage };
|
|
762
777
|
|
|
763
778
|
//# 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-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: type({\n namespaces: type({\n '[string]': type({\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n }),\n }),\n }),\n storage: type({\n '+': 'reject',\n namespaces: type({ '[string]': namespaceEnvelope }),\n 'storageHash?': 'string',\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, MongoModelDefinition } 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 [namespaceId, namespace] of Object.entries(contract.domain.namespaces)) {\n const models = namespace.models as Record<string, MongoModelDefinition>;\n for (const [modelName, model] of Object.entries(models)) {\n const qualifiedName = `${namespaceId}:${modelName}`;\n if (\n model.storage.collection &&\n !storageDeclaresCollection(contract.storage, model.storage.collection)\n ) {\n errors.push(\n `Model \"${qualifiedName}\" 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 = 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 \"${qualifiedName}\" 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 = 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 \"${qualifiedName}\"`,\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 \"${qualifiedName}\"`,\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\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/default-namespace.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 ControlPolicySchema = type(\"'managed' | 'tolerated' | 'external' | 'observed'\");\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 'control?': ControlPolicySchema,\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 entries: type({\n 'collection?': type({ '[string]': collectionEntrySchema(fragments) }),\n }),\n }).narrow((ns, ctx) => {\n if (typeof ns !== 'object' || ns === null || Array.isArray(ns)) {\n return ctx.mustBe('an object');\n }\n if (Object.hasOwn(ns, 'collections') || Object.hasOwn(ns, 'tables')) {\n return ctx.reject({\n expected:\n 'namespace must use `entries: { collection? }`; flat `collections` / `tables` keys are no longer accepted',\n });\n }\n return true;\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 'defaultControlPolicy?': ControlPolicySchema,\n 'sources?': 'Record<string, unknown>',\n '_generated?': 'Record<string, unknown>',\n domain: type({\n namespaces: type({\n '[string]': type({\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n }),\n }),\n }),\n storage: type({\n '+': 'reject',\n namespaces: type({ '[string]': namespaceEnvelope }),\n 'storageHash?': 'string',\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 { UNBOUND_DOMAIN_NAMESPACE_ID } from '@prisma-next/contract/default-namespace';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\n\n/** Default storage namespace for Mongo-family contracts at runtime. */\nexport const defaultMongoStorageNamespaceId = UNBOUND_NAMESPACE_ID;\n\n/** Default domain namespace for Mongo-family contracts at runtime. */\nexport const defaultMongoDomainNamespaceId = UNBOUND_DOMAIN_NAMESPACE_ID;\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 type { ControlPolicy } from '@prisma-next/contract/types';\nimport { 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>].entries.collection[<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 readonly control?: ControlPolicy;\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 declare readonly control?: ControlPolicy;\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 if (input.control !== undefined) this.control = input.control;\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 entries: Readonly<{\n readonly collection: Readonly<Record<string, MongoCollection>>;\n }> = Object.freeze({ collection: 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 entries: Readonly<{\n readonly collection: Readonly<Record<string, MongoCollection>>;\n }>;\n\n static fromCollectionsInput(input: MongoNamespaceCollectionsInput): MongoNamespace {\n const collectionCount = Object.keys(input.entries.collection).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.entries = Object.freeze({\n collection: Object.freeze(\n Object.fromEntries(\n Object.entries(input.entries.collection).map(([name, c]) => [\n name,\n c instanceof MongoCollection ? c : new MongoCollection(c),\n ]),\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(\n blindCast<\n MongoNamespaceCollectionsInput,\n 'non-materialized Mongo namespace map entry is a MongoNamespaceCollectionsInput'\n >(ns),\n ),\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 entries: {\n readonly collection: Record<string, MongoCollection | MongoCollectionInput>;\n };\n}\n\n// Mongo concretions store `MongoCollection` instances under\n// `entries.collection` (Mongo idiom — distinct from the SQL family's\n// `entries.table`). Narrowing the namespace map here lets target/family-\n// level consumers iterate collection slots and recover the concrete type\n// without the framework's wider `Namespace` tripping them up.\nexport type MongoNamespace = Namespace & {\n readonly entries: Readonly<{\n readonly collection: Readonly<Record<string, MongoCollection>>;\n }>;\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, MongoModelDefinition } 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.entries.collection, 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 [namespaceId, namespace] of Object.entries(contract.domain.namespaces)) {\n const models = namespace.models as Record<string, MongoModelDefinition>;\n for (const [modelName, model] of Object.entries(models)) {\n const qualifiedName = `${namespaceId}:${modelName}`;\n if (\n model.storage.collection &&\n !storageDeclaresCollection(contract.storage, model.storage.collection)\n ) {\n errors.push(\n `Model \"${qualifiedName}\" 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 = 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 \"${qualifiedName}\" 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 = 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 \"${qualifiedName}\"`,\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 \"${qualifiedName}\"`,\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\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,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/mongo-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0-dev.2",
|
|
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.
|
|
10
|
-
"@prisma-next/framework-components": "0.
|
|
11
|
-
"@prisma-next/utils": "0.
|
|
9
|
+
"@prisma-next/contract": "0.13.0-dev.2",
|
|
10
|
+
"@prisma-next/framework-components": "0.13.0-dev.2",
|
|
11
|
+
"@prisma-next/utils": "0.13.0-dev.2",
|
|
12
12
|
"arktype": "^2.2.0"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@prisma-next/test-utils": "0.
|
|
16
|
-
"@prisma-next/tsconfig": "0.
|
|
17
|
-
"@prisma-next/tsdown": "0.
|
|
18
|
-
"tsdown": "0.22.
|
|
15
|
+
"@prisma-next/test-utils": "0.13.0-dev.2",
|
|
16
|
+
"@prisma-next/tsconfig": "0.13.0-dev.2",
|
|
17
|
+
"@prisma-next/tsdown": "0.13.0-dev.2",
|
|
18
|
+
"tsdown": "0.22.1",
|
|
19
19
|
"typescript": "5.9.3",
|
|
20
|
-
"vitest": "4.1.
|
|
20
|
+
"vitest": "4.1.8"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"typescript": ">=5.9"
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsdown",
|
|
50
|
-
"test": "vitest run
|
|
50
|
+
"test": "vitest run",
|
|
51
51
|
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
52
52
|
"typecheck": "tsc --noEmit",
|
|
53
53
|
"lint": "biome check . --error-on-warnings",
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from '@prisma-next/contract/hashing-utils';
|
|
6
6
|
|
|
7
7
|
const preserveEmptyPatterns = [
|
|
8
|
-
['storage', 'namespaces', '*', '
|
|
9
|
-
['storage', 'namespaces', '*', '
|
|
8
|
+
['storage', 'namespaces', '*', 'entries', 'collection'],
|
|
9
|
+
['storage', 'namespaces', '*', 'entries', 'collection', '*'],
|
|
10
10
|
] as const satisfies readonly PathPattern[];
|
|
11
11
|
|
|
12
12
|
const matchesPreserveEmptyPattern = createPreserveEmptyPredicate(preserveEmptyPatterns);
|
package/src/contract-schema.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { CrossReferenceSchema } from '@prisma-next/contract/types';
|
|
|
2
2
|
import { type Type, type } from 'arktype';
|
|
3
3
|
import type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';
|
|
4
4
|
|
|
5
|
+
const ControlPolicySchema = type("'managed' | 'tolerated' | 'external' | 'observed'");
|
|
6
|
+
|
|
5
7
|
const ScalarFieldTypeSchema = type({
|
|
6
8
|
'+': 'reject',
|
|
7
9
|
kind: "'scalar'",
|
|
@@ -316,6 +318,7 @@ const StorageCollectionSchema = type({
|
|
|
316
318
|
'indexes?': MongoStorageIndexSchema.array(),
|
|
317
319
|
'validator?': MongoStorageValidatorSchema,
|
|
318
320
|
'options?': MongoCollectionOptionsSchema,
|
|
321
|
+
'control?': ControlPolicySchema,
|
|
319
322
|
});
|
|
320
323
|
|
|
321
324
|
function collectionEntrySchema(fragments?: ReadonlyMap<string, Type<unknown>>): Type<unknown> {
|
|
@@ -363,7 +366,20 @@ export function createMongoNamespaceEnvelopeSchema(
|
|
|
363
366
|
'+': 'reject',
|
|
364
367
|
id: 'string',
|
|
365
368
|
'kind?': 'string',
|
|
366
|
-
|
|
369
|
+
entries: type({
|
|
370
|
+
'collection?': type({ '[string]': collectionEntrySchema(fragments) }),
|
|
371
|
+
}),
|
|
372
|
+
}).narrow((ns, ctx) => {
|
|
373
|
+
if (typeof ns !== 'object' || ns === null || Array.isArray(ns)) {
|
|
374
|
+
return ctx.mustBe('an object');
|
|
375
|
+
}
|
|
376
|
+
if (Object.hasOwn(ns, 'collections') || Object.hasOwn(ns, 'tables')) {
|
|
377
|
+
return ctx.reject({
|
|
378
|
+
expected:
|
|
379
|
+
'namespace must use `entries: { collection? }`; flat `collections` / `tables` keys are no longer accepted',
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
return true;
|
|
367
383
|
}) as Type<unknown>;
|
|
368
384
|
}
|
|
369
385
|
|
|
@@ -387,6 +403,7 @@ export function createMongoContractSchema(
|
|
|
387
403
|
'capabilities?': 'Record<string, unknown>',
|
|
388
404
|
'extensionPacks?': 'Record<string, unknown>',
|
|
389
405
|
'meta?': 'Record<string, unknown>',
|
|
406
|
+
'defaultControlPolicy?': ControlPolicySchema,
|
|
390
407
|
'sources?': 'Record<string, unknown>',
|
|
391
408
|
'_generated?': 'Record<string, unknown>',
|
|
392
409
|
domain: type({
|
package/src/contract-types.ts
CHANGED
|
@@ -2,9 +2,9 @@ import type {
|
|
|
2
2
|
Contract,
|
|
3
3
|
ContractField,
|
|
4
4
|
ContractModel,
|
|
5
|
-
|
|
5
|
+
ContractModelDefinitions,
|
|
6
6
|
ContractValueObject,
|
|
7
|
-
|
|
7
|
+
ContractValueObjectDefinitions,
|
|
8
8
|
StorageBase,
|
|
9
9
|
} from '@prisma-next/contract/types';
|
|
10
10
|
import type { Namespace } from '@prisma-next/framework-components/ir';
|
|
@@ -63,7 +63,9 @@ export type MongoStorageShape<THash extends string = string> = StorageBase<THash
|
|
|
63
63
|
readonly namespaces: Record<
|
|
64
64
|
string,
|
|
65
65
|
Namespace & {
|
|
66
|
-
readonly
|
|
66
|
+
readonly entries: Readonly<{
|
|
67
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
68
|
+
}>;
|
|
67
69
|
}
|
|
68
70
|
>;
|
|
69
71
|
};
|
|
@@ -74,13 +76,13 @@ export type MongoContract<
|
|
|
74
76
|
> = Contract<S, M>;
|
|
75
77
|
|
|
76
78
|
/** Model map inferred from a {@link MongoContract} (domain.namespaces union). */
|
|
77
|
-
export type MongoModelsMap<TContract extends MongoContract> =
|
|
79
|
+
export type MongoModelsMap<TContract extends MongoContract> = ContractModelDefinitions<TContract>;
|
|
78
80
|
|
|
79
81
|
export type RootModelName<
|
|
80
82
|
TContract extends MongoContract,
|
|
81
83
|
RootName extends keyof TContract['roots'] & string,
|
|
82
84
|
> = TContract['roots'][RootName] extends { readonly model: infer M extends string }
|
|
83
|
-
? M & keyof import('@prisma-next/contract/types').
|
|
85
|
+
? M & keyof import('@prisma-next/contract/types').ContractModelDefinitions<TContract>
|
|
84
86
|
: never;
|
|
85
87
|
|
|
86
88
|
export type MongoTypeMaps<
|
|
@@ -130,7 +132,7 @@ export type ExtractMongoFieldInputTypes<T> =
|
|
|
130
132
|
: Record<string, never>
|
|
131
133
|
: Record<string, never>;
|
|
132
134
|
|
|
133
|
-
type ExtractValueObjects<TContract extends Contract> =
|
|
135
|
+
type ExtractValueObjects<TContract extends Contract> = ContractValueObjectDefinitions<TContract>;
|
|
134
136
|
|
|
135
137
|
type NormalizeContractFields<TFields> = {
|
|
136
138
|
[K in keyof TFields]: TFields[K] extends ContractField ? TFields[K] : never;
|
|
@@ -182,8 +184,11 @@ type InferFieldType<
|
|
|
182
184
|
|
|
183
185
|
export type InferModelRow<
|
|
184
186
|
TContract extends MongoContractWithTypeMaps<MongoContract, MongoTypeMaps>,
|
|
185
|
-
ModelName extends string & keyof
|
|
186
|
-
TFields extends Record<
|
|
187
|
+
ModelName extends string & keyof ContractModelDefinitions<TContract>,
|
|
188
|
+
TFields extends Record<
|
|
189
|
+
string,
|
|
190
|
+
ContractField
|
|
191
|
+
> = ContractModelDefinitions<TContract>[ModelName]['fields'],
|
|
187
192
|
TCodecTypes extends Record<string, { output: unknown }> = ExtractMongoCodecTypes<TContract>,
|
|
188
193
|
TValueObjects extends Record<string, ContractValueObject> = ExtractValueObjects<TContract>,
|
|
189
194
|
> = {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UNBOUND_DOMAIN_NAMESPACE_ID } from '@prisma-next/contract/default-namespace';
|
|
2
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
3
|
+
|
|
4
|
+
/** Default storage namespace for Mongo-family contracts at runtime. */
|
|
5
|
+
export const defaultMongoStorageNamespaceId = UNBOUND_NAMESPACE_ID;
|
|
6
|
+
|
|
7
|
+
/** Default domain namespace for Mongo-family contracts at runtime. */
|
|
8
|
+
export const defaultMongoDomainNamespaceId = UNBOUND_DOMAIN_NAMESPACE_ID;
|
package/src/exports/index.ts
CHANGED
|
@@ -28,6 +28,10 @@ export type {
|
|
|
28
28
|
MongoWildcardProjection,
|
|
29
29
|
RootModelName,
|
|
30
30
|
} from '../contract-types';
|
|
31
|
+
export {
|
|
32
|
+
defaultMongoDomainNamespaceId,
|
|
33
|
+
defaultMongoStorageNamespaceId,
|
|
34
|
+
} from '../default-namespace';
|
|
31
35
|
export { buildMongoNamespace, buildMongoNamespaceMap } from '../ir/build-mongo-namespace';
|
|
32
36
|
export type { MongoChangeStreamPreAndPostImagesOptionsInput } from '../ir/mongo-change-stream-pre-and-post-images-options';
|
|
33
37
|
export { MongoChangeStreamPreAndPostImagesOptions } from '../ir/mongo-change-stream-pre-and-post-images-options';
|
|
@@ -28,10 +28,12 @@ class MongoBoundNamespace extends NamespaceBase {
|
|
|
28
28
|
declare readonly kind: string;
|
|
29
29
|
|
|
30
30
|
readonly id: string;
|
|
31
|
-
readonly
|
|
31
|
+
readonly entries: Readonly<{
|
|
32
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
33
|
+
}>;
|
|
32
34
|
|
|
33
35
|
static fromCollectionsInput(input: MongoNamespaceCollectionsInput): MongoNamespace {
|
|
34
|
-
const collectionCount = Object.keys(input.
|
|
36
|
+
const collectionCount = Object.keys(input.entries.collection).length;
|
|
35
37
|
if (input.id === UNBOUND_NAMESPACE_ID && collectionCount === 0) {
|
|
36
38
|
return castAs<MongoNamespace>(MongoUnboundNamespace.instance);
|
|
37
39
|
}
|
|
@@ -41,14 +43,16 @@ class MongoBoundNamespace extends NamespaceBase {
|
|
|
41
43
|
private constructor(input: MongoNamespaceCollectionsInput) {
|
|
42
44
|
super();
|
|
43
45
|
this.id = input.id;
|
|
44
|
-
this.
|
|
45
|
-
Object.
|
|
46
|
-
Object.
|
|
47
|
-
name,
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
this.entries = Object.freeze({
|
|
47
|
+
collection: Object.freeze(
|
|
48
|
+
Object.fromEntries(
|
|
49
|
+
Object.entries(input.entries.collection).map(([name, c]) => [
|
|
50
|
+
name,
|
|
51
|
+
c instanceof MongoCollection ? c : new MongoCollection(c),
|
|
52
|
+
]),
|
|
53
|
+
),
|
|
50
54
|
),
|
|
51
|
-
);
|
|
55
|
+
});
|
|
52
56
|
Object.defineProperty(this, 'kind', {
|
|
53
57
|
value: MONGO_NAMESPACE_KIND,
|
|
54
58
|
writable: false,
|
|
@@ -74,7 +78,12 @@ export function buildMongoNamespaceMap(
|
|
|
74
78
|
MongoNamespace,
|
|
75
79
|
'a materialised Mongo-family namespace entry in a namespace map is a MongoNamespace'
|
|
76
80
|
>(ns)
|
|
77
|
-
: MongoBoundNamespace.fromCollectionsInput(
|
|
81
|
+
: MongoBoundNamespace.fromCollectionsInput(
|
|
82
|
+
blindCast<
|
|
83
|
+
MongoNamespaceCollectionsInput,
|
|
84
|
+
'non-materialized Mongo namespace map entry is a MongoNamespaceCollectionsInput'
|
|
85
|
+
>(ns),
|
|
86
|
+
),
|
|
78
87
|
]),
|
|
79
88
|
);
|
|
80
89
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ControlPolicy } from '@prisma-next/contract/types';
|
|
1
2
|
import { freezeNode, IRNodeBase } from '@prisma-next/framework-components/ir';
|
|
2
3
|
import {
|
|
3
4
|
MongoCollectionOptions,
|
|
@@ -9,7 +10,7 @@ import { MongoValidator, type MongoValidatorInput } from './mongo-validator';
|
|
|
9
10
|
/**
|
|
10
11
|
* Hydration / construction input shape for {@link MongoCollection}.
|
|
11
12
|
* Mirrors the on-disk storage JSON envelope exactly (the value held at
|
|
12
|
-
* `contract.storage.namespaces[<namespaceId>].
|
|
13
|
+
* `contract.storage.namespaces[<namespaceId>].entries.collection[<name>]`) so the family-base
|
|
13
14
|
* serializer's hydration walker can hand an arktype-validated literal
|
|
14
15
|
* straight to `new`. Nested IR-class fields may be supplied as either
|
|
15
16
|
* plain data literals (typical for JSON-derived input) or
|
|
@@ -19,6 +20,7 @@ export interface MongoCollectionInput {
|
|
|
19
20
|
readonly indexes?: ReadonlyArray<MongoIndex | MongoIndexInput>;
|
|
20
21
|
readonly validator?: MongoValidator | MongoValidatorInput;
|
|
21
22
|
readonly options?: MongoCollectionOptions | MongoCollectionOptionsInput;
|
|
23
|
+
readonly control?: ControlPolicy;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -46,6 +48,7 @@ export class MongoCollection extends IRNodeBase {
|
|
|
46
48
|
declare readonly indexes?: ReadonlyArray<MongoIndex>;
|
|
47
49
|
declare readonly validator?: MongoValidator;
|
|
48
50
|
declare readonly options?: MongoCollectionOptions;
|
|
51
|
+
declare readonly control?: ControlPolicy;
|
|
49
52
|
|
|
50
53
|
constructor(input: MongoCollectionInput = {}) {
|
|
51
54
|
super();
|
|
@@ -66,6 +69,7 @@ export class MongoCollection extends IRNodeBase {
|
|
|
66
69
|
? input.options
|
|
67
70
|
: new MongoCollectionOptions(input.options);
|
|
68
71
|
}
|
|
72
|
+
if (input.control !== undefined) this.control = input.control;
|
|
69
73
|
freezeNode(this);
|
|
70
74
|
}
|
|
71
75
|
}
|
package/src/ir/mongo-storage.ts
CHANGED
|
@@ -9,17 +9,20 @@ import type { MongoCollection, MongoCollectionInput } from './mongo-collection';
|
|
|
9
9
|
|
|
10
10
|
export interface MongoNamespaceCollectionsInput {
|
|
11
11
|
readonly id: string;
|
|
12
|
-
readonly
|
|
12
|
+
readonly entries: {
|
|
13
|
+
readonly collection: Record<string, MongoCollection | MongoCollectionInput>;
|
|
14
|
+
};
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
// Mongo concretions
|
|
16
|
-
// `
|
|
17
|
-
// Narrowing the namespace map here lets target/family-
|
|
18
|
-
// iterate
|
|
19
|
-
//
|
|
20
|
-
// them up.
|
|
17
|
+
// Mongo concretions store `MongoCollection` instances under
|
|
18
|
+
// `entries.collection` (Mongo idiom — distinct from the SQL family's
|
|
19
|
+
// `entries.table`). Narrowing the namespace map here lets target/family-
|
|
20
|
+
// level consumers iterate collection slots and recover the concrete type
|
|
21
|
+
// without the framework's wider `Namespace` tripping them up.
|
|
21
22
|
export type MongoNamespace = Namespace & {
|
|
22
|
-
readonly
|
|
23
|
+
readonly entries: Readonly<{
|
|
24
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
25
|
+
}>;
|
|
23
26
|
};
|
|
24
27
|
|
|
25
28
|
export interface MongoStorageInput<THash extends string = string> {
|
|
@@ -9,7 +9,9 @@ export class MongoUnboundNamespace extends NamespaceBase {
|
|
|
9
9
|
static readonly instance: MongoUnboundNamespace = new MongoUnboundNamespace();
|
|
10
10
|
|
|
11
11
|
readonly id = UNBOUND_NAMESPACE_ID;
|
|
12
|
-
readonly
|
|
12
|
+
readonly entries: Readonly<{
|
|
13
|
+
readonly collection: Readonly<Record<string, MongoCollection>>;
|
|
14
|
+
}> = Object.freeze({ collection: Object.freeze({}) });
|
|
13
15
|
declare readonly kind: string;
|
|
14
16
|
|
|
15
17
|
private constructor() {
|
package/src/validate-storage.ts
CHANGED
|
@@ -9,7 +9,7 @@ function storageDeclaresCollection(
|
|
|
9
9
|
collectionName: string,
|
|
10
10
|
): boolean {
|
|
11
11
|
for (const ns of Object.values(storage.namespaces)) {
|
|
12
|
-
if (Object.hasOwn(ns.
|
|
12
|
+
if (Object.hasOwn(ns.entries.collection, collectionName)) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
15
|
}
|