tsondb 0.1.3 → 0.3.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.
Files changed (110) hide show
  1. package/lib/ModelContainer.js +9 -7
  2. package/lib/Schema.js +1 -3
  3. package/lib/client/api.d.ts +14 -1
  4. package/lib/client/api.js +119 -0
  5. package/lib/client/components/Git.d.ts +2 -0
  6. package/lib/client/components/Git.js +116 -0
  7. package/lib/client/components/Layout.js +2 -1
  8. package/lib/client/components/typeInputs/ArrayTypeInput.js +3 -2
  9. package/lib/client/components/typeInputs/EnumTypeInput.d.ts +13 -0
  10. package/lib/client/components/typeInputs/{utils/EnumDeclField.js → EnumTypeInput.js} +13 -13
  11. package/lib/client/components/typeInputs/IncludeIdentifierTypeInput.js +1 -10
  12. package/lib/client/components/typeInputs/StringTypeInput.js +8 -5
  13. package/lib/client/components/typeInputs/TypeInput.js +3 -0
  14. package/lib/client/components/typeInputs/utils/Markdown.d.ts +6 -0
  15. package/lib/client/components/typeInputs/utils/Markdown.js +26 -0
  16. package/lib/client/hooks/useAPIResource.d.ts +1 -0
  17. package/lib/client/hooks/useAPIResource.js +2 -0
  18. package/lib/client/hooks/useMappedAPIResource.d.ts +1 -0
  19. package/lib/client/hooks/useMappedAPIResource.js +19 -0
  20. package/lib/client/routes/Entity.js +18 -24
  21. package/lib/client/routes/Home.js +3 -12
  22. package/lib/client/utils/typeSkeleton.js +10 -16
  23. package/lib/renderers/jsonschema/index.d.ts +1 -1
  24. package/lib/renderers/jsonschema/index.js +30 -7
  25. package/lib/renderers/jsonschema/render.d.ts +5 -1
  26. package/lib/renderers/jsonschema/render.js +43 -16
  27. package/lib/renderers/ts/index.d.ts +1 -1
  28. package/lib/renderers/ts/index.js +37 -6
  29. package/lib/renderers/ts/render.d.ts +2 -0
  30. package/lib/renderers/ts/render.js +59 -33
  31. package/lib/schema/Node.d.ts +2 -0
  32. package/lib/schema/Node.js +7 -1
  33. package/lib/schema/declarations/Declaration.d.ts +5 -3
  34. package/lib/schema/declarations/Declaration.js +14 -10
  35. package/lib/schema/declarations/EntityDecl.d.ts +6 -0
  36. package/lib/schema/declarations/EnumDecl.d.ts +11 -8
  37. package/lib/schema/declarations/EnumDecl.js +16 -68
  38. package/lib/schema/declarations/TypeAliasDecl.d.ts +4 -0
  39. package/lib/schema/declarations/TypeAliasDecl.js +1 -1
  40. package/lib/schema/index.d.ts +1 -0
  41. package/lib/schema/index.js +1 -0
  42. package/lib/schema/types/Type.d.ts +8 -2
  43. package/lib/schema/types/Type.js +57 -11
  44. package/lib/schema/types/generic/ArrayType.d.ts +2 -1
  45. package/lib/schema/types/generic/ArrayType.js +3 -2
  46. package/lib/schema/types/generic/EnumType.d.ts +38 -0
  47. package/lib/schema/types/generic/EnumType.js +96 -0
  48. package/lib/schema/types/generic/ObjectType.d.ts +6 -1
  49. package/lib/schema/types/generic/ObjectType.js +9 -4
  50. package/lib/schema/types/primitives/BooleanType.d.ts +2 -1
  51. package/lib/schema/types/primitives/BooleanType.js +1 -0
  52. package/lib/schema/types/primitives/DateType.d.ts +2 -1
  53. package/lib/schema/types/primitives/DateType.js +1 -0
  54. package/lib/schema/types/primitives/FloatType.d.ts +2 -1
  55. package/lib/schema/types/primitives/FloatType.js +1 -0
  56. package/lib/schema/types/primitives/IntegerType.d.ts +2 -1
  57. package/lib/schema/types/primitives/IntegerType.js +1 -0
  58. package/lib/schema/types/primitives/StringType.d.ts +2 -1
  59. package/lib/schema/types/primitives/StringType.js +1 -0
  60. package/lib/schema/types/references/GenericArgumentIdentifierType.d.ts +2 -1
  61. package/lib/schema/types/references/GenericArgumentIdentifierType.js +1 -0
  62. package/lib/schema/types/references/IncludeIdentifierType.d.ts +5 -3
  63. package/lib/schema/types/references/IncludeIdentifierType.js +18 -3
  64. package/lib/schema/types/references/NestedEntityMapType.d.ts +2 -1
  65. package/lib/schema/types/references/NestedEntityMapType.js +6 -13
  66. package/lib/schema/types/references/ReferenceIdentifierType.d.ts +6 -7
  67. package/lib/schema/types/references/ReferenceIdentifierType.js +5 -2
  68. package/lib/server/api/declarations.d.ts +1 -0
  69. package/lib/server/api/declarations.js +154 -0
  70. package/lib/server/api/git.d.ts +1 -0
  71. package/lib/server/api/git.js +174 -0
  72. package/lib/server/api/index.d.ts +1 -0
  73. package/lib/server/api/index.js +8 -0
  74. package/lib/server/api/instanceOperations.d.ts +6 -0
  75. package/lib/server/api/instanceOperations.js +82 -0
  76. package/lib/server/api/instances.d.ts +1 -0
  77. package/lib/server/api/instances.js +23 -0
  78. package/lib/server/index.d.ts +22 -1
  79. package/lib/server/index.js +11 -165
  80. package/lib/server/init.d.ts +5 -0
  81. package/lib/server/init.js +56 -0
  82. package/lib/shared/api.d.ts +12 -1
  83. package/lib/shared/utils/array.d.ts +19 -0
  84. package/lib/shared/utils/array.js +27 -0
  85. package/lib/shared/utils/git.d.ts +12 -0
  86. package/lib/shared/utils/git.js +98 -0
  87. package/lib/shared/utils/instances.d.ts +10 -0
  88. package/lib/shared/utils/instances.js +8 -1
  89. package/lib/shared/utils/markdown.d.ts +14 -0
  90. package/lib/shared/utils/markdown.js +42 -0
  91. package/lib/shared/utils/object.d.ts +1 -0
  92. package/lib/shared/utils/object.js +4 -0
  93. package/lib/shared/utils/string.d.ts +1 -0
  94. package/lib/shared/utils/string.js +9 -0
  95. package/lib/tsconfig.tsbuildinfo +1 -1
  96. package/lib/utils/git.d.ts +3 -0
  97. package/lib/utils/git.js +12 -0
  98. package/lib/utils/instances.d.ts +3 -2
  99. package/lib/utils/instances.js +9 -2
  100. package/lib/utils/path.d.ts +1 -0
  101. package/lib/utils/path.js +2 -0
  102. package/lib/utils/references.d.ts +7 -0
  103. package/lib/utils/references.js +40 -0
  104. package/lib/utils/render.d.ts +6 -1
  105. package/lib/utils/render.js +27 -1
  106. package/package.json +8 -2
  107. package/public/css/styles.css +238 -1
  108. package/lib/client/components/typeInputs/utils/EnumDeclField.d.ts +0 -13
  109. package/lib/server/instanceOperations.d.ts +0 -7
  110. package/lib/server/instanceOperations.js +0 -67
