@prisma-next/mongo-contract 0.3.0-dev.146 → 0.3.0-dev.148
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/index.d.mts +101 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +113 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
- package/src/contract-schema.ts +164 -1
- package/src/contract-types.ts +138 -11
- package/src/exports/index.ts +23 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,100 @@
|
|
|
1
1
|
import { Contract, ContractField, ContractModel, ContractValueObject, StorageBase } from "@prisma-next/contract/types";
|
|
2
2
|
|
|
3
3
|
//#region src/contract-types.d.ts
|
|
4
|
-
type
|
|
4
|
+
type MongoIndexFieldValue = 1 | -1 | 'text' | '2dsphere' | '2d' | 'hashed';
|
|
5
|
+
type MongoIndexFields = Record<string, MongoIndexFieldValue>;
|
|
6
|
+
type MongoJsonPrimitive = string | number | boolean | null;
|
|
7
|
+
type MongoJsonValue = MongoJsonPrimitive | readonly MongoJsonValue[] | MongoJsonObject;
|
|
8
|
+
type MongoJsonObject = {
|
|
9
|
+
readonly [key: string]: MongoJsonValue;
|
|
10
|
+
};
|
|
11
|
+
type MongoCollationCaseFirst = 'off' | 'upper' | 'lower';
|
|
12
|
+
type MongoCollationStrength = 1 | 2 | 3 | 4 | 5;
|
|
13
|
+
type MongoCollationAlternate = 'non-ignorable' | 'shifted';
|
|
14
|
+
type MongoCollationMaxVariable = 'punct' | 'space';
|
|
15
|
+
type MongoCollationOptions = {
|
|
16
|
+
readonly locale: string;
|
|
17
|
+
readonly caseLevel?: boolean;
|
|
18
|
+
readonly caseFirst?: MongoCollationCaseFirst;
|
|
19
|
+
readonly strength?: MongoCollationStrength;
|
|
20
|
+
readonly numericOrdering?: boolean;
|
|
21
|
+
readonly alternate?: MongoCollationAlternate;
|
|
22
|
+
readonly maxVariable?: MongoCollationMaxVariable;
|
|
23
|
+
readonly backwards?: boolean;
|
|
24
|
+
readonly normalization?: boolean;
|
|
25
|
+
};
|
|
26
|
+
type MongoWildcardProjection = Readonly<Record<string, 0 | 1>>;
|
|
27
|
+
type MongoIndexOptions = {
|
|
28
|
+
readonly unique?: boolean;
|
|
29
|
+
readonly name?: string;
|
|
30
|
+
readonly partialFilterExpression?: MongoJsonObject;
|
|
31
|
+
readonly sparse?: boolean;
|
|
32
|
+
readonly expireAfterSeconds?: number;
|
|
33
|
+
readonly weights?: Readonly<Record<string, number>>;
|
|
34
|
+
readonly default_language?: string;
|
|
35
|
+
readonly language_override?: string;
|
|
36
|
+
readonly textIndexVersion?: number;
|
|
37
|
+
readonly '2dsphereIndexVersion'?: number;
|
|
38
|
+
readonly bits?: number;
|
|
39
|
+
readonly min?: number;
|
|
40
|
+
readonly max?: number;
|
|
41
|
+
readonly bucketSize?: number;
|
|
42
|
+
readonly hidden?: boolean;
|
|
43
|
+
readonly collation?: MongoCollationOptions;
|
|
44
|
+
readonly wildcardProjection?: MongoWildcardProjection;
|
|
45
|
+
};
|
|
46
|
+
type MongoIndex = {
|
|
47
|
+
readonly fields: MongoIndexFields;
|
|
48
|
+
readonly options?: MongoIndexOptions;
|
|
49
|
+
};
|
|
50
|
+
type MongoIndexOptionDefaults = {
|
|
51
|
+
readonly storageEngine?: MongoJsonObject;
|
|
52
|
+
};
|
|
53
|
+
type MongoTimeSeriesGranularity = 'seconds' | 'minutes' | 'hours';
|
|
54
|
+
type MongoTimeSeriesCollectionOptions = {
|
|
55
|
+
readonly timeField: string;
|
|
56
|
+
readonly metaField?: string;
|
|
57
|
+
readonly granularity?: MongoTimeSeriesGranularity;
|
|
58
|
+
readonly bucketMaxSpanSeconds?: number;
|
|
59
|
+
readonly bucketRoundingSeconds?: number;
|
|
60
|
+
};
|
|
61
|
+
type MongoClusteredCollectionKey = Readonly<Record<string, 1>>;
|
|
62
|
+
type MongoClusteredCollectionOptions = {
|
|
63
|
+
readonly name?: string;
|
|
64
|
+
readonly key: MongoClusteredCollectionKey;
|
|
65
|
+
readonly unique: boolean;
|
|
66
|
+
};
|
|
67
|
+
type MongoChangeStreamPreAndPostImagesOptions = {
|
|
68
|
+
readonly enabled: boolean;
|
|
69
|
+
};
|
|
70
|
+
type MongoCollectionOptions = {
|
|
71
|
+
readonly capped?: boolean;
|
|
72
|
+
readonly size?: number;
|
|
73
|
+
readonly max?: number;
|
|
74
|
+
readonly storageEngine?: MongoJsonObject;
|
|
75
|
+
readonly indexOptionDefaults?: MongoIndexOptionDefaults;
|
|
76
|
+
readonly collation?: MongoCollationOptions;
|
|
77
|
+
readonly timeseries?: MongoTimeSeriesCollectionOptions;
|
|
78
|
+
readonly clusteredIndex?: MongoClusteredCollectionOptions;
|
|
79
|
+
readonly expireAfterSeconds?: number;
|
|
80
|
+
readonly changeStreamPreAndPostImages?: MongoChangeStreamPreAndPostImagesOptions;
|
|
81
|
+
};
|
|
82
|
+
type MongoIndexKeyDirection = 1 | -1 | 'text' | '2dsphere' | '2d' | 'hashed';
|
|
83
|
+
interface MongoIndexKey {
|
|
84
|
+
readonly field: string;
|
|
85
|
+
readonly direction: MongoIndexKeyDirection;
|
|
86
|
+
}
|
|
87
|
+
interface MongoStorageIndex {
|
|
88
|
+
readonly keys: ReadonlyArray<MongoIndexKey>;
|
|
89
|
+
readonly unique?: boolean;
|
|
90
|
+
readonly sparse?: boolean;
|
|
91
|
+
readonly expireAfterSeconds?: number;
|
|
92
|
+
readonly partialFilterExpression?: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
interface MongoStorageCollection {
|
|
95
|
+
readonly indexes?: readonly MongoIndex[];
|
|
96
|
+
readonly options?: MongoCollectionOptions;
|
|
97
|
+
}
|
|
5
98
|
type MongoStorage<THash extends string = string> = StorageBase<THash> & {
|
|
6
99
|
readonly collections: Record<string, MongoStorageCollection>;
|
|
7
100
|
};
|
|
@@ -36,6 +129,8 @@ type ExtractMongoFieldOutputTypes<T> = ExtractMongoTypeMaps<T> extends {
|
|
|
36
129
|
type ExtractValueObjects<TContract> = TContract extends {
|
|
37
130
|
valueObjects: infer VO extends Record<string, ContractValueObject>;
|
|
38
131
|
} ? VO : Record<never, never>;
|
|
132
|
+
type NormalizeContractFields<TFields> = { [K in keyof TFields]: TFields[K] extends ContractField ? TFields[K] : never };
|
|
133
|
+
type ExtractValueObjectFields<TValueObjects extends Record<string, ContractValueObject>, VOName$1 extends keyof TValueObjects> = NormalizeContractFields<TValueObjects[VOName$1]['fields']>;
|
|
39
134
|
type InferFieldBaseType<TFieldType, TValueObjects extends Record<string, ContractValueObject>, TCodecTypes extends Record<string, {
|
|
40
135
|
output: unknown;
|
|
41
136
|
}>> = TFieldType extends {
|
|
@@ -44,15 +139,15 @@ type InferFieldBaseType<TFieldType, TValueObjects extends Record<string, Contrac
|
|
|
44
139
|
} ? TCodecTypes[CId]['output'] : TFieldType extends {
|
|
45
140
|
kind: 'valueObject';
|
|
46
141
|
name: infer VOName extends string;
|
|
47
|
-
} ? VOName extends keyof TValueObjects ? { -readonly [K in keyof TValueObjects
|
|
142
|
+
} ? VOName extends keyof TValueObjects ? { -readonly [K in keyof ExtractValueObjectFields<TValueObjects, VOName>]: InferFieldType<ExtractValueObjectFields<TValueObjects, VOName>[K], TValueObjects, TCodecTypes> } : unknown : TFieldType extends {
|
|
48
143
|
kind: 'union';
|
|
49
144
|
members: infer TMembers extends ReadonlyArray<unknown>;
|
|
50
145
|
} ? TMembers[number] extends infer TMember ? InferFieldBaseType<TMember, TValueObjects, TCodecTypes> : unknown : unknown;
|
|
51
|
-
type InferFieldType<TField
|
|
146
|
+
type InferFieldType<TField, TValueObjects extends Record<string, ContractValueObject>, TCodecTypes extends Record<string, {
|
|
52
147
|
output: unknown;
|
|
53
|
-
}>> = TField extends {
|
|
148
|
+
}>> = TField extends ContractField ? TField extends {
|
|
54
149
|
many: true;
|
|
55
|
-
} ? 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
|
|
150
|
+
} ? 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;
|
|
56
151
|
type InferModelRow<TContract extends MongoContractWithTypeMaps<MongoContract, MongoTypeMaps>, ModelName extends string & keyof TContract['models'], TFields extends Record<string, ContractField> = TContract['models'][ModelName]['fields'], TCodecTypes extends Record<string, {
|
|
57
152
|
output: unknown;
|
|
58
153
|
}> = ExtractMongoCodecTypes<TContract>, TValueObjects extends Record<string, ContractValueObject> = ExtractValueObjects<TContract>> = { -readonly [FieldName in keyof TFields]: InferFieldType<TFields[FieldName], TValueObjects, TCodecTypes> };
|
|
@@ -71,5 +166,5 @@ declare function validateMongoContract<TContract extends MongoContract>(value: u
|
|
|
71
166
|
//#region src/validate-storage.d.ts
|
|
72
167
|
declare function validateMongoStorage(contract: MongoContract): void;
|
|
73
168
|
//#endregion
|
|
74
|
-
export { type ExtractMongoCodecTypes, type ExtractMongoFieldOutputTypes, type ExtractMongoTypeMaps, type InferModelRow, type MongoContract, type MongoContractIndices, type MongoContractWithTypeMaps, type MongoModelDefinition, type MongoModelStorage, type MongoStorage, type MongoStorageCollection, type MongoTypeMaps, type MongoTypeMapsPhantomKey, type ValidatedMongoContract, validateMongoContract, validateMongoStorage };
|
|
169
|
+
export { type ExtractMongoCodecTypes, type ExtractMongoFieldOutputTypes, type ExtractMongoTypeMaps, type InferModelRow, type MongoChangeStreamPreAndPostImagesOptions, type MongoClusteredCollectionKey, type MongoClusteredCollectionOptions, type MongoCollationAlternate, type MongoCollationCaseFirst, type MongoCollationMaxVariable, type MongoCollationOptions, type MongoCollationStrength, type MongoCollectionOptions, type MongoContract, type MongoContractIndices, type MongoContractWithTypeMaps, type MongoIndex, type MongoIndexFieldValue, type MongoIndexFields, type MongoIndexKey, type MongoIndexKeyDirection, type MongoIndexOptionDefaults, type MongoIndexOptions, type MongoJsonObject, type MongoJsonPrimitive, type MongoJsonValue, type MongoModelDefinition, type MongoModelStorage, type MongoStorage, type MongoStorageCollection, type MongoStorageIndex, type MongoTimeSeriesCollectionOptions, type MongoTimeSeriesGranularity, type MongoTypeMaps, type MongoTypeMapsPhantomKey, type MongoWildcardProjection, type ValidatedMongoContract, validateMongoContract, validateMongoStorage };
|
|
75
170
|
//# 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-types.ts","../src/validate-mongo-contract.ts","../src/validate-storage.ts"],"sourcesContent":[],"mappings":";;;KAQY,sBAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/contract-types.ts","../src/validate-mongo-contract.ts","../src/validate-storage.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -44,6 +44,85 @@ const StorageRelationEntrySchema = type({
|
|
|
44
44
|
"+": "reject",
|
|
45
45
|
field: "string"
|
|
46
46
|
});
|
|
47
|
+
const MongoJsonPrimitiveSchema = type.declare().type("string | number | boolean | null");
|
|
48
|
+
function isMongoJsonRecord(value) {
|
|
49
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
50
|
+
const prototype = Object.getPrototypeOf(value);
|
|
51
|
+
return prototype === Object.prototype || prototype === null;
|
|
52
|
+
}
|
|
53
|
+
function withUnseenReference(value, seen, visit) {
|
|
54
|
+
if (seen.has(value)) return false;
|
|
55
|
+
seen.add(value);
|
|
56
|
+
const result = visit();
|
|
57
|
+
seen.delete(value);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
function isMongoJsonObject(value, seen) {
|
|
61
|
+
return isMongoJsonRecord(value) && withUnseenReference(value, seen, () => Object.values(value).every((entry) => isMongoJsonValue(entry, seen)));
|
|
62
|
+
}
|
|
63
|
+
function isMongoJsonValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
64
|
+
if (MongoJsonPrimitiveSchema.allows(value)) return true;
|
|
65
|
+
if (Array.isArray(value)) return withUnseenReference(value, seen, () => value.every((entry) => isMongoJsonValue(entry, seen)));
|
|
66
|
+
return isMongoJsonObject(value, seen);
|
|
67
|
+
}
|
|
68
|
+
const MongoJsonValueSchema = type("unknown").narrow((value, ctx) => isMongoJsonValue(value) ? true : ctx.mustBe("a JSON-serializable MongoJsonValue"));
|
|
69
|
+
const MongoJsonObjectSchema = type({ "[string]": "unknown" }).narrow((value, ctx) => isMongoJsonRecord(value) && Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry)) ? true : ctx.mustBe("a JSON object with MongoJsonValue entries"));
|
|
70
|
+
const NumberRecordSchema = type({ "[string]": "number" });
|
|
71
|
+
const IndexFieldsSchema = type({
|
|
72
|
+
"+": "reject",
|
|
73
|
+
"[string]": "1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\""
|
|
74
|
+
}).narrow((fields, ctx) => Object.keys(fields).length > 0 ? true : ctx.mustBe("an index field map with at least one entry"));
|
|
75
|
+
const CollationSchema = type({
|
|
76
|
+
"+": "reject",
|
|
77
|
+
locale: "string",
|
|
78
|
+
"caseLevel?": "boolean",
|
|
79
|
+
"caseFirst?": "\"off\" | \"upper\" | \"lower\"",
|
|
80
|
+
"strength?": "1 | 2 | 3 | 4 | 5",
|
|
81
|
+
"numericOrdering?": "boolean",
|
|
82
|
+
"alternate?": "\"non-ignorable\" | \"shifted\"",
|
|
83
|
+
"maxVariable?": "\"punct\" | \"space\"",
|
|
84
|
+
"backwards?": "boolean",
|
|
85
|
+
"normalization?": "boolean"
|
|
86
|
+
});
|
|
87
|
+
const IndexOptionDefaultsSchema = type({
|
|
88
|
+
"+": "reject",
|
|
89
|
+
"storageEngine?": MongoJsonObjectSchema
|
|
90
|
+
});
|
|
91
|
+
const TimeSeriesCollectionOptionsSchema = type({
|
|
92
|
+
"+": "reject",
|
|
93
|
+
timeField: "string",
|
|
94
|
+
"metaField?": "string",
|
|
95
|
+
"granularity?": "\"seconds\" | \"minutes\" | \"hours\"",
|
|
96
|
+
"bucketMaxSpanSeconds?": "number",
|
|
97
|
+
"bucketRoundingSeconds?": "number"
|
|
98
|
+
});
|
|
99
|
+
const ClusteredCollectionKeySchema = type({
|
|
100
|
+
"+": "reject",
|
|
101
|
+
"[string]": "1"
|
|
102
|
+
}).narrow((key, ctx) => Object.keys(key).length > 0 ? true : ctx.mustBe("a clustered index key map with at least one entry"));
|
|
103
|
+
const ClusteredCollectionOptionsSchema = type({
|
|
104
|
+
"+": "reject",
|
|
105
|
+
"name?": "string",
|
|
106
|
+
key: ClusteredCollectionKeySchema,
|
|
107
|
+
unique: "boolean"
|
|
108
|
+
});
|
|
109
|
+
const ChangeStreamPreAndPostImagesSchema = type({
|
|
110
|
+
"+": "reject",
|
|
111
|
+
enabled: "boolean"
|
|
112
|
+
});
|
|
113
|
+
const CollectionOptionsSchema = type({
|
|
114
|
+
"+": "reject",
|
|
115
|
+
"capped?": "boolean",
|
|
116
|
+
"size?": "number",
|
|
117
|
+
"max?": "number",
|
|
118
|
+
"storageEngine?": MongoJsonObjectSchema,
|
|
119
|
+
"indexOptionDefaults?": IndexOptionDefaultsSchema,
|
|
120
|
+
"collation?": CollationSchema,
|
|
121
|
+
"timeseries?": TimeSeriesCollectionOptionsSchema,
|
|
122
|
+
"clusteredIndex?": ClusteredCollectionOptionsSchema,
|
|
123
|
+
"expireAfterSeconds?": "number",
|
|
124
|
+
"changeStreamPreAndPostImages?": ChangeStreamPreAndPostImagesSchema
|
|
125
|
+
});
|
|
47
126
|
const ModelStorageSchema = type({
|
|
48
127
|
"+": "reject",
|
|
49
128
|
"collection?": "string",
|
|
@@ -67,7 +146,40 @@ const ModelDefinitionSchema = type({
|
|
|
67
146
|
"base?": "string",
|
|
68
147
|
"owner?": "string"
|
|
69
148
|
});
|
|
70
|
-
const
|
|
149
|
+
const WildcardProjectionSchema = type({
|
|
150
|
+
"+": "reject",
|
|
151
|
+
"[string]": "0 | 1"
|
|
152
|
+
});
|
|
153
|
+
const IndexOptionsSchema = type({
|
|
154
|
+
"+": "reject",
|
|
155
|
+
"unique?": "boolean",
|
|
156
|
+
"name?": "string",
|
|
157
|
+
"partialFilterExpression?": MongoJsonObjectSchema,
|
|
158
|
+
"sparse?": "boolean",
|
|
159
|
+
"expireAfterSeconds?": "number",
|
|
160
|
+
"weights?": NumberRecordSchema,
|
|
161
|
+
"default_language?": "string",
|
|
162
|
+
"language_override?": "string",
|
|
163
|
+
"textIndexVersion?": "number",
|
|
164
|
+
"2dsphereIndexVersion?": "number",
|
|
165
|
+
"bits?": "number",
|
|
166
|
+
"min?": "number",
|
|
167
|
+
"max?": "number",
|
|
168
|
+
"bucketSize?": "number",
|
|
169
|
+
"hidden?": "boolean",
|
|
170
|
+
"collation?": CollationSchema,
|
|
171
|
+
"wildcardProjection?": WildcardProjectionSchema
|
|
172
|
+
});
|
|
173
|
+
const IndexSchema = type({
|
|
174
|
+
"+": "reject",
|
|
175
|
+
fields: IndexFieldsSchema,
|
|
176
|
+
"options?": IndexOptionsSchema
|
|
177
|
+
});
|
|
178
|
+
const StorageCollectionSchema = type({
|
|
179
|
+
"+": "reject",
|
|
180
|
+
"indexes?": IndexSchema.array(),
|
|
181
|
+
"options?": CollectionOptionsSchema
|
|
182
|
+
});
|
|
71
183
|
const MongoContractSchema = type({
|
|
72
184
|
"+": "reject",
|
|
73
185
|
targetFamily: "'mongo'",
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["errors: string[]","arktypeType","variantToBase: Record<string, string>","modelToVariants: Record<string, string[]>"],"sources":["../src/contract-schema.ts","../src/validate-storage.ts","../src/validate-mongo-contract.ts"],"sourcesContent":["import { type } from 'arktype';\n\nconst ScalarFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'scalar'\",\n codecId: 'string',\n 'typeParams?': 'Record<string, unknown>',\n});\n\nconst ValueObjectFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'valueObject'\",\n name: 'string',\n});\n\nconst UnionFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'union'\",\n members: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).array(),\n});\n\nconst FieldTypeSchema = ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).or(\n UnionFieldTypeSchema,\n);\n\nconst RawFieldSchema = type({\n '+': 'reject',\n type: FieldTypeSchema,\n 'nullable?': 'boolean',\n 'many?': 'boolean',\n 'dict?': 'boolean',\n});\n\nconst FieldSchema = RawFieldSchema.pipe((field) => ({\n ...field,\n nullable: field.nullable ?? false,\n}));\n\nconst RelationOnSchema = type({\n '+': 'reject',\n localFields: 'string[]',\n targetFields: 'string[]',\n});\n\nconst RelationSchema = type({\n '+': 'reject',\n to: 'string',\n cardinality: \"'1:1' | '1:N' | 'N:1'\",\n 'on?': RelationOnSchema,\n});\n\nconst StorageRelationEntrySchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst ModelStorageSchema = type({\n '+': 'reject',\n 'collection?': 'string',\n 'relations?': type({ '[string]': StorageRelationEntrySchema }),\n});\n\nconst DiscriminatorSchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst VariantEntrySchema = type({\n '+': 'reject',\n value: 'string',\n});\n\nconst ModelDefinitionSchema = type({\n '+': 'reject',\n fields: type({ '[string]': FieldSchema }),\n storage: ModelStorageSchema,\n 'relations?': type({ '[string]': RelationSchema }),\n 'discriminator?': DiscriminatorSchema,\n 'variants?': type({ '[string]': VariantEntrySchema }),\n 'base?': 'string',\n 'owner?': 'string',\n});\n\nconst StorageCollectionSchema = type({ '+': 'reject' });\n\nexport const MongoContractSchema = type({\n '+': 'reject',\n targetFamily: \"'mongo'\",\n 'schemaVersion?': 'string',\n 'target?': 'string',\n 'storageHash?': 'string',\n 'profileHash?': 'string',\n roots: 'Record<string, string>',\n 'capabilities?': 'Record<string, unknown>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': 'Record<string, unknown>',\n 'sources?': 'Record<string, unknown>',\n '_generated?': 'Record<string, unknown>',\n storage: type({\n '+': 'reject',\n collections: type({ '[string]': StorageCollectionSchema }),\n 'storageHash?': 'string',\n }),\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n});\n","import type { MongoContract } from './contract-types';\n\nexport function validateMongoStorage(contract: MongoContract): void {\n const errors: string[] = [];\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (model.storage.collection && !(model.storage.collection in contract.storage.collections)) {\n errors.push(\n `Model \"${modelName}\" references collection \"${model.storage.collection}\" which is not in storage.collections`,\n );\n }\n\n // Mongo does not support multi-table inheritance (ADR 2): all variants of a base\n // must share the same collection (single-table inheritance only).\n if (model.base) {\n const baseModel = contract.models[model.base];\n if (baseModel) {\n const variantCollection = model.storage.collection;\n const baseCollection = baseModel.storage.collection;\n if (variantCollection !== baseCollection) {\n errors.push(\n `Mongo does not support multi-table inheritance; variant \"${modelName}\" must share its base's collection (\"${baseCollection ?? '(none)'}\"), but has \"${variantCollection ?? '(none)'}\"`,\n );\n }\n }\n }\n\n for (const [relName, relation] of Object.entries(model.relations ?? {})) {\n const targetModel = contract.models[relation.to];\n\n if (targetModel?.owner) {\n if (targetModel.owner !== modelName) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which is owned by \"${targetModel.owner}\", not \"${modelName}\"`,\n );\n }\n if (targetModel.storage.collection) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which must not have a collection`,\n );\n }\n } else if ('on' in relation && relation.on) {\n for (const localField of relation.on.localFields) {\n if (!(localField in model.fields)) {\n errors.push(\n `Reference relation \"${relName}\": localField \"${localField}\" is not a field on model \"${modelName}\"`,\n );\n }\n }\n\n if (targetModel) {\n for (const targetField of relation.on.targetFields) {\n if (!(targetField in targetModel.fields)) {\n errors.push(\n `Reference relation \"${relName}\": targetField \"${targetField}\" is not a field on model \"${relation.to}\"`,\n );\n }\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(`Contract storage validation failed:\\n- ${errors.join('\\n- ')}`);\n }\n}\n","import { validateContractDomain } from '@prisma-next/contract/validate-domain';\nimport { type as arktypeType } from 'arktype';\nimport { MongoContractSchema } from './contract-schema';\nimport type { MongoContract } from './contract-types';\nimport { validateMongoStorage } from './validate-storage';\n\nexport interface MongoContractIndices {\n readonly variantToBase: Record<string, string>;\n readonly modelToVariants: Record<string, string[]>;\n}\n\nexport interface ValidatedMongoContract<TContract extends MongoContract> {\n readonly contract: TContract;\n readonly indices: MongoContractIndices;\n}\n\nexport function validateMongoContract<TContract extends MongoContract>(\n value: unknown,\n): ValidatedMongoContract<TContract> {\n const parsed = MongoContractSchema(value);\n if (parsed instanceof arktypeType.errors) {\n throw new Error(`Contract structural validation failed: ${parsed.summary}`);\n }\n\n const contract = parsed as unknown as TContract;\n\n validateContractDomain(contract);\n validateMongoStorage(contract);\n\n const indices = buildIndices(contract);\n\n return { contract, indices };\n}\n\nfunction buildIndices(contract: MongoContract): MongoContractIndices {\n const variantToBase: Record<string, string> = {};\n const modelToVariants: Record<string, string[]> = {};\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (model.base) {\n variantToBase[modelName] = model.base;\n }\n if (model.variants) {\n modelToVariants[modelName] = Object.keys(model.variants);\n }\n }\n\n return { variantToBase, modelToVariants };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["errors: string[]","arktypeType","variantToBase: Record<string, string>","modelToVariants: Record<string, string[]>"],"sources":["../src/contract-schema.ts","../src/validate-storage.ts","../src/validate-mongo-contract.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';\n\nconst ScalarFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'scalar'\",\n codecId: 'string',\n 'typeParams?': 'Record<string, unknown>',\n});\n\nconst ValueObjectFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'valueObject'\",\n name: 'string',\n});\n\nconst UnionFieldTypeSchema = type({\n '+': 'reject',\n kind: \"'union'\",\n members: ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).array(),\n});\n\nconst FieldTypeSchema = ScalarFieldTypeSchema.or(ValueObjectFieldTypeSchema).or(\n UnionFieldTypeSchema,\n);\n\nconst RawFieldSchema = type({\n '+': 'reject',\n type: FieldTypeSchema,\n 'nullable?': 'boolean',\n 'many?': 'boolean',\n 'dict?': 'boolean',\n});\n\nconst FieldSchema = RawFieldSchema.pipe((field) => ({\n ...field,\n nullable: field.nullable ?? false,\n}));\n\nconst RelationOnSchema = type({\n '+': 'reject',\n localFields: 'string[]',\n targetFields: 'string[]',\n});\n\nconst RelationSchema = type({\n '+': 'reject',\n to: 'string',\n cardinality: \"'1:1' | '1:N' | 'N:1'\",\n 'on?': RelationOnSchema,\n});\n\nconst StorageRelationEntrySchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst MongoJsonPrimitiveSchema = type\n .declare<MongoJsonPrimitive>()\n .type('string | number | boolean | null');\n\nfunction isMongoJsonRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction withUnseenReference(value: object, seen: WeakSet<object>, visit: () => boolean): boolean {\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n const result = visit();\n seen.delete(value);\n return result;\n}\n\nfunction isMongoJsonObject(value: unknown, seen: WeakSet<object>): value is MongoJsonObject {\n return (\n isMongoJsonRecord(value) &&\n withUnseenReference(value, seen, () =>\n Object.values(value).every((entry) => isMongoJsonValue(entry, seen)),\n )\n );\n}\n\nfunction isMongoJsonValue(value: unknown, seen = new WeakSet<object>()): value is MongoJsonValue {\n if (MongoJsonPrimitiveSchema.allows(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return withUnseenReference(value, seen, () =>\n value.every((entry) => isMongoJsonValue(entry, seen)),\n );\n }\n return isMongoJsonObject(value, seen);\n}\n\nconst MongoJsonValueSchema = type('unknown').narrow((value, ctx) =>\n isMongoJsonValue(value) ? true : ctx.mustBe('a JSON-serializable MongoJsonValue'),\n);\n\nconst MongoJsonObjectSchema = type({ '[string]': 'unknown' }).narrow((value, ctx) =>\n isMongoJsonRecord(value) &&\n Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry))\n ? true\n : ctx.mustBe('a JSON object with MongoJsonValue entries'),\n);\n\nconst NumberRecordSchema = type({ '[string]': 'number' });\n\nconst IndexFieldsSchema = type({\n '+': 'reject',\n '[string]': '1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"',\n}).narrow((fields, ctx) =>\n Object.keys(fields).length > 0 ? true : ctx.mustBe('an index field map with at least one entry'),\n);\n\nconst CollationSchema = type({\n '+': 'reject',\n 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 'storageEngine?': MongoJsonObjectSchema,\n});\n\nconst TimeSeriesCollectionOptionsSchema = type({\n '+': 'reject',\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 'name?': 'string',\n key: ClusteredCollectionKeySchema,\n unique: 'boolean',\n});\n\nconst ChangeStreamPreAndPostImagesSchema = type({\n '+': 'reject',\n enabled: 'boolean',\n});\n\nconst CollectionOptionsSchema = type({\n '+': 'reject',\n 'capped?': 'boolean',\n 'size?': 'number',\n 'max?': 'number',\n 'storageEngine?': MongoJsonObjectSchema,\n 'indexOptionDefaults?': IndexOptionDefaultsSchema,\n 'collation?': CollationSchema,\n 'timeseries?': TimeSeriesCollectionOptionsSchema,\n 'clusteredIndex?': ClusteredCollectionOptionsSchema,\n 'expireAfterSeconds?': 'number',\n 'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,\n});\n\nconst ModelStorageSchema = type({\n '+': 'reject',\n 'collection?': 'string',\n 'relations?': type({ '[string]': StorageRelationEntrySchema }),\n});\n\nconst DiscriminatorSchema = type({\n '+': 'reject',\n field: 'string',\n});\n\nconst VariantEntrySchema = type({\n '+': 'reject',\n value: 'string',\n});\n\nconst ModelDefinitionSchema = type({\n '+': 'reject',\n fields: type({ '[string]': FieldSchema }),\n storage: ModelStorageSchema,\n 'relations?': type({ '[string]': RelationSchema }),\n 'discriminator?': DiscriminatorSchema,\n 'variants?': type({ '[string]': VariantEntrySchema }),\n 'base?': 'string',\n 'owner?': 'string',\n});\n\nconst WildcardProjectionSchema = type({\n '+': 'reject',\n '[string]': '0 | 1',\n});\n\nconst IndexOptionsSchema = type({\n '+': 'reject',\n '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 StorageCollectionSchema = type({\n '+': 'reject',\n 'indexes?': IndexSchema.array(),\n 'options?': CollectionOptionsSchema,\n});\n\nexport const MongoContractSchema = type({\n '+': 'reject',\n targetFamily: \"'mongo'\",\n 'schemaVersion?': 'string',\n 'target?': 'string',\n 'storageHash?': 'string',\n 'profileHash?': 'string',\n roots: 'Record<string, string>',\n 'capabilities?': 'Record<string, unknown>',\n 'extensionPacks?': 'Record<string, unknown>',\n 'meta?': 'Record<string, unknown>',\n 'sources?': 'Record<string, unknown>',\n '_generated?': 'Record<string, unknown>',\n storage: type({\n '+': 'reject',\n collections: type({ '[string]': StorageCollectionSchema }),\n 'storageHash?': 'string',\n }),\n models: type({ '[string]': ModelDefinitionSchema }),\n 'valueObjects?': type({\n '[string]': type({ '+': 'reject', fields: type({ '[string]': FieldSchema }) }),\n }),\n});\n","import type { MongoContract } from './contract-types';\n\nexport function validateMongoStorage(contract: MongoContract): void {\n const errors: string[] = [];\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (model.storage.collection && !(model.storage.collection in contract.storage.collections)) {\n errors.push(\n `Model \"${modelName}\" references collection \"${model.storage.collection}\" which is not in storage.collections`,\n );\n }\n\n // Mongo does not support multi-table inheritance (ADR 2): all variants of a base\n // must share the same collection (single-table inheritance only).\n if (model.base) {\n const baseModel = contract.models[model.base];\n if (baseModel) {\n const variantCollection = model.storage.collection;\n const baseCollection = baseModel.storage.collection;\n if (variantCollection !== baseCollection) {\n errors.push(\n `Mongo does not support multi-table inheritance; variant \"${modelName}\" must share its base's collection (\"${baseCollection ?? '(none)'}\"), but has \"${variantCollection ?? '(none)'}\"`,\n );\n }\n }\n }\n\n for (const [relName, relation] of Object.entries(model.relations ?? {})) {\n const targetModel = contract.models[relation.to];\n\n if (targetModel?.owner) {\n if (targetModel.owner !== modelName) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which is owned by \"${targetModel.owner}\", not \"${modelName}\"`,\n );\n }\n if (targetModel.storage.collection) {\n errors.push(\n `Embed relation \"${relName}\" targets \"${relation.to}\" which must not have a collection`,\n );\n }\n } else if ('on' in relation && relation.on) {\n for (const localField of relation.on.localFields) {\n if (!(localField in model.fields)) {\n errors.push(\n `Reference relation \"${relName}\": localField \"${localField}\" is not a field on model \"${modelName}\"`,\n );\n }\n }\n\n if (targetModel) {\n for (const targetField of relation.on.targetFields) {\n if (!(targetField in targetModel.fields)) {\n errors.push(\n `Reference relation \"${relName}\": targetField \"${targetField}\" is not a field on model \"${relation.to}\"`,\n );\n }\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(`Contract storage validation failed:\\n- ${errors.join('\\n- ')}`);\n }\n}\n","import { validateContractDomain } from '@prisma-next/contract/validate-domain';\nimport { type as arktypeType } from 'arktype';\nimport { MongoContractSchema } from './contract-schema';\nimport type { MongoContract } from './contract-types';\nimport { validateMongoStorage } from './validate-storage';\n\nexport interface MongoContractIndices {\n readonly variantToBase: Record<string, string>;\n readonly modelToVariants: Record<string, string[]>;\n}\n\nexport interface ValidatedMongoContract<TContract extends MongoContract> {\n readonly contract: TContract;\n readonly indices: MongoContractIndices;\n}\n\nexport function validateMongoContract<TContract extends MongoContract>(\n value: unknown,\n): ValidatedMongoContract<TContract> {\n const parsed = MongoContractSchema(value);\n if (parsed instanceof arktypeType.errors) {\n throw new Error(`Contract structural validation failed: ${parsed.summary}`);\n }\n\n const contract = parsed as unknown as TContract;\n\n validateContractDomain(contract);\n validateMongoStorage(contract);\n\n const indices = buildIndices(contract);\n\n return { contract, indices };\n}\n\nfunction buildIndices(contract: MongoContract): MongoContractIndices {\n const variantToBase: Record<string, string> = {};\n const modelToVariants: Record<string, string[]> = {};\n\n for (const [modelName, model] of Object.entries(contract.models)) {\n if (model.base) {\n variantToBase[modelName] = model.base;\n }\n if (model.variants) {\n modelToVariants[modelName] = Object.keys(model.variants);\n }\n }\n\n return { variantToBase, modelToVariants };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/mongo-contract",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.148",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Contract types and validation for Prisma Next MongoDB support",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.1.29",
|
|
9
|
-
"@prisma-next/contract": "0.3.0-dev.
|
|
9
|
+
"@prisma-next/contract": "0.3.0-dev.148"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"tsdown": "0.18.4",
|
|
13
13
|
"typescript": "5.9.3",
|
|
14
14
|
"vitest": "4.0.17",
|
|
15
|
-
"@prisma-next/adapter-mongo": "0.3.0-dev.146",
|
|
16
|
-
"@prisma-next/test-utils": "0.0.1",
|
|
17
15
|
"@prisma-next/tsdown": "0.0.0",
|
|
16
|
+
"@prisma-next/test-utils": "0.0.1",
|
|
18
17
|
"@prisma-next/tsconfig": "0.0.0"
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
package/src/contract-schema.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type } from 'arktype';
|
|
2
|
+
import type { MongoJsonObject, MongoJsonPrimitive, MongoJsonValue } from './contract-types';
|
|
2
3
|
|
|
3
4
|
const ScalarFieldTypeSchema = type({
|
|
4
5
|
'+': 'reject',
|
|
@@ -54,6 +55,132 @@ const StorageRelationEntrySchema = type({
|
|
|
54
55
|
field: 'string',
|
|
55
56
|
});
|
|
56
57
|
|
|
58
|
+
const MongoJsonPrimitiveSchema = type
|
|
59
|
+
.declare<MongoJsonPrimitive>()
|
|
60
|
+
.type('string | number | boolean | null');
|
|
61
|
+
|
|
62
|
+
function isMongoJsonRecord(value: unknown): value is Record<string, unknown> {
|
|
63
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const prototype = Object.getPrototypeOf(value);
|
|
67
|
+
return prototype === Object.prototype || prototype === null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function withUnseenReference(value: object, seen: WeakSet<object>, visit: () => boolean): boolean {
|
|
71
|
+
if (seen.has(value)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
seen.add(value);
|
|
76
|
+
const result = visit();
|
|
77
|
+
seen.delete(value);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isMongoJsonObject(value: unknown, seen: WeakSet<object>): value is MongoJsonObject {
|
|
82
|
+
return (
|
|
83
|
+
isMongoJsonRecord(value) &&
|
|
84
|
+
withUnseenReference(value, seen, () =>
|
|
85
|
+
Object.values(value).every((entry) => isMongoJsonValue(entry, seen)),
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isMongoJsonValue(value: unknown, seen = new WeakSet<object>()): value is MongoJsonValue {
|
|
91
|
+
if (MongoJsonPrimitiveSchema.allows(value)) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
return withUnseenReference(value, seen, () =>
|
|
96
|
+
value.every((entry) => isMongoJsonValue(entry, seen)),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return isMongoJsonObject(value, seen);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const MongoJsonValueSchema = type('unknown').narrow((value, ctx) =>
|
|
103
|
+
isMongoJsonValue(value) ? true : ctx.mustBe('a JSON-serializable MongoJsonValue'),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const MongoJsonObjectSchema = type({ '[string]': 'unknown' }).narrow((value, ctx) =>
|
|
107
|
+
isMongoJsonRecord(value) &&
|
|
108
|
+
Object.values(value).every((entry) => MongoJsonValueSchema.allows(entry))
|
|
109
|
+
? true
|
|
110
|
+
: ctx.mustBe('a JSON object with MongoJsonValue entries'),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const NumberRecordSchema = type({ '[string]': 'number' });
|
|
114
|
+
|
|
115
|
+
const IndexFieldsSchema = type({
|
|
116
|
+
'+': 'reject',
|
|
117
|
+
'[string]': '1 | -1 | "text" | "2dsphere" | "2d" | "hashed"',
|
|
118
|
+
}).narrow((fields, ctx) =>
|
|
119
|
+
Object.keys(fields).length > 0 ? true : ctx.mustBe('an index field map with at least one entry'),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const CollationSchema = type({
|
|
123
|
+
'+': 'reject',
|
|
124
|
+
locale: 'string',
|
|
125
|
+
'caseLevel?': 'boolean',
|
|
126
|
+
'caseFirst?': '"off" | "upper" | "lower"',
|
|
127
|
+
'strength?': '1 | 2 | 3 | 4 | 5',
|
|
128
|
+
'numericOrdering?': 'boolean',
|
|
129
|
+
'alternate?': '"non-ignorable" | "shifted"',
|
|
130
|
+
'maxVariable?': '"punct" | "space"',
|
|
131
|
+
'backwards?': 'boolean',
|
|
132
|
+
'normalization?': 'boolean',
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const IndexOptionDefaultsSchema = type({
|
|
136
|
+
'+': 'reject',
|
|
137
|
+
'storageEngine?': MongoJsonObjectSchema,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const TimeSeriesCollectionOptionsSchema = type({
|
|
141
|
+
'+': 'reject',
|
|
142
|
+
timeField: 'string',
|
|
143
|
+
'metaField?': 'string',
|
|
144
|
+
'granularity?': '"seconds" | "minutes" | "hours"',
|
|
145
|
+
'bucketMaxSpanSeconds?': 'number',
|
|
146
|
+
'bucketRoundingSeconds?': 'number',
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const ClusteredCollectionKeySchema = type({
|
|
150
|
+
'+': 'reject',
|
|
151
|
+
'[string]': '1',
|
|
152
|
+
}).narrow((key, ctx) =>
|
|
153
|
+
Object.keys(key).length > 0
|
|
154
|
+
? true
|
|
155
|
+
: ctx.mustBe('a clustered index key map with at least one entry'),
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const ClusteredCollectionOptionsSchema = type({
|
|
159
|
+
'+': 'reject',
|
|
160
|
+
'name?': 'string',
|
|
161
|
+
key: ClusteredCollectionKeySchema,
|
|
162
|
+
unique: 'boolean',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const ChangeStreamPreAndPostImagesSchema = type({
|
|
166
|
+
'+': 'reject',
|
|
167
|
+
enabled: 'boolean',
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const CollectionOptionsSchema = type({
|
|
171
|
+
'+': 'reject',
|
|
172
|
+
'capped?': 'boolean',
|
|
173
|
+
'size?': 'number',
|
|
174
|
+
'max?': 'number',
|
|
175
|
+
'storageEngine?': MongoJsonObjectSchema,
|
|
176
|
+
'indexOptionDefaults?': IndexOptionDefaultsSchema,
|
|
177
|
+
'collation?': CollationSchema,
|
|
178
|
+
'timeseries?': TimeSeriesCollectionOptionsSchema,
|
|
179
|
+
'clusteredIndex?': ClusteredCollectionOptionsSchema,
|
|
180
|
+
'expireAfterSeconds?': 'number',
|
|
181
|
+
'changeStreamPreAndPostImages?': ChangeStreamPreAndPostImagesSchema,
|
|
182
|
+
});
|
|
183
|
+
|
|
57
184
|
const ModelStorageSchema = type({
|
|
58
185
|
'+': 'reject',
|
|
59
186
|
'collection?': 'string',
|
|
@@ -81,7 +208,43 @@ const ModelDefinitionSchema = type({
|
|
|
81
208
|
'owner?': 'string',
|
|
82
209
|
});
|
|
83
210
|
|
|
84
|
-
const
|
|
211
|
+
const WildcardProjectionSchema = type({
|
|
212
|
+
'+': 'reject',
|
|
213
|
+
'[string]': '0 | 1',
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const IndexOptionsSchema = type({
|
|
217
|
+
'+': 'reject',
|
|
218
|
+
'unique?': 'boolean',
|
|
219
|
+
'name?': 'string',
|
|
220
|
+
'partialFilterExpression?': MongoJsonObjectSchema,
|
|
221
|
+
'sparse?': 'boolean',
|
|
222
|
+
'expireAfterSeconds?': 'number',
|
|
223
|
+
'weights?': NumberRecordSchema,
|
|
224
|
+
'default_language?': 'string',
|
|
225
|
+
'language_override?': 'string',
|
|
226
|
+
'textIndexVersion?': 'number',
|
|
227
|
+
'2dsphereIndexVersion?': 'number',
|
|
228
|
+
'bits?': 'number',
|
|
229
|
+
'min?': 'number',
|
|
230
|
+
'max?': 'number',
|
|
231
|
+
'bucketSize?': 'number',
|
|
232
|
+
'hidden?': 'boolean',
|
|
233
|
+
'collation?': CollationSchema,
|
|
234
|
+
'wildcardProjection?': WildcardProjectionSchema,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const IndexSchema = type({
|
|
238
|
+
'+': 'reject',
|
|
239
|
+
fields: IndexFieldsSchema,
|
|
240
|
+
'options?': IndexOptionsSchema,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const StorageCollectionSchema = type({
|
|
244
|
+
'+': 'reject',
|
|
245
|
+
'indexes?': IndexSchema.array(),
|
|
246
|
+
'options?': CollectionOptionsSchema,
|
|
247
|
+
});
|
|
85
248
|
|
|
86
249
|
export const MongoContractSchema = type({
|
|
87
250
|
'+': 'reject',
|
package/src/contract-types.ts
CHANGED
|
@@ -6,7 +6,123 @@ import type {
|
|
|
6
6
|
StorageBase,
|
|
7
7
|
} from '@prisma-next/contract/types';
|
|
8
8
|
|
|
9
|
-
export type
|
|
9
|
+
export type MongoIndexFieldValue = 1 | -1 | 'text' | '2dsphere' | '2d' | 'hashed';
|
|
10
|
+
|
|
11
|
+
export type MongoIndexFields = Record<string, MongoIndexFieldValue>;
|
|
12
|
+
|
|
13
|
+
export type MongoJsonPrimitive = string | number | boolean | null;
|
|
14
|
+
|
|
15
|
+
export type MongoJsonValue = MongoJsonPrimitive | readonly MongoJsonValue[] | MongoJsonObject;
|
|
16
|
+
|
|
17
|
+
export type MongoJsonObject = {
|
|
18
|
+
readonly [key: string]: MongoJsonValue;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type MongoCollationCaseFirst = 'off' | 'upper' | 'lower';
|
|
22
|
+
|
|
23
|
+
export type MongoCollationStrength = 1 | 2 | 3 | 4 | 5;
|
|
24
|
+
|
|
25
|
+
export type MongoCollationAlternate = 'non-ignorable' | 'shifted';
|
|
26
|
+
|
|
27
|
+
export type MongoCollationMaxVariable = 'punct' | 'space';
|
|
28
|
+
|
|
29
|
+
export type MongoCollationOptions = {
|
|
30
|
+
readonly locale: string;
|
|
31
|
+
readonly caseLevel?: boolean;
|
|
32
|
+
readonly caseFirst?: MongoCollationCaseFirst;
|
|
33
|
+
readonly strength?: MongoCollationStrength;
|
|
34
|
+
readonly numericOrdering?: boolean;
|
|
35
|
+
readonly alternate?: MongoCollationAlternate;
|
|
36
|
+
readonly maxVariable?: MongoCollationMaxVariable;
|
|
37
|
+
readonly backwards?: boolean;
|
|
38
|
+
readonly normalization?: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type MongoWildcardProjection = Readonly<Record<string, 0 | 1>>;
|
|
42
|
+
|
|
43
|
+
export type MongoIndexOptions = {
|
|
44
|
+
readonly unique?: boolean;
|
|
45
|
+
readonly name?: string;
|
|
46
|
+
readonly partialFilterExpression?: MongoJsonObject;
|
|
47
|
+
readonly sparse?: boolean;
|
|
48
|
+
readonly expireAfterSeconds?: number;
|
|
49
|
+
readonly weights?: Readonly<Record<string, number>>;
|
|
50
|
+
readonly default_language?: string;
|
|
51
|
+
readonly language_override?: string;
|
|
52
|
+
readonly textIndexVersion?: number;
|
|
53
|
+
readonly '2dsphereIndexVersion'?: number;
|
|
54
|
+
readonly bits?: number;
|
|
55
|
+
readonly min?: number;
|
|
56
|
+
readonly max?: number;
|
|
57
|
+
readonly bucketSize?: number;
|
|
58
|
+
readonly hidden?: boolean;
|
|
59
|
+
readonly collation?: MongoCollationOptions;
|
|
60
|
+
readonly wildcardProjection?: MongoWildcardProjection;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type MongoIndex = {
|
|
64
|
+
readonly fields: MongoIndexFields;
|
|
65
|
+
readonly options?: MongoIndexOptions;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type MongoIndexOptionDefaults = {
|
|
69
|
+
readonly storageEngine?: MongoJsonObject;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type MongoTimeSeriesGranularity = 'seconds' | 'minutes' | 'hours';
|
|
73
|
+
|
|
74
|
+
export type MongoTimeSeriesCollectionOptions = {
|
|
75
|
+
readonly timeField: string;
|
|
76
|
+
readonly metaField?: string;
|
|
77
|
+
readonly granularity?: MongoTimeSeriesGranularity;
|
|
78
|
+
readonly bucketMaxSpanSeconds?: number;
|
|
79
|
+
readonly bucketRoundingSeconds?: number;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type MongoClusteredCollectionKey = Readonly<Record<string, 1>>;
|
|
83
|
+
|
|
84
|
+
export type MongoClusteredCollectionOptions = {
|
|
85
|
+
readonly name?: string;
|
|
86
|
+
readonly key: MongoClusteredCollectionKey;
|
|
87
|
+
readonly unique: boolean;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type MongoChangeStreamPreAndPostImagesOptions = {
|
|
91
|
+
readonly enabled: boolean;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export type MongoCollectionOptions = {
|
|
95
|
+
readonly capped?: boolean;
|
|
96
|
+
readonly size?: number;
|
|
97
|
+
readonly max?: number;
|
|
98
|
+
readonly storageEngine?: MongoJsonObject;
|
|
99
|
+
readonly indexOptionDefaults?: MongoIndexOptionDefaults;
|
|
100
|
+
readonly collation?: MongoCollationOptions;
|
|
101
|
+
readonly timeseries?: MongoTimeSeriesCollectionOptions;
|
|
102
|
+
readonly clusteredIndex?: MongoClusteredCollectionOptions;
|
|
103
|
+
readonly expireAfterSeconds?: number;
|
|
104
|
+
readonly changeStreamPreAndPostImages?: MongoChangeStreamPreAndPostImagesOptions;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type MongoIndexKeyDirection = 1 | -1 | 'text' | '2dsphere' | '2d' | 'hashed';
|
|
108
|
+
|
|
109
|
+
export interface MongoIndexKey {
|
|
110
|
+
readonly field: string;
|
|
111
|
+
readonly direction: MongoIndexKeyDirection;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface MongoStorageIndex {
|
|
115
|
+
readonly keys: ReadonlyArray<MongoIndexKey>;
|
|
116
|
+
readonly unique?: boolean;
|
|
117
|
+
readonly sparse?: boolean;
|
|
118
|
+
readonly expireAfterSeconds?: number;
|
|
119
|
+
readonly partialFilterExpression?: Record<string, unknown>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface MongoStorageCollection {
|
|
123
|
+
readonly indexes?: readonly MongoIndex[];
|
|
124
|
+
readonly options?: MongoCollectionOptions;
|
|
125
|
+
}
|
|
10
126
|
|
|
11
127
|
export type MongoStorage<THash extends string = string> = StorageBase<THash> & {
|
|
12
128
|
readonly collections: Record<string, MongoStorageCollection>;
|
|
@@ -67,6 +183,15 @@ type ExtractValueObjects<TContract> = TContract extends {
|
|
|
67
183
|
? VO
|
|
68
184
|
: Record<never, never>;
|
|
69
185
|
|
|
186
|
+
type NormalizeContractFields<TFields> = {
|
|
187
|
+
[K in keyof TFields]: TFields[K] extends ContractField ? TFields[K] : never;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
type ExtractValueObjectFields<
|
|
191
|
+
TValueObjects extends Record<string, ContractValueObject>,
|
|
192
|
+
VOName extends keyof TValueObjects,
|
|
193
|
+
> = NormalizeContractFields<TValueObjects[VOName]['fields']>;
|
|
194
|
+
|
|
70
195
|
type InferFieldBaseType<
|
|
71
196
|
TFieldType,
|
|
72
197
|
TValueObjects extends Record<string, ContractValueObject>,
|
|
@@ -76,8 +201,8 @@ type InferFieldBaseType<
|
|
|
76
201
|
: TFieldType extends { kind: 'valueObject'; name: infer VOName extends string }
|
|
77
202
|
? VOName extends keyof TValueObjects
|
|
78
203
|
? {
|
|
79
|
-
-readonly [K in keyof TValueObjects
|
|
80
|
-
TValueObjects
|
|
204
|
+
-readonly [K in keyof ExtractValueObjectFields<TValueObjects, VOName>]: InferFieldType<
|
|
205
|
+
ExtractValueObjectFields<TValueObjects, VOName>[K],
|
|
81
206
|
TValueObjects,
|
|
82
207
|
TCodecTypes
|
|
83
208
|
>;
|
|
@@ -93,16 +218,18 @@ type InferFieldBaseType<
|
|
|
93
218
|
: unknown;
|
|
94
219
|
|
|
95
220
|
type InferFieldType<
|
|
96
|
-
TField
|
|
221
|
+
TField,
|
|
97
222
|
TValueObjects extends Record<string, ContractValueObject>,
|
|
98
223
|
TCodecTypes extends Record<string, { output: unknown }>,
|
|
99
|
-
> = TField extends
|
|
100
|
-
? TField
|
|
101
|
-
?
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
224
|
+
> = TField extends ContractField
|
|
225
|
+
? TField extends { many: true }
|
|
226
|
+
? TField['nullable'] extends true
|
|
227
|
+
? InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes>[] | null
|
|
228
|
+
: InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes>[]
|
|
229
|
+
: TField['nullable'] extends true
|
|
230
|
+
? InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes> | null
|
|
231
|
+
: InferFieldBaseType<TField['type'], TValueObjects, TCodecTypes>
|
|
232
|
+
: never;
|
|
106
233
|
|
|
107
234
|
export type InferModelRow<
|
|
108
235
|
TContract extends MongoContractWithTypeMaps<MongoContract, MongoTypeMaps>,
|
package/src/exports/index.ts
CHANGED
|
@@ -3,14 +3,37 @@ export type {
|
|
|
3
3
|
ExtractMongoFieldOutputTypes,
|
|
4
4
|
ExtractMongoTypeMaps,
|
|
5
5
|
InferModelRow,
|
|
6
|
+
MongoChangeStreamPreAndPostImagesOptions,
|
|
7
|
+
MongoClusteredCollectionKey,
|
|
8
|
+
MongoClusteredCollectionOptions,
|
|
9
|
+
MongoCollationAlternate,
|
|
10
|
+
MongoCollationCaseFirst,
|
|
11
|
+
MongoCollationMaxVariable,
|
|
12
|
+
MongoCollationOptions,
|
|
13
|
+
MongoCollationStrength,
|
|
14
|
+
MongoCollectionOptions,
|
|
6
15
|
MongoContract,
|
|
7
16
|
MongoContractWithTypeMaps,
|
|
17
|
+
MongoIndex,
|
|
18
|
+
MongoIndexFields,
|
|
19
|
+
MongoIndexFieldValue,
|
|
20
|
+
MongoIndexKey,
|
|
21
|
+
MongoIndexKeyDirection,
|
|
22
|
+
MongoIndexOptionDefaults,
|
|
23
|
+
MongoIndexOptions,
|
|
24
|
+
MongoJsonObject,
|
|
25
|
+
MongoJsonPrimitive,
|
|
26
|
+
MongoJsonValue,
|
|
8
27
|
MongoModelDefinition,
|
|
9
28
|
MongoModelStorage,
|
|
10
29
|
MongoStorage,
|
|
11
30
|
MongoStorageCollection,
|
|
31
|
+
MongoStorageIndex,
|
|
32
|
+
MongoTimeSeriesCollectionOptions,
|
|
33
|
+
MongoTimeSeriesGranularity,
|
|
12
34
|
MongoTypeMaps,
|
|
13
35
|
MongoTypeMapsPhantomKey,
|
|
36
|
+
MongoWildcardProjection,
|
|
14
37
|
} from '../contract-types';
|
|
15
38
|
export type { MongoContractIndices, ValidatedMongoContract } from '../validate-mongo-contract';
|
|
16
39
|
export { validateMongoContract } from '../validate-mongo-contract';
|