tsondb 0.2.0 → 0.4.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 (228) hide show
  1. package/LICENSE +385 -0
  2. package/README.md +173 -1
  3. package/lib/bin/tsondb.d.ts +8 -0
  4. package/lib/bin/tsondb.js +83 -0
  5. package/lib/index.d.ts +2 -1
  6. package/lib/index.js +1 -1
  7. package/lib/{Schema.d.ts → node/Schema.d.ts} +2 -2
  8. package/lib/{Schema.js → node/Schema.js} +1 -1
  9. package/lib/node/index.d.ts +8 -0
  10. package/lib/node/index.js +62 -0
  11. package/lib/{renderers → node/renderers}/Output.d.ts +1 -1
  12. package/lib/node/renderers/jsonschema/index.d.ts +6 -0
  13. package/lib/node/renderers/jsonschema/index.js +35 -0
  14. package/lib/node/renderers/jsonschema/render.d.ts +9 -0
  15. package/lib/{renderers → node/renderers}/jsonschema/render.js +42 -23
  16. package/lib/node/renderers/ts/index.d.ts +6 -0
  17. package/lib/node/renderers/ts/index.js +42 -0
  18. package/lib/{renderers → node/renderers}/ts/render.d.ts +3 -1
  19. package/lib/node/renderers/ts/render.js +136 -0
  20. package/lib/{schema → node/schema}/Node.d.ts +5 -4
  21. package/lib/{schema → node/schema}/Node.js +11 -6
  22. package/lib/{schema/parameters → node/schema}/TypeParameter.d.ts +3 -2
  23. package/lib/{schema/parameters → node/schema}/TypeParameter.js +2 -2
  24. package/lib/{schema → node/schema}/declarations/Declaration.d.ts +11 -10
  25. package/lib/{schema → node/schema}/declarations/Declaration.js +10 -4
  26. package/lib/{schema → node/schema}/declarations/EntityDecl.d.ts +13 -9
  27. package/lib/{schema → node/schema}/declarations/EntityDecl.js +2 -2
  28. package/lib/{schema → node/schema}/declarations/EnumDecl.d.ts +11 -26
  29. package/lib/node/schema/declarations/EnumDecl.js +52 -0
  30. package/lib/{schema → node/schema}/declarations/TypeAliasDecl.d.ts +8 -7
  31. package/lib/{schema → node/schema}/declarations/TypeAliasDecl.js +3 -3
  32. package/lib/{schema → node/schema}/index.d.ts +4 -3
  33. package/lib/{schema → node/schema}/index.js +3 -3
  34. package/lib/node/schema/types/Type.d.ts +48 -0
  35. package/lib/{schema → node/schema}/types/Type.js +90 -28
  36. package/lib/{schema → node/schema}/types/generic/ArrayType.d.ts +6 -4
  37. package/lib/{schema → node/schema}/types/generic/ArrayType.js +5 -4
  38. package/lib/node/schema/types/generic/EnumType.d.ts +39 -0
  39. package/lib/node/schema/types/generic/EnumType.js +98 -0
  40. package/lib/{schema → node/schema}/types/generic/ObjectType.d.ts +9 -7
  41. package/lib/{schema → node/schema}/types/generic/ObjectType.js +11 -3
  42. package/lib/{schema → node/schema}/types/primitives/BooleanType.d.ts +5 -3
  43. package/lib/{schema → node/schema}/types/primitives/BooleanType.js +1 -0
  44. package/lib/{schema → node/schema}/types/primitives/DateType.d.ts +6 -4
  45. package/lib/{schema → node/schema}/types/primitives/DateType.js +2 -1
  46. package/lib/{schema → node/schema}/types/primitives/FloatType.d.ts +6 -4
  47. package/lib/{schema → node/schema}/types/primitives/FloatType.js +2 -1
  48. package/lib/{schema → node/schema}/types/primitives/IntegerType.d.ts +6 -4
  49. package/lib/{schema → node/schema}/types/primitives/IntegerType.js +2 -1
  50. package/lib/{schema → node/schema}/types/primitives/NumericType.d.ts +2 -2
  51. package/lib/node/schema/types/primitives/PrimitiveType.d.ts +6 -0
  52. package/lib/{schema → node/schema}/types/primitives/StringType.d.ts +6 -4
  53. package/lib/{schema → node/schema}/types/primitives/StringType.js +2 -1
  54. package/lib/{schema → node/schema}/types/references/IncludeIdentifierType.d.ts +11 -8
  55. package/lib/{schema → node/schema}/types/references/IncludeIdentifierType.js +15 -2
  56. package/lib/{schema → node/schema}/types/references/NestedEntityMapType.d.ts +11 -9
  57. package/lib/{schema → node/schema}/types/references/NestedEntityMapType.js +6 -2
  58. package/lib/{schema → node/schema}/types/references/ReferenceIdentifierType.d.ts +8 -6
  59. package/lib/{schema → node/schema}/types/references/ReferenceIdentifierType.js +1 -0
  60. package/lib/node/schema/types/references/TypeArgumentType.d.ts +23 -0
  61. package/lib/node/schema/types/references/TypeArgumentType.js +19 -0
  62. package/lib/node/schema/validation/type.d.ts +4 -0
  63. package/lib/node/server/api/declarations.d.ts +1 -0
  64. package/lib/node/server/api/declarations.js +154 -0
  65. package/lib/node/server/api/git.d.ts +1 -0
  66. package/lib/node/server/api/git.js +178 -0
  67. package/lib/node/server/api/index.d.ts +1 -0
  68. package/lib/node/server/api/index.js +8 -0
  69. package/lib/node/server/api/instanceOperations.d.ts +6 -0
  70. package/lib/node/server/api/instanceOperations.js +91 -0
  71. package/lib/node/server/api/instances.d.ts +1 -0
  72. package/lib/node/server/api/instances.js +27 -0
  73. package/lib/node/server/index.d.ts +28 -0
  74. package/lib/node/server/index.js +53 -0
  75. package/lib/node/server/init.d.ts +5 -0
  76. package/lib/node/server/init.js +56 -0
  77. package/lib/{utils → node/utils}/error.js +4 -1
  78. package/lib/node/utils/git.d.ts +3 -0
  79. package/lib/node/utils/git.js +12 -0
  80. package/lib/node/utils/instances.d.ts +5 -0
  81. package/lib/node/utils/instances.js +21 -0
  82. package/lib/node/utils/path.d.ts +1 -0
  83. package/lib/node/utils/path.js +2 -0
  84. package/lib/node/utils/references.d.ts +7 -0
  85. package/lib/node/utils/references.js +40 -0
  86. package/lib/node/utils/render.d.ts +9 -0
  87. package/lib/node/utils/render.js +34 -0
  88. package/lib/shared/api.d.ts +19 -2
  89. package/lib/shared/utils/array.d.ts +19 -0
  90. package/lib/shared/utils/array.js +30 -0
  91. package/lib/shared/utils/displayName.d.ts +1 -1
  92. package/lib/shared/utils/displayName.js +4 -2
  93. package/lib/shared/utils/git.d.ts +12 -0
  94. package/lib/shared/utils/git.js +98 -0
  95. package/lib/shared/utils/instances.d.ts +10 -0
  96. package/lib/shared/utils/instances.js +8 -1
  97. package/lib/{utils → shared/utils}/lazy.js +1 -1
  98. package/lib/shared/utils/markdown.d.ts +14 -0
  99. package/lib/shared/utils/markdown.js +42 -0
  100. package/lib/shared/utils/object.d.ts +4 -0
  101. package/lib/shared/utils/object.js +5 -0
  102. package/lib/{utils → shared/utils}/result.js +2 -2
  103. package/lib/shared/utils/string.d.ts +1 -0
  104. package/lib/shared/utils/string.js +16 -4
  105. package/lib/shared/utils/validation.js +3 -2
  106. package/lib/shared/validation/number.js +3 -3
  107. package/lib/shared/validation/object.js +4 -3
  108. package/lib/shared/validation/string.js +12 -7
  109. package/lib/web/api.d.ts +24 -0
  110. package/lib/web/api.js +204 -0
  111. package/lib/web/components/Git.d.ts +2 -0
  112. package/lib/web/components/Git.js +160 -0
  113. package/lib/{client → web}/components/Layout.d.ts +1 -1
  114. package/lib/{client → web}/components/Layout.js +2 -1
  115. package/lib/web/components/Select.d.ts +3 -0
  116. package/lib/web/components/Select.js +5 -0
  117. package/lib/web/components/typeInputs/ArrayTypeInput.d.ts +13 -0
  118. package/lib/{client → web}/components/typeInputs/ArrayTypeInput.js +8 -1
  119. package/lib/{client → web}/components/typeInputs/BooleanTypeInput.d.ts +2 -2
  120. package/lib/{client → web}/components/typeInputs/DateTypeInput.d.ts +2 -2
  121. package/lib/web/components/typeInputs/EnumTypeInput.d.ts +13 -0
  122. package/lib/{client/components/typeInputs/utils/EnumDeclField.js → web/components/typeInputs/EnumTypeInput.js} +11 -11
  123. package/lib/{client → web}/components/typeInputs/FloatTypeInput.d.ts +2 -2
  124. package/lib/web/components/typeInputs/GenericTypeArgumentIdentifierTypeInput.d.ts +7 -0
  125. package/lib/{client → web}/components/typeInputs/GenericTypeArgumentIdentifierTypeInput.js +1 -1
  126. package/lib/web/components/typeInputs/IncludeIdentifierTypeInput.d.ts +13 -0
  127. package/lib/web/components/typeInputs/IncludeIdentifierTypeInput.js +9 -0
  128. package/lib/{client → web}/components/typeInputs/IntegerTypeInput.d.ts +2 -2
  129. package/lib/web/components/typeInputs/NestedEntityMapTypeInput.d.ts +13 -0
  130. package/lib/{client → web}/components/typeInputs/NestedEntityMapTypeInput.js +7 -2
  131. package/lib/{client → web}/components/typeInputs/ObjectTypeInput.d.ts +4 -4
  132. package/lib/{client → web}/components/typeInputs/ObjectTypeInput.js +4 -1
  133. package/lib/{client → web}/components/typeInputs/ReferenceIdentifierTypeInput.d.ts +3 -3
  134. package/lib/web/components/typeInputs/ReferenceIdentifierTypeInput.js +11 -0
  135. package/lib/{client → web}/components/typeInputs/StringTypeInput.d.ts +2 -2
  136. package/lib/web/components/typeInputs/TypeInput.d.ts +13 -0
  137. package/lib/{client → web}/components/typeInputs/TypeInput.js +6 -3
  138. package/lib/{client → web}/components/typeInputs/utils/Markdown.d.ts +1 -1
  139. package/lib/web/components/typeInputs/utils/Markdown.js +26 -0
  140. package/lib/{client → web}/components/typeInputs/utils/MismatchingTypeError.d.ts +1 -1
  141. package/lib/{client → web}/components/typeInputs/utils/ValidationErrors.d.ts +1 -1
  142. package/lib/web/hooks/useAPIResource.d.ts +1 -0
  143. package/lib/web/hooks/useAPIResource.js +2 -0
  144. package/lib/{client → web}/hooks/useEntityFromRoute.d.ts +1 -1
  145. package/lib/{client → web}/hooks/useEntityFromRoute.js +1 -1
  146. package/lib/{client → web}/hooks/useInstanceNamesByEntity.d.ts +1 -1
  147. package/lib/{client → web}/hooks/useInstanceNamesByEntity.js +8 -6
  148. package/lib/web/hooks/useMappedAPIResource.d.ts +1 -0
  149. package/lib/web/hooks/useMappedAPIResource.js +17 -0
  150. package/lib/{client → web}/hooks/useSecondaryDeclarations.d.ts +1 -1
  151. package/lib/{client → web}/hooks/useSecondaryDeclarations.js +4 -2
  152. package/lib/{client → web}/routes/CreateInstance.d.ts +1 -1
  153. package/lib/{client → web}/routes/CreateInstance.js +4 -2
  154. package/lib/web/routes/Entity.d.ts +2 -0
  155. package/lib/web/routes/Entity.js +43 -0
  156. package/lib/web/routes/Home.d.ts +2 -0
  157. package/lib/web/routes/Home.js +9 -0
  158. package/lib/{client → web}/routes/Instance.d.ts +1 -1
  159. package/lib/{client → web}/routes/Instance.js +14 -8
  160. package/lib/{client → web}/routes/NotFound.d.ts +1 -1
  161. package/lib/web/utils/typeSkeleton.d.ts +3 -0
  162. package/lib/{client → web}/utils/typeSkeleton.js +14 -17
  163. package/package.json +35 -15
  164. package/public/css/styles.css +200 -1
  165. package/lib/ModelContainer.d.ts +0 -17
  166. package/lib/ModelContainer.js +0 -63
  167. package/lib/client/api.d.ts +0 -11
  168. package/lib/client/api.js +0 -83
  169. package/lib/client/components/Select.d.ts +0 -3
  170. package/lib/client/components/Select.js +0 -2
  171. package/lib/client/components/typeInputs/ArrayTypeInput.d.ts +0 -13
  172. package/lib/client/components/typeInputs/GenericTypeArgumentIdentifierTypeInput.d.ts +0 -7
  173. package/lib/client/components/typeInputs/IncludeIdentifierTypeInput.d.ts +0 -13
  174. package/lib/client/components/typeInputs/IncludeIdentifierTypeInput.js +0 -18
  175. package/lib/client/components/typeInputs/NestedEntityMapTypeInput.d.ts +0 -13
  176. package/lib/client/components/typeInputs/ReferenceIdentifierTypeInput.js +0 -9
  177. package/lib/client/components/typeInputs/TypeInput.d.ts +0 -13
  178. package/lib/client/components/typeInputs/utils/EnumDeclField.d.ts +0 -13
  179. package/lib/client/components/typeInputs/utils/Markdown.js +0 -57
  180. package/lib/client/routes/Entity.d.ts +0 -2
  181. package/lib/client/routes/Entity.js +0 -47
  182. package/lib/client/routes/Home.d.ts +0 -2
  183. package/lib/client/routes/Home.js +0 -18
  184. package/lib/client/utils/typeSkeleton.d.ts +0 -3
  185. package/lib/renderers/jsonschema/index.d.ts +0 -6
  186. package/lib/renderers/jsonschema/index.js +0 -12
  187. package/lib/renderers/jsonschema/render.d.ts +0 -5
  188. package/lib/renderers/ts/index.d.ts +0 -6
  189. package/lib/renderers/ts/index.js +0 -11
  190. package/lib/renderers/ts/render.js +0 -112
  191. package/lib/schema/declarations/EnumDecl.js +0 -115
  192. package/lib/schema/types/Type.d.ts +0 -42
  193. package/lib/schema/types/primitives/PrimitiveType.d.ts +0 -6
  194. package/lib/schema/types/references/GenericArgumentIdentifierType.d.ts +0 -21
  195. package/lib/schema/types/references/GenericArgumentIdentifierType.js +0 -18
  196. package/lib/schema/validation/type.d.ts +0 -4
  197. package/lib/server/index.d.ts +0 -8
  198. package/lib/server/index.js +0 -207
  199. package/lib/server/instanceOperations.d.ts +0 -7
  200. package/lib/server/instanceOperations.js +0 -67
  201. package/lib/tsconfig.tsbuildinfo +0 -1
  202. package/lib/utils/instances.d.ts +0 -4
  203. package/lib/utils/instances.js +0 -12
  204. package/lib/utils/object.d.ts +0 -3
  205. package/lib/utils/object.js +0 -1
  206. package/lib/utils/render.d.ts +0 -4
  207. package/lib/utils/render.js +0 -8
  208. /package/lib/{renderers → node/renderers}/Output.js +0 -0
  209. /package/lib/{schema → node/schema}/types/primitives/NumericType.js +0 -0
  210. /package/lib/{schema → node/schema}/types/primitives/PrimitiveType.js +0 -0
  211. /package/lib/{schema → node/schema}/validation/options.d.ts +0 -0
  212. /package/lib/{schema → node/schema}/validation/options.js +0 -0
  213. /package/lib/{schema → node/schema}/validation/type.js +0 -0
  214. /package/lib/{utils → node/utils}/error.d.ts +0 -0
  215. /package/lib/{utils → shared/utils}/enum.d.ts +0 -0
  216. /package/lib/{utils → shared/utils}/enum.js +0 -0
  217. /package/lib/{utils → shared/utils}/lazy.d.ts +0 -0
  218. /package/lib/{utils → shared/utils}/result.d.ts +0 -0
  219. /package/lib/{client → web}/components/typeInputs/BooleanTypeInput.js +0 -0
  220. /package/lib/{client → web}/components/typeInputs/DateTypeInput.js +0 -0
  221. /package/lib/{client → web}/components/typeInputs/FloatTypeInput.js +0 -0
  222. /package/lib/{client → web}/components/typeInputs/IntegerTypeInput.js +0 -0
  223. /package/lib/{client → web}/components/typeInputs/StringTypeInput.js +0 -0
  224. /package/lib/{client → web}/components/typeInputs/utils/MismatchingTypeError.js +0 -0
  225. /package/lib/{client → web}/components/typeInputs/utils/ValidationErrors.js +0 -0
  226. /package/lib/{client → web}/index.d.ts +0 -0
  227. /package/lib/{client → web}/index.js +0 -0
  228. /package/lib/{client → web}/routes/NotFound.js +0 -0
@@ -0,0 +1,8 @@
1
+ import type { Output } from "./renderers/Output.ts";
2
+ import type { Schema } from "./Schema.ts";
3
+ import type { ServerOptions } from "./server/index.ts";
4
+ export declare const generateOutputs: (schema: Schema, outputs: Output[]) => Promise<void>;
5
+ export declare const validate: (schema: Schema, dataRootPath: string) => Promise<void>;
6
+ export declare const generateAndValidate: (schema: Schema, outputs: Output[], dataRootPath: string) => Promise<void>;
7
+ export declare const serve: (schema: Schema, dataRootPath: string, serverOptions?: Partial<ServerOptions>) => Promise<void>;
8
+ export declare const generateValidateAndServe: (schema: Schema, outputs: Output[], dataRootPath: string, serverOptions?: Partial<ServerOptions>) => Promise<void>;
@@ -0,0 +1,62 @@
1
+ import Debug from "debug";
2
+ import { mkdir } from "fs/promises";
3
+ import { join } from "path";
4
+ import { parallelizeErrors } from "../shared/utils/validation.js";
5
+ import { getEntities } from "./Schema.js";
6
+ import { createValidators, validateEntityDecl } from "./schema/index.js";
7
+ import { createServer } from "./server/index.js";
8
+ import { getErrorMessageForDisplay, wrapErrorsIfAny } from "./utils/error.js";
9
+ import { getInstancesByEntityName } from "./utils/instances.js";
10
+ const debug = Debug("tsondb:schema");
11
+ const prepareFolders = async (dataRootPath, entities) => {
12
+ await mkdir(dataRootPath, { recursive: true });
13
+ for (const entity of entities) {
14
+ const entityDir = join(dataRootPath, entity.name);
15
+ await mkdir(entityDir, { recursive: true });
16
+ }
17
+ };
18
+ export const generateOutputs = async (schema, outputs) => {
19
+ for (const output of outputs) {
20
+ await output.run(schema);
21
+ }
22
+ };
23
+ const _validate = (entities, instancesByEntityName) => {
24
+ const errors = entities.flatMap(entity => parallelizeErrors(instancesByEntityName[entity.name]?.map(instance => wrapErrorsIfAny(`in file "${entity.name}/${instance.fileName}"`, validateEntityDecl(createValidators(instancesByEntityName), entity, instance.content))) ?? []));
25
+ if (errors.length === 0) {
26
+ debug("All entities are valid");
27
+ }
28
+ else {
29
+ debug("Errors:\n");
30
+ for (const error of errors) {
31
+ debug(getErrorMessageForDisplay(error) + "\n");
32
+ }
33
+ throw new Error("Validation failed");
34
+ }
35
+ };
36
+ export const validate = async (schema, dataRootPath) => {
37
+ const entities = getEntities(schema);
38
+ await prepareFolders(dataRootPath, entities);
39
+ const instancesByEntityName = await getInstancesByEntityName(dataRootPath, entities);
40
+ _validate(entities, instancesByEntityName);
41
+ };
42
+ export const generateAndValidate = async (schema, outputs, dataRootPath) => {
43
+ await generateOutputs(schema, outputs);
44
+ const entities = getEntities(schema);
45
+ await prepareFolders(dataRootPath, entities);
46
+ const instancesByEntityName = await getInstancesByEntityName(dataRootPath, entities);
47
+ _validate(entities, instancesByEntityName);
48
+ };
49
+ export const serve = async (schema, dataRootPath, serverOptions) => {
50
+ const entities = getEntities(schema);
51
+ await prepareFolders(dataRootPath, entities);
52
+ const instancesByEntityName = await getInstancesByEntityName(dataRootPath, entities);
53
+ await createServer(schema, dataRootPath, instancesByEntityName, serverOptions);
54
+ };
55
+ export const generateValidateAndServe = async (schema, outputs, dataRootPath, serverOptions) => {
56
+ await generateOutputs(schema, outputs);
57
+ const entities = getEntities(schema);
58
+ await prepareFolders(dataRootPath, entities);
59
+ const instancesByEntityName = await getInstancesByEntityName(dataRootPath, entities);
60
+ _validate(entities, instancesByEntityName);
61
+ await createServer(schema, dataRootPath, instancesByEntityName, serverOptions);
62
+ };
@@ -1,4 +1,4 @@
1
- import { Schema } from "../Schema.js";
1
+ import type { Schema } from "../Schema.js";
2
2
  export interface Output {
3
3
  run: (schema: Schema) => Promise<void>;
4
4
  }
@@ -0,0 +1,6 @@
1
+ import type { Output } from "../Output.js";
2
+ import type { JsonSchemaRendererOptions } from "./render.js";
3
+ export declare const JsonSchemaOutput: (options: {
4
+ targetPath: string;
5
+ rendererOptions?: Partial<JsonSchemaRendererOptions>;
6
+ }) => Output;
@@ -0,0 +1,35 @@
1
+ import { mkdir, rm, writeFile } from "node:fs/promises";
2
+ import { basename, dirname, extname, join, relative } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { commonPrefix } from "../../../shared/utils/string.js";
5
+ import { groupDeclarationsBySourceUrl, resolveTypeArgumentsInDecls } from "../../schema/index.js";
6
+ import { render } from "./render.js";
7
+ const extension = ".schema.json";
8
+ export const JsonSchemaOutput = (options) => ({
9
+ run: async (schema) => {
10
+ if (options.rendererOptions?.preserveFiles === true) {
11
+ await rm(options.targetPath, { recursive: true, force: true });
12
+ await mkdir(options.targetPath, { recursive: true });
13
+ const declarationsBySourceUrl = groupDeclarationsBySourceUrl(resolveTypeArgumentsInDecls(schema.declarations));
14
+ const sourceRootPath = fileURLToPath(commonPrefix(...Object.keys(declarationsBySourceUrl)));
15
+ if (sourceRootPath) {
16
+ for (const [sourceUrl, decls] of Object.entries(declarationsBySourceUrl)) {
17
+ const sourcePath = fileURLToPath(sourceUrl);
18
+ const relativePath = dirname(relative(sourceRootPath, sourcePath));
19
+ const newDir = join(options.targetPath, relativePath);
20
+ const newPath = join(newDir, basename(sourcePath, extname(sourcePath)) + extension);
21
+ await mkdir(newDir, { recursive: true });
22
+ await writeFile(newPath, render(options.rendererOptions, decls ?? []), {
23
+ encoding: "utf-8",
24
+ });
25
+ }
26
+ }
27
+ }
28
+ else {
29
+ await mkdir(dirname(options.targetPath), { recursive: true });
30
+ await writeFile(options.targetPath, render(options.rendererOptions, resolveTypeArgumentsInDecls(schema.declarations)), {
31
+ encoding: "utf-8",
32
+ });
33
+ }
34
+ },
35
+ });
@@ -0,0 +1,9 @@
1
+ import type { Decl } from "../../schema/declarations/Declaration.js";
2
+ export type JsonSchemaRendererOptions = {
3
+ format: "minified" | "tabs" | {
4
+ kind: "spaces";
5
+ indentation?: number;
6
+ };
7
+ preserveFiles: boolean;
8
+ };
9
+ export declare const render: (options: Partial<JsonSchemaRendererOptions> | undefined, declarations: readonly Decl[]) => string;
@@ -1,12 +1,16 @@
1
+ import { dirname, relative } from "node:path";
2
+ import { discriminatorKey } from "../../../shared/enum.js";
3
+ import { assertExhaustive } from "../../../shared/utils/typeSafety.js";
1
4
  import { addEphemeralUUIDToType, createEntityIdentifierTypeAsDecl, isEntityDecl, } from "../../schema/declarations/EntityDecl.js";
2
5
  import { TypeAliasDecl } from "../../schema/declarations/TypeAliasDecl.js";
3
6
  import { flatMapAuxiliaryDecls, NodeKind } from "../../schema/Node.js";
4
- import { isNestedEntityMapType, } from "../../schema/types/references/NestedEntityMapType.js";
7
+ import { isNestedEntityMapType } from "../../schema/types/references/NestedEntityMapType.js";
5
8
  import { getParentDecl } from "../../schema/types/Type.js";
6
- import { discriminatorKey } from "../../shared/enum.js";
7
- import { assertExhaustive } from "../../shared/utils/typeSafety.js";
9
+ import { ensureSpecialDirStart } from "../../utils/path.js";
10
+ const defaultIndentation = 2;
8
11
  const defaultOptions = {
9
- indentation: 2,
12
+ format: { kind: "spaces" },
13
+ preserveFiles: false,
10
14
  };
11
15
  const renderArrayType = (options, type) => ({
12
16
  type: "array",
@@ -63,21 +67,40 @@ const renderStringType = (_options, type) => ({
63
67
  maxLength: type.maxLength,
64
68
  pattern: type.pattern?.source,
65
69
  });
66
- const renderGenericArgumentIdentifierType = (_options, _type) => {
67
- throw new TypeError("GenericArgumentIdentifierType is not supported in JSON Schema.");
70
+ const renderTypeArgumentType = (_options, _type) => {
71
+ throw new TypeError("TypeArgumentType is not supported in JSON Schema.");
68
72
  };
69
73
  const renderReferenceIdentifierType = (_options, type) => ({
70
74
  $ref: `#/$defs/${type.entity.name}_ID`,
71
75
  });
72
- const renderIncludeIdentifierType = (_options, type) => ({
73
- $ref: `#/$defs/${type.reference.name}`,
74
- });
76
+ const renderIncludeIdentifierType = (options, type) => {
77
+ const sourceUrl = getParentDecl(type)?.sourceUrl ?? "";
78
+ const filePath = options.preserveFiles && sourceUrl !== type.reference.sourceUrl
79
+ ? ensureSpecialDirStart(relative(dirname(sourceUrl), type.reference.sourceUrl))
80
+ : "";
81
+ return {
82
+ $ref: `${filePath}#/$defs/${type.reference.name}`,
83
+ };
84
+ };
75
85
  const renderNestedEntityMapType = (_options, type) => ({
76
86
  type: "object",
77
87
  additionalProperties: {
78
88
  $ref: `#/$defs/${type.name}`,
79
89
  },
80
90
  });
91
+ const renderEnumType = (options, type) => ({
92
+ oneOf: Object.entries(type.values).map(([caseName, caseDef]) => ({
93
+ type: "object",
94
+ deprecated: caseDef.isDeprecated,
95
+ properties: {
96
+ [discriminatorKey]: {
97
+ const: caseName,
98
+ },
99
+ ...(caseDef.type === null ? {} : { [caseName]: renderType(options, caseDef.type) }),
100
+ },
101
+ required: [discriminatorKey, ...(caseDef.type === null ? [] : [caseName])],
102
+ })),
103
+ });
81
104
  const renderType = (options, type) => {
82
105
  switch (type.kind) {
83
106
  case NodeKind.ArrayType:
@@ -94,14 +117,16 @@ const renderType = (options, type) => {
94
117
  return renderIntegerType(options, type);
95
118
  case NodeKind.StringType:
96
119
  return renderStringType(options, type);
97
- case NodeKind.GenericArgumentIdentifierType:
98
- return renderGenericArgumentIdentifierType(options, type);
120
+ case NodeKind.TypeArgumentType:
121
+ return renderTypeArgumentType(options, type);
99
122
  case NodeKind.ReferenceIdentifierType:
100
123
  return renderReferenceIdentifierType(options, type);
101
124
  case NodeKind.IncludeIdentifierType:
102
125
  return renderIncludeIdentifierType(options, type);
103
126
  case NodeKind.NestedEntityMapType:
104
127
  return renderNestedEntityMapType(options, type);
128
+ case NodeKind.EnumType:
129
+ return renderEnumType(options, type);
105
130
  default:
106
131
  return assertExhaustive(type, "Unknown type");
107
132
  }
@@ -114,17 +139,7 @@ const renderEntityDecl = (options, decl) => ({
114
139
  const renderEnumDecl = (options, decl) => ({
115
140
  description: decl.comment,
116
141
  deprecated: decl.isDeprecated,
117
- oneOf: Object.entries(decl.values.value).map(([caseName, caseDef]) => ({
118
- type: "object",
119
- deprecated: caseDef.isDeprecated,
120
- properties: {
121
- [discriminatorKey]: {
122
- const: caseName,
123
- },
124
- ...(caseDef.type === null ? {} : { [caseName]: renderType(options, caseDef.type) }),
125
- },
126
- required: [discriminatorKey, ...(caseDef === null ? [] : [caseName])],
127
- })),
142
+ ...renderEnumType(options, decl.type.value),
128
143
  });
129
144
  const renderTypeAliasDecl = (options, decl) => ({
130
145
  description: decl.comment,
@@ -160,5 +175,9 @@ export const render = (options = defaultOptions, declarations) => {
160
175
  }
161
176
  return undefined;
162
177
  }, declarations)),
163
- }, undefined, finalOptions.indentation);
178
+ }, undefined, finalOptions.format === "minified"
179
+ ? undefined
180
+ : finalOptions.format === "tabs"
181
+ ? "\t"
182
+ : (finalOptions.format.indentation ?? defaultIndentation));
164
183
  };
@@ -0,0 +1,6 @@
1
+ import type { Output } from "../Output.js";
2
+ import type { TypeScriptRendererOptions } from "./render.js";
3
+ export declare const TypeScriptOutput: (options: {
4
+ targetPath: string;
5
+ rendererOptions?: Partial<TypeScriptRendererOptions>;
6
+ }) => Output;
@@ -0,0 +1,42 @@
1
+ import Debug from "debug";
2
+ import { mkdir, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, extname, join, relative } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { commonPrefix } from "../../../shared/utils/string.js";
6
+ import { groupDeclarationsBySourceUrl } from "../../schema/declarations/Declaration.js";
7
+ import { render } from "./render.js";
8
+ const debug = Debug("tsondb:renderer:ts");
9
+ const extension = ".d.ts";
10
+ export const TypeScriptOutput = (options) => ({
11
+ run: async (schema) => {
12
+ if (options.rendererOptions?.preserveFiles === true) {
13
+ debug("emitting declarations to multiple files...");
14
+ await rm(options.targetPath, { recursive: true, force: true });
15
+ await mkdir(options.targetPath, { recursive: true });
16
+ const declarationsBySourceUrl = groupDeclarationsBySourceUrl(schema.declarations);
17
+ const sourceRootPath = fileURLToPath(commonPrefix(...Object.keys(declarationsBySourceUrl)));
18
+ debug("common source root path: %s", sourceRootPath);
19
+ if (sourceRootPath) {
20
+ for (const [sourceUrl, decls] of Object.entries(declarationsBySourceUrl)) {
21
+ const sourcePath = fileURLToPath(sourceUrl);
22
+ const relativePath = dirname(relative(sourceRootPath, sourcePath));
23
+ const newDir = join(options.targetPath, relativePath);
24
+ const newPath = join(newDir, basename(sourcePath, extname(sourcePath)) + extension);
25
+ await mkdir(newDir, { recursive: true });
26
+ await writeFile(newPath, render(options.rendererOptions, decls ?? []), {
27
+ encoding: "utf-8",
28
+ });
29
+ }
30
+ debug("emitted declaration files to %s", options.targetPath);
31
+ }
32
+ }
33
+ else {
34
+ debug("emitting declarations to single file...");
35
+ await mkdir(dirname(options.targetPath), { recursive: true });
36
+ await writeFile(options.targetPath, render(options.rendererOptions, schema.declarations), {
37
+ encoding: "utf-8",
38
+ });
39
+ debug("emitted declarations to %s", options.targetPath);
40
+ }
41
+ },
42
+ });
@@ -1,5 +1,7 @@
1
- import { Decl } from "../../schema/declarations/Declaration.js";
1
+ import type { Decl } from "../../schema/declarations/Declaration.js";
2
2
  export type TypeScriptRendererOptions = {
3
3
  indentation: number;
4
+ objectTypeKeyword: "interface" | "type";
5
+ preserveFiles: boolean;
4
6
  };
5
7
  export declare const render: (options: Partial<TypeScriptRendererOptions> | undefined, declarations: readonly Decl[]) => string;
@@ -0,0 +1,136 @@
1
+ import { EOL } from "node:os";
2
+ import { dirname, relative } from "node:path";
3
+ import { discriminatorKey } from "../../../shared/enum.js";
4
+ import { toCamelCase } from "../../../shared/utils/string.js";
5
+ import { assertExhaustive } from "../../../shared/utils/typeSafety.js";
6
+ import { addEphemeralUUIDToType, createEntityIdentifierTypeAsDecl, isEntityDecl, } from "../../schema/declarations/EntityDecl.js";
7
+ import { TypeAliasDecl } from "../../schema/declarations/TypeAliasDecl.js";
8
+ import { flatMapAuxiliaryDecls, NodeKind } from "../../schema/Node.js";
9
+ import { isObjectType } from "../../schema/types/generic/ObjectType.js";
10
+ import { isNestedEntityMapType } from "../../schema/types/references/NestedEntityMapType.js";
11
+ import { getParentDecl } from "../../schema/types/Type.js";
12
+ import { ensureSpecialDirStart } from "../../utils/path.js";
13
+ import { combineSyntaxes, indent, prefixLines, syntax } from "../../utils/render.js";
14
+ const defaultOptions = {
15
+ indentation: 2,
16
+ objectTypeKeyword: "interface",
17
+ preserveFiles: false,
18
+ };
19
+ const renderDocumentation = (comment, isDeprecated) => syntax `${comment === undefined
20
+ ? ""
21
+ : syntax `/**
22
+ ${prefixLines(" * ", comment, true)}${isDeprecated
23
+ ? syntax `
24
+ * @deprecated`
25
+ : ""}
26
+ */
27
+ `}`;
28
+ const renderTypeParameters = (options, params) => syntax `${params.length === 0
29
+ ? ""
30
+ : syntax `<${combineSyntaxes(params.map(param => param.constraint === undefined
31
+ ? param.name
32
+ : syntax `${param.name} extends ${renderType(options, param.constraint)}`), ", ")}>`}`;
33
+ const renderArrayType = (options, type) => syntax `${renderType(options, type.items)}[]`;
34
+ const wrapAsObject = (options, str) => syntax `{${EOL}${indent(options.indentation, 1, str)}${EOL}}`;
35
+ const renderObjectType = (options, type) => {
36
+ return wrapAsObject(options, combineSyntaxes(Object.entries(type.properties).map(([name, config]) => syntax `${renderDocumentation(config.comment, config.isDeprecated)}${name}${config.isRequired ? "" : "?"}: ${renderType(options, config.type)}`), Object.values(type.properties).some(prop => prop.comment !== undefined) ? EOL + EOL : EOL));
37
+ };
38
+ const renderBooleanType = (_options, _type) => syntax `boolean`;
39
+ const renderDateType = (_options, _type) => syntax `Date`;
40
+ const renderNumericType = (_options, _type) => syntax `number`;
41
+ const renderStringType = (_options, _type) => syntax `string`;
42
+ const renderTypeArgumentType = (_options, type) => syntax `${type.argument.name}`;
43
+ const renderReferenceIdentifierType = (_options, type) => [
44
+ { [type.entity.sourceUrl]: [type.entity.name + "_ID"] },
45
+ type.entity.name + "_ID",
46
+ ];
47
+ const renderIncludeIdentifierType = (options, type) => combineSyntaxes([
48
+ [{ [type.reference.sourceUrl]: [type.reference.name] }, type.reference.name],
49
+ type.args.length === 0
50
+ ? ""
51
+ : syntax `<${combineSyntaxes(type.args.map(arg => renderType(options, arg)), ", ")}>`,
52
+ ]);
53
+ const renderNestedEntityMapType = (options, type) => wrapAsObject(options, syntax `[${toCamelCase(type.secondaryEntity.name)}Id: string]: ${type.name}`);
54
+ const renderEnumType = (options, type) => combineSyntaxes(Object.entries(type.values).map(([caseName, caseDef]) => indent(options.indentation, 1, syntax `${EOL}| {${EOL}${indent(options.indentation, 1, syntax `${discriminatorKey}: "${caseName}"${caseDef.type === null
55
+ ? ""
56
+ : syntax `${EOL}${caseName}: ${renderType(options, caseDef.type)}`}`)}${EOL}}`)));
57
+ const renderType = (options, type) => {
58
+ switch (type.kind) {
59
+ case NodeKind.ArrayType:
60
+ return renderArrayType(options, type);
61
+ case NodeKind.ObjectType:
62
+ return renderObjectType(options, type);
63
+ case NodeKind.BooleanType:
64
+ return renderBooleanType(options, type);
65
+ case NodeKind.DateType:
66
+ return renderDateType(options, type);
67
+ case NodeKind.FloatType:
68
+ return renderNumericType(options, type);
69
+ case NodeKind.IntegerType:
70
+ return renderNumericType(options, type);
71
+ case NodeKind.StringType:
72
+ return renderStringType(options, type);
73
+ case NodeKind.TypeArgumentType:
74
+ return renderTypeArgumentType(options, type);
75
+ case NodeKind.ReferenceIdentifierType:
76
+ return renderReferenceIdentifierType(options, type);
77
+ case NodeKind.IncludeIdentifierType:
78
+ return renderIncludeIdentifierType(options, type);
79
+ case NodeKind.NestedEntityMapType:
80
+ return renderNestedEntityMapType(options, type);
81
+ case NodeKind.EnumType:
82
+ return renderEnumType(options, type);
83
+ default:
84
+ return assertExhaustive(type, "Unknown type");
85
+ }
86
+ };
87
+ const renderEntityDecl = (options, decl) => syntax `${renderDocumentation(decl.comment, decl.isDeprecated)}export ${options.objectTypeKeyword} ${decl.name} ${options.objectTypeKeyword === "type" ? "= " : ""}${renderType(options, addEphemeralUUIDToType(decl))}`;
88
+ const renderEnumDecl = (options, decl) => syntax `${renderDocumentation(decl.comment, decl.isDeprecated)}export type ${decl.name}${renderTypeParameters(options, decl.parameters)} =${renderEnumType(options, decl.type.value)}`;
89
+ const renderTypeAliasDecl = (options, decl) => isObjectType(decl.type.value)
90
+ ? syntax `${renderDocumentation(decl.comment, decl.isDeprecated)}export ${options.objectTypeKeyword} ${decl.name}${renderTypeParameters(options, decl.parameters)} ${options.objectTypeKeyword === "type" ? "= " : ""}${renderType(options, decl.type.value)}`
91
+ : syntax `${renderDocumentation(decl.comment, decl.isDeprecated)}export type ${decl.name}${renderTypeParameters(options, decl.parameters)} = ${renderType(options, decl.type.value)}`;
92
+ const renderDecl = (options, decl) => {
93
+ switch (decl.kind) {
94
+ case NodeKind.EntityDecl:
95
+ return renderEntityDecl(options, decl);
96
+ case NodeKind.EnumDecl:
97
+ return renderEnumDecl(options, decl);
98
+ case NodeKind.TypeAliasDecl:
99
+ return renderTypeAliasDecl(options, decl);
100
+ default:
101
+ return assertExhaustive(decl, "Unknown declaration");
102
+ }
103
+ };
104
+ const renderDeclarations = (options, declarations) => combineSyntaxes(declarations.map(decl => renderDecl(options, decl)), EOL + EOL);
105
+ const renderImports = (currentUrl, imports) => {
106
+ const importsSyntax = Object.entries(imports)
107
+ .filter(([sourceUrl]) => sourceUrl !== currentUrl)
108
+ .map(([sourceUrl, names]) => [
109
+ ensureSpecialDirStart(relative(dirname(currentUrl), sourceUrl)),
110
+ names,
111
+ ])
112
+ .toSorted(([sourceUrlA], [sourceUrlB]) => sourceUrlA.localeCompare(sourceUrlB))
113
+ .map(([sourceUrl, names]) => `import { ${names.toSorted((a, b) => a.localeCompare(b)).join(", ")} } from "${sourceUrl}"`)
114
+ .join(EOL);
115
+ return importsSyntax.length > 0 ? importsSyntax + EOL + EOL : "";
116
+ };
117
+ export const render = (options = defaultOptions, declarations) => {
118
+ const finalOptions = { ...defaultOptions, ...options };
119
+ const [imports, content] = renderDeclarations(finalOptions, flatMapAuxiliaryDecls(node => {
120
+ if (isNestedEntityMapType(node)) {
121
+ return TypeAliasDecl(getParentDecl(node)?.sourceUrl ?? "", {
122
+ name: node.name,
123
+ comment: node.comment,
124
+ type: () => node.type.value,
125
+ });
126
+ }
127
+ else if (isEntityDecl(node)) {
128
+ return createEntityIdentifierTypeAsDecl(node);
129
+ }
130
+ return undefined;
131
+ }, declarations));
132
+ return finalOptions.preserveFiles
133
+ ? (declarations[0] === undefined ? "" : renderImports(declarations[0].sourceUrl, imports)) +
134
+ content
135
+ : content;
136
+ };
@@ -1,6 +1,6 @@
1
- import { InstancesByEntityName } from "../shared/utils/instances.js";
2
- import { Decl } from "./declarations/Declaration.js";
3
- import { Type } from "./types/Type.js";
1
+ import type { InstancesByEntityName } from "../../shared/utils/instances.js";
2
+ import type { Decl } from "./declarations/Declaration.js";
3
+ import type { Type } from "./types/Type.js";
4
4
  export interface NodeKind {
5
5
  EntityDecl: "EntityDecl";
6
6
  EnumDecl: "EnumDecl";
@@ -14,11 +14,12 @@ export interface NodeKind {
14
14
  IntegerType: "IntegerType";
15
15
  StringType: "StringType";
16
16
  DateType: "DateType";
17
- GenericArgumentIdentifierType: "GenericArgumentIdentifierType";
17
+ TypeArgumentType: "TypeArgumentType";
18
18
  GenericParameter: "GenericParameter";
19
19
  ReferenceIdentifierType: "ReferenceIdentifierType";
20
20
  IncludeIdentifierType: "IncludeIdentifierType";
21
21
  NestedEntityMapType: "NestedEntityMapType";
22
+ EnumType: "EnumType";
22
23
  }
23
24
  export declare const NodeKind: NodeKind;
24
25
  export interface BaseNode {
@@ -1,5 +1,5 @@
1
- import { assertExhaustive } from "../shared/utils/typeSafety.js";
2
- import { enumOfObject } from "../utils/enum.js";
1
+ import { enumOfObject } from "../../shared/utils/enum.js";
2
+ import { assertExhaustive } from "../../shared/utils/typeSafety.js";
3
3
  export const NodeKind = enumOfObject({
4
4
  EntityDecl: null,
5
5
  EnumDecl: null,
@@ -13,11 +13,12 @@ export const NodeKind = enumOfObject({
13
13
  IntegerType: null,
14
14
  StringType: null,
15
15
  DateType: null,
16
- GenericArgumentIdentifierType: null,
16
+ TypeArgumentType: null,
17
17
  GenericParameter: null,
18
18
  ReferenceIdentifierType: null,
19
19
  IncludeIdentifierType: null,
20
20
  NestedEntityMapType: null,
21
+ EnumType: null,
21
22
  });
22
23
  export const flatMapAuxiliaryDecls = (callbackFn, declarations) => {
23
24
  const mapNodeTree = (callbackFn, node, decls) => {
@@ -28,7 +29,7 @@ export const flatMapAuxiliaryDecls = (callbackFn, declarations) => {
28
29
  }
29
30
  case NodeKind.EnumDecl: {
30
31
  const newDecls = callbackFn(node, decls);
31
- return Object.values(node.values.value).reduce((newDeclsAcc, caseDef) => caseDef.type === null ? newDecls : mapNodeTree(callbackFn, caseDef.type, newDeclsAcc), newDecls);
32
+ return mapNodeTree(callbackFn, node.type.value, newDecls);
32
33
  }
33
34
  case NodeKind.TypeAliasDecl: {
34
35
  const newDecls = callbackFn(node, decls);
@@ -47,11 +48,15 @@ export const flatMapAuxiliaryDecls = (callbackFn, declarations) => {
47
48
  case NodeKind.FloatType:
48
49
  case NodeKind.IntegerType:
49
50
  case NodeKind.StringType:
50
- case NodeKind.GenericArgumentIdentifierType:
51
+ case NodeKind.TypeArgumentType:
51
52
  case NodeKind.ReferenceIdentifierType:
52
53
  case NodeKind.IncludeIdentifierType:
53
54
  case NodeKind.NestedEntityMapType:
54
55
  return callbackFn(node, decls);
56
+ case NodeKind.EnumType: {
57
+ const newDecls = callbackFn(node, decls);
58
+ return Object.values(node.values).reduce((newDeclsAcc, caseDef) => caseDef.type === null ? newDecls : mapNodeTree(callbackFn, caseDef.type, newDeclsAcc), newDecls);
59
+ }
55
60
  default:
56
61
  return assertExhaustive(node);
57
62
  }
@@ -69,7 +74,7 @@ export const flatMapAuxiliaryDecls = (callbackFn, declarations) => {
69
74
  return declarations.reduce((decls, node) => mapNodeTree(reducer, node, [...decls, node]), []);
70
75
  };
71
76
  export const createValidators = (instancesByEntityName) => ({
72
- checkReferentialIntegrity: ({ name, value }) => instancesByEntityName[name].some(instance => typeof instance.content === "object" &&
77
+ checkReferentialIntegrity: ({ name, value }) => instancesByEntityName[name]?.some(instance => typeof instance.content === "object" &&
73
78
  instance.content !== null &&
74
79
  !Array.isArray(instance.content) &&
75
80
  instance.id === value)
@@ -1,5 +1,6 @@
1
- import { NodeKind, Serializer } from "../Node.js";
2
- import { SerializedBaseType, SerializedType, Type } from "../types/Type.js";
1
+ import type { Serializer } from "./Node.js";
2
+ import { NodeKind } from "./Node.js";
3
+ import type { SerializedBaseType, SerializedType, Type } from "./types/Type.js";
3
4
  export interface TypeParameter<N extends string = string, T extends Type = Type> {
4
5
  kind: NodeKind["GenericParameter"];
5
6
  name: N;
@@ -1,5 +1,5 @@
1
- import { NodeKind } from "../Node.js";
2
- import { removeParentKey, serializeType, } from "../types/Type.js";
1
+ import { NodeKind } from "./Node.js";
2
+ import { removeParentKey, serializeType } from "./types/Type.js";
3
3
  export const Param = (name, constraint) => ({
4
4
  kind: NodeKind.GenericParameter,
5
5
  name,
@@ -1,11 +1,11 @@
1
- import { BaseNode, GetReferences, Node, Serializer } from "../Node.js";
2
- import { SerializedTypeParameter, TypeParameter } from "../parameters/TypeParameter.js";
3
- import { ObjectType, SerializedObjectType } from "../types/generic/ObjectType.js";
4
- import { SerializedType, Type } from "../types/Type.js";
5
- import { ValidatorHelpers } from "../validation/type.js";
6
- import { EntityDecl, SerializedEntityDecl } from "./EntityDecl.js";
7
- import { EnumCaseDecl, EnumDecl, SerializedEnumCaseDecl, SerializedEnumDecl } from "./EnumDecl.js";
8
- import { SerializedTypeAliasDecl, TypeAliasDecl } from "./TypeAliasDecl.js";
1
+ import type { BaseNode, GetReferences, Node, Serializer } from "../Node.js";
2
+ import type { SerializedTypeParameter, TypeParameter } from "../TypeParameter.js";
3
+ import type { EnumCaseDecl, SerializedEnumCaseDecl } from "../types/generic/EnumType.js";
4
+ import type { SerializedType, Type } from "../types/Type.js";
5
+ import type { ValidatorHelpers } from "../validation/type.js";
6
+ import type { EntityDecl, SerializedEntityDecl } from "./EntityDecl.js";
7
+ import type { EnumDecl, SerializedEnumDecl } from "./EnumDecl.js";
8
+ import type { SerializedTypeAliasDecl, TypeAliasDecl } from "./TypeAliasDecl.js";
9
9
  export type TypeArguments<Params extends TypeParameter[]> = {
10
10
  [K in keyof Params]: Params[K] extends TypeParameter<string, infer T> ? T : Type;
11
11
  };
@@ -16,8 +16,8 @@ export declare const getParameterNames: (decl: Decl) => string[];
16
16
  export declare const getTypeArgumentsRecord: <Params extends TypeParameter[]>(decl: DeclP<Params>, args: TypeArguments<Params>) => Record<string, Type>;
17
17
  export type Decl = EntityDecl | EnumDecl | TypeAliasDecl;
18
18
  export type SerializedDecl = SerializedEntityDecl | SerializedEnumDecl | SerializedTypeAliasDecl;
19
- export type DeclP<Params extends TypeParameter[] = TypeParameter[]> = EntityDecl<string, ObjectType> | EnumDecl<string, Record<string, EnumCaseDecl>, Params> | TypeAliasDecl<string, Type, Params>;
20
- export type SerializedDeclP<Params extends SerializedTypeParameter[] = SerializedTypeParameter[]> = SerializedEntityDecl<string, SerializedObjectType> | SerializedEnumDecl<string, Record<string, SerializedEnumCaseDecl>, Params> | SerializedTypeAliasDecl<string, SerializedType, Params>;
19
+ export type DeclP<Params extends TypeParameter[] = TypeParameter[]> = EntityDecl | EnumDecl<string, Record<string, EnumCaseDecl>, Params> | TypeAliasDecl<string, Type, Params>;
20
+ export type SerializedDeclP<Params extends SerializedTypeParameter[] = SerializedTypeParameter[]> = SerializedEntityDecl | SerializedEnumDecl<string, Record<string, SerializedEnumCaseDecl>, Params> | SerializedTypeAliasDecl<string, SerializedType, Params>;
21
21
  export type SecondaryDecl = EnumDecl | TypeAliasDecl;
22
22
  export type SerializedSecondaryDecl = SerializedEnumDecl | SerializedTypeAliasDecl;
23
23
  export declare const getNestedDeclarations: GetNestedDeclarations;
@@ -42,3 +42,4 @@ export declare const isDeclWithoutTypeParameters: (decl: Decl) => decl is DeclP<
42
42
  export declare const resolveTypeArgumentsInDecls: (decls: readonly Decl[]) => DeclP<[]>[];
43
43
  export declare const serializeDecl: Serializer<Decl, SerializedDecl>;
44
44
  export declare const getReferencesForDecl: GetReferences<Decl>;
45
+ export declare const groupDeclarationsBySourceUrl: (decls: readonly Decl[]) => Partial<Record<string, Decl[]>>;
@@ -1,7 +1,8 @@
1
- import { assertExhaustive } from "../../shared/utils/typeSafety.js";
1
+ import { assertExhaustive } from "../../../shared/utils/typeSafety.js";
2
2
  import { NodeKind } from "../Node.js";
3
3
  import { getNestedDeclarationsInArrayType } from "../types/generic/ArrayType.js";
4
- import { getNestedDeclarationsInObjectType, } from "../types/generic/ObjectType.js";
4
+ import { getNestedDeclarationsInEnumType } from "../types/generic/EnumType.js";
5
+ import { getNestedDeclarationsInObjectType } from "../types/generic/ObjectType.js";
5
6
  import { getNestedDeclarationsInIncludeIdentifierType } from "../types/references/IncludeIdentifierType.js";
6
7
  import { getNestedDeclarationsInNestedEntityMapType } from "../types/references/NestedEntityMapType.js";
7
8
  import { getNestedDeclarationsInReferenceIdentifierType } from "../types/references/ReferenceIdentifierType.js";
@@ -9,7 +10,9 @@ import { getNestedDeclarationsInEntityDecl, getReferencesForEntityDecl, isEntity
9
10
  import { getNestedDeclarationsInEnumDecl, getReferencesForEnumDecl, isEnumDecl, resolveTypeArgumentsInEnumDecl, serializeEnumDecl, validateEnumDecl, } from "./EnumDecl.js";
10
11
  import { getNestedDeclarationsInTypeAliasDecl, getReferencesForTypeAliasDecl, isTypeAliasDecl, resolveTypeArgumentsInTypeAliasDecl, serializeTypeAliasDecl, validateTypeAliasDecl, } from "./TypeAliasDecl.js";
11
12
  export const getParameterNames = (decl) => decl.parameters.map(param => param.name);
12
- export const getTypeArgumentsRecord = (decl, args) => Object.fromEntries(args.map((arg, i) => [decl.parameters[i].name, arg]));
13
+ export const getTypeArgumentsRecord = (decl, args) => Object.fromEntries(
14
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
15
+ args.slice(0, decl.parameters.length).map((arg, i) => [decl.parameters[i].name, arg]));
13
16
  export const getNestedDeclarations = (addedDecls, node) => {
14
17
  switch (node.kind) {
15
18
  case NodeKind.EntityDecl:
@@ -27,7 +30,7 @@ export const getNestedDeclarations = (addedDecls, node) => {
27
30
  case NodeKind.FloatType:
28
31
  case NodeKind.IntegerType:
29
32
  case NodeKind.StringType:
30
- case NodeKind.GenericArgumentIdentifierType:
33
+ case NodeKind.TypeArgumentType:
31
34
  return addedDecls;
32
35
  case NodeKind.ReferenceIdentifierType:
33
36
  return getNestedDeclarationsInReferenceIdentifierType(addedDecls, node);
@@ -35,6 +38,8 @@ export const getNestedDeclarations = (addedDecls, node) => {
35
38
  return getNestedDeclarationsInIncludeIdentifierType(addedDecls, node);
36
39
  case NodeKind.NestedEntityMapType:
37
40
  return getNestedDeclarationsInNestedEntityMapType(addedDecls, node);
41
+ case NodeKind.EnumType:
42
+ return getNestedDeclarationsInEnumType(addedDecls, node);
38
43
  default:
39
44
  return assertExhaustive(node);
40
45
  }
@@ -96,3 +101,4 @@ export const getReferencesForDecl = (decl, value) => {
96
101
  return assertExhaustive(decl);
97
102
  }
98
103
  };
104
+ export const groupDeclarationsBySourceUrl = (decls) => Object.groupBy(decls, decl => decl.sourceUrl);