@@ -1,25 +1,28 @@
1
1
  import { Lazy } from "../../utils/lazy.js";
2
2
  import { GetReferences, Node, NodeKind, Serializer } from "../Node.js";
3
3
  import { SerializedTypeParameter, TypeParameter } from "../parameters/TypeParameter.js";
4
- import { SerializedType, Type } from "../types/Type.js";
4
+ import { EnumCaseDecl, EnumType, SerializedEnumCaseDecl, SerializedEnumType } from "../types/generic/EnumType.js";
5
+ import { Type } from "../types/Type.js";
5
6
  import { ValidatorHelpers } from "../validation/type.js";
6
7
  import { BaseDecl, GetNestedDeclarations, SerializedBaseDecl, TypeArguments } from "./Declaration.js";
7
- export interface EnumDecl<Name extends string = string, T extends Record<string, Type | null> = Record<string, Type | null>, Params extends TypeParameter[] = TypeParameter[]> extends BaseDecl<Name, Params> {
8
+ export interface EnumDecl<Name extends string = string, T extends Record<string, EnumCaseDecl> = Record<string, EnumCaseDecl>, Params extends TypeParameter[] = TypeParameter[]> extends BaseDecl<Name, Params> {
8
9
  kind: NodeKind["EnumDecl"];
9
- values: Lazy<T>;
10
+ type: Lazy<EnumType<T>>;
11
+ isDeprecated?: boolean;
10
12
  }
11
- export interface SerializedEnumDecl<Name extends string = string, T extends Record<string, SerializedType | null> = Record<string, SerializedType | null>, Params extends SerializedTypeParameter[] = SerializedTypeParameter[]> extends SerializedBaseDecl<Name, Params> {
13
+ export interface SerializedEnumDecl<Name extends string = string, T extends Record<string, SerializedEnumCaseDecl> = Record<string, SerializedEnumCaseDecl>, Params extends SerializedTypeParameter[] = SerializedTypeParameter[]> extends SerializedBaseDecl<Name, Params> {
12
14
  kind: NodeKind["EnumDecl"];
13
- values: T;
15
+ type: SerializedEnumType<T>;
16
+ isDeprecated?: boolean;
14
17
  }
15
- export declare const GenEnumDecl: <Name extends string, T extends Record<string, Type | null>, Params extends TypeParameter[]>(sourceUrl: string, options: {
18
+ export declare const GenEnumDecl: <Name extends string, T extends Record<string, EnumCaseDecl>, Params extends TypeParameter[]>(sourceUrl: string, options: {
16
19
  name: Name;
17
20
  comment?: string;
18
21
  parameters: Params;
19
22
  values: (...args: Params) => T;
20
23
  }) => EnumDecl<Name, T, Params>;
21
24
  export { GenEnumDecl as GenEnum };
22
- export declare const EnumDecl: <Name extends string, T extends Record<string, Type | null>>(sourceUrl: string, options: {
25
+ export declare const EnumDecl: <Name extends string, T extends Record<string, EnumCaseDecl>>(sourceUrl: string, options: {
23
26
  name: Name;
24
27
  comment?: string;
25
28
  values: () => T;
@@ -28,6 +31,6 @@ export { EnumDecl as Enum };
28
31
  export declare const isEnumDecl: (node: Node) => node is EnumDecl;
29
32
  export declare const getNestedDeclarationsInEnumDecl: GetNestedDeclarations<EnumDecl>;
30
33
  export declare const validateEnumDecl: (helpers: ValidatorHelpers, decl: EnumDecl, args: Type[], value: unknown) => Error[];
31
- export declare const resolveTypeArgumentsInEnumDecl: <Params extends TypeParameter[]>(decl: EnumDecl<string, Record<string, Type | null>, Params>, args: TypeArguments<Params>) => EnumDecl<string, Record<string, Type | null>, []>;
34
+ export declare const resolveTypeArgumentsInEnumDecl: <Params extends TypeParameter[]>(decl: EnumDecl<string, Record<string, EnumCaseDecl>, Params>, args: TypeArguments<Params>) => EnumDecl<string, Record<string, EnumCaseDecl>, []>;
32
35
  export declare const serializeEnumDecl: Serializer<EnumDecl, SerializedEnumDecl>;
33
36
  export declare const getReferencesForEnumDecl: GetReferences<EnumDecl>;
@@ -1,22 +1,17 @@
1
- import { discriminatorKey } from "../../shared/enum.js";
2
1
  import { Lazy } from "../../utils/lazy.js";
3
2
  import { NodeKind } from "../Node.js";
4
3
  import { serializeTypeParameter, } from "../parameters/TypeParameter.js";
5
- import { getReferencesForType, resolveTypeArgumentsInType, serializeType, validate, } from "../types/Type.js";
6
- import { getNestedDeclarations, getTypeArgumentsRecord, validateDeclName, } from "./Declaration.js";
4
+ import { EnumType, getNestedDeclarationsInEnumType, getReferencesForEnumType, resolveTypeArgumentsInEnumType, serializeEnumType, validateEnumType, } from "../types/generic/EnumType.js";
5
+ import { getTypeArgumentsRecord, validateDeclName, } from "./Declaration.js";
7
6
  export const GenEnumDecl = (sourceUrl, options) => {
8
7
  validateDeclName(options.name);
9
8
  const decl = {
10
9
  ...options,
11
10
  kind: NodeKind.EnumDecl,
12
11
  sourceUrl,
13
- values: Lazy.of(() => {
14
- const type = options.values(...options.parameters);
15
- Object.values(type).forEach(type => {
16
- if (type) {
17
- type.parent = decl;
18
- }
19
- });
12
+ type: Lazy.of(() => {
13
+ const type = EnumType(options.values(...options.parameters));
14
+ type.parent = decl;
20
15
  return type;
21
16
  }),
22
17
  };
@@ -30,13 +25,9 @@ export const EnumDecl = (sourceUrl, options) => {
30
25
  kind: NodeKind.EnumDecl,
31
26
  sourceUrl,
32
27
  parameters: [],
33
- values: Lazy.of(() => {
34
- const type = options.values();
35
- Object.values(type).forEach(type => {
36
- if (type) {
37
- type.parent = decl;
38
- }
39
- });
28
+ type: Lazy.of(() => {
29
+ const type = EnumType(options.values());
30
+ type.parent = decl;
40
31
  return type;
41
32
  }),
42
33
  };
@@ -44,61 +35,18 @@ export const EnumDecl = (sourceUrl, options) => {
44
35
  };
45
36
  export { EnumDecl as Enum };
46
37
  export const isEnumDecl = (node) => node.kind === NodeKind.EnumDecl;
47
- export const getNestedDeclarationsInEnumDecl = (isDeclAdded, decl) => Object.values(decl.values.value).flatMap(caseDef => caseDef === null ? [] : getNestedDeclarations(isDeclAdded, caseDef));
48
- export const validateEnumDecl = (helpers, decl, args, value) => {
49
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
50
- return [TypeError(`expected an object, but got ${JSON.stringify(value)}`)];
51
- }
52
- const actualKeys = Object.keys(value);
53
- if (!(discriminatorKey in value) || typeof value[discriminatorKey] !== "string") {
54
- return [
55
- TypeError(`missing required discriminator value at key "${discriminatorKey}" of type string`),
56
- ];
57
- }
58
- const caseName = value[discriminatorKey];
59
- if (!(caseName in decl.values.value)) {
60
- return [TypeError(`discriminator "${caseName}" is not a valid enum case`)];
61
- }
62
- const unknownKeyErrors = actualKeys.flatMap(actualKey => actualKey === discriminatorKey || actualKey in decl.values.value
63
- ? []
64
- : [TypeError(`key "${actualKey}" is not the discriminator key or a valid enum case`)]);
65
- if (unknownKeyErrors.length > 0) {
66
- return unknownKeyErrors;
67
- }
68
- const associatedType = decl.values.value[caseName];
69
- if (associatedType != null) {
70
- if (!(caseName in value)) {
71
- return [TypeError(`missing required associated value for case "${caseName}"`)];
72
- }
73
- return validate(helpers, resolveTypeArgumentsInType(getTypeArgumentsRecord(decl, args), associatedType), value[caseName]);
74
- }
75
- return [];
76
- };
38
+ export const getNestedDeclarationsInEnumDecl = (addedDecls, decl) => getNestedDeclarationsInEnumType(addedDecls, decl.type.value);
39
+ export const validateEnumDecl = (helpers, decl, args, value) => validateEnumType(helpers, resolveTypeArgumentsInEnumType(getTypeArgumentsRecord(decl, args), decl.type.value), value);
77
40
  export const resolveTypeArgumentsInEnumDecl = (decl, args) => {
78
41
  const resolvedArgs = getTypeArgumentsRecord(decl, args);
79
42
  return EnumDecl(decl.sourceUrl, {
80
43
  ...decl,
81
- values: () => Object.fromEntries(Object.entries(decl.values.value).map(([key, value]) => [
82
- key,
83
- value === null ? null : resolveTypeArgumentsInType(resolvedArgs, value),
84
- ])),
44
+ values: () => resolveTypeArgumentsInEnumType(resolvedArgs, decl.type.value).values,
85
45
  });
86
46
  };
87
- export const serializeEnumDecl = type => ({
88
- ...type,
89
- values: Object.fromEntries(Object.entries(type.values.value).map(([key, value]) => [
90
- key,
91
- value === null ? null : serializeType(value),
92
- ])),
93
- parameters: type.parameters.map(param => serializeTypeParameter(param)),
47
+ export const serializeEnumDecl = decl => ({
48
+ ...decl,
49
+ type: serializeEnumType(decl.type.value),
50
+ parameters: decl.parameters.map(param => serializeTypeParameter(param)),
94
51
  });
95
- export const getReferencesForEnumDecl = (decl, value) => typeof value === "object" &&
96
- value !== null &&
97
- !Array.isArray(value) &&
98
- discriminatorKey in value &&
99
- typeof value[discriminatorKey] === "string" &&
100
- value[discriminatorKey] in decl.values.value &&
101
- decl.values.value[value[discriminatorKey]] !== null &&
102
- value[discriminatorKey] in value
103
- ? getReferencesForType(decl.values.value[value[discriminatorKey]], value[value[discriminatorKey]])
104
- : [];
52
+ export const getReferencesForEnumDecl = (decl, value) => getReferencesForEnumType(decl.type.value, value);
@@ -7,14 +7,17 @@ import { BaseDecl, GetNestedDeclarations, SerializedBaseDecl, TypeArguments } fr
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>;
10
+ isDeprecated?: boolean;
10
11
  }
11
12
  export interface SerializedTypeAliasDecl<Name extends string = string, T extends SerializedType = SerializedType, Params extends SerializedTypeParameter[] = SerializedTypeParameter[]> extends SerializedBaseDecl<Name, Params> {
12
13
  kind: NodeKind["TypeAliasDecl"];
13
14
  type: T;
15
+ isDeprecated?: boolean;
14
16
  }
15
17
  export declare const GenTypeAliasDecl: <Name extends string, T extends Type, Params extends TypeParameter[]>(sourceUrl: string, options: {
16
18
  name: Name;
17
19
  comment?: string;
20
+ isDeprecated?: boolean;
18
21
  parameters: Params;
19
22
  type: (...args: Params) => T;
20
23
  }) => TypeAliasDecl<Name, T, Params>;
@@ -22,6 +25,7 @@ export { GenTypeAliasDecl as GenTypeAlias };
22
25
  export declare const TypeAliasDecl: <Name extends string, T extends Type>(sourceUrl: string, options: {
23
26
  name: Name;
24
27
  comment?: string;
28
+ isDeprecated?: boolean;
25
29
  type: () => T;
26
30
  }) => TypeAliasDecl<Name, T, []>;
27
31
  export { TypeAliasDecl as TypeAlias };
@@ -35,7 +35,7 @@ export const TypeAliasDecl = (sourceUrl, options) => {
35
35
  };
36
36
  export { TypeAliasDecl as TypeAlias };
37
37
  export const isTypeAliasDecl = (node) => node.kind === NodeKind.TypeAliasDecl;
38
- export const getNestedDeclarationsInTypeAliasDecl = (isDeclAdded, decl) => getNestedDeclarations(isDeclAdded, decl.type.value);
38
+ export const getNestedDeclarationsInTypeAliasDecl = (addedDecls, decl) => getNestedDeclarations(addedDecls, decl.type.value);
39
39
  export const validateTypeAliasDecl = (helpers, decl, args, value) => validate(helpers, resolveTypeArgumentsInType(getTypeArgumentsRecord(decl, args), decl.type.value), value);
40
40
  export const resolveTypeArgumentsInTypeAliasDecl = (decl, args) => TypeAliasDecl(decl.sourceUrl, {
41
41
  ...decl,
@@ -5,6 +5,7 @@ export * from "./declarations/TypeAliasDecl.js";
5
5
  export * from "./Node.js";
6
6
  export * from "./parameters/TypeParameter.js";
7
7
  export * from "./types/generic/ArrayType.js";
8
+ export { EnumCase } from "./types/generic/EnumType.js";
8
9
  export * from "./types/generic/ObjectType.js";
9
10
  export * from "./types/primitives/BooleanType.js";
10
11
  export * from "./types/primitives/DateType.js";
@@ -5,6 +5,7 @@ export * from "./declarations/TypeAliasDecl.js";
5
5
  export * from "./Node.js";
6
6
  export * from "./parameters/TypeParameter.js";
7
7
  export * from "./types/generic/ArrayType.js";
8
+ export { EnumCase } from "./types/generic/EnumType.js";
8
9
  export * from "./types/generic/ObjectType.js";
9
10
  export * from "./types/primitives/BooleanType.js";
10
11
  export * from "./types/primitives/DateType.js";
@@ -2,6 +2,7 @@ import { Decl } from "../declarations/Declaration.js";
2
2
  import { BaseNode, GetReferences, Serializer } from "../Node.js";
3
3
  import { Validator } from "../validation/type.js";
4
4
  import { ArrayType, SerializedArrayType } from "./generic/ArrayType.js";
5
+ import { EnumType, SerializedEnumType } from "./generic/EnumType.js";
5
6
  import { MemberDecl, ObjectType, SerializedMemberDecl, SerializedObjectType } from "./generic/ObjectType.js";
6
7
  import { BooleanType, SerializedBooleanType } from "./primitives/BooleanType.js";
7
8
  import { DateType, SerializedDateType } from "./primitives/DateType.js";
@@ -21,8 +22,8 @@ export interface BaseType extends BaseNode {
21
22
  }
22
23
  export interface SerializedBaseType extends BaseNode {
23
24
  }
24
- export type Type = PrimitiveType | ArrayType | ObjectType | GenericArgumentIdentifierType | ReferenceIdentifierType | IncludeIdentifierType | NestedEntityMapType;
25
- export type SerializedType = SerializedPrimitiveType | SerializedArrayType | SerializedObjectType | SerializedGenericArgumentIdentifierType | SerializedReferenceIdentifierType | SerializedIncludeIdentifierType | SerializedNestedEntityMapType;
25
+ export type Type = PrimitiveType | ArrayType | ObjectType | GenericArgumentIdentifierType | ReferenceIdentifierType | IncludeIdentifierType | NestedEntityMapType | EnumType;
26
+ export type SerializedType = SerializedPrimitiveType | SerializedArrayType | SerializedObjectType | SerializedGenericArgumentIdentifierType | SerializedReferenceIdentifierType | SerializedIncludeIdentifierType | SerializedNestedEntityMapType | SerializedEnumType;
26
27
  export declare const validate: Validator<Type>;
27
28
  export declare const resolveTypeArgumentsInType: <Args extends Record<string, Type>>(args: Args, type: Type) => Type;
28
29
  export declare function walkTypeNodeTree(callbackFn: (type: Type) => void, type: Type): void;
@@ -40,3 +41,8 @@ export declare const findTypeAtPath: (type: Type, path: string[]) => Type | unde
40
41
  export declare const serializeType: Serializer<Type, SerializedType>;
41
42
  export declare const removeParentKey: <T extends BaseType>(type: T) => Omit<T, "parent">;
42
43
  export declare const getReferencesForType: GetReferences<Type>;
44
+ /**
45
+ * Format the structure of a value to always look the same when serialized as JSON.
46
+ */
47
+ export type StructureFormatter<T extends Type> = (type: T, value: unknown) => unknown;
48
+ export declare const formatValue: StructureFormatter<Type>;
@@ -1,17 +1,18 @@
1
1
  import { assertExhaustive } from "../../shared/utils/typeSafety.js";
2
2
  import { isDecl } from "../declarations/Declaration.js";
3
3
  import { NodeKind } from "../Node.js";
4
- import { getReferencesForArrayType, resolveTypeArgumentsInArrayType, serializeArrayType, validateArrayType, } from "./generic/ArrayType.js";
5
- import { getReferencesForObjectType, resolveTypeArgumentsInObjectType, serializeObjectType, validateObjectType, } from "./generic/ObjectType.js";
6
- import { getReferencesForBooleanType, serializeBooleanType, validateBooleanType, } from "./primitives/BooleanType.js";
7
- import { getReferencesForDateType, serializeDateType, validateDateType, } from "./primitives/DateType.js";
8
- import { getReferencesForFloatType, serializeFloatType, validateFloatType, } from "./primitives/FloatType.js";
9
- import { getReferencesForIntegerType, serializeIntegerType, validateIntegerType, } from "./primitives/IntegerType.js";
10
- import { getReferencesForStringType, serializeStringType, validateStringType, } from "./primitives/StringType.js";
11
- import { getReferencesForGenericArgumentIdentifierType, resolveTypeArgumentsInGenericArgumentIdentifierType, serializeGenericArgumentIdentifierType, validateGenericArgumentIdentifierType, } from "./references/GenericArgumentIdentifierType.js";
12
- import { getReferencesForIncludeIdentifierType, resolveTypeArgumentsInIncludeIdentifierType, serializeIncludeIdentifierType, validateIncludeIdentifierType, } from "./references/IncludeIdentifierType.js";
13
- import { getReferencesForNestedEntityMapType, resolveTypeArgumentsInNestedEntityMapType, serializeNestedEntityMapType, validateNestedEntityMapType, } from "./references/NestedEntityMapType.js";
14
- import { getReferencesForReferenceIdentifierType, resolveTypeArgumentsInReferenceIdentifierType, serializeReferenceIdentifierType, validateReferenceIdentifierType, } from "./references/ReferenceIdentifierType.js";
4
+ import { formatArrayValue, getReferencesForArrayType, resolveTypeArgumentsInArrayType, serializeArrayType, validateArrayType, } from "./generic/ArrayType.js";
5
+ import { formatEnumType, getReferencesForEnumType, resolveTypeArgumentsInEnumType, serializeEnumType, validateEnumType, } from "./generic/EnumType.js";
6
+ import { formatObjectValue, getReferencesForObjectType, resolveTypeArgumentsInObjectType, serializeObjectType, validateObjectType, } from "./generic/ObjectType.js";
7
+ import { formatBooleanValue, getReferencesForBooleanType, serializeBooleanType, validateBooleanType, } from "./primitives/BooleanType.js";
8
+ import { formatDateValue, getReferencesForDateType, serializeDateType, validateDateType, } from "./primitives/DateType.js";
9
+ import { formatFloatValue, getReferencesForFloatType, serializeFloatType, validateFloatType, } from "./primitives/FloatType.js";
10
+ import { formatIntegerValue, getReferencesForIntegerType, serializeIntegerType, validateIntegerType, } from "./primitives/IntegerType.js";
11
+ import { formatStringValue, getReferencesForStringType, serializeStringType, validateStringType, } from "./primitives/StringType.js";
12
+ import { formatGenericArgumentIdentifierValue, getReferencesForGenericArgumentIdentifierType, resolveTypeArgumentsInGenericArgumentIdentifierType, serializeGenericArgumentIdentifierType, validateGenericArgumentIdentifierType, } from "./references/GenericArgumentIdentifierType.js";
13
+ import { formatIncludeIdentifierValue, getReferencesForIncludeIdentifierType, resolveTypeArgumentsInIncludeIdentifierType, serializeIncludeIdentifierType, validateIncludeIdentifierType, } from "./references/IncludeIdentifierType.js";
14
+ import { formatNestedEntityMapValue, getReferencesForNestedEntityMapType, resolveTypeArgumentsInNestedEntityMapType, serializeNestedEntityMapType, validateNestedEntityMapType, } from "./references/NestedEntityMapType.js";
15
+ import { formatReferenceIdentifierValue, getReferencesForReferenceIdentifierType, resolveTypeArgumentsInReferenceIdentifierType, serializeReferenceIdentifierType, validateReferenceIdentifierType, } from "./references/ReferenceIdentifierType.js";
15
16
  export const validate = (helpers, type, value) => {
16
17
  switch (type.kind) {
17
18
  case NodeKind.ArrayType:
@@ -36,6 +37,8 @@ export const validate = (helpers, type, value) => {
36
37
  return validateIncludeIdentifierType(helpers, type, value);
37
38
  case NodeKind.NestedEntityMapType:
38
39
  return validateNestedEntityMapType(helpers, type, value);
40
+ case NodeKind.EnumType:
41
+ return validateEnumType(helpers, type, value);
39
42
  default:
40
43
  return assertExhaustive(type);
41
44
  }
@@ -60,6 +63,8 @@ export const resolveTypeArgumentsInType = (args, type) => {
60
63
  return resolveTypeArgumentsInIncludeIdentifierType(args, type);
61
64
  case NodeKind.NestedEntityMapType:
62
65
  return resolveTypeArgumentsInNestedEntityMapType(args, type);
66
+ case NodeKind.EnumType:
67
+ return resolveTypeArgumentsInEnumType(args, type);
63
68
  default:
64
69
  return assertExhaustive(type);
65
70
  }
@@ -84,6 +89,13 @@ export function walkTypeNodeTree(callbackFn, type) {
84
89
  case NodeKind.ReferenceIdentifierType:
85
90
  case NodeKind.IncludeIdentifierType:
86
91
  return callbackFn(type);
92
+ case NodeKind.EnumType:
93
+ callbackFn(type);
94
+ return Object.values(type.values).forEach(value => {
95
+ if (value.type) {
96
+ walkTypeNodeTree(callbackFn, value.type);
97
+ }
98
+ });
87
99
  default:
88
100
  return assertExhaustive(type);
89
101
  }
@@ -139,6 +151,8 @@ export const serializeType = type => {
139
151
  return serializeIncludeIdentifierType(type);
140
152
  case NodeKind.NestedEntityMapType:
141
153
  return serializeNestedEntityMapType(type);
154
+ case NodeKind.EnumType:
155
+ return serializeEnumType(type);
142
156
  default:
143
157
  return assertExhaustive(type);
144
158
  }
@@ -171,6 +185,38 @@ export const getReferencesForType = (type, value) => {
171
185
  return getReferencesForIncludeIdentifierType(type, value);
172
186
  case NodeKind.NestedEntityMapType:
173
187
  return getReferencesForNestedEntityMapType(type, value);
188
+ case NodeKind.EnumType:
189
+ return getReferencesForEnumType(type, value);
190
+ default:
191
+ return assertExhaustive(type);
192
+ }
193
+ };
194
+ export const formatValue = (type, value) => {
195
+ switch (type.kind) {
196
+ case NodeKind.ArrayType:
197
+ return formatArrayValue(type, value);
198
+ case NodeKind.ObjectType:
199
+ return formatObjectValue(type, value);
200
+ case NodeKind.BooleanType:
201
+ return formatBooleanValue(type, value);
202
+ case NodeKind.DateType:
203
+ return formatDateValue(type, value);
204
+ case NodeKind.FloatType:
205
+ return formatFloatValue(type, value);
206
+ case NodeKind.IntegerType:
207
+ return formatIntegerValue(type, value);
208
+ case NodeKind.StringType:
209
+ return formatStringValue(type, value);
210
+ case NodeKind.GenericArgumentIdentifierType:
211
+ return formatGenericArgumentIdentifierValue(type, value);
212
+ case NodeKind.IncludeIdentifierType:
213
+ return formatIncludeIdentifierValue(type, value);
214
+ case NodeKind.NestedEntityMapType:
215
+ return formatNestedEntityMapValue(type, value);
216
+ case NodeKind.ReferenceIdentifierType:
217
+ return formatReferenceIdentifierValue(type, value);
218
+ case NodeKind.EnumType:
219
+ return formatEnumType(type, value);
174
220
  default:
175
221
  return assertExhaustive(type);
176
222
  }
@@ -1,7 +1,7 @@
1
1
  import { GetNestedDeclarations } from "../../declarations/Declaration.js";
2
2
  import { GetReferences, Node, NodeKind, Serializer } from "../../Node.js";
3
3
  import { Validator } from "../../validation/type.js";
4
- import { BaseType, SerializedBaseType, SerializedType, Type } from "../Type.js";
4
+ import { BaseType, SerializedBaseType, SerializedType, StructureFormatter, Type } from "../Type.js";
5
5
  export interface ArrayType<T extends Type = Type> extends BaseType {
6
6
  kind: NodeKind["ArrayType"];
7
7
  minItems?: number;
@@ -28,3 +28,4 @@ export declare const validateArrayType: Validator<ArrayType>;
28
28
  export declare const resolveTypeArgumentsInArrayType: (args: Record<string, Type>, type: ArrayType) => ArrayType;
29
29
  export declare const serializeArrayType: Serializer<ArrayType, SerializedArrayType>;
30
30
  export declare const getReferencesForArrayType: GetReferences<ArrayType>;
31
+ export declare const formatArrayValue: StructureFormatter<ArrayType>;
@@ -4,7 +4,7 @@ import { wrapErrorsIfAny } from "../../../utils/error.js";
4
4
  import { getNestedDeclarations } from "../../declarations/Declaration.js";
5
5
  import { NodeKind } from "../../Node.js";
6
6
  import { validateOption } from "../../validation/options.js";
7
- import { getReferencesForType, removeParentKey, resolveTypeArgumentsInType, serializeType, validate, } from "../Type.js";
7
+ import { formatValue, getReferencesForType, removeParentKey, resolveTypeArgumentsInType, serializeType, validate, } from "../Type.js";
8
8
  export const ArrayType = (items, options = {}) => {
9
9
  const type = {
10
10
  ...options,
@@ -18,7 +18,7 @@ export const ArrayType = (items, options = {}) => {
18
18
  };
19
19
  export { ArrayType as Array };
20
20
  export const isArrayType = (node) => node.kind === NodeKind.ArrayType;
21
- export const getNestedDeclarationsInArrayType = (isDeclAdded, type) => getNestedDeclarations(isDeclAdded, type.items);
21
+ export const getNestedDeclarationsInArrayType = (addedDecls, type) => getNestedDeclarations(addedDecls, type.items);
22
22
  export const validateArrayType = (helpers, type, value) => {
23
23
  if (!Array.isArray(value)) {
24
24
  return [TypeError(`expected an array, but got ${JSON.stringify(value)}`)];
@@ -36,3 +36,4 @@ export const serializeArrayType = type => ({
36
36
  items: serializeType(type.items),
37
37
  });
38
38
  export const getReferencesForArrayType = (type, value) => Array.isArray(value) ? value.flatMap(item => getReferencesForType(type.items, item)) : [];
39
+ export const formatArrayValue = (type, value) => Array.isArray(value) ? value.map(item => formatValue(type.items, item)) : value;
@@ -0,0 +1,38 @@
1
+ import { GetNestedDeclarations } from "../../declarations/Declaration.js";
2
+ import { GetReferences, Node, NodeKind, Serializer } from "../../Node.js";
3
+ import { Validator } from "../../validation/type.js";
4
+ import { BaseType, SerializedBaseType, SerializedType, StructureFormatter, Type } from "../Type.js";
5
+ export interface EnumType<T extends Record<string, EnumCaseDecl> = Record<string, EnumCaseDecl>> extends BaseType {
6
+ kind: NodeKind["EnumType"];
7
+ values: T;
8
+ }
9
+ export interface SerializedEnumType<T extends Record<string, SerializedEnumCaseDecl> = Record<string, SerializedEnumCaseDecl>> extends SerializedBaseType {
10
+ kind: NodeKind["EnumType"];
11
+ values: T;
12
+ }
13
+ export declare const EnumType: <T extends Record<string, EnumCaseDecl> = Record<string, EnumCaseDecl>>(values: T) => EnumType<T>;
14
+ export declare const isEnumType: (node: Node) => node is EnumType;
15
+ export declare const getNestedDeclarationsInEnumType: GetNestedDeclarations<EnumType>;
16
+ export declare const validateEnumType: Validator<EnumType>;
17
+ export declare const resolveTypeArgumentsInEnumType: (args: Record<string, Type>, type: EnumType) => EnumType;
18
+ export interface EnumCaseDecl<T extends Type | null = Type | null> {
19
+ kind: NodeKind["EnumCaseDecl"];
20
+ type: T;
21
+ comment?: string;
22
+ isDeprecated?: boolean;
23
+ }
24
+ export interface SerializedEnumCaseDecl<T extends SerializedType | null = SerializedType | null> {
25
+ kind: NodeKind["EnumCaseDecl"];
26
+ type: T;
27
+ comment?: string;
28
+ isDeprecated?: boolean;
29
+ }
30
+ export declare const EnumCaseDecl: <T extends Type | null>(options: {
31
+ type: T;
32
+ comment?: string;
33
+ isDeprecated?: boolean;
34
+ }) => EnumCaseDecl<T>;
35
+ export { EnumCaseDecl as EnumCase };
36
+ export declare const serializeEnumType: Serializer<EnumType, SerializedEnumType>;
37
+ export declare const getReferencesForEnumType: GetReferences<EnumType>;
38
+ export declare const formatEnumType: StructureFormatter<EnumType>;
@@ -0,0 +1,96 @@
1
+ import { discriminatorKey } from "../../../shared/enum.js";
2
+ import { getNestedDeclarations } from "../../declarations/Declaration.js";
3
+ import { NodeKind } from "../../Node.js";
4
+ import { formatValue, getReferencesForType, removeParentKey, resolveTypeArgumentsInType, serializeType, validate, } from "../Type.js";
5
+ export const EnumType = (values) => {
6
+ const type = {
7
+ kind: NodeKind.EnumType,
8
+ values,
9
+ };
10
+ type.values = Object.fromEntries(Object.entries(values).map(([caseName, caseDef]) => [
11
+ caseName,
12
+ { ...caseDef, type: caseDef.type === null ? null : { ...caseDef.type, parent: type } },
13
+ ]));
14
+ return type;
15
+ };
16
+ export const isEnumType = (node) => node.kind === NodeKind.EnumType;
17
+ export const getNestedDeclarationsInEnumType = (addedDecls, type) => Object.values(type.values).reduce((acc, caseMember) => caseMember.type === null ? acc : getNestedDeclarations(acc, caseMember.type), addedDecls);
18
+ export const validateEnumType = (helpers, type, value) => {
19
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
20
+ return [TypeError(`expected an object, but got ${JSON.stringify(value)}`)];
21
+ }
22
+ const actualKeys = Object.keys(value);
23
+ if (!(discriminatorKey in value) || typeof value[discriminatorKey] !== "string") {
24
+ return [
25
+ TypeError(`missing required discriminator value at key "${discriminatorKey}" of type string`),
26
+ ];
27
+ }
28
+ const caseName = value[discriminatorKey];
29
+ if (!(caseName in type.values)) {
30
+ return [TypeError(`discriminator "${caseName}" is not a valid enum case`)];
31
+ }
32
+ const unknownKeyErrors = actualKeys.flatMap(actualKey => actualKey === discriminatorKey || actualKey in type.values
33
+ ? []
34
+ : [TypeError(`key "${actualKey}" is not the discriminator key or a valid enum case`)]);
35
+ if (unknownKeyErrors.length > 0) {
36
+ return unknownKeyErrors;
37
+ }
38
+ const associatedType = type.values[caseName]?.type;
39
+ if (associatedType != null) {
40
+ if (!(caseName in value)) {
41
+ return [TypeError(`missing required associated value for case "${caseName}"`)];
42
+ }
43
+ return validate(helpers, associatedType, value[caseName]);
44
+ }
45
+ return [];
46
+ };
47
+ export const resolveTypeArgumentsInEnumType = (args, type) => EnumType(Object.fromEntries(Object.entries(type.values).map(([key, { type, ...caseMember }]) => [
48
+ key,
49
+ {
50
+ ...caseMember,
51
+ type: type === null ? null : resolveTypeArgumentsInType(args, type),
52
+ },
53
+ ])));
54
+ export const EnumCaseDecl = (options) => ({
55
+ ...options,
56
+ kind: NodeKind.EnumCaseDecl,
57
+ });
58
+ export { EnumCaseDecl as EnumCase };
59
+ export const serializeEnumType = type => ({
60
+ ...removeParentKey(type),
61
+ values: Object.fromEntries(Object.entries(type.values).map(([key, caseMember]) => [
62
+ key,
63
+ {
64
+ ...caseMember,
65
+ type: caseMember.type === null ? null : serializeType(caseMember.type),
66
+ },
67
+ ])),
68
+ });
69
+ export const getReferencesForEnumType = (type, value) => typeof value === "object" &&
70
+ value !== null &&
71
+ !Array.isArray(value) &&
72
+ discriminatorKey in value &&
73
+ typeof value[discriminatorKey] === "string" &&
74
+ value[discriminatorKey] in type.values &&
75
+ type.values[value[discriminatorKey]]?.type == null &&
76
+ value[discriminatorKey] in value
77
+ ? getReferencesForType(type.values[value[discriminatorKey]].type, value[value[discriminatorKey]])
78
+ : [];
79
+ export const formatEnumType = (type, value) => {
80
+ if (typeof value === "object" &&
81
+ value !== null &&
82
+ !Array.isArray(value) &&
83
+ discriminatorKey in value &&
84
+ typeof value[discriminatorKey] === "string") {
85
+ const caseName = value[discriminatorKey];
86
+ const caseValue = value[caseName];
87
+ const caseType = type.values[caseName]?.type;
88
+ return {
89
+ [discriminatorKey]: caseName,
90
+ ...(caseValue == null || caseType == null
91
+ ? {}
92
+ : { [caseName]: formatValue(caseType, caseValue) }),
93
+ };
94
+ }
95
+ return value;
96
+ };
@@ -2,7 +2,7 @@ import { ObjectConstraints } from "../../../shared/validation/object.js";
2
2
  import { GetNestedDeclarations } from "../../declarations/Declaration.js";
3
3
  import { GetReferences, Node, NodeKind, Serializer } from "../../Node.js";
4
4
  import { Validator } from "../../validation/type.js";
5
- import { BaseType, SerializedBaseType, SerializedType, Type } from "../Type.js";
5
+ import { BaseType, SerializedBaseType, SerializedType, StructureFormatter, Type } from "../Type.js";
6
6
  type TConstraint = Record<string, MemberDecl<Type, boolean>>;
7
7
  export interface ObjectType<T extends TConstraint = TConstraint> extends BaseType, ObjectConstraints {
8
8
  kind: NodeKind["ObjectType"];
@@ -28,20 +28,25 @@ export interface MemberDecl<T extends Type = Type, R extends boolean = boolean>
28
28
  isRequired: R;
29
29
  type: T;
30
30
  comment?: string;
31
+ isDeprecated?: boolean;
31
32
  }
32
33
  export interface SerializedMemberDecl<T extends SerializedType = SerializedType, R extends boolean = boolean> {
33
34
  kind: NodeKind["MemberDecl"];
34
35
  isRequired: R;
35
36
  type: T;
36
37
  comment?: string;
38
+ isDeprecated?: boolean;
37
39
  }
38
40
  export declare const Required: <T extends Type>(options: {
39
41
  comment?: string;
42
+ isDeprecated?: boolean;
40
43
  type: T;
41
44
  }) => MemberDecl<T, true>;
42
45
  export declare const Optional: <T extends Type>(options: {
43
46
  comment?: string;
47
+ isDeprecated?: boolean;
44
48
  type: T;
45
49
  }) => MemberDecl<T, false>;
46
50
  export declare const serializeObjectType: Serializer<ObjectType, SerializedObjectType>;
47
51
  export declare const getReferencesForObjectType: GetReferences<ObjectType>;
52
+ export declare const formatObjectValue: StructureFormatter<ObjectType>;
@@ -1,3 +1,4 @@
1
+ import { sortObjectKeys } from "../../../shared/utils/object.js";
1
2
  import { parallelizeErrors } from "../../../shared/utils/validation.js";
2
3
  import { validateObjectConstraints } from "../../../shared/validation/object.js";
3
4
  import { wrapErrorsIfAny } from "../../../utils/error.js";
@@ -24,7 +25,7 @@ export const ObjectType = (properties, options = {}) => {
24
25
  };
25
26
  export { ObjectType as Object };
26
27
  export const isObjectType = (node) => node.kind === NodeKind.ObjectType;
27
- export const getNestedDeclarationsInObjectType = (isDeclAdded, type) => Object.values(type.properties).flatMap(prop => getNestedDeclarations(isDeclAdded, prop.type));
28
+ export const getNestedDeclarationsInObjectType = (addedDecls, type) => Object.values(type.properties).reduce((acc, prop) => getNestedDeclarations(acc, prop.type), addedDecls);
28
29
  export const validateObjectType = (helpers, type, value) => {
29
30
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
30
31
  return [TypeError(`expected an object, but got ${JSON.stringify(value)}`)];
@@ -47,14 +48,15 @@ export const validateObjectType = (helpers, type, value) => {
47
48
  export const resolveTypeArgumentsInObjectType = (args, type) => ObjectType(Object.fromEntries(Object.entries(type.properties).map(([key, config]) => [key, { ...config, type: resolveTypeArgumentsInType(args, config.type) }])), {
48
49
  ...type,
49
50
  });
50
- const MemberDecl = (isRequired, type, comment) => ({
51
+ const MemberDecl = (isRequired, type, comment, isDeprecated) => ({
51
52
  kind: NodeKind.MemberDecl,
52
53
  isRequired,
53
54
  type,
54
55
  comment,
56
+ isDeprecated,
55
57
  });
56
- export const Required = (options) => MemberDecl(true, options.type, options.comment);
57
- export const Optional = (options) => MemberDecl(false, options.type, options.comment);
58
+ export const Required = (options) => MemberDecl(true, options.type, options.comment, options.isDeprecated);
59
+ export const Optional = (options) => MemberDecl(false, options.type, options.comment, options.isDeprecated);
58
60
  export const serializeObjectType = type => ({
59
61
  ...removeParentKey(type),
60
62
  properties: Object.fromEntries(Object.entries(type.properties).map(([key, prop]) => [
@@ -68,3 +70,6 @@ export const serializeObjectType = type => ({
68
70
  export const getReferencesForObjectType = (type, value) => typeof value === "object" && value !== null
69
71
  ? Object.entries(value).flatMap(([key, propValue]) => key in type.properties ? getReferencesForType(type.properties[key].type, propValue) : [])
70
72
  : [];
73
+ export const formatObjectValue = (type, value) => typeof value === "object" && value !== null && !Array.isArray(value)
74
+ ? sortObjectKeys(value, Object.keys(type.properties))
75
+ : value;
@@ -1,6 +1,6 @@
1
1
  import { GetReferences, Node, NodeKind, Serializer } from "../../Node.js";
2
2
  import { Validator } from "../../validation/type.js";
3
- import { BaseType, SerializedBaseType } from "../Type.js";
3
+ import { BaseType, SerializedBaseType, StructureFormatter } from "../Type.js";
4
4
  export interface BooleanType extends BaseType {
5
5
  kind: NodeKind["BooleanType"];
6
6
  }
@@ -13,3 +13,4 @@ export declare const isBooleanType: (node: Node) => node is BooleanType;
13
13
  export declare const validateBooleanType: Validator<BooleanType>;
14
14
  export declare const serializeBooleanType: Serializer<BooleanType, SerializedBooleanType>;
15
15
  export declare const getReferencesForBooleanType: GetReferences<BooleanType>;
16
+ export declare const formatBooleanValue: StructureFormatter<BooleanType>;
@@ -13,3 +13,4 @@ export const validateBooleanType = (_helpers, _type, value) => {
13
13
  };
14
14
  export const serializeBooleanType = type => removeParentKey(type);
15
15
  export const getReferencesForBooleanType = (_type, _value) => [];
16
+ export const formatBooleanValue = (_type, value) => value;
@@ -1,7 +1,7 @@
1
1
  import { DateConstraints } from "../../../shared/validation/date.js";
2
2
  import { GetReferences, Node, NodeKind, Serializer } from "../../Node.js";
3
3
  import { Validator } from "../../validation/type.js";
4
- import { BaseType, SerializedBaseType } from "../Type.js";
4
+ import { BaseType, SerializedBaseType, StructureFormatter } from "../Type.js";
5
5
  export interface DateType extends BaseType, DateConstraints {
6
6
  kind: NodeKind["DateType"];
7
7
  }
@@ -14,3 +14,4 @@ export declare const isDateType: (node: Node) => node is DateType;
14
14
  export declare const validateDateType: Validator<DateType>;
15
15
  export declare const serializeDateType: Serializer<DateType, SerializedDateType>;
16
16
  export declare const getReferencesForDateType: GetReferences<DateType>;
17
+ export declare const formatDateValue: StructureFormatter<DateType>;