tsondb 0.21.1 → 0.21.3

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.
Files changed (70) hide show
  1. package/dist/src/node/config.d.ts +2 -2
  2. package/dist/src/node/git.d.ts +4 -4
  3. package/dist/src/node/git.js +1 -1
  4. package/dist/src/node/index.d.ts +56 -5
  5. package/dist/src/node/index.js +140 -12
  6. package/dist/src/node/renderers/jsonschema/render.js +7 -0
  7. package/dist/src/node/renderers/ts/render.d.ts +4 -0
  8. package/dist/src/node/renderers/ts/render.js +7 -1
  9. package/dist/src/node/schema/dsl/declarations/Decl.d.ts +3 -2
  10. package/dist/src/node/schema/dsl/declarations/Decl.js +2 -1
  11. package/dist/src/node/schema/dsl/declarations/SingletonEntityDecl.d.ts +35 -0
  12. package/dist/src/node/schema/dsl/declarations/SingletonEntityDecl.js +23 -0
  13. package/dist/src/node/schema/dsl/index.d.ts +1 -0
  14. package/dist/src/node/schema/dsl/index.js +1 -0
  15. package/dist/src/node/schema/generatedTypeHelpers.d.ts +18 -0
  16. package/dist/src/node/schema/guards.d.ts +1 -0
  17. package/dist/src/node/schema/guards.js +1 -0
  18. package/dist/src/node/schema/helpers.js +1 -0
  19. package/dist/src/node/schema/index.d.ts +12 -1
  20. package/dist/src/node/schema/index.js +51 -0
  21. package/dist/src/node/schema/treeOperations/customConstraints.d.ts +2 -1
  22. package/dist/src/node/schema/treeOperations/customConstraints.js +10 -10
  23. package/dist/src/node/schema/treeOperations/implicitSchema.js +1 -0
  24. package/dist/src/node/schema/treeOperations/references.js +1 -0
  25. package/dist/src/node/schema/treeOperations/serialization.d.ts +4 -1
  26. package/dist/src/node/schema/treeOperations/serialization.js +8 -0
  27. package/dist/src/node/schema/treeOperations/typeResolution.d.ts +4 -1
  28. package/dist/src/node/schema/treeOperations/typeResolution.js +6 -0
  29. package/dist/src/node/schema/treeOperations/validation.js +3 -1
  30. package/dist/src/node/server/api/declarations.js +209 -23
  31. package/dist/src/node/server/utils/instanceOperations.js +1 -1
  32. package/dist/src/node/transaction.d.ts +33 -11
  33. package/dist/src/node/transaction.js +142 -1
  34. package/dist/src/node/utils/childInstances.js +1 -1
  35. package/dist/src/node/utils/customConstraints.d.ts +6 -5
  36. package/dist/src/node/utils/customConstraints.js +34 -15
  37. package/dist/src/node/utils/databaseInMemory.d.ts +28 -8
  38. package/dist/src/node/utils/databaseInMemory.js +126 -9
  39. package/dist/src/node/utils/databaseOnDisk.js +27 -30
  40. package/dist/src/node/utils/error.d.ts +0 -8
  41. package/dist/src/node/utils/error.js +1 -39
  42. package/dist/src/node/utils/files.d.ts +7 -2
  43. package/dist/src/node/utils/files.js +9 -0
  44. package/dist/src/node/utils/references.d.ts +2 -0
  45. package/dist/src/node/utils/references.js +6 -1
  46. package/dist/src/node/utils/sortOrder.d.ts +13 -0
  47. package/dist/src/node/utils/sortOrder.js +12 -0
  48. package/dist/src/node/utils/unique.d.ts +0 -4
  49. package/dist/src/node/utils/unique.js +1 -7
  50. package/dist/src/shared/api.d.ts +59 -2
  51. package/dist/src/shared/schema/Node.d.ts +5 -1
  52. package/dist/src/shared/schema/Node.js +6 -0
  53. package/dist/src/shared/schema/declarations/Declaration.d.ts +3 -2
  54. package/dist/src/shared/schema/declarations/SingletonEntityDecl.d.ts +18 -0
  55. package/dist/src/shared/schema/declarations/SingletonEntityDecl.js +8 -0
  56. package/dist/src/shared/schema/utils/keyPath.d.ts +1 -0
  57. package/dist/src/shared/schema/utils/keyPath.js +30 -0
  58. package/dist/src/shared/schema/utils/sortOrder.d.ts +9 -0
  59. package/dist/src/shared/schema/utils/sortOrder.js +11 -0
  60. package/dist/src/shared/utils/childInstances.d.ts +4 -0
  61. package/dist/src/shared/utils/error.d.ts +8 -0
  62. package/dist/src/shared/utils/error.js +39 -0
  63. package/dist/src/shared/utils/instances.d.ts +4 -0
  64. package/dist/src/{node → shared}/utils/render.js +1 -1
  65. package/dist/src/shared/utils/unique.d.ts +4 -0
  66. package/dist/src/shared/utils/unique.js +7 -0
  67. package/dist/src/web/web.js +687 -165
  68. package/package.json +1 -1
  69. package/public/css/styles.css +4 -2
  70. /package/dist/src/{node → shared}/utils/render.d.ts +0 -0
