@routier/core 0.0.1-alpha.1
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/CHANGELOG.md +8 -0
- package/package.json +91 -0
- package/rspack.config.mjs +65 -0
- package/src/assertions/index.ts +37 -0
- package/src/codegen/SlotPath.ts +20 -0
- package/src/codegen/blocks.ts +578 -0
- package/src/codegen/handlers/CloneHandlerBuilder.ts +13 -0
- package/src/codegen/handlers/CompareHandlerBuilder.ts +13 -0
- package/src/codegen/handlers/DeserializeHandlerBuilder.ts +20 -0
- package/src/codegen/handlers/EnableChangeTrackingHandlerBuilder.ts +13 -0
- package/src/codegen/handlers/EnrichmentHandlerBuilder.ts +28 -0
- package/src/codegen/handlers/FreezeHandlerBuilder.ts +13 -0
- package/src/codegen/handlers/HashHandlerBuilder.ts +25 -0
- package/src/codegen/handlers/HashTypeHandlerBuilder.ts +11 -0
- package/src/codegen/handlers/IdSelectorHandlerBuilder.ts +10 -0
- package/src/codegen/handlers/MergeHandlerBuilder.ts +19 -0
- package/src/codegen/handlers/PrepareHandlerBuilder.ts +23 -0
- package/src/codegen/handlers/SerializeHandlerBuilder.ts +15 -0
- package/src/codegen/handlers/StripHandlerBuilder.ts +18 -0
- package/src/codegen/handlers/clone/CloneObjectHandler.ts +29 -0
- package/src/codegen/handlers/clone/CloneValueHandler.ts +33 -0
- package/src/codegen/handlers/compare/CompareObjectHandler.ts +15 -0
- package/src/codegen/handlers/compare/CompareValueHandler.ts +27 -0
- package/src/codegen/handlers/deserialize/DeserializeComputedValueHandler.ts +16 -0
- package/src/codegen/handlers/deserialize/DeserializeDateHandler.ts +45 -0
- package/src/codegen/handlers/deserialize/DeserializeFunctionHandler.ts +16 -0
- package/src/codegen/handlers/deserialize/DeserializeObjectHandler.ts +29 -0
- package/src/codegen/handlers/deserialize/DeserializeValueHandler.ts +33 -0
- package/src/codegen/handlers/enableChangeTracking/EnableChangeTrackingObjectHandler.ts +20 -0
- package/src/codegen/handlers/enableChangeTracking/EnableChangeTrackingPrimitiveValueHandler.ts +15 -0
- package/src/codegen/handlers/enrichment/EnrichmentComputedValueHandler.ts +37 -0
- package/src/codegen/handlers/enrichment/EnrichmentDefaultFunctionHandler.ts +50 -0
- package/src/codegen/handlers/enrichment/EnrichmentDefaultValueHandler.ts +18 -0
- package/src/codegen/handlers/enrichment/EnrichmentFunctionHandler.ts +38 -0
- package/src/codegen/handlers/enrichment/EnrichmentNullableObjectHandler.ts +44 -0
- package/src/codegen/handlers/enrichment/EnrichmentObjectHandler.ts +29 -0
- package/src/codegen/handlers/enrichment/EnrichmentObjectIdentityHandler.ts +16 -0
- package/src/codegen/handlers/enrichment/EnrichmentPrimitiveHandler.ts +13 -0
- package/src/codegen/handlers/enrichment/EnrichmentPrimitiveIdentityHandler.ts +21 -0
- package/src/codegen/handlers/freeze/FreezeObjectHandler.ts +20 -0
- package/src/codegen/handlers/freeze/FreezePrimitiveValueHandler.ts +15 -0
- package/src/codegen/handlers/hash/HashComputedValueHandler.ts +15 -0
- package/src/codegen/handlers/hash/HashDateHandler.ts +26 -0
- package/src/codegen/handlers/hash/HashFunctionHandler.ts +16 -0
- package/src/codegen/handlers/hash/HashIdentityHandler.ts +15 -0
- package/src/codegen/handlers/hash/HashKeyHandler.ts +26 -0
- package/src/codegen/handlers/hash/HashValueHandler.ts +26 -0
- package/src/codegen/handlers/hashType/HashTypeValueHandler.ts +20 -0
- package/src/codegen/handlers/idSelector/IdSelectorValueHandler.ts +28 -0
- package/src/codegen/handlers/index.ts +13 -0
- package/src/codegen/handlers/merge/MergeComputedValueHandler.ts +37 -0
- package/src/codegen/handlers/merge/MergeDefaultFunctionHandler.ts +40 -0
- package/src/codegen/handlers/merge/MergeDefaultValueHandler.ts +32 -0
- package/src/codegen/handlers/merge/MergeFunctionHandler.ts +16 -0
- package/src/codegen/handlers/merge/MergePrimitiveHandler.ts +21 -0
- package/src/codegen/handlers/prepare/PrepareComputedValueHandler.ts +16 -0
- package/src/codegen/handlers/prepare/PrepareFunctionHandler.ts +16 -0
- package/src/codegen/handlers/prepare/PrepareIdentityHandler.ts +21 -0
- package/src/codegen/handlers/prepare/PrepareKeyHandler.ts +21 -0
- package/src/codegen/handlers/prepare/PrepareObjectHandler.ts +38 -0
- package/src/codegen/handlers/prepare/PrepareValueHandler.ts +36 -0
- package/src/codegen/handlers/serialize/SerializeDateHandler.ts +45 -0
- package/src/codegen/handlers/serialize/SerializeObjectHandler.ts +28 -0
- package/src/codegen/handlers/serialize/SerializeValueHandler.ts +33 -0
- package/src/codegen/handlers/strip/StripIdentityHandler.ts +15 -0
- package/src/codegen/handlers/strip/StripKeyHandler.ts +15 -0
- package/src/codegen/handlers/strip/StripObjectHandler.ts +35 -0
- package/src/codegen/handlers/strip/StripValueHandler.ts +36 -0
- package/src/codegen/handlers/types.ts +119 -0
- package/src/codegen/index.ts +2 -0
- package/src/codegen/types.ts +2 -0
- package/src/codegen/utils.ts +74 -0
- package/src/collections/Changes.test.ts +337 -0
- package/src/collections/Changes.ts +177 -0
- package/src/collections/IdSet.ts +28 -0
- package/src/collections/MemoryDataCollection.test.ts +424 -0
- package/src/collections/MemoryDataCollection.ts +134 -0
- package/src/collections/SchemaCollection.ts +22 -0
- package/src/collections/TagCollection.test.ts +443 -0
- package/src/collections/TagCollection.ts +62 -0
- package/src/collections/index.ts +5 -0
- package/src/errors/SchemaError.ts +6 -0
- package/src/errors/index.ts +1 -0
- package/src/expressions/index.ts +3 -0
- package/src/expressions/parser.test.ts +913 -0
- package/src/expressions/parser.ts +661 -0
- package/src/expressions/types.ts +184 -0
- package/src/expressions/utils.test.ts +346 -0
- package/src/expressions/utils.ts +59 -0
- package/src/index.ts +12 -0
- package/src/performance/index.ts +26 -0
- package/src/pipeline/SyncronousQueue.test.ts +269 -0
- package/src/pipeline/SyncronousQueue.ts +30 -0
- package/src/pipeline/TrampolinePipeline.test.ts +374 -0
- package/src/pipeline/TrampolinePipeline.ts +437 -0
- package/src/pipeline/index.ts +2 -0
- package/src/plugins/EphemeralDataPlugin.ts +132 -0
- package/src/plugins/capabilities/DbPluginCapability.ts +111 -0
- package/src/plugins/capabilities/index.ts +2 -0
- package/src/plugins/capabilities/logging/DbPluginLoggingCapability.ts +261 -0
- package/src/plugins/capabilities/logging/index.ts +1 -0
- package/src/plugins/index.ts +6 -0
- package/src/plugins/query/Query.ts +67 -0
- package/src/plugins/query/QueryOptionsCollection.test.ts +86 -0
- package/src/plugins/query/QueryOptionsCollection.ts +154 -0
- package/src/plugins/query/index.ts +3 -0
- package/src/plugins/query/types.ts +46 -0
- package/src/plugins/replication/OptimisticReplicationDbPlugin.ts +202 -0
- package/src/plugins/replication/ReplicationDbPlugin.ts +137 -0
- package/src/plugins/replication/index.ts +3 -0
- package/src/plugins/replication/types.ts +5 -0
- package/src/plugins/translators/DataTranslator.ts +46 -0
- package/src/plugins/translators/JsonTranslator.test.ts +618 -0
- package/src/plugins/translators/JsonTranslator.ts +211 -0
- package/src/plugins/translators/SqlTranslator.ts +45 -0
- package/src/plugins/translators/index.ts +3 -0
- package/src/plugins/types.ts +114 -0
- package/src/results/Result.ts +91 -0
- package/src/results/index.ts +3 -0
- package/src/results/types.ts +17 -0
- package/src/results/utils.ts +15 -0
- package/src/schema/PropertyInfo.test.ts +479 -0
- package/src/schema/PropertyInfo.ts +374 -0
- package/src/schema/SchemaDefinition.ts +626 -0
- package/src/schema/builder.ts +18 -0
- package/src/schema/index.ts +7 -0
- package/src/schema/property/base/SchemaBase.ts +49 -0
- package/src/schema/property/base/index.ts +1 -0
- package/src/schema/property/modifiers/SchemaDefault.ts +29 -0
- package/src/schema/property/modifiers/SchemaDeserialize.ts +23 -0
- package/src/schema/property/modifiers/SchemaDistinct.ts +14 -0
- package/src/schema/property/modifiers/SchemaFrom.ts +54 -0
- package/src/schema/property/modifiers/SchemaIdentity.ts +13 -0
- package/src/schema/property/modifiers/SchemaIndex.ts +60 -0
- package/src/schema/property/modifiers/SchemaKey.ts +28 -0
- package/src/schema/property/modifiers/SchemaNullable.ts +18 -0
- package/src/schema/property/modifiers/SchemaOptional.ts +19 -0
- package/src/schema/property/modifiers/SchemaReadonly.ts +34 -0
- package/src/schema/property/modifiers/SchemaSerialize.ts +18 -0
- package/src/schema/property/modifiers/SchemaTracked.ts +14 -0
- package/src/schema/property/modifiers/index.ts +12 -0
- package/src/schema/property/types/SchemaArray.ts +50 -0
- package/src/schema/property/types/SchemaBoolean.ts +59 -0
- package/src/schema/property/types/SchemaDate.ts +58 -0
- package/src/schema/property/types/SchemaNumber.ts +69 -0
- package/src/schema/property/types/SchemaObject.ts +44 -0
- package/src/schema/property/types/SchemaString.ts +69 -0
- package/src/schema/property/types/index.ts +6 -0
- package/src/schema/table/SchemaComputed.ts +20 -0
- package/src/schema/table/SchemaFunction.ts +15 -0
- package/src/schema/table/index.ts +2 -0
- package/src/schema/types.ts +238 -0
- package/src/types/index.ts +5 -0
- package/src/utilities/arrays.test.ts +312 -0
- package/src/utilities/arrays.ts +12 -0
- package/src/utilities/dates.test.ts +388 -0
- package/src/utilities/dates.ts +11 -0
- package/src/utilities/dbPluginEventUtils.ts +44 -0
- package/src/utilities/index.ts +10 -0
- package/src/utilities/objects.ts +7 -0
- package/src/utilities/queryOptionsCollection.ts +16 -0
- package/src/utilities/replication.ts +23 -0
- package/src/utilities/runtime.ts +3 -0
- package/src/utilities/strings.ts +18 -0
- package/src/utilities/types.ts +1 -0
- package/src/utilities/uuid.ts +56 -0
- package/tsconfig.json +28 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
import { SchemaFunction } from './table/SchemaFunction';
|
|
2
|
+
import { SchemaComputed } from './table/SchemaComputed';
|
|
3
|
+
import { SchemaBase } from "./property/base/SchemaBase";
|
|
4
|
+
import { PropertyInfo } from './PropertyInfo';
|
|
5
|
+
import { CodeBuilder } from '../codegen';
|
|
6
|
+
import { EnrichmentHandlerBuilder } from '../codegen/handlers/EnrichmentHandlerBuilder';
|
|
7
|
+
import { MergeHandlerBuilder } from '../codegen/handlers/MergeHandlerBuilder';
|
|
8
|
+
import { PrepareHandlerBuilder } from '../codegen/handlers/PrepareHandlerBuilder';
|
|
9
|
+
import { StripHandlerBuilder } from '../codegen/handlers/StripHandlerBuilder';
|
|
10
|
+
import { CloneHandlerBuilder } from '../codegen/handlers/CloneHandlerBuilder';
|
|
11
|
+
import { CompareHandlerBuilder } from '../codegen/handlers/CompareHandlerBuilder';
|
|
12
|
+
import { DeserializeHandlerBuilder } from '../codegen/handlers/DeserializeHandlerBuilder';
|
|
13
|
+
import { HashTypeHandlerBuilder } from '../codegen/handlers/HashTypeHandlerBuilder';
|
|
14
|
+
import { IdSelectorHandlerBuilder } from '../codegen/handlers/IdSelectorHandlerBuilder';
|
|
15
|
+
import { HashHandlerBuilder } from '../codegen/handlers/HashHandlerBuilder';
|
|
16
|
+
import { EnableChangeTrackingHandlerBuilder } from '../codegen/handlers/EnableChangeTrackingHandlerBuilder';
|
|
17
|
+
import { FreezeHandlerBuilder } from '../codegen/handlers/FreezeHandlerBuilder';
|
|
18
|
+
import { SchemaError } from '../errors/SchemaError';
|
|
19
|
+
import { SerializeHandlerBuilder } from "../codegen/handlers/SerializeHandlerBuilder";
|
|
20
|
+
import { uuid, hash } from "../utilities";
|
|
21
|
+
import { CompiledSchema, GetHashTypeFunction, HashFunction, HashType, ICollectionSubscription, IdType, Index, InferCreateType, InferType, SchemaTypes, SubscriptionChanges } from './types';
|
|
22
|
+
import { DeepPartial } from '../types';
|
|
23
|
+
|
|
24
|
+
type UniDirectionalSubscriptionPayload<T extends {}> = {
|
|
25
|
+
id: string;
|
|
26
|
+
changes: SubscriptionChanges<T>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// This is intented to run the "OnMessage" event whenever we "send". For context
|
|
30
|
+
// when we make a change, we query to see if we have any changes. We need to run a fetch because we could have
|
|
31
|
+
// many db sets
|
|
32
|
+
class CollectionSubscription<T extends {}> implements ICollectionSubscription<T> {
|
|
33
|
+
|
|
34
|
+
private _channel;
|
|
35
|
+
private _id = uuid();
|
|
36
|
+
private _callback: ((changes: SubscriptionChanges<T>) => void) | null = null;
|
|
37
|
+
|
|
38
|
+
constructor(id: number, signal?: AbortSignal) {
|
|
39
|
+
// The id is the computed id from the collection. We need a static id so we can communicate across different
|
|
40
|
+
// instances of a data store
|
|
41
|
+
this._channel = new BroadcastChannel(`__routier-unidirectional-subscription-channel-${id}`);
|
|
42
|
+
this._channel.onmessage = (event: any) => {
|
|
43
|
+
const message = event.data as UniDirectionalSubscriptionPayload<T>;
|
|
44
|
+
if (message.id === this._id) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (this._callback != null) {
|
|
49
|
+
this._callback(message.changes);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
if (signal) {
|
|
54
|
+
signal.addEventListener("abort", () => {
|
|
55
|
+
this[Symbol.dispose]();
|
|
56
|
+
}, { once: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
send(changes: SubscriptionChanges<T>) {
|
|
61
|
+
const message: UniDirectionalSubscriptionPayload<T> = {
|
|
62
|
+
id: this._id,
|
|
63
|
+
changes
|
|
64
|
+
}
|
|
65
|
+
this._channel.postMessage(message)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
onMessage(callback: (changes: SubscriptionChanges<T>) => void) {
|
|
69
|
+
this._callback = callback;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
dispose() {
|
|
73
|
+
this[Symbol.dispose]();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[Symbol.dispose](): void {
|
|
77
|
+
this._channel.onmessage = null;
|
|
78
|
+
this._channel.close();
|
|
79
|
+
this._channel = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class SchemaDefinition<T extends {}> extends SchemaBase<T, any> {
|
|
84
|
+
|
|
85
|
+
instance: T;
|
|
86
|
+
type = SchemaTypes.Definition;
|
|
87
|
+
collectionName: string;
|
|
88
|
+
|
|
89
|
+
constructor(collectionName: string, schema: T) {
|
|
90
|
+
super();
|
|
91
|
+
this.collectionName = collectionName;
|
|
92
|
+
this.instance = schema;
|
|
93
|
+
this.isNullable = false;
|
|
94
|
+
this.isOptional = false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
modify<R>(builder: (d: {
|
|
98
|
+
function: <UU, I = never>(fn: (entity: InferType<CompiledSchema<T>>, collectionName: string, injected: I) => UU, injected?: I) => SchemaFunction<UU, I, "unmapped">;
|
|
99
|
+
computed: <UU, I = never>(fn: (entity: InferType<CompiledSchema<T>>, collectionName: string, injected: I) => UU, injected?: I) => SchemaComputed<UU, I, "unmapped">;
|
|
100
|
+
}) => R) {
|
|
101
|
+
|
|
102
|
+
const b = {
|
|
103
|
+
function: <UU, I = never>(fn: (entity: InferType<CompiledSchema<T>>, collectionName: string, injected?: I) => UU, injected?: I) => new SchemaFunction<UU, I, "unmapped">(fn as any, injected),
|
|
104
|
+
computed: <UU, I = never>(fn: (entity: InferType<CompiledSchema<T>>, collectionName: string, injected?: I) => UU, injected?: I) => new SchemaComputed<UU, I, "unmapped">(fn as any, injected)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const r = builder(b)
|
|
108
|
+
|
|
109
|
+
return new SchemaDefinition<R & T>(this.collectionName, { ...this.instance, ...r });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private _iterate(
|
|
113
|
+
instance: SchemaBase<any, any>,
|
|
114
|
+
callback: (property: PropertyInfo<any>) => void
|
|
115
|
+
) {
|
|
116
|
+
const explore: {
|
|
117
|
+
path: string | null;
|
|
118
|
+
instance:
|
|
119
|
+
| SchemaBase<any, any>
|
|
120
|
+
| { [key: string]: SchemaBase<any, any> };
|
|
121
|
+
parents: {
|
|
122
|
+
schema: { [key: string]: SchemaBase<any, any> };
|
|
123
|
+
propertyInfo: PropertyInfo<any>;
|
|
124
|
+
}[];
|
|
125
|
+
propertyInfo: PropertyInfo<any> | null;
|
|
126
|
+
}[] = [
|
|
127
|
+
{ path: null, instance, parents: [], propertyInfo: null }
|
|
128
|
+
];
|
|
129
|
+
const properties: PropertyInfo<any>[] = [];
|
|
130
|
+
|
|
131
|
+
for (let i = 0; i < explore.length; i++) {
|
|
132
|
+
const item = explore[i];
|
|
133
|
+
|
|
134
|
+
if (item.instance.type === SchemaTypes.Definition) {
|
|
135
|
+
explore.push({
|
|
136
|
+
path: null,
|
|
137
|
+
instance: item.instance.instance,
|
|
138
|
+
parents: [],
|
|
139
|
+
propertyInfo: null
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const instanceObj = item.instance as {
|
|
145
|
+
[key: string]: SchemaBase<any, any>;
|
|
146
|
+
};
|
|
147
|
+
for (const key in instanceObj) {
|
|
148
|
+
const propertyInstance = instanceObj[key] as SchemaBase<any, any>;
|
|
149
|
+
const previousParent =
|
|
150
|
+
item.parents.length === 0
|
|
151
|
+
? null
|
|
152
|
+
: item.parents[item.parents.length - 1].propertyInfo;
|
|
153
|
+
|
|
154
|
+
if (propertyInstance.type === SchemaTypes.Object) {
|
|
155
|
+
const propertyInfo = new PropertyInfo<any>(
|
|
156
|
+
propertyInstance,
|
|
157
|
+
key,
|
|
158
|
+
previousParent
|
|
159
|
+
);
|
|
160
|
+
explore.push({
|
|
161
|
+
path: [item.path, key].filter((w) => w != null).join("."),
|
|
162
|
+
instance: propertyInstance.instance,
|
|
163
|
+
parents: [
|
|
164
|
+
...item.parents,
|
|
165
|
+
{ schema: instanceObj, propertyInfo: propertyInfo }
|
|
166
|
+
],
|
|
167
|
+
propertyInfo
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (previousParent === null) {
|
|
171
|
+
properties.push(propertyInfo);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
previousParent.children.push(propertyInfo);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const childPrimitivePropertyInfo = new PropertyInfo<any>(
|
|
180
|
+
(item.instance as any)[key],
|
|
181
|
+
key,
|
|
182
|
+
previousParent
|
|
183
|
+
);
|
|
184
|
+
if (previousParent === null) {
|
|
185
|
+
properties.push(childPrimitivePropertyInfo);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
previousParent.children.push(childPrimitivePropertyInfo);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Recursively trigger callbacks on properties and their children
|
|
194
|
+
function recursiveCallback(prop: PropertyInfo<any>) {
|
|
195
|
+
callback(prop);
|
|
196
|
+
for (const child of prop.children) {
|
|
197
|
+
recursiveCallback(child);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
for (const prop of properties) {
|
|
202
|
+
recursiveCallback(prop);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private createChangeTracker() {
|
|
207
|
+
|
|
208
|
+
const DIRTY_ENTITY_MARKER: string = "isDirty";
|
|
209
|
+
const CHANGES_ENTITY_KEY: string = "changes";
|
|
210
|
+
const ORIGINAL_ENTITY_KEY: string = "original";
|
|
211
|
+
const PAUSED_ENTITY_KEY: string = "isPaused";
|
|
212
|
+
const TRACKING_KEY: string = "__tracking__";
|
|
213
|
+
const PROXY_MARKER: string = "__isProxy__";
|
|
214
|
+
|
|
215
|
+
return <TEntity extends {}>(entity: TEntity, path?: string, parent?: TEntity) => {
|
|
216
|
+
|
|
217
|
+
const proxyHandler: ProxyHandler<TEntity> = {
|
|
218
|
+
set: (entity, property, value) => {
|
|
219
|
+
const indexableEntity: { [key: string]: any } = entity;
|
|
220
|
+
const key = String(property);
|
|
221
|
+
const originalValue = indexableEntity[key];
|
|
222
|
+
|
|
223
|
+
// if values are the same, do nothing
|
|
224
|
+
if (originalValue === value) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const resolvedParent: { [key: string]: any } = parent ?? entity;
|
|
229
|
+
|
|
230
|
+
if (resolvedParent[TRACKING_KEY] == null) {
|
|
231
|
+
resolvedParent[TRACKING_KEY] = {
|
|
232
|
+
[CHANGES_ENTITY_KEY]: {},
|
|
233
|
+
[DIRTY_ENTITY_MARKER]: false,
|
|
234
|
+
[ORIGINAL_ENTITY_KEY]: {},
|
|
235
|
+
[PAUSED_ENTITY_KEY]: false
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (key == TRACKING_KEY) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (resolvedParent[TRACKING_KEY] != null && resolvedParent[TRACKING_KEY][PAUSED_ENTITY_KEY] === true) {
|
|
244
|
+
Reflect.set(indexableEntity, property, value);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const resolvedPath = path == null ? key : `${path}.${key}`;
|
|
249
|
+
const changes = resolvedParent[TRACKING_KEY];
|
|
250
|
+
|
|
251
|
+
if (changes[CHANGES_ENTITY_KEY][resolvedPath] != null) {
|
|
252
|
+
|
|
253
|
+
if (changes[ORIGINAL_ENTITY_KEY][resolvedPath] === value) {
|
|
254
|
+
// we are changing the value back to the original value, remove the change
|
|
255
|
+
delete changes[ORIGINAL_ENTITY_KEY][resolvedPath];
|
|
256
|
+
delete changes[CHANGES_ENTITY_KEY][resolvedPath];
|
|
257
|
+
} else {
|
|
258
|
+
// track the change
|
|
259
|
+
changes[CHANGES_ENTITY_KEY][resolvedPath] = value;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
} else if (changes[CHANGES_ENTITY_KEY][resolvedPath] == null) {
|
|
263
|
+
// don't keep updating, keep the original value
|
|
264
|
+
changes[CHANGES_ENTITY_KEY][resolvedPath] = value;
|
|
265
|
+
changes[ORIGINAL_ENTITY_KEY][resolvedPath] = originalValue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const isDirty = Object.keys(changes[ORIGINAL_ENTITY_KEY]).length > 0;
|
|
269
|
+
changes[DIRTY_ENTITY_MARKER] = isDirty;
|
|
270
|
+
|
|
271
|
+
Reflect.set(indexableEntity, property, value);
|
|
272
|
+
|
|
273
|
+
return true;
|
|
274
|
+
},
|
|
275
|
+
get: (target, property, receiver) => {
|
|
276
|
+
|
|
277
|
+
if (property === PROXY_MARKER) {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return Reflect.get(target, property, receiver);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return new Proxy(entity, proxyHandler) as TEntity
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
compile(): CompiledSchema<T> {
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
const schema = this;
|
|
293
|
+
const properties: PropertyInfo<T>[] = [];
|
|
294
|
+
const propertyMap: Map<string, PropertyInfo<T>> = new Map<string, PropertyInfo<T>>();
|
|
295
|
+
|
|
296
|
+
const enrichmentHandlerBuilder = new EnrichmentHandlerBuilder();
|
|
297
|
+
const mergeHandlerFactory = new MergeHandlerBuilder();
|
|
298
|
+
const prepareHandlerBuilder = new PrepareHandlerBuilder();
|
|
299
|
+
const stripHandlerBuilder = new StripHandlerBuilder();
|
|
300
|
+
const cloneHandlerBuilder = new CloneHandlerBuilder();
|
|
301
|
+
const compareHandlerBuilder = new CompareHandlerBuilder();
|
|
302
|
+
const deserializeHandlerBuilder = new DeserializeHandlerBuilder();
|
|
303
|
+
const hashTypeHandlerBuilder = new HashTypeHandlerBuilder();
|
|
304
|
+
const idSelectorHandlerBuilder = new IdSelectorHandlerBuilder();
|
|
305
|
+
const hashHandlerBuilder = new HashHandlerBuilder();
|
|
306
|
+
const enableChangeTrackingHandlerBuilder = new EnableChangeTrackingHandlerBuilder();
|
|
307
|
+
const freezeHandlerBuilder = new FreezeHandlerBuilder();
|
|
308
|
+
const serializeHandlerBuilder = new SerializeHandlerBuilder();
|
|
309
|
+
|
|
310
|
+
const enricher = enrichmentHandlerBuilder.build();
|
|
311
|
+
const merge = mergeHandlerFactory.build();
|
|
312
|
+
const prepare = prepareHandlerBuilder.build();
|
|
313
|
+
const strip = stripHandlerBuilder.build();
|
|
314
|
+
const clone = cloneHandlerBuilder.build();
|
|
315
|
+
const compare = compareHandlerBuilder.build();
|
|
316
|
+
const deserialize = deserializeHandlerBuilder.build();
|
|
317
|
+
const hashTypeHandler = hashTypeHandlerBuilder.build();
|
|
318
|
+
const idSelectorHandler = idSelectorHandlerBuilder.build();
|
|
319
|
+
const hashHandler = hashHandlerBuilder.build();
|
|
320
|
+
const enableChangeTrackingHandler = enableChangeTrackingHandlerBuilder.build();
|
|
321
|
+
const freezeHandler = freezeHandlerBuilder.build();
|
|
322
|
+
const serializeHandler = serializeHandlerBuilder.build();
|
|
323
|
+
|
|
324
|
+
const changeTrackingCodeBuilder = new CodeBuilder();
|
|
325
|
+
changeTrackingCodeBuilder.raw(`function ${this.createChangeTracker.toString()}`);
|
|
326
|
+
changeTrackingCodeBuilder.slot("declarations").variable("enableChangeTracking").value('createChangeTracker()');
|
|
327
|
+
changeTrackingCodeBuilder.slot("assignment");
|
|
328
|
+
changeTrackingCodeBuilder.slot("return").raw('\treturn enableChangeTracking(entity);');
|
|
329
|
+
|
|
330
|
+
const freezeCodeBuilder = new CodeBuilder();
|
|
331
|
+
freezeCodeBuilder.slot("assignment");
|
|
332
|
+
freezeCodeBuilder.slot("return").raw('\treturn Object.freeze(entity);');
|
|
333
|
+
|
|
334
|
+
const enricherCodeBuilder = new CodeBuilder();
|
|
335
|
+
const enricherFunctionRoot = enricherCodeBuilder.factory("factory", { name: "factory" }).parameters({ name: "collectionName", value: this.collectionName });
|
|
336
|
+
const enricherFunctionBody = enricherFunctionRoot.function(undefined, { name: "function" }).parameters("entity", "changeTrackingType").return();
|
|
337
|
+
|
|
338
|
+
enricherFunctionBody.raw(`function ${this.createChangeTracker.toString()}`);
|
|
339
|
+
enricherFunctionBody.variable("enableChangeTracking").value('changeTrackingType === "proxy" ? createChangeTracker() : e => e');
|
|
340
|
+
|
|
341
|
+
enricherFunctionBody.slot("enriched");
|
|
342
|
+
enricherFunctionBody.slot("declarations");
|
|
343
|
+
enricherFunctionBody.slot("assignment");
|
|
344
|
+
enricherFunctionBody.slot("ifs");
|
|
345
|
+
enricherFunctionBody.slot("tracking").if('changeTrackingType === "immutable"', { name: "freeze" });
|
|
346
|
+
enricherFunctionBody.raw('\treturn enableChangeTracking(enriched);');
|
|
347
|
+
|
|
348
|
+
const mergeCodeBuilder = new CodeBuilder();
|
|
349
|
+
|
|
350
|
+
const mergeFunctionRoot = mergeCodeBuilder.factory("factory", { name: "factory" }).parameters({ name: "collectionName", value: this.collectionName });
|
|
351
|
+
const mergeFunctionBody = mergeFunctionRoot.function(undefined, { name: "function" }).parameters("destination", "source").return();
|
|
352
|
+
|
|
353
|
+
const pauseFunctionBody = mergeFunctionBody.function("pause")
|
|
354
|
+
.appendBody("// initiate change tracking if needed");
|
|
355
|
+
|
|
356
|
+
pauseFunctionBody.if("destination.__tracking__ == null")
|
|
357
|
+
.appendBody("destination.__tracking__ = {};");
|
|
358
|
+
|
|
359
|
+
pauseFunctionBody.appendBody("destination.__tracking__.isPaused = true;");
|
|
360
|
+
|
|
361
|
+
mergeFunctionBody.function("unpause")
|
|
362
|
+
.appendBody("// unpause change tracking if needed")
|
|
363
|
+
.if("destination.__tracking__ != null")
|
|
364
|
+
.appendBody("destination.__tracking__.isPaused = false;");
|
|
365
|
+
|
|
366
|
+
mergeFunctionBody.slot("header").raw(`pause()`);
|
|
367
|
+
mergeFunctionBody.slot("assignments");
|
|
368
|
+
mergeFunctionBody.slot("ifs");
|
|
369
|
+
mergeFunctionBody.slot("return").raw(`
|
|
370
|
+
unpause();
|
|
371
|
+
|
|
372
|
+
return destination;`);
|
|
373
|
+
|
|
374
|
+
const prepareCodeBuilder = new CodeBuilder();
|
|
375
|
+
prepareCodeBuilder.slot("result");
|
|
376
|
+
prepareCodeBuilder.slot("assignments");
|
|
377
|
+
prepareCodeBuilder.slot("return").raw(` return result;`);
|
|
378
|
+
|
|
379
|
+
const stripCodeBuilder = new CodeBuilder();
|
|
380
|
+
stripCodeBuilder.slot("result");
|
|
381
|
+
stripCodeBuilder.slot("return").raw(` return result;`);
|
|
382
|
+
|
|
383
|
+
const cloneCodeBuilder = new CodeBuilder();
|
|
384
|
+
cloneCodeBuilder.slot("result");
|
|
385
|
+
cloneCodeBuilder.slot("return").raw(` return result;`);
|
|
386
|
+
|
|
387
|
+
const compareCodeBuilder = new CodeBuilder();
|
|
388
|
+
compareCodeBuilder.slot("result");
|
|
389
|
+
compareCodeBuilder.slot("return").raw(` return result;`);
|
|
390
|
+
|
|
391
|
+
const deserializeCodeBuilder = new CodeBuilder();
|
|
392
|
+
deserializeCodeBuilder.slot("result");
|
|
393
|
+
deserializeCodeBuilder.slot("if");
|
|
394
|
+
deserializeCodeBuilder.slot("return").raw(` return result;`);
|
|
395
|
+
|
|
396
|
+
const serializeCodeBuilder = new CodeBuilder();
|
|
397
|
+
serializeCodeBuilder.slot("result");
|
|
398
|
+
serializeCodeBuilder.slot("if");
|
|
399
|
+
serializeCodeBuilder.slot("return").raw(` return result;`);
|
|
400
|
+
|
|
401
|
+
const idSelectorCodeBuilder = new CodeBuilder();
|
|
402
|
+
idSelectorCodeBuilder.slot("result");
|
|
403
|
+
idSelectorCodeBuilder.slot("return").raw(` return result;`);
|
|
404
|
+
|
|
405
|
+
const hashTypeCodeBuilder = new CodeBuilder();
|
|
406
|
+
hashTypeCodeBuilder.slot("ifs");
|
|
407
|
+
hashTypeCodeBuilder.slot("return").raw(` return "Ids";`);
|
|
408
|
+
|
|
409
|
+
const hashCodeBuilder = new CodeBuilder();
|
|
410
|
+
hashCodeBuilder.slot("functions").raw(`
|
|
411
|
+
function stringifyDate(d) {
|
|
412
|
+
|
|
413
|
+
if (d == null) {
|
|
414
|
+
return "";
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (typeof d === "string") {
|
|
418
|
+
return d;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (d.toISOString != null) {
|
|
422
|
+
return d.toISOString();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return d.toString();
|
|
426
|
+
}
|
|
427
|
+
`);
|
|
428
|
+
const hashCodeBuilderIfBlock = hashCodeBuilder.if(`type === "Ids"`, { name: "hash-id-if" });
|
|
429
|
+
hashCodeBuilderIfBlock.slot("if-body");
|
|
430
|
+
hashCodeBuilderIfBlock.appendBody("return result");
|
|
431
|
+
hashCodeBuilder.slot("hash-object-return");
|
|
432
|
+
hashCodeBuilder.raw(` return result;`)
|
|
433
|
+
|
|
434
|
+
const idProperties: PropertyInfo<any>[] = [];
|
|
435
|
+
const allPropertyNamesAndPaths: string[] = [];
|
|
436
|
+
let hashType: HashType = HashType.Ids;
|
|
437
|
+
let hasIdentities = false;
|
|
438
|
+
let hasIdentityKeys = false;
|
|
439
|
+
|
|
440
|
+
this._iterate(schema, (property) => {
|
|
441
|
+
|
|
442
|
+
properties.push(property);
|
|
443
|
+
propertyMap.set(property.id, property);
|
|
444
|
+
allPropertyNamesAndPaths.push(property.getSelectrorPath({ parent: "entity" }));
|
|
445
|
+
|
|
446
|
+
if (property.isIdentity === true) {
|
|
447
|
+
hasIdentities = true;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (property.isKey === true) {
|
|
451
|
+
idProperties.push(property);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (property.isKey === true && property.isIdentity === true) {
|
|
455
|
+
hasIdentityKeys = true;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
enricher.handle(property, enricherCodeBuilder);
|
|
459
|
+
merge.handle(property, mergeCodeBuilder);
|
|
460
|
+
prepare.handle(property, prepareCodeBuilder);
|
|
461
|
+
strip.handle(property, stripCodeBuilder);
|
|
462
|
+
clone.handle(property, cloneCodeBuilder);
|
|
463
|
+
compare.handle(property, compareCodeBuilder);
|
|
464
|
+
deserialize.handle(property, deserializeCodeBuilder);
|
|
465
|
+
serializeHandler.handle(property, serializeCodeBuilder)
|
|
466
|
+
hashTypeHandler.handle(property, hashTypeCodeBuilder);
|
|
467
|
+
idSelectorHandler.handle(property, idSelectorCodeBuilder);
|
|
468
|
+
hashHandler.handle(property, hashCodeBuilder);
|
|
469
|
+
enableChangeTrackingHandler.handle(property, changeTrackingCodeBuilder);
|
|
470
|
+
freezeHandler.handle(property, freezeCodeBuilder);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
if (idProperties.length === 0) {
|
|
474
|
+
throw new Error(`Schema must have a key. Use .key() to mark a property as a key. Collection Name: ${this.collectionName}`)
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const enrichParams = enricherFunctionRoot.getParameters()
|
|
478
|
+
const mergeParams = mergeFunctionRoot.getParameters()
|
|
479
|
+
const enrichGenerator = Function(`return ${enricherCodeBuilder.toString()}`);
|
|
480
|
+
const mergeGenerator = Function(`return ${mergeCodeBuilder.toString()}`);
|
|
481
|
+
|
|
482
|
+
const getIdsFunction = Function("entity", idSelectorCodeBuilder.toString()) as (entity: InferType<T>) => [IdType];
|
|
483
|
+
const getHashTypeFunction = Function("entity", hashTypeCodeBuilder.toString()) as GetHashTypeFunction<T>;
|
|
484
|
+
const prepareFunction = Function("entity", prepareCodeBuilder.toString()) as (entity: InferCreateType<T>) => InferCreateType<T>;
|
|
485
|
+
const cloneFunction = Function("entity", cloneCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
486
|
+
const deserializeFunction = Function("entity", deserializeCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
487
|
+
const serializeFunction = Function("entity", serializeCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
488
|
+
const compareFunction = Function("a", "b", compareCodeBuilder.toString()) as (a: InferType<T>, fromDb: InferType<T>) => boolean;;
|
|
489
|
+
const stripFunction = Function("entity", stripCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
490
|
+
const hashFunction = Function("entity", "type", hashCodeBuilder.toString()) as HashFunction<T>;
|
|
491
|
+
const enableChangeTrackingFunction = Function("entity", changeTrackingCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
492
|
+
const freezeFunction = Function("entity", freezeCodeBuilder.toString()) as (entity: InferType<T>) => InferType<T>;
|
|
493
|
+
|
|
494
|
+
const enricherFactoryFunction = enrichGenerator();
|
|
495
|
+
const mergeFactoryFunction = mergeGenerator();
|
|
496
|
+
const enricherFunction = enricherFactoryFunction(...enrichParams.map(w => w.value));
|
|
497
|
+
const mergeFunction = mergeFactoryFunction(...mergeParams.map(w => w.value));
|
|
498
|
+
|
|
499
|
+
const idPropertyNames = idProperties.map(w => w.name);
|
|
500
|
+
const getId = (entity: InferType<T>) => {
|
|
501
|
+
if (idPropertyNames.length > 1) {
|
|
502
|
+
return hashFunction(entity, HashType.Ids) as IdType;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return getIdsFunction(entity as any)[0] as IdType;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const getProperty = (id: string) => propertyMap.get(id);
|
|
509
|
+
const id = hash([...allPropertyNamesAndPaths, this.collectionName].join(","));
|
|
510
|
+
const paths = new Set(properties.map(x => x.getAssignmentPath()));
|
|
511
|
+
|
|
512
|
+
// memoize this by the validProperties
|
|
513
|
+
// TODO: See if we can generate a function to do this and eliminate loops
|
|
514
|
+
const deserializePartial = (item: Record<string, unknown>, properties: PropertyInfo<T>[]) => {
|
|
515
|
+
|
|
516
|
+
for (let i = 0, length = properties.length; i < length; i++) {
|
|
517
|
+
const property = properties[i];
|
|
518
|
+
const value = property.getValue(item);
|
|
519
|
+
|
|
520
|
+
if (value == null) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const deserialized = property.deserialize(value);
|
|
525
|
+
property.setValue(item, deserialized);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return item as DeepPartial<InferType<T>>;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return {
|
|
532
|
+
createSubscription: (signal?: AbortSignal) => new CollectionSubscription(id, signal),
|
|
533
|
+
getId,
|
|
534
|
+
getProperty,
|
|
535
|
+
properties,
|
|
536
|
+
idProperties,
|
|
537
|
+
hasIdentities,
|
|
538
|
+
hashType,
|
|
539
|
+
getHashType: getHashTypeFunction,
|
|
540
|
+
merge: mergeFunction,
|
|
541
|
+
prepare: prepareFunction,
|
|
542
|
+
clone: cloneFunction,
|
|
543
|
+
deserializePartial,
|
|
544
|
+
deserialize: deserializeFunction,
|
|
545
|
+
serialize: serializeFunction,
|
|
546
|
+
compare: compareFunction,
|
|
547
|
+
strip: stripFunction,
|
|
548
|
+
hash: hashFunction,
|
|
549
|
+
id,
|
|
550
|
+
getIds: getIdsFunction,
|
|
551
|
+
enrich: enricherFunction,
|
|
552
|
+
collectionName: this.collectionName,
|
|
553
|
+
hasIdentityKeys,
|
|
554
|
+
freeze: freezeFunction,
|
|
555
|
+
enableChangeTracking: enableChangeTrackingFunction,
|
|
556
|
+
definition: this,
|
|
557
|
+
getIndexes: () => {
|
|
558
|
+
|
|
559
|
+
const indexes: Index[] = [];
|
|
560
|
+
|
|
561
|
+
for (let i = 0, length = properties.length; i < length; i++) {
|
|
562
|
+
const property = properties[i];
|
|
563
|
+
|
|
564
|
+
if (property.indexes.length === 0) {
|
|
565
|
+
continue; // No Index
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
for (let j = 0, l = property.indexes.length; j < l; j++) {
|
|
569
|
+
const indexName = property.indexes[j];
|
|
570
|
+
|
|
571
|
+
// Test for compound indexes
|
|
572
|
+
const connections = properties.filter(w =>
|
|
573
|
+
w !== property && // Don't match with self
|
|
574
|
+
w.indexes.some(index => index === indexName)
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
const indexedProperties = [property, ...connections];
|
|
578
|
+
|
|
579
|
+
if (indexedProperties.length === 1) {
|
|
580
|
+
// Not a compound property
|
|
581
|
+
if (indexedProperties[0].isKey) {
|
|
582
|
+
indexes.push({
|
|
583
|
+
properties: indexedProperties,
|
|
584
|
+
type: "primary-key",
|
|
585
|
+
name: indexName
|
|
586
|
+
});
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (indexedProperties[0].isDistinct) {
|
|
591
|
+
indexes.push({
|
|
592
|
+
properties: indexedProperties,
|
|
593
|
+
type: "unique",
|
|
594
|
+
name: indexName
|
|
595
|
+
});
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
indexes.push({
|
|
600
|
+
properties: indexedProperties,
|
|
601
|
+
type: "single",
|
|
602
|
+
name: indexName
|
|
603
|
+
});
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (indexes.some(w => w.name === indexName)) {
|
|
608
|
+
continue; // Already in a compound index
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
indexes.push({
|
|
612
|
+
properties: indexedProperties,
|
|
613
|
+
type: "compound",
|
|
614
|
+
name: indexName
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
return indexes;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
} catch (e) {
|
|
623
|
+
throw new SchemaError(e, `Error compiling schema for collection: ${this.collectionName}`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SchemaArray } from "./property/types/SchemaArray";
|
|
2
|
+
import { SchemaBase } from "./property/base/SchemaBase";
|
|
3
|
+
import { SchemaBoolean } from "./property/types/SchemaBoolean";
|
|
4
|
+
import { SchemaDate } from "./property/types/SchemaDate";
|
|
5
|
+
import { SchemaDefinition } from "./SchemaDefinition";
|
|
6
|
+
import { SchemaNumber } from "./property/types/SchemaNumber";
|
|
7
|
+
import { SchemaObject } from "./property/types/SchemaObject";
|
|
8
|
+
import { SchemaString } from "./property/types/SchemaString";
|
|
9
|
+
|
|
10
|
+
export const s = {
|
|
11
|
+
number: <T extends number[] = number[]>(...literals: T) => new SchemaNumber<T[number] extends never ? number : T[number], never>(null, literals),
|
|
12
|
+
string: <T extends string[] = string[]>(...literals: T) => new SchemaString<T[number] extends never ? string : T[number], never>(null, literals),
|
|
13
|
+
boolean: <T extends boolean = boolean>() => new SchemaBoolean<T, never>(),
|
|
14
|
+
date: <T extends Date = Date>() => new SchemaDate<T, never>(),
|
|
15
|
+
array: <T extends any>(schema: SchemaBase<T, never>) => new SchemaArray<SchemaBase<T, never>, never>(schema as any),
|
|
16
|
+
object: <T extends {} = {}>(schema: T) => new SchemaObject<T, never>(schema),
|
|
17
|
+
define: <T extends {}>(collectionName: string, schema: T) => new SchemaDefinition<T>(collectionName, schema)
|
|
18
|
+
}
|