tsondb 0.10.2 → 0.11.0
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/src/node/index.js +1 -1
- package/dist/src/node/schema/Node.d.ts +5 -5
- package/dist/src/node/schema/Node.js +53 -53
- package/dist/src/node/schema/Schema.js +58 -1
- package/dist/src/node/schema/declarations/Declaration.js +1 -1
- package/dist/src/node/schema/declarations/EntityDecl.js +4 -4
- package/dist/src/node/schema/declarations/EnumDecl.js +7 -4
- package/dist/src/node/schema/declarations/TypeAliasDecl.d.ts +2 -2
- package/dist/src/node/schema/declarations/TypeAliasDecl.js +4 -4
- package/dist/src/node/schema/types/generic/ArrayType.js +4 -4
- package/dist/src/node/schema/types/generic/EnumType.js +6 -6
- package/dist/src/node/schema/types/generic/ObjectType.js +5 -5
- package/dist/src/node/schema/types/primitives/BooleanType.js +1 -1
- package/dist/src/node/schema/types/primitives/DateType.js +1 -1
- package/dist/src/node/schema/types/primitives/FloatType.js +1 -1
- package/dist/src/node/schema/types/primitives/IntegerType.js +1 -1
- package/dist/src/node/schema/types/primitives/StringType.js +1 -1
- package/dist/src/node/schema/types/references/IncludeIdentifierType.d.ts +3 -3
- package/dist/src/node/schema/types/references/IncludeIdentifierType.js +30 -6
- package/dist/src/node/schema/types/references/NestedEntityMapType.js +7 -7
- package/dist/src/node/schema/types/references/ReferenceIdentifierType.js +1 -1
- package/dist/src/node/schema/types/references/TypeArgumentType.js +1 -1
- package/dist/src/node/utils/instanceOperations.js +1 -1
- package/dist/src/node/utils/references.js +4 -4
- package/dist/src/web/routes/Entity.js +4 -4
- package/package.json +1 -1
package/dist/src/node/index.js
CHANGED
|
@@ -34,7 +34,7 @@ const _validate = (dataRootPath, entities, instancesByEntityName, options = {})
|
|
|
34
34
|
const errors = (checkOnlyEntities.length > 0
|
|
35
35
|
? entities.filter(entity => checkOnlyEntities.includes(entity.name))
|
|
36
36
|
: entities)
|
|
37
|
-
.flatMap(entity => parallelizeErrors(instancesByEntityName[entity.name]?.map(instance => wrapErrorsIfAny(`in file ${styleText("white", `"${dataRootPath}${sep}${styleText("bold", join(entity.name, getFileNameForId(instance.id)))}"`)}`, validateEntityDecl(validationHelpers, entity, instance.content))) ?? []))
|
|
37
|
+
.flatMap(entity => parallelizeErrors(instancesByEntityName[entity.name]?.map(instance => wrapErrorsIfAny(`in file ${styleText("white", `"${dataRootPath}${sep}${styleText("bold", join(entity.name, getFileNameForId(instance.id)))}"`)}`, validateEntityDecl(validationHelpers, [], entity, instance.content))) ?? []))
|
|
38
38
|
.toSorted((a, b) => a.message.localeCompare(b.message));
|
|
39
39
|
if (errors.length === 0) {
|
|
40
40
|
debug("All entities are valid");
|
|
@@ -64,8 +64,8 @@ export declare const createValidators: (instancesByEntityName: InstancesByEntity
|
|
|
64
64
|
export type Predicate<T extends Node> = (node: Node) => node is T;
|
|
65
65
|
export type GetNestedDeclarations<T extends Node = Node> = (addedDecls: NestedDecl[], node: T, parentDecl: Decl | undefined) => NestedDecl[];
|
|
66
66
|
export declare const getNestedDeclarations: GetNestedDeclarations;
|
|
67
|
-
export type Validator<T extends Node = Node> = (helpers: Validators, node: T, value: unknown) => Error[];
|
|
68
|
-
export type ValidatorOfParamDecl<T extends Node = Node> = (helpers: Validators, node: T, typeArgs: Type[], value: unknown) => Error[];
|
|
67
|
+
export type Validator<T extends Node = Node> = (helpers: Validators, inDecls: Decl[], node: T, value: unknown) => Error[];
|
|
68
|
+
export type ValidatorOfParamDecl<T extends Node = Node> = (helpers: Validators, inDecls: Decl[], node: T, typeArgs: Type[], value: unknown) => Error[];
|
|
69
69
|
export declare const validateDecl: ValidatorOfParamDecl<Decl>;
|
|
70
70
|
export declare const validateType: Validator<Type>;
|
|
71
71
|
export type NodeWithResolvedTypeArguments<T extends Node | null> = T extends BooleanType | DateType | FloatType | IntegerType | StringType | ReferenceIdentifierType ? T : T extends EntityDecl<infer N, infer P, infer FK> ? EntityDecl<N, {
|
|
@@ -80,8 +80,8 @@ export type NodeWithResolvedTypeArguments<T extends Node | null> = T extends Boo
|
|
|
80
80
|
}> : T extends TypeArgumentType ? Type : T extends IncludeIdentifierType<[], IncludableDeclP<[]>> ? T : T extends IncludeIdentifierType ? Type : T extends NestedEntityMapType<infer N, infer P> ? NestedEntityMapType<N, {
|
|
81
81
|
[K in keyof P]: P[K] extends MemberDecl<infer PT, infer R> ? MemberDecl<NodeWithResolvedTypeArguments<PT>, R> : never;
|
|
82
82
|
}> : T extends TypeParameter<infer N, infer C> ? TypeParameter<N, NodeWithResolvedTypeArguments<C>> : T extends ChildEntitiesType<infer E> ? ChildEntitiesType<E> : T extends null ? null : never;
|
|
83
|
-
export type TypeArgumentsResolver<T extends Node = Node> = (args: Record<string, Type>, node: T) => NodeWithResolvedTypeArguments<T>;
|
|
84
|
-
export declare const resolveTypeArguments: <T extends Node = Node>(args: Record<string, Type>, node: T) => NodeWithResolvedTypeArguments<T>;
|
|
83
|
+
export type TypeArgumentsResolver<T extends Node = Node> = (args: Record<string, Type>, node: T, inDecl: Decl[]) => NodeWithResolvedTypeArguments<T>;
|
|
84
|
+
export declare const resolveTypeArguments: <T extends Node = Node>(args: Record<string, Type>, node: T, inDecl: Decl[]) => NodeWithResolvedTypeArguments<T>;
|
|
85
85
|
export type SerializedNodeMap = {
|
|
86
86
|
[NodeKind.EntityDecl]: [EntityDecl, SerializedEntityDecl];
|
|
87
87
|
[NodeKind.EnumDecl]: [EnumDecl, SerializedEnumDecl];
|
|
@@ -114,5 +114,5 @@ export type Serialized<T extends Node> = T extends EntityDecl<infer Name, infer
|
|
|
114
114
|
export type SerializedOf<T extends Node> = SerializedNodeMap[T["kind"]][1];
|
|
115
115
|
export type Serializer<T extends Node = Node> = (node: T) => Serialized<T>;
|
|
116
116
|
export declare const serializeNode: <T extends Node>(node: T) => Serialized<T>;
|
|
117
|
-
export type GetReferences<T extends Node = Node> = (node: T, value: unknown) => string[];
|
|
117
|
+
export type GetReferences<T extends Node = Node> = (node: T, value: unknown, inDecl: Decl[]) => string[];
|
|
118
118
|
export declare const getReferences: GetReferences;
|
|
@@ -147,86 +147,86 @@ export const getNestedDeclarations = (addedDecls, node, parentDecl) => {
|
|
|
147
147
|
return assertExhaustive(node);
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
|
-
export const validateDecl = (helpers, decl, typeArgs, value) => {
|
|
150
|
+
export const validateDecl = (helpers, inDecls, decl, typeArgs, value) => {
|
|
151
151
|
switch (decl.kind) {
|
|
152
152
|
case NodeKind.EntityDecl:
|
|
153
|
-
return validateEntityDecl(helpers, decl, value);
|
|
153
|
+
return validateEntityDecl(helpers, inDecls, decl, value);
|
|
154
154
|
case NodeKind.EnumDecl:
|
|
155
|
-
return validateEnumDecl(helpers, decl, typeArgs, value);
|
|
155
|
+
return validateEnumDecl(helpers, inDecls, decl, typeArgs, value);
|
|
156
156
|
case NodeKind.TypeAliasDecl:
|
|
157
|
-
return validateTypeAliasDecl(helpers, decl, typeArgs, value);
|
|
157
|
+
return validateTypeAliasDecl(helpers, inDecls, decl, typeArgs, value);
|
|
158
158
|
default:
|
|
159
159
|
return assertExhaustive(decl);
|
|
160
160
|
}
|
|
161
161
|
};
|
|
162
|
-
export const validateType = (helpers, type, value) => {
|
|
162
|
+
export const validateType = (helpers, inDecls, type, value) => {
|
|
163
163
|
switch (type.kind) {
|
|
164
164
|
case NodeKind.ArrayType:
|
|
165
|
-
return validateArrayType(helpers, type, value);
|
|
165
|
+
return validateArrayType(helpers, inDecls, type, value);
|
|
166
166
|
case NodeKind.ObjectType:
|
|
167
|
-
return validateObjectType(helpers, type, value);
|
|
167
|
+
return validateObjectType(helpers, inDecls, type, value);
|
|
168
168
|
case NodeKind.BooleanType:
|
|
169
|
-
return validateBooleanType(helpers, type, value);
|
|
169
|
+
return validateBooleanType(helpers, inDecls, type, value);
|
|
170
170
|
case NodeKind.DateType:
|
|
171
|
-
return validateDateType(helpers, type, value);
|
|
171
|
+
return validateDateType(helpers, inDecls, type, value);
|
|
172
172
|
case NodeKind.FloatType:
|
|
173
|
-
return validateFloatType(helpers, type, value);
|
|
173
|
+
return validateFloatType(helpers, inDecls, type, value);
|
|
174
174
|
case NodeKind.IntegerType:
|
|
175
|
-
return validateIntegerType(helpers, type, value);
|
|
175
|
+
return validateIntegerType(helpers, inDecls, type, value);
|
|
176
176
|
case NodeKind.StringType:
|
|
177
|
-
return validateStringType(helpers, type, value);
|
|
177
|
+
return validateStringType(helpers, inDecls, type, value);
|
|
178
178
|
case NodeKind.TypeArgumentType:
|
|
179
|
-
return validateTypeArgumentType(helpers, type, value);
|
|
179
|
+
return validateTypeArgumentType(helpers, inDecls, type, value);
|
|
180
180
|
case NodeKind.ReferenceIdentifierType:
|
|
181
|
-
return validateReferenceIdentifierType(helpers, type, value);
|
|
181
|
+
return validateReferenceIdentifierType(helpers, inDecls, type, value);
|
|
182
182
|
case NodeKind.IncludeIdentifierType:
|
|
183
|
-
return validateIncludeIdentifierType(helpers, type, value);
|
|
183
|
+
return validateIncludeIdentifierType(helpers, inDecls, type, value);
|
|
184
184
|
case NodeKind.NestedEntityMapType:
|
|
185
|
-
return validateNestedEntityMapType(helpers, type, value);
|
|
185
|
+
return validateNestedEntityMapType(helpers, inDecls, type, value);
|
|
186
186
|
case NodeKind.EnumType:
|
|
187
|
-
return validateEnumType(helpers, type, value);
|
|
187
|
+
return validateEnumType(helpers, inDecls, type, value);
|
|
188
188
|
case NodeKind.ChildEntitiesType:
|
|
189
|
-
return validateChildEntitiesType(helpers, type, value);
|
|
189
|
+
return validateChildEntitiesType(helpers, inDecls, type, value);
|
|
190
190
|
default:
|
|
191
191
|
return assertExhaustive(type);
|
|
192
192
|
}
|
|
193
193
|
};
|
|
194
|
-
export const resolveTypeArguments = (args, node) => {
|
|
194
|
+
export const resolveTypeArguments = (args, node, inDecl) => {
|
|
195
195
|
switch (node.kind) {
|
|
196
196
|
case NodeKind.EntityDecl:
|
|
197
|
-
return resolveTypeArgumentsInEntityDecl(args, node);
|
|
197
|
+
return resolveTypeArgumentsInEntityDecl(args, node, inDecl);
|
|
198
198
|
case NodeKind.EnumDecl:
|
|
199
|
-
return resolveTypeArgumentsInEnumDecl(args, node);
|
|
199
|
+
return resolveTypeArgumentsInEnumDecl(args, node, inDecl);
|
|
200
200
|
case NodeKind.TypeAliasDecl:
|
|
201
|
-
return resolveTypeArgumentsInTypeAliasDecl(args, node);
|
|
201
|
+
return resolveTypeArgumentsInTypeAliasDecl(args, node, inDecl);
|
|
202
202
|
case NodeKind.ArrayType:
|
|
203
|
-
return resolveTypeArgumentsInArrayType(args, node);
|
|
203
|
+
return resolveTypeArgumentsInArrayType(args, node, inDecl);
|
|
204
204
|
case NodeKind.ObjectType:
|
|
205
|
-
return resolveTypeArgumentsInObjectType(args, node);
|
|
205
|
+
return resolveTypeArgumentsInObjectType(args, node, inDecl);
|
|
206
206
|
case NodeKind.BooleanType:
|
|
207
|
-
return resolveTypeArgumentsInBooleanType(args, node);
|
|
207
|
+
return resolveTypeArgumentsInBooleanType(args, node, inDecl);
|
|
208
208
|
case NodeKind.DateType:
|
|
209
|
-
return resolveTypeArgumentsInDateType(args, node);
|
|
209
|
+
return resolveTypeArgumentsInDateType(args, node, inDecl);
|
|
210
210
|
case NodeKind.FloatType:
|
|
211
|
-
return resolveTypeArgumentsInFloatType(args, node);
|
|
211
|
+
return resolveTypeArgumentsInFloatType(args, node, inDecl);
|
|
212
212
|
case NodeKind.IntegerType:
|
|
213
|
-
return resolveTypeArgumentsInIntegerType(args, node);
|
|
213
|
+
return resolveTypeArgumentsInIntegerType(args, node, inDecl);
|
|
214
214
|
case NodeKind.StringType:
|
|
215
|
-
return resolveTypeArgumentsInStringType(args, node);
|
|
215
|
+
return resolveTypeArgumentsInStringType(args, node, inDecl);
|
|
216
216
|
case NodeKind.TypeArgumentType:
|
|
217
217
|
return resolveTypeArgumentsInTypeArgumentType(args, node);
|
|
218
218
|
case NodeKind.ReferenceIdentifierType:
|
|
219
|
-
return resolveTypeArgumentsInReferenceIdentifierType(args, node);
|
|
219
|
+
return resolveTypeArgumentsInReferenceIdentifierType(args, node, inDecl);
|
|
220
220
|
case NodeKind.IncludeIdentifierType:
|
|
221
|
-
return resolveTypeArgumentsInIncludeIdentifierType(args, node);
|
|
221
|
+
return resolveTypeArgumentsInIncludeIdentifierType(args, node, inDecl);
|
|
222
222
|
case NodeKind.NestedEntityMapType:
|
|
223
|
-
return resolveTypeArgumentsInNestedEntityMapType(args, node);
|
|
223
|
+
return resolveTypeArgumentsInNestedEntityMapType(args, node, inDecl);
|
|
224
224
|
case NodeKind.EnumType:
|
|
225
|
-
return resolveTypeArgumentsInEnumType(args, node);
|
|
225
|
+
return resolveTypeArgumentsInEnumType(args, node, inDecl);
|
|
226
226
|
case NodeKind.TypeParameter:
|
|
227
|
-
return resolveTypeArgumentsInTypeParameter(args, node);
|
|
227
|
+
return resolveTypeArgumentsInTypeParameter(args, node, inDecl);
|
|
228
228
|
case NodeKind.ChildEntitiesType:
|
|
229
|
-
return resolveTypeArgumentsInChildEntitiesType(args, node);
|
|
229
|
+
return resolveTypeArgumentsInChildEntitiesType(args, node, inDecl);
|
|
230
230
|
default:
|
|
231
231
|
return assertExhaustive(node);
|
|
232
232
|
}
|
|
@@ -271,42 +271,42 @@ export const serializeNode = (node) => {
|
|
|
271
271
|
return assertExhaustive(node);
|
|
272
272
|
}
|
|
273
273
|
};
|
|
274
|
-
export const getReferences = (node, value) => {
|
|
274
|
+
export const getReferences = (node, value, inDecl) => {
|
|
275
275
|
switch (node.kind) {
|
|
276
276
|
case NodeKind.EntityDecl:
|
|
277
|
-
return getReferencesForEntityDecl(node, value);
|
|
277
|
+
return getReferencesForEntityDecl(node, value, inDecl);
|
|
278
278
|
case NodeKind.EnumDecl:
|
|
279
|
-
return getReferencesForEnumDecl(node, value);
|
|
279
|
+
return getReferencesForEnumDecl(node, value, inDecl);
|
|
280
280
|
case NodeKind.TypeAliasDecl:
|
|
281
|
-
return getReferencesForTypeAliasDecl(node, value);
|
|
281
|
+
return getReferencesForTypeAliasDecl(node, value, inDecl);
|
|
282
282
|
case NodeKind.ArrayType:
|
|
283
|
-
return getReferencesForArrayType(node, value);
|
|
283
|
+
return getReferencesForArrayType(node, value, inDecl);
|
|
284
284
|
case NodeKind.ObjectType:
|
|
285
|
-
return getReferencesForObjectType(node, value);
|
|
285
|
+
return getReferencesForObjectType(node, value, inDecl);
|
|
286
286
|
case NodeKind.BooleanType:
|
|
287
|
-
return getReferencesForBooleanType(node, value);
|
|
287
|
+
return getReferencesForBooleanType(node, value, inDecl);
|
|
288
288
|
case NodeKind.DateType:
|
|
289
|
-
return getReferencesForDateType(node, value);
|
|
289
|
+
return getReferencesForDateType(node, value, inDecl);
|
|
290
290
|
case NodeKind.FloatType:
|
|
291
|
-
return getReferencesForFloatType(node, value);
|
|
291
|
+
return getReferencesForFloatType(node, value, inDecl);
|
|
292
292
|
case NodeKind.IntegerType:
|
|
293
|
-
return getReferencesForIntegerType(node, value);
|
|
293
|
+
return getReferencesForIntegerType(node, value, inDecl);
|
|
294
294
|
case NodeKind.StringType:
|
|
295
|
-
return getReferencesForStringType(node, value);
|
|
295
|
+
return getReferencesForStringType(node, value, inDecl);
|
|
296
296
|
case NodeKind.TypeArgumentType:
|
|
297
|
-
return getReferencesForTypeArgumentType(node, value);
|
|
297
|
+
return getReferencesForTypeArgumentType(node, value, inDecl);
|
|
298
298
|
case NodeKind.ReferenceIdentifierType:
|
|
299
|
-
return getReferencesForReferenceIdentifierType(node, value);
|
|
299
|
+
return getReferencesForReferenceIdentifierType(node, value, inDecl);
|
|
300
300
|
case NodeKind.IncludeIdentifierType:
|
|
301
|
-
return getReferencesForIncludeIdentifierType(node, value);
|
|
301
|
+
return getReferencesForIncludeIdentifierType(node, value, inDecl);
|
|
302
302
|
case NodeKind.NestedEntityMapType:
|
|
303
|
-
return getReferencesForNestedEntityMapType(node, value);
|
|
303
|
+
return getReferencesForNestedEntityMapType(node, value, inDecl);
|
|
304
304
|
case NodeKind.EnumType:
|
|
305
|
-
return getReferencesForEnumType(node, value);
|
|
305
|
+
return getReferencesForEnumType(node, value, inDecl);
|
|
306
306
|
case NodeKind.TypeParameter:
|
|
307
|
-
return getReferencesForTypeParameter(node, value);
|
|
307
|
+
return getReferencesForTypeParameter(node, value, inDecl);
|
|
308
308
|
case NodeKind.ChildEntitiesType:
|
|
309
|
-
return getReferencesForChildEntitiesType(node, value);
|
|
309
|
+
return getReferencesForChildEntitiesType(node, value, inDecl);
|
|
310
310
|
default:
|
|
311
311
|
return assertExhaustive(node);
|
|
312
312
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Debug from "debug";
|
|
2
|
+
import { assertExhaustive } from "../../shared/utils/typeSafety.js";
|
|
2
3
|
import { getParameterNames, walkNodeTree } from "./declarations/Declaration.js";
|
|
3
4
|
import { isEntityDecl } from "./declarations/EntityDecl.js";
|
|
4
5
|
import { cases, isEnumDecl } from "./declarations/EnumDecl.js";
|
|
5
|
-
import { getNestedDeclarations } from "./Node.js";
|
|
6
|
+
import { getNestedDeclarations, NodeKind } from "./Node.js";
|
|
6
7
|
import { isObjectType } from "./types/generic/ObjectType.js";
|
|
7
8
|
import { isStringType } from "./types/primitives/StringType.js";
|
|
8
9
|
import { isChildEntitiesType } from "./types/references/ChildEntitiesType.js";
|
|
@@ -152,6 +153,60 @@ const checkChildEntitiesProvideCorrectPathToParentReferenceIdentifierType = (dec
|
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
};
|
|
156
|
+
const isDeclarationRecursive = (declToCheck) => {
|
|
157
|
+
const isDeclarationIncludedInNode = (visitedDecls, node) => {
|
|
158
|
+
switch (node.kind) {
|
|
159
|
+
case NodeKind.EntityDecl:
|
|
160
|
+
case NodeKind.EnumDecl:
|
|
161
|
+
case NodeKind.TypeAliasDecl:
|
|
162
|
+
return visitedDecls.includes(node)
|
|
163
|
+
? false
|
|
164
|
+
: declToCheck === node ||
|
|
165
|
+
isDeclarationIncludedInNode([...visitedDecls, node], node.type.value);
|
|
166
|
+
case NodeKind.BooleanType:
|
|
167
|
+
case NodeKind.DateType:
|
|
168
|
+
case NodeKind.FloatType:
|
|
169
|
+
case NodeKind.IntegerType:
|
|
170
|
+
case NodeKind.StringType:
|
|
171
|
+
case NodeKind.TypeArgumentType:
|
|
172
|
+
case NodeKind.ReferenceIdentifierType:
|
|
173
|
+
case NodeKind.TypeParameter:
|
|
174
|
+
case NodeKind.ChildEntitiesType:
|
|
175
|
+
return false;
|
|
176
|
+
case NodeKind.ArrayType:
|
|
177
|
+
return isDeclarationIncludedInNode(visitedDecls, node.items);
|
|
178
|
+
case NodeKind.ObjectType:
|
|
179
|
+
return Object.entries(node.properties).some(([_, memberDecl]) => isDeclarationIncludedInNode(visitedDecls, memberDecl.type));
|
|
180
|
+
case NodeKind.IncludeIdentifierType:
|
|
181
|
+
return (declToCheck === node.reference ||
|
|
182
|
+
isDeclarationIncludedInNode(visitedDecls, node.reference));
|
|
183
|
+
case NodeKind.NestedEntityMapType:
|
|
184
|
+
return isDeclarationIncludedInNode(visitedDecls, node.type.value);
|
|
185
|
+
case NodeKind.EnumType:
|
|
186
|
+
return Object.entries(node.values).some(([_, caseDecl]) => caseDecl.type !== null && isDeclarationIncludedInNode(visitedDecls, caseDecl.type));
|
|
187
|
+
default:
|
|
188
|
+
return assertExhaustive(node);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
return isDeclarationIncludedInNode([declToCheck], declToCheck.type.value);
|
|
192
|
+
};
|
|
193
|
+
const checkRecursiveGenericTypeAliasesAndEnumerationsAreOnlyParameterizedDirectlyInTypeAliases = (declarations) => {
|
|
194
|
+
const genericRecursiveDeclarations = declarations.filter(decl => isDeclarationRecursive(decl) && decl.parameters.length > 0);
|
|
195
|
+
for (const decl of declarations) {
|
|
196
|
+
walkNodeTree((node, parentTypes) => {
|
|
197
|
+
if (isIncludeIdentifierType(node) &&
|
|
198
|
+
genericRecursiveDeclarations.includes(node.reference) &&
|
|
199
|
+
decl !== node.reference) {
|
|
200
|
+
if (parentTypes.length > 0) {
|
|
201
|
+
throw TypeError(`generic recursive type "${node.reference.name}", referenced in declaration "${decl.name}", may only be included as a direct descendant of a type alias. This is required for resolving generics for outputs without support for generics, as well as internal type validation.`);
|
|
202
|
+
}
|
|
203
|
+
if (decl.parameters.length > 0) {
|
|
204
|
+
throw TypeError(`generic recursive type "${node.reference.name}", referenced in declaration "${decl.name}", may only be included in a non-generic type alias. This is required for resolving generics for outputs without support for generics, as well as internal type validation.`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}, decl);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
155
210
|
const addDeclarations = (existingDecls, declsToAdd) => declsToAdd.reduce((accDecls, decl) => {
|
|
156
211
|
if (!accDecls.includes(decl)) {
|
|
157
212
|
return getNestedDeclarations(accDecls, decl.kind === "NestedEntity" ? decl.type : decl, undefined);
|
|
@@ -176,6 +231,8 @@ export const Schema = (declarations, localeEntity) => {
|
|
|
176
231
|
checkChildEntitiesProvideCorrectPathToParentReferenceIdentifierType(allDeclsWithoutNestedEntities);
|
|
177
232
|
debug("checking child entity types ...");
|
|
178
233
|
checkChildEntityTypes(localeEntity, allDeclsWithoutNestedEntities);
|
|
234
|
+
debug("checking generic recursive types ...");
|
|
235
|
+
checkRecursiveGenericTypeAliasesAndEnumerationsAreOnlyParameterizedDirectlyInTypeAliases(allDeclsWithoutNestedEntities);
|
|
179
236
|
debug("created schema, no integrity violations found");
|
|
180
237
|
return {
|
|
181
238
|
declarations: allDeclsWithoutNestedEntities,
|
|
@@ -16,7 +16,7 @@ export const validateDeclName = (name) => {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
export const isDeclWithoutTypeParameters = (decl) => decl.parameters.length === 0;
|
|
19
|
-
export const resolveTypeArgumentsInDecls = (decls) => decls.filter(isDeclWithoutTypeParameters).map(decl => resolveTypeArguments({}, decl));
|
|
19
|
+
export const resolveTypeArgumentsInDecls = (decls) => decls.filter(isDeclWithoutTypeParameters).map(decl => resolveTypeArguments({}, decl, []));
|
|
20
20
|
export function walkNodeTree(callbackFn, decl) {
|
|
21
21
|
callbackFn(decl, [], decl);
|
|
22
22
|
walkTypeNodeTree(callbackFn, decl.type.value, [], decl);
|
|
@@ -27,10 +27,10 @@ export { EntityDecl as Entity };
|
|
|
27
27
|
export const isEntityDecl = node => node.kind === NodeKind.EntityDecl;
|
|
28
28
|
export const isEntityDeclWithParentReference = (decl) => decl.parentReferenceKey !== undefined;
|
|
29
29
|
export const getNestedDeclarationsInEntityDecl = (isDeclAdded, decl) => getNestedDeclarationsInObjectType(isDeclAdded, decl.type.value, decl);
|
|
30
|
-
export const validateEntityDecl = (helpers, decl, value) => validateType(helpers, decl.type.value, value);
|
|
31
|
-
export const resolveTypeArgumentsInEntityDecl = (_args, decl) => EntityDecl(decl.sourceUrl, {
|
|
30
|
+
export const validateEntityDecl = (helpers, inDecls, decl, value) => validateType(helpers, inDecls, decl.type.value, value);
|
|
31
|
+
export const resolveTypeArgumentsInEntityDecl = (_args, decl, inDecl) => EntityDecl(decl.sourceUrl, {
|
|
32
32
|
...decl,
|
|
33
|
-
type: () => resolveTypeArguments({}, decl.type.value),
|
|
33
|
+
type: () => resolveTypeArguments({}, decl.type.value, [...inDecl, decl]),
|
|
34
34
|
});
|
|
35
35
|
const createEntityIdentifierComment = () => "The entity’s identifier. A UUID or a locale code if it is registered as the locale entity.";
|
|
36
36
|
export const addEphemeralUUIDToType = (decl) => ({
|
|
@@ -57,4 +57,4 @@ export const serializeEntityDecl = (type) => ({
|
|
|
57
57
|
: type.displayName,
|
|
58
58
|
displayNameCustomizer: type.displayNameCustomizer !== undefined,
|
|
59
59
|
});
|
|
60
|
-
export const getReferencesForEntityDecl = (decl, value) => getReferencesForObjectType(decl.type.value, value);
|
|
60
|
+
export const getReferencesForEntityDecl = (decl, value, inDecl) => getReferencesForObjectType(decl.type.value, value, [...inDecl, decl]);
|
|
@@ -29,17 +29,20 @@ export const EnumDecl = (sourceUrl, options) => {
|
|
|
29
29
|
export { EnumDecl as Enum };
|
|
30
30
|
export const isEnumDecl = node => node.kind === NodeKind.EnumDecl;
|
|
31
31
|
export const getNestedDeclarationsInEnumDecl = (addedDecls, decl) => getNestedDeclarationsInEnumType(addedDecls, decl.type.value, decl);
|
|
32
|
-
export const validateEnumDecl = (helpers, decl, args, value) => validateEnumType(helpers, resolveTypeArgumentsInEnumType(getTypeArgumentsRecord(decl, args), decl.type.value
|
|
33
|
-
|
|
32
|
+
export const validateEnumDecl = (helpers, inDecls, decl, args, value) => validateEnumType(helpers, [...inDecls, decl], resolveTypeArgumentsInEnumType(getTypeArgumentsRecord(decl, args), decl.type.value, [
|
|
33
|
+
...inDecls,
|
|
34
|
+
decl,
|
|
35
|
+
]), value);
|
|
36
|
+
export const resolveTypeArgumentsInEnumDecl = (args, decl, inDecl) => EnumDecl(decl.sourceUrl, {
|
|
34
37
|
name: decl.name,
|
|
35
38
|
comment: decl.comment,
|
|
36
39
|
isDeprecated: decl.isDeprecated,
|
|
37
|
-
values: () => resolveTypeArgumentsInEnumType(args, decl.type.value).values,
|
|
40
|
+
values: () => resolveTypeArgumentsInEnumType(args, decl.type.value, [...inDecl, decl]).values,
|
|
38
41
|
});
|
|
39
42
|
export const serializeEnumDecl = decl => ({
|
|
40
43
|
...decl,
|
|
41
44
|
type: serializeEnumType(decl.type.value),
|
|
42
45
|
parameters: decl.parameters.map(param => serializeTypeParameter(param)),
|
|
43
46
|
});
|
|
44
|
-
export const getReferencesForEnumDecl = (decl, value) => getReferencesForEnumType(decl.type.value, value);
|
|
47
|
+
export const getReferencesForEnumDecl = (decl, value, inDecl) => getReferencesForEnumType(decl.type.value, value, [...inDecl, decl]);
|
|
45
48
|
export const cases = (decl) => Object.values(decl.type.value.values);
|
|
@@ -3,7 +3,7 @@ import type { GetNestedDeclarations, GetReferences, Predicate, Serializer, TypeA
|
|
|
3
3
|
import { NodeKind } from "../Node.ts";
|
|
4
4
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
5
5
|
import type { Type } from "../types/Type.ts";
|
|
6
|
-
import type { BaseDecl, TypeArguments } from "./Declaration.ts";
|
|
6
|
+
import type { BaseDecl, Decl, TypeArguments } from "./Declaration.ts";
|
|
7
7
|
export interface TypeAliasDecl<Name extends string = string, T extends Type = Type, Params extends TypeParameter[] = TypeParameter[]> extends BaseDecl<Name, Params> {
|
|
8
8
|
kind: NodeKind["TypeAliasDecl"];
|
|
9
9
|
type: Lazy<T>;
|
|
@@ -26,7 +26,7 @@ export declare const TypeAliasDecl: <Name extends string, T extends Type>(source
|
|
|
26
26
|
export { TypeAliasDecl as TypeAlias };
|
|
27
27
|
export declare const isTypeAliasDecl: Predicate<TypeAliasDecl>;
|
|
28
28
|
export declare const getNestedDeclarationsInTypeAliasDecl: GetNestedDeclarations<TypeAliasDecl>;
|
|
29
|
-
export declare const validateTypeAliasDecl: <Params extends TypeParameter[]>(helpers: Validators, decl: TypeAliasDecl<string, Type, Params>, args: TypeArguments<Params>, value: unknown) => Error[];
|
|
29
|
+
export declare const validateTypeAliasDecl: <Params extends TypeParameter[]>(helpers: Validators, inDecls: Decl[], decl: TypeAliasDecl<string, Type, Params>, args: TypeArguments<Params>, value: unknown) => Error[];
|
|
30
30
|
export declare const resolveTypeArgumentsInTypeAliasDecl: TypeArgumentsResolver<TypeAliasDecl>;
|
|
31
31
|
export declare const serializeTypeAliasDecl: Serializer<TypeAliasDecl>;
|
|
32
32
|
export declare const getReferencesForTypeAliasDecl: GetReferences<TypeAliasDecl>;
|
|
@@ -27,14 +27,14 @@ export const TypeAliasDecl = (sourceUrl, options) => {
|
|
|
27
27
|
export { TypeAliasDecl as TypeAlias };
|
|
28
28
|
export const isTypeAliasDecl = node => node.kind === NodeKind.TypeAliasDecl;
|
|
29
29
|
export const getNestedDeclarationsInTypeAliasDecl = (addedDecls, decl) => getNestedDeclarations(addedDecls, decl.type.value, decl);
|
|
30
|
-
export const validateTypeAliasDecl = ((helpers, decl, args, value) => validateType(helpers, resolveTypeArguments(getTypeArgumentsRecord(decl, args), decl.type.value), value));
|
|
31
|
-
export const resolveTypeArgumentsInTypeAliasDecl = (args, decl) => TypeAliasDecl(decl.sourceUrl, {
|
|
30
|
+
export const validateTypeAliasDecl = ((helpers, inDecls, decl, args, value) => validateType(helpers, [...inDecls, decl], resolveTypeArguments(getTypeArgumentsRecord(decl, args), decl.type.value, [...inDecls, decl]), value));
|
|
31
|
+
export const resolveTypeArgumentsInTypeAliasDecl = (args, decl, inDecl) => TypeAliasDecl(decl.sourceUrl, {
|
|
32
32
|
...decl,
|
|
33
|
-
type: () => resolveTypeArguments(args, decl.type.value),
|
|
33
|
+
type: () => resolveTypeArguments(args, decl.type.value, [...inDecl, decl]),
|
|
34
34
|
});
|
|
35
35
|
export const serializeTypeAliasDecl = type => ({
|
|
36
36
|
...type,
|
|
37
37
|
type: serializeNode(type.type.value),
|
|
38
38
|
parameters: type.parameters.map(param => serializeTypeParameter(param)),
|
|
39
39
|
});
|
|
40
|
-
export const getReferencesForTypeAliasDecl = (decl, value) => getReferences(decl.type.value, value);
|
|
40
|
+
export const getReferencesForTypeAliasDecl = (decl, value, inDecl) => getReferences(decl.type.value, value, [...inDecl, decl]);
|
|
@@ -15,21 +15,21 @@ export const ArrayType = (items, options = {}) => ({
|
|
|
15
15
|
export { ArrayType as Array };
|
|
16
16
|
export const isArrayType = node => node.kind === NodeKind.ArrayType;
|
|
17
17
|
export const getNestedDeclarationsInArrayType = (addedDecls, type, parentDecl) => getNestedDeclarations(addedDecls, type.items, parentDecl);
|
|
18
|
-
export const validateArrayType = (helpers, type, value) => {
|
|
18
|
+
export const validateArrayType = (helpers, inDecls, type, value) => {
|
|
19
19
|
if (!Array.isArray(value)) {
|
|
20
20
|
return [TypeError(`expected an array, but got ${json(value, helpers.useStyling)}`)];
|
|
21
21
|
}
|
|
22
22
|
return parallelizeErrors([
|
|
23
23
|
...validateArrayConstraints(type, value),
|
|
24
|
-
...value.map((item, index) => wrapErrorsIfAny(`at index ${key(index.toString(), helpers.useStyling)}`, validateType(helpers, type.items, item))),
|
|
24
|
+
...value.map((item, index) => wrapErrorsIfAny(`at index ${key(index.toString(), helpers.useStyling)}`, validateType(helpers, inDecls, type.items, item))),
|
|
25
25
|
]);
|
|
26
26
|
};
|
|
27
|
-
export const resolveTypeArgumentsInArrayType = (args, type) => ArrayType(resolveTypeArguments(args, type.items), {
|
|
27
|
+
export const resolveTypeArgumentsInArrayType = (args, type, inDecl) => ArrayType(resolveTypeArguments(args, type.items, inDecl), {
|
|
28
28
|
...type,
|
|
29
29
|
});
|
|
30
30
|
export const serializeArrayType = type => ({
|
|
31
31
|
...type,
|
|
32
32
|
items: serializeNode(type.items),
|
|
33
33
|
});
|
|
34
|
-
export const getReferencesForArrayType = (type, value) => Array.isArray(value) ? value.flatMap(item => getReferences(type.items, item)) : [];
|
|
34
|
+
export const getReferencesForArrayType = (type, value, inDecl) => Array.isArray(value) ? value.flatMap(item => getReferences(type.items, item, inDecl)) : [];
|
|
35
35
|
export const formatArrayValue = (type, value) => Array.isArray(value) ? value.map(item => formatValue(type.items, item)) : value;
|
|
@@ -10,7 +10,7 @@ export const EnumType = (values) => ({
|
|
|
10
10
|
});
|
|
11
11
|
export const isEnumType = node => node.kind === NodeKind.EnumType;
|
|
12
12
|
export const getNestedDeclarationsInEnumType = (addedDecls, type, parentDecl) => Object.values(type.values).reduce((acc, caseMember) => caseMember.type === null ? acc : getNestedDeclarations(acc, caseMember.type, parentDecl), addedDecls);
|
|
13
|
-
export const validateEnumType = (helpers, type, value) => {
|
|
13
|
+
export const validateEnumType = (helpers, inDecls, type, value) => {
|
|
14
14
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
15
15
|
return [TypeError(`expected an object, but got ${json(value, helpers.useStyling)}`)];
|
|
16
16
|
}
|
|
@@ -42,16 +42,16 @@ export const validateEnumType = (helpers, type, value) => {
|
|
|
42
42
|
];
|
|
43
43
|
}
|
|
44
44
|
return parallelizeErrors([
|
|
45
|
-
wrapErrorsIfAny(`at enum case ${key(`"${caseName}"`, helpers.useStyling)}`, validateType(helpers, associatedType, value[caseName])),
|
|
45
|
+
wrapErrorsIfAny(`at enum case ${key(`"${caseName}"`, helpers.useStyling)}`, validateType(helpers, inDecls, associatedType, value[caseName])),
|
|
46
46
|
]);
|
|
47
47
|
}
|
|
48
48
|
return [];
|
|
49
49
|
};
|
|
50
|
-
export const resolveTypeArgumentsInEnumType = (args, type) => EnumType(Object.fromEntries(Object.entries(type.values).map(([key, { type, ...caseMember }]) => [
|
|
50
|
+
export const resolveTypeArgumentsInEnumType = (args, type, inDecl) => EnumType(Object.fromEntries(Object.entries(type.values).map(([key, { type, ...caseMember }]) => [
|
|
51
51
|
key,
|
|
52
52
|
{
|
|
53
53
|
...caseMember,
|
|
54
|
-
type: type === null ? null : resolveTypeArguments(args, type),
|
|
54
|
+
type: type === null ? null : resolveTypeArguments(args, type, inDecl),
|
|
55
55
|
},
|
|
56
56
|
])));
|
|
57
57
|
export const EnumCaseDecl = (options) => ({
|
|
@@ -69,7 +69,7 @@ export const serializeEnumType = type => ({
|
|
|
69
69
|
},
|
|
70
70
|
])),
|
|
71
71
|
});
|
|
72
|
-
export const getReferencesForEnumType = (type, value) => {
|
|
72
|
+
export const getReferencesForEnumType = (type, value, inDecl) => {
|
|
73
73
|
if (typeof value !== "object" ||
|
|
74
74
|
value === null ||
|
|
75
75
|
Array.isArray(value) ||
|
|
@@ -82,7 +82,7 @@ export const getReferencesForEnumType = (type, value) => {
|
|
|
82
82
|
type.values[enumCase] !== undefined &&
|
|
83
83
|
type.values[enumCase].type !== null &&
|
|
84
84
|
enumCase in value
|
|
85
|
-
? getReferences(type.values[enumCase].type, value[enumCase])
|
|
85
|
+
? getReferences(type.values[enumCase].type, value[enumCase], inDecl)
|
|
86
86
|
: [];
|
|
87
87
|
};
|
|
88
88
|
export const formatEnumType = (type, value) => {
|
|
@@ -26,7 +26,7 @@ export const ObjectType = (properties, options = {}) => {
|
|
|
26
26
|
export { ObjectType as Object };
|
|
27
27
|
export const isObjectType = node => node.kind === NodeKind.ObjectType;
|
|
28
28
|
export const getNestedDeclarationsInObjectType = (addedDecls, type, parentDecl) => Object.values(type.properties).reduce((acc, prop) => getNestedDeclarations(acc, prop.type, parentDecl), addedDecls);
|
|
29
|
-
export const validateObjectType = (helpers, type, value) => {
|
|
29
|
+
export const validateObjectType = (helpers, inDecls, type, value) => {
|
|
30
30
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
31
31
|
return [TypeError(`expected an object, but got ${json(value, helpers.useStyling)}`)];
|
|
32
32
|
}
|
|
@@ -40,13 +40,13 @@ export const validateObjectType = (helpers, type, value) => {
|
|
|
40
40
|
return TypeError(`missing required property ${keyColor(`"${key}"`, helpers.useStyling)}`);
|
|
41
41
|
}
|
|
42
42
|
else if (prop.isRequired || value[key] !== undefined) {
|
|
43
|
-
return wrapErrorsIfAny(`at object key ${keyColor(`"${key}"`, helpers.useStyling)}`, validateType(helpers, prop.type, value[key]));
|
|
43
|
+
return wrapErrorsIfAny(`at object key ${keyColor(`"${key}"`, helpers.useStyling)}`, validateType(helpers, inDecls, prop.type, value[key]));
|
|
44
44
|
}
|
|
45
45
|
return undefined;
|
|
46
46
|
}),
|
|
47
47
|
]);
|
|
48
48
|
};
|
|
49
|
-
export const resolveTypeArgumentsInObjectType = (args, type) => ObjectType(Object.fromEntries(Object.entries(type.properties).map(([key, config]) => [key, { ...config, type: resolveTypeArguments(args, config.type) }])), {
|
|
49
|
+
export const resolveTypeArgumentsInObjectType = (args, type, inDecl) => ObjectType(Object.fromEntries(Object.entries(type.properties).map(([key, config]) => [key, { ...config, type: resolveTypeArguments(args, config.type, inDecl) }])), {
|
|
50
50
|
...type,
|
|
51
51
|
});
|
|
52
52
|
const MemberDecl = (isRequired, type, comment, isDeprecated) => ({
|
|
@@ -68,8 +68,8 @@ export const serializeObjectType = (type) => ({
|
|
|
68
68
|
},
|
|
69
69
|
])),
|
|
70
70
|
});
|
|
71
|
-
export const getReferencesForObjectType = (type, value) => typeof value === "object" && value !== null
|
|
72
|
-
? Object.entries(value).flatMap(([key, propValue]) => type.properties[key] ? getReferences(type.properties[key].type, propValue) : [])
|
|
71
|
+
export const getReferencesForObjectType = (type, value, inDecl) => typeof value === "object" && value !== null
|
|
72
|
+
? Object.entries(value).flatMap(([key, propValue]) => type.properties[key] ? getReferences(type.properties[key].type, propValue, inDecl) : [])
|
|
73
73
|
: [];
|
|
74
74
|
export const formatObjectValue = (type, value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
75
75
|
? sortObjectKeys(Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
@@ -6,7 +6,7 @@ export const BooleanType = () => ({
|
|
|
6
6
|
export { BooleanType as Boolean };
|
|
7
7
|
export const isBooleanType = node => node.kind === NodeKind.BooleanType;
|
|
8
8
|
export const getNestedDeclarationsInBooleanType = addedDecls => addedDecls;
|
|
9
|
-
export const validateBooleanType = (helpers, _type, value) => {
|
|
9
|
+
export const validateBooleanType = (helpers, _inDecls, _type, value) => {
|
|
10
10
|
if (typeof value !== "boolean") {
|
|
11
11
|
return [TypeError(`expected a boolean value, but got ${json(value, helpers.useStyling)}`)];
|
|
12
12
|
}
|
|
@@ -8,7 +8,7 @@ export const DateType = (options) => ({
|
|
|
8
8
|
export { DateType as Date };
|
|
9
9
|
export const isDateType = node => node.kind === NodeKind.DateType;
|
|
10
10
|
export const getNestedDeclarationsInDateType = addedDecls => addedDecls;
|
|
11
|
-
export const validateDateType = (helpers, type, value) => {
|
|
11
|
+
export const validateDateType = (helpers, _inDecls, type, value) => {
|
|
12
12
|
if (typeof value !== "string") {
|
|
13
13
|
return [TypeError(`expected a string, but got ${json(value, helpers.useStyling)}`)];
|
|
14
14
|
}
|
|
@@ -8,7 +8,7 @@ export const FloatType = (options = {}) => ({
|
|
|
8
8
|
export { FloatType as Float };
|
|
9
9
|
export const isFloatType = node => node.kind === NodeKind.FloatType;
|
|
10
10
|
export const getNestedDeclarationsInFloatType = addedDecls => addedDecls;
|
|
11
|
-
export const validateFloatType = (helpers, type, value) => {
|
|
11
|
+
export const validateFloatType = (helpers, _inDecls, type, value) => {
|
|
12
12
|
if (typeof value !== "number") {
|
|
13
13
|
return [
|
|
14
14
|
TypeError(`expected a floating-point number, but got ${json(value, helpers.useStyling)}`),
|
|
@@ -12,7 +12,7 @@ export const IntegerType = (options = {}) => ({
|
|
|
12
12
|
export { IntegerType as Integer };
|
|
13
13
|
export const isIntegerType = node => node.kind === NodeKind.IntegerType;
|
|
14
14
|
export const getNestedDeclarationsInIntegerType = addedDecls => addedDecls;
|
|
15
|
-
export const validateIntegerType = (helpers, type, value) => {
|
|
15
|
+
export const validateIntegerType = (helpers, _inDecls, type, value) => {
|
|
16
16
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
17
17
|
return [TypeError(`expected an integer, but got ${json(value, helpers.useStyling)}`)];
|
|
18
18
|
}
|
|
@@ -8,7 +8,7 @@ export const StringType = (options = {}) => ({
|
|
|
8
8
|
export { StringType as String };
|
|
9
9
|
export const isStringType = node => node.kind === NodeKind.StringType;
|
|
10
10
|
export const getNestedDeclarationsInStringType = addedDecls => addedDecls;
|
|
11
|
-
export const validateStringType = (helpers, type, value) => {
|
|
11
|
+
export const validateStringType = (helpers, _inDecls, type, value) => {
|
|
12
12
|
if (typeof value !== "string") {
|
|
13
13
|
return [TypeError(`expected a string, but got ${json(value, helpers.useStyling)}`)];
|
|
14
14
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SerializedIncludeIdentifierType } from "../../../../shared/schema/types/IncludeIdentifierType.ts";
|
|
2
|
-
import type { IncludableDeclP, TypeArguments } from "../../declarations/Declaration.ts";
|
|
2
|
+
import type { Decl, IncludableDeclP, TypeArguments } from "../../declarations/Declaration.ts";
|
|
3
3
|
import type { EnumDecl } from "../../declarations/EnumDecl.ts";
|
|
4
|
-
import type
|
|
4
|
+
import { type TypeAliasDecl } from "../../declarations/TypeAliasDecl.ts";
|
|
5
5
|
import type { GetNestedDeclarations, GetReferences, Predicate, SerializedTypeParameters, Validator } from "../../Node.ts";
|
|
6
6
|
import { NodeKind } from "../../Node.ts";
|
|
7
7
|
import type { TypeParameter } from "../../TypeParameter.ts";
|
|
@@ -20,7 +20,7 @@ export { IncludeIdentifierType as IncludeIdentifier };
|
|
|
20
20
|
export declare const isIncludeIdentifierType: Predicate<IncludeIdentifierType>;
|
|
21
21
|
export declare const getNestedDeclarationsInIncludeIdentifierType: GetNestedDeclarations<IncludeIdentifierType>;
|
|
22
22
|
export declare const validateIncludeIdentifierType: Validator<IncludeIdentifierType>;
|
|
23
|
-
export declare const resolveTypeArgumentsInIncludeIdentifierType: <T extends IncludeIdentifierType>(args: Record<string, Type>, type: T) => T extends IncludeIdentifierType<[], IncludableDeclP<[]>> ? T : Type;
|
|
23
|
+
export declare const resolveTypeArgumentsInIncludeIdentifierType: <T extends IncludeIdentifierType>(args: Record<string, Type>, type: T, inDecl: Decl[]) => (T & IncludeIdentifierType<[], IncludableDeclP<[]>>) | (T extends IncludeIdentifierType<[], IncludableDeclP<[]>> ? T : Type);
|
|
24
24
|
export declare const serializeIncludeIdentifierType: <Params extends TypeParameter[] = TypeParameter<string, Type>[], T extends TConstraint<Params> = TConstraint<Params>>(type: IncludeIdentifierType<Params, T>) => SerializedIncludeIdentifierType<SerializedTypeParameters<Params>>;
|
|
25
25
|
export declare const getReferencesForIncludeIdentifierType: GetReferences<IncludeIdentifierType>;
|
|
26
26
|
export declare const formatIncludeIdentifierValue: StructureFormatter<IncludeIdentifierType>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { getTypeArgumentsRecord } from "../../declarations/Declaration.js";
|
|
1
|
+
import { getTypeArgumentsRecord, isDeclWithoutTypeParameters, } from "../../declarations/Declaration.js";
|
|
2
|
+
import { isTypeAliasDecl } from "../../declarations/TypeAliasDecl.js";
|
|
2
3
|
import { getNestedDeclarations, getReferences, NodeKind, resolveTypeArguments, serializeNode, validateDecl, } from "../../Node.js";
|
|
3
4
|
import { formatEnumType } from "../generic/EnumType.js";
|
|
4
5
|
import { formatValue } from "../Type.js";
|
|
6
|
+
import { isTypeArgumentType } from "./TypeArgumentType.js";
|
|
5
7
|
export const GenIncludeIdentifierType = (reference, args) => ({
|
|
6
8
|
kind: NodeKind.IncludeIdentifierType,
|
|
7
9
|
reference,
|
|
@@ -19,16 +21,38 @@ const isNoGenericIncludeIdentifierType = (node) => node.args.length === 0 && nod
|
|
|
19
21
|
export const getNestedDeclarationsInIncludeIdentifierType = (addedDecls, type, parentDecl) => type.args.reduce((accAddedDecls, arg) => getNestedDeclarations(accAddedDecls, arg, parentDecl), addedDecls.includes(type.reference)
|
|
20
22
|
? addedDecls
|
|
21
23
|
: getNestedDeclarations(addedDecls, type.reference, parentDecl));
|
|
22
|
-
export const validateIncludeIdentifierType = (helpers, type, value) => validateDecl(helpers, type.reference, type.args, value);
|
|
23
|
-
export const resolveTypeArgumentsInIncludeIdentifierType = ((args, type) =>
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
export const validateIncludeIdentifierType = (helpers, inDecls, type, value) => validateDecl(helpers, inDecls, type.reference, type.args, value);
|
|
25
|
+
export const resolveTypeArgumentsInIncludeIdentifierType = ((args, type, inDecl) => {
|
|
26
|
+
if (isNoGenericIncludeIdentifierType(type)) {
|
|
27
|
+
return type;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const parentDecl = inDecl[inDecl.length - 1];
|
|
31
|
+
const grandParentDecl = inDecl[inDecl.length - 2];
|
|
32
|
+
if (grandParentDecl?.name === "AdventurePointsDependingOnActiveInstancesMultiplier") {
|
|
33
|
+
console.log(type.args.every((arg, argIndex) => isTypeArgumentType(arg) && parentDecl?.parameters[argIndex] === arg.argument));
|
|
34
|
+
}
|
|
35
|
+
if (type.reference === parentDecl &&
|
|
36
|
+
parentDecl.parameters.length > 0 &&
|
|
37
|
+
grandParentDecl &&
|
|
38
|
+
isDeclWithoutTypeParameters(grandParentDecl) &&
|
|
39
|
+
isTypeAliasDecl(grandParentDecl) &&
|
|
40
|
+
type.args.every((arg, argIndex) => isTypeArgumentType(arg) && parentDecl.parameters[argIndex] === arg.argument)) {
|
|
41
|
+
const grandParentDeclType = grandParentDecl.type.value;
|
|
42
|
+
if (isIncludeIdentifierType(grandParentDeclType) &&
|
|
43
|
+
grandParentDeclType.reference === type.reference) {
|
|
44
|
+
return IncludeIdentifierType(grandParentDecl);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return resolveTypeArguments(getTypeArgumentsRecord(type.reference, type.args.map(arg => resolveTypeArguments(args, arg, inDecl))), type.reference, inDecl).type.value;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
26
50
|
export const serializeIncludeIdentifierType = ((type) => ({
|
|
27
51
|
...type,
|
|
28
52
|
reference: type.reference.name,
|
|
29
53
|
args: type.args.map(arg => serializeNode(arg)),
|
|
30
54
|
}));
|
|
31
|
-
export const getReferencesForIncludeIdentifierType = (type, value) => getReferences(resolveTypeArguments(getTypeArgumentsRecord(type.reference, type.args), type.reference), value);
|
|
55
|
+
export const getReferencesForIncludeIdentifierType = (type, value, inDecl) => getReferences(resolveTypeArguments(getTypeArgumentsRecord(type.reference, type.args), type.reference, inDecl), value, inDecl);
|
|
32
56
|
export const formatIncludeIdentifierValue = (type, value) => {
|
|
33
57
|
switch (type.reference.kind) {
|
|
34
58
|
case NodeKind.TypeAliasDecl:
|
|
@@ -27,18 +27,18 @@ const _NestedEntityMapType = (options) => {
|
|
|
27
27
|
};
|
|
28
28
|
export const isNestedEntityMapType = node => node.kind === NodeKind.NestedEntityMapType;
|
|
29
29
|
export const getNestedDeclarationsInNestedEntityMapType = (addedDecls, type, parentDecl) => getNestedDeclarations(getNestedDeclarations(addedDecls, type.secondaryEntity, parentDecl), type.type.value, parentDecl);
|
|
30
|
-
export const validateNestedEntityMapType = (helpers, type, value) => {
|
|
30
|
+
export const validateNestedEntityMapType = (helpers, inDecls, type, value) => {
|
|
31
31
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
32
32
|
return [TypeError(`expected an object, but got ${json(value, helpers.useStyling)}`)];
|
|
33
33
|
}
|
|
34
|
-
return parallelizeErrors(Object.keys(value).map(key => wrapErrorsIfAny(`at nested entity map ${entity(`"${type.name}"`, helpers.useStyling)} at key ${keyColor(`"${key}"`, helpers.useStyling)}`, validateType(helpers, type.type.value, value[key]).concat(helpers.checkReferentialIntegrity({
|
|
34
|
+
return parallelizeErrors(Object.keys(value).map(key => wrapErrorsIfAny(`at nested entity map ${entity(`"${type.name}"`, helpers.useStyling)} at key ${keyColor(`"${key}"`, helpers.useStyling)}`, validateType(helpers, inDecls, type.type.value, value[key]).concat(helpers.checkReferentialIntegrity({
|
|
35
35
|
name: type.secondaryEntity.name,
|
|
36
36
|
value: key,
|
|
37
37
|
})))));
|
|
38
38
|
};
|
|
39
|
-
export const resolveTypeArgumentsInNestedEntityMapType = (args, type) => _NestedEntityMapType({
|
|
39
|
+
export const resolveTypeArgumentsInNestedEntityMapType = (args, type, inDecl) => _NestedEntityMapType({
|
|
40
40
|
...type,
|
|
41
|
-
type: () => resolveTypeArguments(args, type.type.value),
|
|
41
|
+
type: () => resolveTypeArguments(args, type.type.value, inDecl),
|
|
42
42
|
});
|
|
43
43
|
export const serializeNestedEntityMapType = type => ({
|
|
44
44
|
...type,
|
|
@@ -47,11 +47,11 @@ export const serializeNestedEntityMapType = type => ({
|
|
|
47
47
|
? serializeObjectType(type.type.value)
|
|
48
48
|
: serializeIncludeIdentifierType(type.type.value),
|
|
49
49
|
});
|
|
50
|
-
export const getReferencesForNestedEntityMapType = (type, value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
50
|
+
export const getReferencesForNestedEntityMapType = (type, value, inDecl) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
51
51
|
? Object.values(value)
|
|
52
52
|
.flatMap(item => isObjectType(type.type.value)
|
|
53
|
-
? getReferencesForObjectType(type.type.value, item)
|
|
54
|
-
: getReferencesForIncludeIdentifierType(type.type.value, item))
|
|
53
|
+
? getReferencesForObjectType(type.type.value, item, inDecl)
|
|
54
|
+
: getReferencesForIncludeIdentifierType(type.type.value, item, inDecl))
|
|
55
55
|
.concat(Object.keys(value))
|
|
56
56
|
: [];
|
|
57
57
|
export const formatNestedEntityMapValue = (type, value) => isObjectType(type.type.value)
|
|
@@ -9,7 +9,7 @@ export const isReferenceIdentifierType = (node) => node.kind === NodeKind.Refere
|
|
|
9
9
|
export const getNestedDeclarationsInReferenceIdentifierType = (addedDecls, type, parentDecl) => addedDecls.includes(type.entity)
|
|
10
10
|
? addedDecls
|
|
11
11
|
: getNestedDeclarations(addedDecls, type.entity, parentDecl);
|
|
12
|
-
export const validateReferenceIdentifierType = (helpers, type, value) => validateType(helpers, createEntityIdentifierType(), value).concat(helpers.checkReferentialIntegrity({
|
|
12
|
+
export const validateReferenceIdentifierType = (helpers, inDecls, type, value) => validateType(helpers, inDecls, createEntityIdentifierType(), value).concat(helpers.checkReferentialIntegrity({
|
|
13
13
|
name: type.entity.name,
|
|
14
14
|
value: value,
|
|
15
15
|
}));
|
|
@@ -7,7 +7,7 @@ export const TypeArgumentType = (argument) => ({
|
|
|
7
7
|
export { TypeArgumentType as TypeArgument };
|
|
8
8
|
export const isTypeArgumentType = (node) => node.kind === NodeKind.TypeArgumentType;
|
|
9
9
|
export const getNestedDeclarationsInTypeArgumentType = addedDecls => addedDecls;
|
|
10
|
-
export const validateTypeArgumentType = (_helpers, type) => {
|
|
10
|
+
export const validateTypeArgumentType = (_helpers, _inDecls, type) => {
|
|
11
11
|
throw new TypeError(`generic argument "${type.argument.name}" has not been replaced with a concrete type`);
|
|
12
12
|
};
|
|
13
13
|
export const resolveTypeArgumentsInTypeArgumentType = ((args, type) => {
|
|
@@ -27,7 +27,7 @@ export const createInstance = async (dataRoot, localeEntity, instancesByEntityNa
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
export const checkUpdateInstancePossible = (instancesByEntityName, entity, instanceContent) => {
|
|
30
|
-
const validationErrors = validateEntityDecl(createValidators(instancesByEntityName, false), entity, instanceContent);
|
|
30
|
+
const validationErrors = validateEntityDecl(createValidators(instancesByEntityName, false), [], entity, instanceContent);
|
|
31
31
|
if (validationErrors.length > 0) {
|
|
32
32
|
return error([400, validationErrors.map(getErrorMessageForDisplay).join("\n\n")]);
|
|
33
33
|
}
|
|
@@ -58,13 +58,13 @@ export const updateReferencesToInstances = (entitiesByName, referencesToInstance
|
|
|
58
58
|
const entity = entitiesByName[entityName];
|
|
59
59
|
if (entity) {
|
|
60
60
|
if (oldInstance === undefined) {
|
|
61
|
-
return addReferences(referencesToInstances, getReferencesForEntityDecl(entity, newInstance), instanceId);
|
|
61
|
+
return addReferences(referencesToInstances, getReferencesForEntityDecl(entity, newInstance, []), instanceId);
|
|
62
62
|
}
|
|
63
63
|
if (newInstance === undefined) {
|
|
64
|
-
return removeReferences(referencesToInstances, getReferencesForEntityDecl(entity, oldInstance), instanceId);
|
|
64
|
+
return removeReferences(referencesToInstances, getReferencesForEntityDecl(entity, oldInstance, []), instanceId);
|
|
65
65
|
}
|
|
66
|
-
const oldReferences = getReferencesForEntityDecl(entity, oldInstance);
|
|
67
|
-
const newReferences = getReferencesForEntityDecl(entity, newInstance);
|
|
66
|
+
const oldReferences = getReferencesForEntityDecl(entity, oldInstance, []);
|
|
67
|
+
const newReferences = getReferencesForEntityDecl(entity, newInstance, []);
|
|
68
68
|
const { added, removed } = difference(oldReferences, newReferences);
|
|
69
69
|
return removeReferences(addReferences(referencesToInstances, added, instanceId), removed, instanceId);
|
|
70
70
|
}
|
|
@@ -26,7 +26,7 @@ export const Entity = () => {
|
|
|
26
26
|
const gitClient = useContext(GitClientContext);
|
|
27
27
|
const { reloadEntities } = useContext(EntitiesContext);
|
|
28
28
|
const { declaration: entity, isLocaleEntity } = entityFromRoute ?? {};
|
|
29
|
-
const [instances, reloadInstances] = useMappedAPIResource(getInstancesByEntityName, mapInstances, locales, name ?? "");
|
|
29
|
+
const [instances, reloadInstances] = useMappedAPIResource(getInstancesByEntityName, mapInstances, locales, entity?.name ?? "");
|
|
30
30
|
const [localeInstances] = useMappedAPIResource(getLocaleInstances, localeMapper, locales, config.localeEntityName);
|
|
31
31
|
useEffect(() => {
|
|
32
32
|
document.title = toTitleCase(entity?.namePlural ?? name ?? "") + " — TSONDB";
|
|
@@ -39,11 +39,11 @@ export const Entity = () => {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
}, [created]);
|
|
42
|
-
if (
|
|
42
|
+
if (entity?.name === undefined) {
|
|
43
43
|
return _jsx(NotFound, {});
|
|
44
44
|
}
|
|
45
|
-
if (!
|
|
46
|
-
return (_jsxs(Layout, { breadcrumbs: [{ url: "/", label: homeTitle }], children: [_jsxs("div", { class: "header-with-btns", children: [_jsx("h1", { children: toTitleCase(entity
|
|
45
|
+
if (!instances) {
|
|
46
|
+
return (_jsxs(Layout, { breadcrumbs: [{ url: "/", label: homeTitle }], children: [_jsxs("div", { class: "header-with-btns", children: [_jsx("h1", { children: toTitleCase(entity.namePlural) }), _jsx("a", { class: "btn btn--primary", "aria-disabled": true, children: "Add" })] }), _jsx("p", { class: "loading", children: "Loading \u2026" })] }));
|
|
47
47
|
}
|
|
48
48
|
const lowerSearchText = searchText.toLowerCase();
|
|
49
49
|
const filteredInstances = (searchText.length === 0
|