@@ -8,6 +8,7 @@ import type { DisplayNameResult } from "../../shared/utils/displayName.ts";
8
8
  import type { InstanceContainer, InstanceContainerOverview, InstanceContent } from "../../shared/utils/instances.ts";
9
9
  import type { DeclarationName, DefaultTSONDBTypes } from "../index.ts";
10
10
  import type { EntityDecl } from "./dsl/declarations/EntityDecl.ts";
11
+ import type { SingletonEntityDecl } from "./dsl/declarations/SingletonEntityDecl.ts";
11
12
  export interface Register {
12
13
  }
13
14
  export type AnyEntityMap = Record<string, InstanceContent>;
@@ -19,6 +20,15 @@ export type RegisteredEntity<Name extends string, T = Register> = T extends {
19
20
  [K in Name]: InstanceContent;
20
21
  };
21
22
  } ? T["entityMap"][Name] : InstanceContent;
23
+ export type AnySingletonEntityMap = Record<string, InstanceContent>;
24
+ export type RegisteredSingletonEntityMap<T = Register> = T extends {
25
+ singletonEntityMap: AnySingletonEntityMap;
26
+ } ? T["singletonEntityMap"] : AnySingletonEntityMap;
27
+ export type RegisteredSingletonEntity<Name extends string, T = Register> = T extends {
28
+ singletonEntityMap: {
29
+ [K in Name]: InstanceContent;
30
+ };
31
+ } ? T["singletonEntityMap"][Name] : InstanceContent;
22
32
  export type AnyChildEntityMap = Record<string, [
23
33
  content: InstanceContent,
24
34
  parentKey: string,
@@ -133,6 +143,14 @@ export type GetDisplayNameAndId<T extends AnyEntityMap = RegisteredEntityMap> =
133
143
  * A function that retrieves an entity declaration by its name.
134
144
  */
135
145
  export type GetEntityByName<T extends AnyEntityMap = RegisteredEntityMap> = <E extends Extract<keyof T, string> = Extract<keyof T, string>>(name: E) => EntityDecl<E> | undefined;
146
+ /**
147
+ * A function that retrieves an entity declaration by its name.
148
+ */
149
+ export type GetSingletonEntityByName<T extends AnySingletonEntityMap = RegisteredSingletonEntityMap> = <E extends Extract<keyof T, string> = Extract<keyof T, string>>(name: E) => SingletonEntityDecl<E> | undefined;
150
+ /**
151
+ * A function that retrieves the singleton instance by its entity if available.
152
+ */
153
+ export type GetSingletonInstance<T extends AnySingletonEntityMap = RegisteredSingletonEntityMap> = <E extends Extract<keyof T, string> = Extract<keyof T, string>>(entity: E) => T[E] | undefined;
136
154
  /**
137
155
  * A type guard function that checks if a given string is a valid declaration name.
138
156
  */
@@ -1,6 +1,7 @@
1
1
  export { isDecl, isDeclWithoutTypeParameters } from "./dsl/declarations/Decl.ts";
2
2
  export { isEntityDecl, isEntityDeclWithParentReference } from "./dsl/declarations/EntityDecl.ts";
3
3
  export { isEnumDecl } from "./dsl/declarations/EnumDecl.ts";
4
+ export { isSingletonEntityDecl } from "./dsl/declarations/SingletonEntityDecl.ts";
4
5
  export { isTypeAliasDecl } from "./dsl/declarations/TypeAliasDecl.ts";
5
6
  export { isArrayType } from "./dsl/types/ArrayType.ts";
6
7
  export { isBooleanType } from "./dsl/types/BooleanType.ts";
@@ -1,6 +1,7 @@
1
1
  export { isDecl, isDeclWithoutTypeParameters } from "./dsl/declarations/Decl.js";
2
2
  export { isEntityDecl, isEntityDeclWithParentReference } from "./dsl/declarations/EntityDecl.js";
3
3
  export { isEnumDecl } from "./dsl/declarations/EnumDecl.js";
4
+ export { isSingletonEntityDecl } from "./dsl/declarations/SingletonEntityDecl.js";
4
5
  export { isTypeAliasDecl } from "./dsl/declarations/TypeAliasDecl.js";
5
6
  export { isArrayType } from "./dsl/types/ArrayType.js";
6
7
  export { isBooleanType } from "./dsl/types/BooleanType.js";
@@ -12,6 +12,7 @@ export const reduceNodes = (reducer, nodes, options = {}) => {
12
12
  const reduceNodeTree = (parentNodes, node, collectedResults, reducedDecls) => {
13
13
  switch (node.kind) {
14
14
  case NodeKind.EntityDecl:
15
+ case NodeKind.SingletonEntityDecl:
15
16
  case NodeKind.EnumDecl:
16
17
  case NodeKind.TypeAliasDecl:
17
18
  return reduceNodeTree([node], node.type.value, reducer(parentNodes, node, collectedResults), [...reducedDecls, node]);
@@ -1,6 +1,7 @@
1
- import type { DeclarationName, DefaultTSONDBTypes, EntityName } from "../index.ts";
1
+ import type { DeclarationName, DefaultTSONDBTypes, EntityName, SingletonEntityName } from "../index.ts";
2
2
  import type { Decl } from "./dsl/declarations/Decl.ts";
3
3
  import type { EntityDecl } from "./dsl/declarations/EntityDecl.ts";
4
+ import type { SingletonEntityDecl } from "./dsl/index.ts";
4
5
  export declare class Schema<T extends DefaultTSONDBTypes = DefaultTSONDBTypes> {
5
6
  #private;
6
7
  constructor(declarations: Decl[], localeEntity?: EntityDecl);
@@ -8,6 +9,10 @@ export declare class Schema<T extends DefaultTSONDBTypes = DefaultTSONDBTypes> {
8
9
  get resolvedEntities(): EntityDecl<EntityName<T>>[];
9
10
  getEntity<E extends EntityName<T>>(name: E): EntityDecl<E> | undefined;
10
11
  getResolvedEntity<E extends EntityName<T>>(name: E): EntityDecl<E> | undefined;
12
+ get singletonEntities(): SingletonEntityDecl<SingletonEntityName<T>>[];
13
+ get resolvedSingletonEntities(): SingletonEntityDecl<SingletonEntityName<T>>[];
14
+ getSingletonEntity<E extends SingletonEntityName<T>>(name: E): SingletonEntityDecl<E> | undefined;
15
+ getResolvedSingletonEntity<E extends SingletonEntityName<T>>(name: E): SingletonEntityDecl<E> | undefined;
11
16
  get declarations(): Decl[];
12
17
  get resolvedDeclarations(): Decl[];
13
18
  getDeclaration<E extends DeclarationName<T>>(name: E): Decl<E> | undefined;
@@ -19,6 +24,12 @@ export declare class Schema<T extends DefaultTSONDBTypes = DefaultTSONDBTypes> {
19
24
  * This includes all entity declarations, but not nested entity declarations, as they cannot be referenced directly by their name.
20
25
  */
21
26
  isEntityName(name: string): name is EntityName<T>;
27
+ /**
28
+ * Checks if the given name is a valid singleton entity name in the schema.
29
+ *
30
+ * This includes all entity declarations, but not nested entity declarations, as they cannot be referenced directly by their name.
31
+ */
32
+ isSingletonEntityName(name: string): name is SingletonEntityName<T>;
22
33
  /**
23
34
  * Checks if the given name is a valid declaration name in the schema. This includes entity declarations, enum declarations and type alias declarations.
24
35
  *
@@ -8,6 +8,7 @@ import { renderKeyPath } from "../../shared/schema/utils/keyPath.js";
8
8
  import { getParameterNames, resolveTypeArgumentsInDecls, walkNodeTree, } from "./dsl/declarations/Decl.js";
9
9
  import { isEntityDecl } from "./dsl/declarations/EntityDecl.js";
10
10
  import { cases, isEnumDecl } from "./dsl/declarations/EnumDecl.js";
11
+ import { isSingletonEntityDecl } from "./dsl/declarations/SingletonEntityDecl.js";
11
12
  import { isChildEntitiesType } from "./dsl/types/ChildEntitiesType.js";
12
13
  import { isFloatType } from "./dsl/types/FloatType.js";
13
14
  import { isIncludeIdentifierType } from "./dsl/types/IncludeIdentifierType.js";
@@ -23,8 +24,10 @@ const debug = Debug("tsondb:schema");
23
24
  export class Schema {
24
25
  #declarations;
25
26
  #entities;
27
+ #singletonEntities;
26
28
  #resolvedDeclarations;
27
29
  #resolvedEntities;
30
+ #resolvedSingletonEntities;
28
31
  #localeEntity;
29
32
  #declarationMap;
30
33
  #resolvedDeclarationMap;
@@ -58,6 +61,8 @@ export class Schema {
58
61
  this.#resolvedDeclarations = resolveTypeArgumentsInDecls(allDeclsWithoutNestedEntities);
59
62
  this.#entities = allDeclsWithoutNestedEntities.filter(isEntityDecl);
60
63
  this.#resolvedEntities = this.#resolvedDeclarations.filter(isEntityDecl);
64
+ this.#singletonEntities = allDeclsWithoutNestedEntities.filter(isSingletonEntityDecl);
65
+ this.#resolvedSingletonEntities = this.#resolvedDeclarations.filter(isSingletonEntityDecl);
61
66
  this.#declarationMap = Dictionary.fromEntries(allDeclsWithoutNestedEntities.map(decl => [decl.name, decl]));
62
67
  this.#resolvedDeclarationMap = Dictionary.fromEntries(this.#resolvedDeclarations.map(decl => [decl.name, decl]));
63
68
  debug("created schema, no integrity violations found");
@@ -76,6 +81,20 @@ export class Schema {
76
81
  const decl = this.#resolvedDeclarationMap.get(name);
77
82
  return decl && isEntityDecl(decl) ? decl : undefined;
78
83
  }
84
+ get singletonEntities() {
85
+ return this.#singletonEntities;
86
+ }
87
+ get resolvedSingletonEntities() {
88
+ return this.#resolvedSingletonEntities;
89
+ }
90
+ getSingletonEntity(name) {
91
+ const decl = this.#declarationMap.get(name);
92
+ return decl && isSingletonEntityDecl(decl) ? decl : undefined;
93
+ }
94
+ getResolvedSingletonEntity(name) {
95
+ const decl = this.#resolvedDeclarationMap.get(name);
96
+ return decl && isSingletonEntityDecl(decl) ? decl : undefined;
97
+ }
79
98
  get declarations() {
80
99
  return this.#declarations;
81
100
  }
@@ -99,6 +118,14 @@ export class Schema {
99
118
  isEntityName(name) {
100
119
  return this.#entities.some(entity => entity.name === name);
101
120
  }
121
+ /**
122
+ * Checks if the given name is a valid singleton entity name in the schema.
123
+ *
124
+ * This includes all entity declarations, but not nested entity declarations, as they cannot be referenced directly by their name.
125
+ */
126
+ isSingletonEntityName(name) {
127
+ return this.#singletonEntities.some(entity => entity.name === name);
128
+ }
102
129
  /**
103
130
  * Checks if the given name is a valid declaration name in the schema. This includes entity declarations, enum declarations and type alias declarations.
104
131
  *
@@ -234,6 +261,19 @@ const checkChildEntityTypeInEntityDecl = (checkedDecls, entityDecl, decl) => {
234
261
  }, decl);
235
262
  }
236
263
  };
264
+ const checkChildEntityTypeInSingletonEntityDecl = (checkedDecls, entityDecl, decl) => {
265
+ if (!checkedDecls.has(decl)) {
266
+ checkedDecls.add(decl);
267
+ walkNodeTree(node => {
268
+ if (isIncludeIdentifierType(node)) {
269
+ checkChildEntityTypeInSingletonEntityDecl(checkedDecls, entityDecl, node.reference);
270
+ }
271
+ else if (isChildEntitiesType(node)) {
272
+ throw new Error(`Child entities type for entity "${node.entity.name}" in entity declaration "${entityDecl.name}" is not allowed in a singleton entity. Use a regular entity instead.`);
273
+ }
274
+ }, decl);
275
+ }
276
+ };
237
277
  const checkChildEntityTypes = (localeEntity, decls) => {
238
278
  if (localeEntity && localeEntity.parentReferenceKey !== undefined) {
239
279
  throw new TypeError(`The locale entity "${localeEntity.name}" cannot be used as a child entity to other entities.`);
@@ -246,6 +286,9 @@ const checkChildEntityTypes = (localeEntity, decls) => {
246
286
  if (isEntityDecl(decl)) {
247
287
  checkChildEntityTypeInEntityDecl(new Set(), decl, decl);
248
288
  }
289
+ if (isSingletonEntityDecl(decl)) {
290
+ checkChildEntityTypeInSingletonEntityDecl(new Set(), decl, decl);
291
+ }
249
292
  }
250
293
  };
251
294
  const checkChildEntitiesProvideCorrectPathToParentReferenceIdentifierType = (decls) => {
@@ -269,6 +312,7 @@ const isDeclarationRecursive = (declToCheck) => {
269
312
  const isDeclarationIncludedInNode = (visitedDecls, node) => {
270
313
  switch (node.kind) {
271
314
  case NodeKind.EntityDecl:
315
+ case NodeKind.SingletonEntityDecl:
272
316
  case NodeKind.EnumDecl:
273
317
  case NodeKind.TypeAliasDecl:
274
318
  return visitedDecls.includes(node)
@@ -396,6 +440,13 @@ const checkSortOrders = (declarations) => {
396
440
  if (!isValidSortOrderType(type)) {
397
441
  throw TypeError(`type at key path "${renderKeyPath(sortOrder.keyPath)}" is not a valid sort order type (string, integer, or float) in entity "${decl.name}"`);
398
442
  }
443
+ if (sortOrder.isIndex &&
444
+ (!isIntegerType(type) ||
445
+ type.maximum !== undefined ||
446
+ (typeof type.minimum === "object" && type.minimum.isExclusive) ||
447
+ type.multipleOf !== undefined)) {
448
+ throw TypeError(`type at key path ${renderKeyPath(sortOrder.keyPath)} is not a valid index sort order type (integer, optional inclusive minimum, no other constraints) in entity "${decl.name}"`);
449
+ }
399
450
  }
400
451
  else {
401
452
  // const entityMapType = getType(decl.type.value, sortOrder.entityMapKeyPath)
@@ -1,5 +1,6 @@
1
1
  import type { InstanceContent } from "../../../shared/utils/instances.ts";
2
2
  import type { CustomConstraintHelpers } from "../../utils/customConstraints.ts";
3
3
  import type { EntityDecl } from "../dsl/declarations/EntityDecl.ts";
4
+ import type { SingletonEntityDecl } from "../dsl/index.ts";
4
5
  export declare const checkCustomConstraintsInEntityDecl: (node: EntityDecl, value: [id: string, content: InstanceContent], helpers: CustomConstraintHelpers) => string[];
5
- export { checkCustomConstraintsInEntityDecl as checkCustomConstraints };
6
+ export declare const checkCustomConstraintsInSingletonEntityDecl: (node: SingletonEntityDecl, value: InstanceContent, helpers: CustomConstraintHelpers) => string[];
@@ -1,31 +1,31 @@
1
1
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
2
2
  import { ENUM_DISCRIMINATOR_KEY } from "../../../shared/schema/declarations/EnumDecl.js";
3
3
  import { NodeKind } from "../../../shared/schema/Node.js";
4
- export const checkCustomConstraintsInEntityDecl = (node, value, helpers) => (node.customConstraints?.({ ...helpers, instanceId: value[0], instanceContent: value[1] }) ?? []).concat(checkCustomConstraints(node.type.value, value, helpers));
5
- export { checkCustomConstraintsInEntityDecl as checkCustomConstraints };
6
- const checkCustomConstraints = (node, value, helpers) => {
4
+ export const checkCustomConstraintsInEntityDecl = (node, value, helpers) => (node.customConstraints?.({ ...helpers, instanceId: value[0], instanceContent: value[1] }) ?? []).concat(checkNestedCustomConstraints(node.type.value, value, helpers));
5
+ export const checkCustomConstraintsInSingletonEntityDecl = (node, value, helpers) => (node.customConstraints?.({ ...helpers, instanceId: node.name, instanceContent: value }) ?? []).concat(checkNestedCustomConstraints(node.type.value, value, helpers));
6
+ const checkNestedCustomConstraints = (node, value, helpers) => {
7
7
  switch (node.kind) {
8
8
  case NodeKind.EnumDecl:
9
- return (node.customConstraints?.({ ...helpers, value }) ?? []).concat(checkCustomConstraints(node.type.value, value, helpers));
9
+ return (node.customConstraints?.({ ...helpers, value }) ?? []).concat(checkNestedCustomConstraints(node.type.value, value, helpers));
10
10
  case NodeKind.TypeAliasDecl:
11
- return (node.customConstraints?.({ ...helpers, value }) ?? []).concat(checkCustomConstraints(node.type.value, value, helpers));
11
+ return (node.customConstraints?.({ ...helpers, value }) ?? []).concat(checkNestedCustomConstraints(node.type.value, value, helpers));
12
12
  case NodeKind.ArrayType:
13
13
  return Array.isArray(value)
14
- ? value.flatMap(item => checkCustomConstraints(node.items, item, helpers))
14
+ ? value.flatMap(item => checkNestedCustomConstraints(node.items, item, helpers))
15
15
  : [];
16
16
  case NodeKind.ObjectType:
17
17
  return typeof value === "object" && value !== null
18
18
  ? Object.entries(value).flatMap(([key, propValue]) => node.properties[key]
19
- ? checkCustomConstraints(node.properties[key].type, propValue, helpers)
19
+ ? checkNestedCustomConstraints(node.properties[key].type, propValue, helpers)
20
20
  : [])
21
21
  : [];
22
22
  case NodeKind.TypeArgumentType: {
23
23
  throw new TypeError(`type argument "${node.argument.name}" is unresolved. Make sure to resolve all type arguments before checking for nested custom constraints.`);
24
24
  }
25
25
  case NodeKind.IncludeIdentifierType:
26
- return checkCustomConstraints(node.reference, value, helpers);
26
+ return checkNestedCustomConstraints(node.reference, value, helpers);
27
27
  case NodeKind.NestedEntityMapType:
28
- return checkCustomConstraints(node.type.value, value, helpers);
28
+ return checkNestedCustomConstraints(node.type.value, value, helpers);
29
29
  case NodeKind.EnumType: {
30
30
  if (typeof value !== "object" ||
31
31
  value === null ||
@@ -39,7 +39,7 @@ const checkCustomConstraints = (node, value, helpers) => {
39
39
  node.values[enumCase] !== undefined &&
40
40
  node.values[enumCase].type !== null &&
41
41
  enumCase in value
42
- ? checkCustomConstraints(node.values[enumCase].type, value[enumCase], helpers)
42
+ ? checkNestedCustomConstraints(node.values[enumCase].type, value[enumCase], helpers)
43
43
  : [];
44
44
  }
45
45
  case NodeKind.BooleanType:
@@ -3,6 +3,7 @@ import { NodeKind } from "../../../shared/schema/Node.js";
3
3
  export const getNestedDeclarations = (addedDecls, node, parentDecl) => {
4
4
  switch (node.kind) {
5
5
  case NodeKind.EntityDecl:
6
+ case NodeKind.SingletonEntityDecl:
6
7
  case NodeKind.EnumDecl:
7
8
  case NodeKind.TypeAliasDecl:
8
9
  return addedDecls.includes(node)
@@ -6,6 +6,7 @@ import { resolveTypeArguments } from "./typeResolution.js";
6
6
  export const getReferences = (node, value, inDecl) => {
7
7
  switch (node.kind) {
8
8
  case NodeKind.EntityDecl:
9
+ case NodeKind.SingletonEntityDecl:
9
10
  case NodeKind.EnumDecl:
10
11
  case NodeKind.TypeAliasDecl:
11
12
  return getReferences(node.type.value, value, [...inDecl, node]);
@@ -1,5 +1,6 @@
1
1
  import type { SerializedEntityDecl } from "../../../shared/schema/declarations/EntityDecl.ts";
2
2
  import type { SerializedEnumDecl } from "../../../shared/schema/declarations/EnumDecl.ts";
3
+ import type { SerializedSingletonEntityDecl } from "../../../shared/schema/declarations/SingletonEntityDecl.ts";
3
4
  import type { SerializedTypeAliasDecl } from "../../../shared/schema/declarations/TypeAliasDecl.ts";
4
5
  import { NodeKind } from "../../../shared/schema/Node.js";
5
6
  import type { SerializedTypeParameter } from "../../../shared/schema/TypeParameter.ts";
@@ -19,6 +20,7 @@ import type { SerializedTranslationObjectType } from "../../../shared/schema/typ
19
20
  import type { SerializedTypeArgumentType } from "../../../shared/schema/types/TypeArgumentType.ts";
20
21
  import { type EntityDecl } from "../dsl/declarations/EntityDecl.ts";
21
22
  import { type EnumDecl } from "../dsl/declarations/EnumDecl.ts";
23
+ import type { SingletonEntityDecl } from "../dsl/declarations/SingletonEntityDecl.ts";
22
24
  import { type TypeAliasDecl } from "../dsl/declarations/TypeAliasDecl.ts";
23
25
  import type { Node, Type } from "../dsl/index.ts";
24
26
  import { type TypeParameter } from "../dsl/TypeParameter.ts";
@@ -38,6 +40,7 @@ import { type TranslationObjectType } from "../dsl/types/TranslationObjectType.t
38
40
  import { type TypeArgumentType } from "../dsl/types/TypeArgumentType.ts";
39
41
  export type SerializedNodeMap = {
40
42
  [NodeKind.EntityDecl]: [EntityDecl, SerializedEntityDecl];
43
+ [NodeKind.SingletonEntityDecl]: [EntityDecl, SerializedSingletonEntityDecl];
41
44
  [NodeKind.EnumDecl]: [EnumDecl, SerializedEnumDecl];
42
45
  [NodeKind.TypeAliasDecl]: [TypeAliasDecl, SerializedTypeAliasDecl];
43
46
  [NodeKind.ArrayType]: [ArrayType, SerializedArrayType];
@@ -65,7 +68,7 @@ export type SerializedMemberDeclObject<T extends Record<string, MemberDecl>> = {
65
68
  export type SerializedEnumCaseDeclObject<T extends Record<string, EnumCaseDecl>> = {
66
69
  [K in keyof T]: T[K] extends EnumCaseDecl<infer CT> ? SerializedEnumCaseDecl<CT extends Type ? Serialized<CT> : null> : never;
67
70
  };
68
- export type Serialized<T extends Node> = T extends EntityDecl<infer Name, infer T, infer FK> ? SerializedEntityDecl<Name, SerializedMemberDeclObject<T>, FK> : T extends EnumDecl<infer Name, infer T, infer Params> ? SerializedEnumDecl<Name, SerializedEnumCaseDeclObject<T>, SerializedTypeParameters<Params>> : T extends TypeAliasDecl<infer Name, infer T, infer Params> ? SerializedTypeAliasDecl<Name, Serialized<T>, SerializedTypeParameters<Params>> : T extends ArrayType<infer T> ? SerializedArrayType<Serialized<T>> : T extends ObjectType<infer T> ? SerializedObjectType<SerializedMemberDeclObject<T>> : T extends BooleanType ? SerializedBooleanType : T extends DateType ? SerializedDateType : T extends FloatType ? SerializedFloatType : T extends IntegerType ? SerializedIntegerType : T extends StringType ? SerializedStringType : T extends TypeArgumentType<infer T> ? SerializedTypeArgumentType<Serialized<T>> : T extends ReferenceIdentifierType ? SerializedReferenceIdentifierType : T extends IncludeIdentifierType<infer Params> ? SerializedIncludeIdentifierType<SerializedTypeParameters<Params>> : T extends NestedEntityMapType<infer Name, infer T> ? SerializedNestedEntityMapType<Name, SerializedMemberDeclObject<T>> : T extends EnumType<infer T> ? SerializedEnumType<SerializedEnumCaseDeclObject<T>> : T extends TypeParameter<infer N, infer C> ? SerializedTypeParameter<N, C extends Type ? Serialized<C> : undefined> : T extends ChildEntitiesType ? SerializedChildEntitiesType : T extends TranslationObjectType<infer E> ? SerializedTranslationObjectType<E> : never;
71
+ export type Serialized<T extends Node> = T extends EntityDecl<infer Name, infer T, infer FK> ? SerializedEntityDecl<Name, SerializedMemberDeclObject<T>, FK> : T extends SingletonEntityDecl<infer Name, infer T> ? SerializedSingletonEntityDecl<Name, SerializedMemberDeclObject<T>> : T extends EnumDecl<infer Name, infer T, infer Params> ? SerializedEnumDecl<Name, SerializedEnumCaseDeclObject<T>, SerializedTypeParameters<Params>> : T extends TypeAliasDecl<infer Name, infer T, infer Params> ? SerializedTypeAliasDecl<Name, Serialized<T>, SerializedTypeParameters<Params>> : T extends ArrayType<infer T> ? SerializedArrayType<Serialized<T>> : T extends ObjectType<infer T> ? SerializedObjectType<SerializedMemberDeclObject<T>> : T extends BooleanType ? SerializedBooleanType : T extends DateType ? SerializedDateType : T extends FloatType ? SerializedFloatType : T extends IntegerType ? SerializedIntegerType : T extends StringType ? SerializedStringType : T extends TypeArgumentType<infer T> ? SerializedTypeArgumentType<Serialized<T>> : T extends ReferenceIdentifierType ? SerializedReferenceIdentifierType : T extends IncludeIdentifierType<infer Params> ? SerializedIncludeIdentifierType<SerializedTypeParameters<Params>> : T extends NestedEntityMapType<infer Name, infer T> ? SerializedNestedEntityMapType<Name, SerializedMemberDeclObject<T>> : T extends EnumType<infer T> ? SerializedEnumType<SerializedEnumCaseDeclObject<T>> : T extends TypeParameter<infer N, infer C> ? SerializedTypeParameter<N, C extends Type ? Serialized<C> : undefined> : T extends ChildEntitiesType ? SerializedChildEntitiesType : T extends TranslationObjectType<infer E> ? SerializedTranslationObjectType<E> : never;
69
72
  export type SerializedOf<T extends Node> = SerializedNodeMap[T["kind"]][1];
70
73
  export type Serializer<T extends Node = Node> = (node: T) => Serialized<T>;
71
74
  export declare const serializeNode: <T extends Node>(node: T) => Serialized<T>;
@@ -30,6 +30,14 @@ export const serializeNode = (node) => {
30
30
  };
31
31
  return serializedNode;
32
32
  }
33
+ case NodeKind.SingletonEntityDecl: {
34
+ const serializedNode = {
35
+ ...node,
36
+ type: serializeNode(node.type.value),
37
+ customConstraints: node.customConstraints !== undefined,
38
+ };
39
+ return serializedNode;
40
+ }
33
41
  case NodeKind.EnumDecl: {
34
42
  const serializedNode = {
35
43
  ...node,
@@ -1,6 +1,7 @@
1
1
  import { type Decl, type IncludableDeclP } from "../dsl/declarations/Decl.ts";
2
2
  import { EntityDecl } from "../dsl/declarations/EntityDecl.ts";
3
3
  import { EnumDecl } from "../dsl/declarations/EnumDecl.ts";
4
+ import { SingletonEntityDecl } from "../dsl/declarations/SingletonEntityDecl.ts";
4
5
  import { TypeAliasDecl } from "../dsl/declarations/TypeAliasDecl.ts";
5
6
  import type { Node, Type } from "../dsl/index.ts";
6
7
  import type { TypeParameter } from "../dsl/TypeParameter.ts";
@@ -22,7 +23,9 @@ import type { TranslationObjectType } from "../dsl/types/TranslationObjectType.t
22
23
  import { type TypeArgumentType } from "../dsl/types/TypeArgumentType.ts";
23
24
  export type NodeWithResolvedTypeArguments<T extends Node | null> = T extends BooleanType | DateType | FloatType | IntegerType | StringType | ReferenceIdentifierType | ChildEntitiesType | TranslationObjectType ? T : T extends EntityDecl<infer N, infer P, infer FK> ? EntityDecl<N, {
24
25
  [K in keyof P]: P[K] extends MemberDecl<infer PT, infer R> ? MemberDecl<NodeWithResolvedTypeArguments<PT>, R> : never;
25
- }, FK> : T extends EnumDecl<infer N, infer V, TypeParameter[]> ? EnumDecl<N, {
26
+ }, FK> : T extends SingletonEntityDecl<infer N, infer P> ? SingletonEntityDecl<N, {
27
+ [K in keyof P]: P[K] extends MemberDecl<infer PT, infer R> ? MemberDecl<NodeWithResolvedTypeArguments<PT>, R> : never;
28
+ }> : T extends EnumDecl<infer N, infer V, TypeParameter[]> ? EnumDecl<N, {
26
29
  [K in keyof V]: V[K] extends EnumCaseDecl<infer CT> ? EnumCaseDecl<NodeWithResolvedTypeArguments<CT>> : never;
27
30
  }, [
28
31
  ]> : T extends TypeAliasDecl<infer N, infer U, TypeParameter[]> ? TypeAliasDecl<N, NodeWithResolvedTypeArguments<U>, []> : T extends ArrayType<infer I> ? ArrayType<NodeWithResolvedTypeArguments<I>> : T extends EnumType<infer V> ? EnumType<{
@@ -3,6 +3,7 @@ import { NodeKind } from "../../../shared/schema/Node.js";
3
3
  import { getTypeArgumentsRecord, isDeclWithoutTypeParameters, } from "../dsl/declarations/Decl.js";
4
4
  import { EntityDecl } from "../dsl/declarations/EntityDecl.js";
5
5
  import { EnumDecl } from "../dsl/declarations/EnumDecl.js";
6
+ import { SingletonEntityDecl } from "../dsl/declarations/SingletonEntityDecl.js";
6
7
  import { isTypeAliasDecl, TypeAliasDecl } from "../dsl/declarations/TypeAliasDecl.js";
7
8
  import { ArrayType } from "../dsl/types/ArrayType.js";
8
9
  import {} from "../dsl/types/BooleanType.js";
@@ -24,6 +25,11 @@ export const resolveTypeArguments = (args, node, inDecl) => {
24
25
  ...node,
25
26
  type: () => resolveTypeArguments({}, node.type.value, [...inDecl, node]),
26
27
  });
28
+ case NodeKind.SingletonEntityDecl:
29
+ return SingletonEntityDecl(node.sourceUrl, {
30
+ ...node,
31
+ type: () => resolveTypeArguments({}, node.type.value, [...inDecl, node]),
32
+ });
27
33
  case NodeKind.EnumDecl:
28
34
  return EnumDecl(node.sourceUrl, {
29
35
  name: node.name,
@@ -4,6 +4,7 @@ import { assertExhaustive } from "@elyukai/utils/typeSafety";
4
4
  import { MessageError, parseMessage, validate } from "messageformat";
5
5
  import { ENUM_DISCRIMINATOR_KEY } from "../../../shared/schema/declarations/EnumDecl.js";
6
6
  import { NodeKind } from "../../../shared/schema/Node.js";
7
+ import { wrapErrorsIfAny } from "../../../shared/utils/error.js";
7
8
  import { extendsParameterTypes, extractParameterTypeNamesFromMessage, } from "../../../shared/utils/translation.js";
8
9
  import { parallelizeErrors } from "../../../shared/utils/validation.js";
9
10
  import { validateArrayConstraints } from "../../../shared/validation/array.js";
@@ -12,7 +13,6 @@ import { validateNumberConstraints } from "../../../shared/validation/number.js"
12
13
  import { validateObjectConstraints, validateObjectRangeConstraints, validateUnknownKeys, } from "../../../shared/validation/object.js";
13
14
  import { validateStringConstraints } from "../../../shared/validation/string.js";
14
15
  import {} from "../../utils/databaseInMemory.js";
15
- import { wrapErrorsIfAny } from "../../utils/error.js";
16
16
  import { entity, json, key } from "../../utils/errorFormatting.js";
17
17
  import { getTypeArgumentsRecord } from "../dsl/declarations/Decl.js";
18
18
  import { createEntityIdentifierType } from "../dsl/declarations/EntityDecl.js";
@@ -34,6 +34,7 @@ export const createReferenceValidator = (isEntityName, databaseInMemory, useStyl
34
34
  export const validateDeclStructuralIntegrity = (helpers, inDecls, decl, typeArgs, value) => {
35
35
  switch (decl.kind) {
36
36
  case NodeKind.EntityDecl:
37
+ case NodeKind.SingletonEntityDecl:
37
38
  return validateTypeStructuralIntegrity(helpers, inDecls, decl.type.value, value);
38
39
  case NodeKind.EnumDecl:
39
40
  case NodeKind.TypeAliasDecl:
@@ -286,6 +287,7 @@ export const validateTypeStructuralIntegrity = (helpers, inDecls, type, value) =
286
287
  export const validateDeclReferentialIntegrity = (helpers, checkEntityName, checkReferentialIntegrity, inDecls, decl, typeArgs, value) => {
287
288
  switch (decl.kind) {
288
289
  case NodeKind.EntityDecl:
290
+ case NodeKind.SingletonEntityDecl:
289
291
  return validateTypeReferentialIntegrity(helpers, checkEntityName, checkReferentialIntegrity, inDecls, decl.type.value, value);
290
292
  case NodeKind.EnumDecl:
291
293
  case NodeKind.TypeAliasDecl: