tsondb 0.21.5 → 0.21.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/node/bin/tsondb.js +10 -4
- package/dist/src/node/index.d.ts +12 -3
- package/dist/src/node/index.js +29 -14
- package/dist/src/node/renderers/jsonschema/index.d.ts +1 -1
- package/dist/src/node/renderers/jsonschema/index.js +2 -2
- package/dist/src/node/renderers/jsonschema/render.js +4 -6
- package/dist/src/node/renderers/ts/index.d.ts +1 -1
- package/dist/src/node/renderers/ts/index.js +2 -2
- package/dist/src/node/renderers/ts/render.js +11 -21
- package/dist/src/node/schema/detached.d.ts +1 -1
- package/dist/src/node/schema/detached.js +0 -1
- package/dist/src/node/schema/dsl/declarations/Decl.d.ts +3 -3
- package/dist/src/node/schema/dsl/declarations/Decl.js +1 -1
- package/dist/src/node/schema/dsl/declarations/EntityDecl.d.ts +2 -2
- package/dist/src/node/schema/dsl/declarations/EntityDecl.js +1 -1
- package/dist/src/node/schema/dsl/declarations/EnumDecl.d.ts +2 -3
- package/dist/src/node/schema/dsl/declarations/SingletonEntityDecl.d.ts +1 -1
- package/dist/src/node/schema/dsl/declarations/TypeAliasDecl.d.ts +1 -1
- package/dist/src/node/schema/dsl/index.d.ts +1 -1
- package/dist/src/node/schema/dsl/types/ChildEntitiesType.d.ts +1 -1
- package/dist/src/node/schema/dsl/types/ChildEntitiesType.js +0 -1
- package/dist/src/node/schema/dsl/types/IncludeIdentifierType.d.ts +1 -1
- package/dist/src/node/schema/dsl/types/IncludeIdentifierType.js +0 -1
- package/dist/src/node/schema/dsl/types/NestedEntityMapType.d.ts +1 -1
- package/dist/src/node/schema/dsl/types/NestedEntityMapType.js +0 -1
- package/dist/src/node/schema/dsl/types/ObjectType.js +1 -1
- package/dist/src/node/schema/helpers.d.ts +4 -4
- package/dist/src/node/schema/helpers.js +8 -11
- package/dist/src/node/schema/index.d.ts +2 -2
- package/dist/src/node/schema/index.js +4 -3
- package/dist/src/node/schema/treeOperations/format.js +2 -1
- package/dist/src/node/schema/treeOperations/serialization.d.ts +19 -19
- package/dist/src/node/schema/treeOperations/serialization.js +0 -18
- package/dist/src/node/schema/treeOperations/typeResolution.d.ts +9 -11
- package/dist/src/node/schema/treeOperations/typeResolution.js +0 -7
- package/dist/src/node/schema/treeOperations/validation.d.ts +1 -1
- package/dist/src/node/schema/treeOperations/validation.js +5 -6
- package/dist/src/node/schema/validation/options.js +2 -1
- package/dist/src/node/server/api/declarations.js +2 -2
- package/dist/src/node/server/api/git.js +2 -2
- package/dist/src/node/server/index.d.ts +2 -2
- package/dist/src/node/server/index.js +2 -2
- package/dist/src/node/server/utils/query.js +1 -1
- package/dist/src/node/transaction.d.ts +2 -2
- package/dist/src/node/transaction.js +0 -2
- package/dist/src/node/utils/childInstances.d.ts +1 -1
- package/dist/src/node/utils/childInstances.js +3 -2
- package/dist/src/node/utils/customConstraints.d.ts +1 -1
- package/dist/src/node/utils/customConstraints.js +0 -1
- package/dist/src/node/utils/databaseInMemory.js +16 -18
- package/dist/src/node/utils/databaseOnDisk.js +8 -0
- package/dist/src/node/utils/displayName.d.ts +1 -1
- package/dist/src/node/utils/displayName.js +24 -29
- package/dist/src/node/utils/files.d.ts +1 -1
- package/dist/src/node/utils/files.js +1 -2
- package/dist/src/node/utils/path.js +2 -1
- package/dist/src/node/utils/references.d.ts +1 -1
- package/dist/src/node/utils/references.js +6 -5
- package/dist/src/node/utils/unique.d.ts +1 -1
- package/dist/src/node/utils/unique.js +8 -17
- package/dist/src/shared/schema/declarations/Declaration.d.ts +1 -1
- package/dist/src/shared/schema/declarations/Declaration.js +0 -1
- package/dist/src/shared/schema/declarations/EnumDecl.js +5 -7
- package/dist/src/shared/schema/types/EnumType.js +2 -2
- package/dist/src/shared/schema/types/NestedEntityMapType.d.ts +1 -2
- package/dist/src/shared/schema/utils/keyPath.js +14 -14
- package/dist/src/shared/schema/utils/sortOrder.js +1 -1
- package/dist/src/shared/utils/git.js +6 -1
- package/dist/src/shared/utils/render.js +3 -3
- package/dist/src/shared/utils/translation.js +15 -16
- package/dist/src/shared/utils/validation.js +4 -4
- package/dist/src/shared/validation/date.js +2 -2
- package/dist/src/shared/validation/identifier.js +1 -1
- package/dist/src/shared/validation/number.js +3 -3
- package/dist/src/shared/validation/object.js +1 -1
- package/dist/src/shared/validation/string.js +1 -1
- package/dist/src/web/web.js +92 -76
- package/package.json +9 -12
|
@@ -8,6 +8,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
8
8
|
return path;
|
|
9
9
|
};
|
|
10
10
|
import { omitUndefinedKeys } from "@elyukai/utils/object";
|
|
11
|
+
import { assertExhaustive } from "@elyukai/utils/typeSafety";
|
|
11
12
|
import Debug from "debug";
|
|
12
13
|
import { access, constants } from "node:fs/promises";
|
|
13
14
|
import { join } from "node:path";
|
|
@@ -87,12 +88,14 @@ const config = await (async () => {
|
|
|
87
88
|
for (const configName of possibleConfigNames) {
|
|
88
89
|
const fullPath = join(cwd(), configName);
|
|
89
90
|
try {
|
|
91
|
+
// oxlint-disable-next-line no-await-in-loop
|
|
90
92
|
await access(fullPath, constants.R_OK);
|
|
91
93
|
}
|
|
92
94
|
catch {
|
|
93
95
|
debug(`could not use config file ${fullPath}, not found`);
|
|
94
96
|
continue;
|
|
95
97
|
}
|
|
98
|
+
// oxlint-disable-next-line no-await-in-loop
|
|
96
99
|
const foundConfigModule = (await import(__rewriteRelativeImportExtension(pathToFileURL(fullPath).toString())));
|
|
97
100
|
if ("default" in foundConfigModule) {
|
|
98
101
|
debug(`config file ${fullPath} found with config`);
|
|
@@ -110,18 +113,19 @@ if (config === undefined) {
|
|
|
110
113
|
if (passedArguments.command === undefined) {
|
|
111
114
|
throw new Error("No command has been specified. Possible commands are: generate, serve, validate.");
|
|
112
115
|
}
|
|
113
|
-
const createDB = (
|
|
114
|
-
...
|
|
116
|
+
const createDB = (dataConfig, validationOptions, skipReferenceCache) => TSONDB.create({
|
|
117
|
+
...dataConfig,
|
|
115
118
|
validationOptions,
|
|
116
119
|
}, skipReferenceCache);
|
|
117
|
-
|
|
120
|
+
const commandName = passedArguments.command.name;
|
|
121
|
+
if (commandName === "generate") {
|
|
118
122
|
debug(`running command: generate`);
|
|
119
123
|
validateConfigForGeneration(config);
|
|
120
124
|
await TSONDB.generateOutputs(config);
|
|
121
125
|
}
|
|
122
126
|
else {
|
|
123
127
|
validateConfigForData(config);
|
|
124
|
-
switch (
|
|
128
|
+
switch (commandName) {
|
|
125
129
|
case "serve": {
|
|
126
130
|
debug(`running command: serve`);
|
|
127
131
|
validateConfigForServer(config);
|
|
@@ -200,5 +204,7 @@ else {
|
|
|
200
204
|
}
|
|
201
205
|
break;
|
|
202
206
|
}
|
|
207
|
+
default:
|
|
208
|
+
assertExhaustive(commandName);
|
|
203
209
|
}
|
|
204
210
|
}
|
package/dist/src/node/index.d.ts
CHANGED
|
@@ -2,9 +2,8 @@ import type { InstanceContainer, InstanceContainerOverview, InstanceContent, Sin
|
|
|
2
2
|
import type { FormatterOptions } from "./config.ts";
|
|
3
3
|
import { Git } from "./git.js";
|
|
4
4
|
import type { Output } from "./output.ts";
|
|
5
|
-
import {
|
|
6
|
-
import type { AnyChildEntityMap, AnyEntityMap, AnyEnumMap, AnySingletonEntityMap, AnyTypeAliasMap } from "./schema/generatedTypeHelpers.ts";
|
|
7
|
-
import { type IdArgsVariant } from "./schema/generatedTypeHelpers.ts";
|
|
5
|
+
import type { EntityDecl } from "./schema/dsl/index.ts";
|
|
6
|
+
import type { AnyChildEntityMap, AnyEntityMap, AnyEnumMap, AnySingletonEntityMap, AnyTypeAliasMap, IdArgsVariant } from "./schema/generatedTypeHelpers.ts";
|
|
8
7
|
import type { Schema } from "./schema/index.ts";
|
|
9
8
|
import { Transaction } from "./transaction.ts";
|
|
10
9
|
export interface DefaultTSONDBTypes {
|
|
@@ -104,6 +103,7 @@ export interface TranslationValidationOptions {
|
|
|
104
103
|
*/
|
|
105
104
|
matchParametersInKeys?: boolean;
|
|
106
105
|
}
|
|
106
|
+
export type HookTrigger = "transaction:before" | "transaction:after";
|
|
107
107
|
/**
|
|
108
108
|
* The main class for managing a typed JSON database.
|
|
109
109
|
*/
|
|
@@ -318,8 +318,17 @@ export declare class TSONDB<T extends DefaultTSONDBTypes = DefaultTSONDBTypes> {
|
|
|
318
318
|
* @param path The file path where the compressed database will be saved.
|
|
319
319
|
*/
|
|
320
320
|
compressToSingleFile(path: string): Promise<void>;
|
|
321
|
+
/**
|
|
322
|
+
* Registers a new hook for the specified trigger. The callback will be invoked whenever the trigger is activated.
|
|
323
|
+
*/
|
|
324
|
+
registerHook(trigger: HookTrigger, callback: (db: TSONDB<T>) => void): void;
|
|
325
|
+
/**
|
|
326
|
+
* Unregisters a hook for the specified trigger.
|
|
327
|
+
*/
|
|
328
|
+
unregisterHook(trigger: HookTrigger, callback: (db: TSONDB<T>) => void): void;
|
|
321
329
|
}
|
|
322
330
|
export type TSONDBWithGit<T extends DefaultTSONDBTypes = DefaultTSONDBTypes> = TSONDB<T> & {
|
|
323
331
|
git: Git<T>;
|
|
324
332
|
};
|
|
325
333
|
export type { Config } from "./config.ts";
|
|
334
|
+
export { createServer } from "./server/index.ts";
|
package/dist/src/node/index.js
CHANGED
|
@@ -15,8 +15,6 @@ import { countError, countErrors, getErrorMessageForDisplay, HTTPError, wrapErro
|
|
|
15
15
|
import { parallelizeErrors } from "../shared/utils/validation.js";
|
|
16
16
|
import { Git } from "./git.js";
|
|
17
17
|
import { getDisplayName, getDisplayNameWithId } from "./schema/detached.js";
|
|
18
|
-
import {} from "./schema/dsl/index.js";
|
|
19
|
-
import {} from "./schema/generatedTypeHelpers.js";
|
|
20
18
|
import { isEntityDecl, isEntityDeclWithParentReference } from "./schema/guards.js";
|
|
21
19
|
import { serializeNode } from "./schema/treeOperations/serialization.js";
|
|
22
20
|
import { createEntityNameValidator, createReferenceValidator, validateDeclReferentialIntegrity, validateDeclStructuralIntegrity, } from "./schema/treeOperations/validation.js";
|
|
@@ -32,15 +30,10 @@ import { checkUniqueConstraintsForAllEntities } from "./utils/unique.js";
|
|
|
32
30
|
const debug = Debug("tsondb:class");
|
|
33
31
|
const prepareFolders = async (dataRootPath, entities) => {
|
|
34
32
|
await mkdir(dataRootPath, { recursive: true });
|
|
35
|
-
|
|
36
|
-
const entityDir = join(dataRootPath, entity.name);
|
|
37
|
-
await mkdir(entityDir, { recursive: true });
|
|
38
|
-
}
|
|
33
|
+
await Promise.all(entities.map(entity => mkdir(join(dataRootPath, entity.name), { recursive: true })));
|
|
39
34
|
};
|
|
40
35
|
const generateOutputs = async (schema, outputs) => {
|
|
41
|
-
|
|
42
|
-
await output.run(schema);
|
|
43
|
-
}
|
|
36
|
+
await Promise.all(outputs.map(output => output.run(schema)));
|
|
44
37
|
};
|
|
45
38
|
const getGit = async (dataRootPath) => {
|
|
46
39
|
const git = simpleGit({ baseDir: dataRootPath });
|
|
@@ -59,7 +52,7 @@ const getGit = async (dataRootPath) => {
|
|
|
59
52
|
}
|
|
60
53
|
};
|
|
61
54
|
const checkLocales = (schema, data, locales) => {
|
|
62
|
-
const localeEntity = schema
|
|
55
|
+
const { localeEntity } = schema;
|
|
63
56
|
if (localeEntity &&
|
|
64
57
|
!locales.every(locale => data.hasInstanceOfEntityById(localeEntity.name, locale))) {
|
|
65
58
|
throw new Error("All provided locales must exist in the database.");
|
|
@@ -71,7 +64,7 @@ const initData = async (dataRootPath, schema, locales, git, gitStatus, skipRefer
|
|
|
71
64
|
debug("done");
|
|
72
65
|
checkLocales(schema, data, locales);
|
|
73
66
|
const serializedDeclarationsByName = Object.fromEntries(schema.resolvedDeclarations.map(decl => [decl.name, serializeNode(decl)]));
|
|
74
|
-
let referencesToInstances;
|
|
67
|
+
let referencesToInstances = {};
|
|
75
68
|
if (!skipReferenceCache) {
|
|
76
69
|
debug("creating references cache ...");
|
|
77
70
|
referencesToInstances = await getReferencesToInstances(data, serializedDeclarationsByName);
|
|
@@ -79,7 +72,6 @@ const initData = async (dataRootPath, schema, locales, git, gitStatus, skipRefer
|
|
|
79
72
|
}
|
|
80
73
|
else {
|
|
81
74
|
debug("skipping references cache creation");
|
|
82
|
-
referencesToInstances = {};
|
|
83
75
|
}
|
|
84
76
|
if (git) {
|
|
85
77
|
const status = gitStatus ?? (await git.client.status());
|
|
@@ -102,6 +94,7 @@ export class TSONDB {
|
|
|
102
94
|
#formatterOptions;
|
|
103
95
|
#gitWrapper;
|
|
104
96
|
#locked = false;
|
|
97
|
+
#hooks = {};
|
|
105
98
|
constructor(options) {
|
|
106
99
|
this.#dataRootPath = options.dataRootPath;
|
|
107
100
|
this.#data = options.data;
|
|
@@ -124,7 +117,7 @@ export class TSONDB {
|
|
|
124
117
|
* @param skipReferenceCache If set to `true`, the reference cache will not be created during initialization. This can speed up the initialization process, but referential integrity checks will not work correctly until the cache is created. This should only be set to `true` if you plan to call `sync()` immediately after initialization.
|
|
125
118
|
*/
|
|
126
119
|
static async create(options, skipReferenceCache = false) {
|
|
127
|
-
const entities = options.schema
|
|
120
|
+
const { entities } = options.schema;
|
|
128
121
|
debug("using data root path: %s", options.dataRootPath);
|
|
129
122
|
await prepareFolders(options.dataRootPath, entities);
|
|
130
123
|
debug("prepared folders");
|
|
@@ -135,7 +128,7 @@ export class TSONDB {
|
|
|
135
128
|
else {
|
|
136
129
|
debug("no git repository found");
|
|
137
130
|
}
|
|
138
|
-
const localeEntity = options.schema
|
|
131
|
+
const { localeEntity } = options.schema;
|
|
139
132
|
if (!localeEntity && options.locales) {
|
|
140
133
|
throw new Error("Schema does not contain a locale entity, locales cannot be provided.");
|
|
141
134
|
}
|
|
@@ -386,6 +379,7 @@ export class TSONDB {
|
|
|
386
379
|
throw new HTTPError(503, "Another transaction is currently running. Transactions cannot be run concurrently.");
|
|
387
380
|
}
|
|
388
381
|
debug("Starting transaction, locking database ...");
|
|
382
|
+
this.#hooks["transaction:before"]?.forEach(hook => hook(this));
|
|
389
383
|
this.#locked = true;
|
|
390
384
|
try {
|
|
391
385
|
const getEntity = this.#schema.getEntity.bind(this.#schema);
|
|
@@ -434,6 +428,7 @@ export class TSONDB {
|
|
|
434
428
|
this.#referencesToInstances = newRefs;
|
|
435
429
|
this.#locked = false;
|
|
436
430
|
debug("Transaction successful, released lock");
|
|
431
|
+
this.#hooks["transaction:after"]?.forEach(hook => hook(this));
|
|
437
432
|
return res;
|
|
438
433
|
}
|
|
439
434
|
catch (error) {
|
|
@@ -732,4 +727,24 @@ export class TSONDB {
|
|
|
732
727
|
async compressToSingleFile(path) {
|
|
733
728
|
await writeFile(path, JSON.stringify(this.#data), "utf-8");
|
|
734
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Registers a new hook for the specified trigger. The callback will be invoked whenever the trigger is activated.
|
|
732
|
+
*/
|
|
733
|
+
registerHook(trigger, callback) {
|
|
734
|
+
;
|
|
735
|
+
(this.#hooks[trigger] ??= []).push(callback);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Unregisters a hook for the specified trigger.
|
|
739
|
+
*/
|
|
740
|
+
unregisterHook(trigger, callback) {
|
|
741
|
+
const callbacks = this.#hooks[trigger];
|
|
742
|
+
if (callbacks) {
|
|
743
|
+
const index = callbacks.indexOf(callback);
|
|
744
|
+
if (index !== -1) {
|
|
745
|
+
callbacks.splice(index, 1);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
735
749
|
}
|
|
750
|
+
export { createServer } from "./server/index.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Output } from "../../output.ts";
|
|
2
|
-
import type
|
|
2
|
+
import { type JsonSchemaRendererOptions } from "./render.ts";
|
|
3
3
|
export declare const JsonSchemaOutput: (options: {
|
|
4
4
|
targetPath: string;
|
|
5
5
|
rendererOptions?: Partial<JsonSchemaRendererOptions>;
|
|
@@ -17,7 +17,7 @@ export const JsonSchemaOutput = (options) => ({
|
|
|
17
17
|
const sourceRootPath = fileURLToPath(commonPrefix(...Object.keys(declarationsBySourceUrl)));
|
|
18
18
|
debug("common source root path: %s", sourceRootPath);
|
|
19
19
|
if (sourceRootPath) {
|
|
20
|
-
|
|
20
|
+
await Promise.all(Object.entries(declarationsBySourceUrl).map(async ([sourceUrl, decls]) => {
|
|
21
21
|
const sourcePath = fileURLToPath(sourceUrl);
|
|
22
22
|
const relativePath = dirname(relative(sourceRootPath, sourcePath));
|
|
23
23
|
const newDir = join(options.targetPath, relativePath);
|
|
@@ -26,7 +26,7 @@ export const JsonSchemaOutput = (options) => ({
|
|
|
26
26
|
await writeFile(newPath, render(options.rendererOptions, decls ?? []), {
|
|
27
27
|
encoding: "utf-8",
|
|
28
28
|
});
|
|
29
|
-
}
|
|
29
|
+
}));
|
|
30
30
|
debug("emitted declaration files to %s", options.targetPath);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -5,8 +5,8 @@ import { NodeKind } from "../../../shared/schema/Node.js";
|
|
|
5
5
|
import { asDecl } from "../../schema/dsl/declarations/Decl.js";
|
|
6
6
|
import { addEphemeralUUIDToType, createEntityIdentifierTypeAsDecl, isEntityDecl, } from "../../schema/dsl/declarations/EntityDecl.js";
|
|
7
7
|
import { TypeAliasDecl } from "../../schema/dsl/declarations/TypeAliasDecl.js";
|
|
8
|
-
import { isNestedEntityMapType } from "../../schema/dsl/types/NestedEntityMapType.js";
|
|
9
|
-
import { getTypeOfKey } from "../../schema/dsl/types/TranslationObjectType.js";
|
|
8
|
+
import { isNestedEntityMapType, } from "../../schema/dsl/types/NestedEntityMapType.js";
|
|
9
|
+
import { getTypeOfKey, } from "../../schema/dsl/types/TranslationObjectType.js";
|
|
10
10
|
import { flatMapAuxiliaryDecls, isFinalChildEntitiesType } from "../../schema/helpers.js";
|
|
11
11
|
import { ensureSpecialDirStart } from "../../utils/path.js";
|
|
12
12
|
const defaultIndentation = 2;
|
|
@@ -24,7 +24,7 @@ const renderArrayType = (options, type) => ({
|
|
|
24
24
|
const renderObjectType = (options, type) => ({
|
|
25
25
|
type: "object",
|
|
26
26
|
properties: Object.fromEntries(Object.entries(type.properties)
|
|
27
|
-
.filter(([
|
|
27
|
+
.filter(([_key, config]) => !isFinalChildEntitiesType(config.type))
|
|
28
28
|
.map(([name, config]) => [
|
|
29
29
|
name,
|
|
30
30
|
{
|
|
@@ -192,9 +192,7 @@ export const render = (options = defaultOptions, declarations) => {
|
|
|
192
192
|
$defs: renderDeclarations(finalOptions, flatMapAuxiliaryDecls((parentNodes, node, existingDecls) => {
|
|
193
193
|
if (isNestedEntityMapType(node)) {
|
|
194
194
|
if (existingDecls.some(decl => decl.name === node.name)) {
|
|
195
|
-
|
|
196
|
-
// TODO: circumvent by defining the nested entity declaration outside the generic declaration
|
|
197
|
-
return undefined;
|
|
195
|
+
throw new Error("A nested entity map type with the same name has already been defined in this schema. Make sure the nested entity map type is defined only once in the schema. If the nested entity map type is defined in a generic declaration, consider defining it outside the generic declaration to avoid this issue.");
|
|
198
196
|
}
|
|
199
197
|
return TypeAliasDecl(asDecl(parentNodes[0])?.sourceUrl ?? "", {
|
|
200
198
|
name: node.name,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Output } from "../../output.ts";
|
|
2
|
-
import type
|
|
2
|
+
import { type TypeScriptRendererOptions } from "./render.ts";
|
|
3
3
|
export declare const TypeScriptOutput: (options: {
|
|
4
4
|
targetPath: string;
|
|
5
5
|
rendererOptions?: Partial<TypeScriptRendererOptions>;
|
|
@@ -18,7 +18,7 @@ export const TypeScriptOutput = (options) => ({
|
|
|
18
18
|
const sourceRootPath = fileURLToPath(commonPrefix(...Object.keys(declarationsBySourceUrl)));
|
|
19
19
|
debug("common source root path: %s", sourceRootPath);
|
|
20
20
|
if (sourceRootPath) {
|
|
21
|
-
|
|
21
|
+
await Promise.all(Object.entries(declarationsBySourceUrl).map(async ([sourceUrl, decls]) => {
|
|
22
22
|
const sourcePath = fileURLToPath(sourceUrl);
|
|
23
23
|
const relativePath = dirname(relative(sourceRootPath, sourcePath));
|
|
24
24
|
const newDir = join(options.targetPath, relativePath);
|
|
@@ -27,7 +27,7 @@ export const TypeScriptOutput = (options) => ({
|
|
|
27
27
|
await writeFile(newPath, pragma + render(options.rendererOptions, decls ?? []), {
|
|
28
28
|
encoding: "utf-8",
|
|
29
29
|
});
|
|
30
|
-
}
|
|
30
|
+
}));
|
|
31
31
|
debug("emitted declaration files to %s", options.targetPath);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -12,9 +12,9 @@ import { addEphemeralUUIDToType, createEntityIdentifierTypeAsDecl, isEntityDecl,
|
|
|
12
12
|
import { isEnumDecl } from "../../schema/dsl/declarations/EnumDecl.js";
|
|
13
13
|
import { isSingletonEntityDecl, } from "../../schema/dsl/declarations/SingletonEntityDecl.js";
|
|
14
14
|
import { isTypeAliasDecl, TypeAliasDecl } from "../../schema/dsl/declarations/TypeAliasDecl.js";
|
|
15
|
-
import { isNestedEntityMapType } from "../../schema/dsl/types/NestedEntityMapType.js";
|
|
16
|
-
import { isObjectType } from "../../schema/dsl/types/ObjectType.js";
|
|
17
|
-
import { getTypeOfKey } from "../../schema/dsl/types/TranslationObjectType.js";
|
|
15
|
+
import { isNestedEntityMapType, } from "../../schema/dsl/types/NestedEntityMapType.js";
|
|
16
|
+
import { isObjectType, } from "../../schema/dsl/types/ObjectType.js";
|
|
17
|
+
import { getTypeOfKey, } from "../../schema/dsl/types/TranslationObjectType.js";
|
|
18
18
|
import { flatMapAuxiliaryDecls, isFinalChildEntitiesType } from "../../schema/helpers.js";
|
|
19
19
|
import { ensureSpecialDirStart } from "../../utils/path.js";
|
|
20
20
|
const defaultOptions = {
|
|
@@ -52,11 +52,9 @@ const renderArrayType = (options, type) => type.minItems !== undefined && type.m
|
|
|
52
52
|
])
|
|
53
53
|
: syntax `${renderType(options, type.items)}[]`;
|
|
54
54
|
const wrapAsObject = (options, str) => syntax `{${EOL}${indent(options.indentation, 1, str)}${EOL}}`;
|
|
55
|
-
const renderObjectType = (options, type) =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.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));
|
|
59
|
-
};
|
|
55
|
+
const renderObjectType = (options, type) => wrapAsObject(options, combineSyntaxes(Object.entries(type.properties)
|
|
56
|
+
.filter(([_key, config]) => !isFinalChildEntitiesType(config.type))
|
|
57
|
+
.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));
|
|
60
58
|
const renderBooleanType = (_options, _type) => syntax `boolean`;
|
|
61
59
|
const renderDateType = (options, _type) => options.dateType === "Date" ? syntax `Date` : syntax `string`;
|
|
62
60
|
const renderFloatType = (_options, _type) => syntax `number`;
|
|
@@ -64,8 +62,8 @@ const renderIntegerType = (_options, _type) => syntax `number`;
|
|
|
64
62
|
const renderStringType = (_options, _type) => syntax `string`;
|
|
65
63
|
const renderTypeArgumentType = (_options, type) => syntax `${type.argument.name}`;
|
|
66
64
|
const renderReferenceIdentifierType = (_options, type) => [
|
|
67
|
-
{ [type.entity.sourceUrl]: [type.entity.name
|
|
68
|
-
type.entity.name
|
|
65
|
+
{ [type.entity.sourceUrl]: [`${type.entity.name}_ID`] },
|
|
66
|
+
`${type.entity.name}_ID`,
|
|
69
67
|
];
|
|
70
68
|
const renderIncludeIdentifierType = (options, type) => combineSyntaxes([
|
|
71
69
|
[{ [type.reference.sourceUrl]: [type.reference.name] }, type.reference.name],
|
|
@@ -111,9 +109,7 @@ const renderTranslationParameterBrand = (options, params) => {
|
|
|
111
109
|
}
|
|
112
110
|
return syntax ` & { __params: { ${entries.map(([name, type]) => `"${name}": ${type}`).join("; ")} } }`;
|
|
113
111
|
};
|
|
114
|
-
const renderTranslationObjectType = (options, type) => {
|
|
115
|
-
return wrapAsObject(options, combineSyntaxes(Object.entries(type.properties).map(([name, config]) => syntax `"${name.replace('"', '\\"')}"${type.allKeysAreRequired ? "" : "?"}: ${renderType(options, getTypeOfKey(config, type))}${renderTranslationParameterBrand(options, mapParameterTypeNames(extractParameterTypeNamesFromMessage(name), typeName => mapTypeNameToType(options, typeName)))}`), EOL));
|
|
116
|
-
};
|
|
112
|
+
const renderTranslationObjectType = (options, type) => wrapAsObject(options, combineSyntaxes(Object.entries(type.properties).map(([name, config]) => syntax `"${name.replace('"', '\\"')}"${type.allKeysAreRequired ? "" : "?"}: ${renderType(options, getTypeOfKey(config, type))}${renderTranslationParameterBrand(options, mapParameterTypeNames(extractParameterTypeNamesFromMessage(name), typeName => mapTypeNameToType(options, typeName)))}`), EOL));
|
|
117
113
|
const renderType = (options, type) => {
|
|
118
114
|
switch (type.kind) {
|
|
119
115
|
case NodeKind.ArrayType:
|
|
@@ -192,7 +188,7 @@ const renderMapHelperType = (options, declarations, key, defaultName, filterFn,
|
|
|
192
188
|
.filter(filterFn)
|
|
193
189
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
194
190
|
.map(renderKeyFn ??
|
|
195
|
-
(decl => `${decl.name}: ${decl.name}${decl.parameters.length > 0 ?
|
|
191
|
+
(decl => `${decl.name}: ${decl.name}${decl.parameters.length > 0 ? `<${decl.parameters.map(param => (param.constraint ? renderType(options, param.constraint)[1] : "unknown")).join(", ")}>` : ""}`))
|
|
196
192
|
.join(EOL))}${EOL}}${EOL + EOL}`
|
|
197
193
|
: "";
|
|
198
194
|
};
|
|
@@ -205,13 +201,7 @@ const renderStringableTranslationParameterType = (options) => options.inferTrans
|
|
|
205
201
|
(options.inferTranslationParameters.defaultTranslationParameterType === undefined ||
|
|
206
202
|
options.inferTranslationParameters.defaultTranslationParameterType ===
|
|
207
203
|
"StringableTranslationParameter")
|
|
208
|
-
?
|
|
209
|
-
EOL +
|
|
210
|
-
prefixLines(getIndentation(options.indentation, 1), "toString(): string") +
|
|
211
|
-
EOL +
|
|
212
|
-
"}" +
|
|
213
|
-
EOL +
|
|
214
|
-
EOL
|
|
204
|
+
? `export type StringableTranslationParameter = {${EOL}${prefixLines(getIndentation(options.indentation, 1), "toString(): string")}${EOL}}${EOL}${EOL}`
|
|
215
205
|
: "";
|
|
216
206
|
// const renderGetterConstruct = (
|
|
217
207
|
// config: GetterOptions | undefined,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Standalone functions for database operations without needing a full TSONDB instance.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import type { DatabaseInMemory } from "../utils/databaseInMemory.ts";
|
|
5
5
|
import { type AnyEntityMap, type GetEntityByName, type IdArgsVariant } from "./generatedTypeHelpers.ts";
|
|
6
6
|
export declare const getDisplayName: <EM extends AnyEntityMap>(getEntity: GetEntityByName<EM>, locales: string[], data: DatabaseInMemory<EM>, ...args: IdArgsVariant<EM>) => string | undefined;
|
|
7
7
|
export declare const getDisplayNameWithId: <EM extends AnyEntityMap>(getEntity: GetEntityByName<EM>, locales: string[], data: DatabaseInMemory<EM>, ...args: IdArgsVariant<EM>) => string;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Standalone functions for database operations without needing a full TSONDB instance.
|
|
3
3
|
*/
|
|
4
|
-
import {} from "../utils/databaseInMemory.js";
|
|
5
4
|
import { getDisplayNameFromEntityInstance } from "../utils/displayName.js";
|
|
6
5
|
import { normalizedIdArgs, } from "./generatedTypeHelpers.js";
|
|
7
6
|
export const getDisplayName = (getEntity, locales, data, ...args) => {
|
|
@@ -3,10 +3,10 @@ import type { Node } from "../index.ts";
|
|
|
3
3
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
4
4
|
import type { EnumCaseDecl } from "../types/EnumType.ts";
|
|
5
5
|
import type { Type } from "../types/Type.ts";
|
|
6
|
-
import type
|
|
7
|
-
import type
|
|
6
|
+
import { type EntityDecl } from "./EntityDecl.ts";
|
|
7
|
+
import { type EnumDecl } from "./EnumDecl.ts";
|
|
8
8
|
import { type SingletonEntityDecl } from "./SingletonEntityDecl.ts";
|
|
9
|
-
import type
|
|
9
|
+
import { type TypeAliasDecl } from "./TypeAliasDecl.ts";
|
|
10
10
|
export type TypeArguments<Params extends TypeParameter[]> = {
|
|
11
11
|
[K in keyof Params]: Params[K] extends TypeParameter<string, infer T> ? T : Type;
|
|
12
12
|
};
|
|
@@ -10,7 +10,7 @@ export const getTypeArgumentsRecord = (decl, args) => Object.fromEntries(
|
|
|
10
10
|
args.slice(0, decl.parameters.length).map((arg, i) => [decl.parameters[i].name, arg]));
|
|
11
11
|
export const isDecl = (node) => isEntityDecl(node) || isSingletonEntityDecl(node) || isEnumDecl(node) || isTypeAliasDecl(node);
|
|
12
12
|
export const asDecl = (node) => node && isDecl(node) ? node : undefined;
|
|
13
|
-
const declNamePattern = /^[a-zA-Z_][a-zA-Z0-9_]
|
|
13
|
+
const declNamePattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/u;
|
|
14
14
|
export const validateDeclName = (name) => {
|
|
15
15
|
if (!declNamePattern.test(name)) {
|
|
16
16
|
throw new Error(`Invalid declaration name "${name}". Declaration names must match the pattern ${declNamePattern.toString()}.`);
|
|
@@ -7,9 +7,9 @@ import type { CustomConstraint, TypedCustomConstraint } from "../../../utils/cus
|
|
|
7
7
|
import type { DisplayNameCustomizer, TypedDisplayNameCustomizer } from "../../../utils/displayName.ts";
|
|
8
8
|
import type { Node } from "../index.ts";
|
|
9
9
|
import type { NestedEntityMapType } from "../types/NestedEntityMapType.ts";
|
|
10
|
-
import type
|
|
10
|
+
import { type MemberDecl, type ObjectType } from "../types/ObjectType.ts";
|
|
11
11
|
import { StringType } from "../types/StringType.ts";
|
|
12
|
-
import type
|
|
12
|
+
import { type BaseDecl } from "./Decl.ts";
|
|
13
13
|
import { TypeAliasDecl } from "./TypeAliasDecl.ts";
|
|
14
14
|
export type EntityDisplayName<T extends TConstraint> = PathTo<T, StringType> | {
|
|
15
15
|
/**
|
|
@@ -41,6 +41,6 @@ export const addEphemeralUUIDToType = (decl) => ({
|
|
|
41
41
|
export const createEntityIdentifierType = () => StringType();
|
|
42
42
|
export const createEntityIdentifierTypeAsDecl = (decl) => TypeAliasDecl(decl.sourceUrl, {
|
|
43
43
|
comment: createEntityIdentifierComment(),
|
|
44
|
-
name:
|
|
44
|
+
name: `${decl.name}_ID`,
|
|
45
45
|
type: createEntityIdentifierType,
|
|
46
46
|
});
|
|
@@ -4,9 +4,8 @@ import { NodeKind } from "../../../../shared/schema/Node.ts";
|
|
|
4
4
|
import type { NestedCustomConstraint, TypedNestedCustomConstraint } from "../../../utils/customConstraints.ts";
|
|
5
5
|
import type { Node } from "../index.ts";
|
|
6
6
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
7
|
-
import type
|
|
8
|
-
import {
|
|
9
|
-
import type { BaseDecl } from "./Decl.ts";
|
|
7
|
+
import { type EnumCaseDecl, EnumType } from "../types/EnumType.ts";
|
|
8
|
+
import { type BaseDecl } from "./Decl.ts";
|
|
10
9
|
type TConstraint = Record<string, EnumCaseDecl>;
|
|
11
10
|
export interface EnumDecl<Name extends string = string, T extends TConstraint = TConstraint, Params extends TypeParameter[] = TypeParameter[]> extends BaseDecl<Name, Params> {
|
|
12
11
|
kind: NodeKind["EnumDecl"];
|
|
@@ -4,7 +4,7 @@ import type { SortOrder } from "../../../../shared/schema/utils/sortOrder.ts";
|
|
|
4
4
|
import type { CustomConstraint, TypedCustomConstraint } from "../../../utils/customConstraints.ts";
|
|
5
5
|
import type { Node } from "../index.ts";
|
|
6
6
|
import type { MemberDecl, ObjectType } from "../types/ObjectType.ts";
|
|
7
|
-
import type
|
|
7
|
+
import { type BaseDecl } from "./Decl.ts";
|
|
8
8
|
type TConstraint = Record<string, MemberDecl>;
|
|
9
9
|
export interface SingletonEntityDecl<Name extends string = string, T extends TConstraint = TConstraint> extends BaseDecl<Name, []> {
|
|
10
10
|
kind: NodeKind["SingletonEntityDecl"];
|
|
@@ -4,7 +4,7 @@ import type { NestedCustomConstraint, TypedNestedCustomConstraint } from "../../
|
|
|
4
4
|
import type { Node } from "../index.ts";
|
|
5
5
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
6
6
|
import type { Type } from "../types/Type.ts";
|
|
7
|
-
import type
|
|
7
|
+
import { type BaseDecl } from "./Decl.ts";
|
|
8
8
|
export interface TypeAliasDecl<Name extends string = string, T extends Type = Type, Params extends TypeParameter[] = TypeParameter[]> extends BaseDecl<Name, Params> {
|
|
9
9
|
kind: NodeKind["TypeAliasDecl"];
|
|
10
10
|
type: Lazy<T>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TypeParameter } from "./TypeParameter.ts";
|
|
2
1
|
import type { Decl } from "./declarations/Decl.ts";
|
|
2
|
+
import type { TypeParameter } from "./TypeParameter.ts";
|
|
3
3
|
import type { Type } from "./types/Type.ts";
|
|
4
4
|
export { Param, TypeParameter } from "./TypeParameter.ts";
|
|
5
5
|
export { type Decl, type DeclP, type IncludableDeclP, type SecondaryDecl, } from "./declarations/Decl.ts";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NodeKind } from "../../../../shared/schema/Node.ts";
|
|
2
|
-
import {
|
|
2
|
+
import type { EntityDecl } from "../declarations/EntityDecl.ts";
|
|
3
3
|
import type { Node } from "../index.ts";
|
|
4
4
|
import type { MemberDecl } from "./ObjectType.ts";
|
|
5
5
|
import type { BaseType } from "./Type.ts";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NodeKind } from "../../../../shared/schema/Node.ts";
|
|
2
2
|
import type { IncludableDeclP, TypeArguments } from "../declarations/Decl.ts";
|
|
3
3
|
import type { EnumDecl } from "../declarations/EnumDecl.ts";
|
|
4
|
-
import {
|
|
4
|
+
import type { TypeAliasDecl } from "../declarations/TypeAliasDecl.ts";
|
|
5
5
|
import type { Node } from "../index.ts";
|
|
6
6
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
7
7
|
import type { EnumCaseDecl } from "./EnumType.ts";
|
|
@@ -4,7 +4,7 @@ import type { EntityDecl } from "../declarations/EntityDecl.ts";
|
|
|
4
4
|
import type { TypeAliasDecl } from "../declarations/TypeAliasDecl.ts";
|
|
5
5
|
import type { Node } from "../index.ts";
|
|
6
6
|
import type { TypeParameter } from "../TypeParameter.ts";
|
|
7
|
-
import {
|
|
7
|
+
import type { IncludeIdentifier } from "./IncludeIdentifierType.ts";
|
|
8
8
|
import type { MemberDecl, ObjectType } from "./ObjectType.ts";
|
|
9
9
|
import type { BaseType } from "./Type.ts";
|
|
10
10
|
type TConstraint = Record<string, MemberDecl>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NodeKind } from "../../../../shared/schema/Node.js";
|
|
2
2
|
import { validateOption } from "../../validation/options.js";
|
|
3
|
-
const keyPattern = /^[a-zA-Z0-9][a-zA-Z0-9_]
|
|
3
|
+
const keyPattern = /^[a-zA-Z0-9][a-zA-Z0-9_]*$/u;
|
|
4
4
|
export const ObjectType = (properties, options = {}) => {
|
|
5
5
|
const type = {
|
|
6
6
|
...options,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type KeyPath } from "../../shared/schema/utils/keyPath.ts";
|
|
2
|
-
import {
|
|
2
|
+
import type { Decl, EntityDecl, EnumDecl, Node, Type, TypeAliasDecl } from "./dsl/index.ts";
|
|
3
3
|
import type { TypeParameter } from "./dsl/TypeParameter.ts";
|
|
4
4
|
import type { ArrayType } from "./dsl/types/ArrayType.ts";
|
|
5
5
|
import type { BooleanType } from "./dsl/types/BooleanType.ts";
|
|
6
|
-
import {
|
|
6
|
+
import type { ChildEntitiesType } from "./dsl/types/ChildEntitiesType.ts";
|
|
7
7
|
import type { DateType } from "./dsl/types/DateType.ts";
|
|
8
8
|
import type { EnumCaseDecl, EnumType } from "./dsl/types/EnumType.ts";
|
|
9
9
|
import type { FloatType } from "./dsl/types/FloatType.ts";
|
|
@@ -13,7 +13,7 @@ import type { NestedEntityMapType } from "./dsl/types/NestedEntityMapType.ts";
|
|
|
13
13
|
import type { MemberDecl, ObjectType } from "./dsl/types/ObjectType.ts";
|
|
14
14
|
import type { ReferenceIdentifierType } from "./dsl/types/ReferenceIdentifierType.ts";
|
|
15
15
|
import type { StringType } from "./dsl/types/StringType.ts";
|
|
16
|
-
import {
|
|
16
|
+
import type { TranslationObjectType } from "./dsl/types/TranslationObjectType.ts";
|
|
17
17
|
import type { TypeArgumentType } from "./dsl/types/TypeArgumentType.ts";
|
|
18
18
|
type KindToTypeMap = {
|
|
19
19
|
ChildEntityDecl: ChildEntitiesType;
|
|
@@ -64,7 +64,7 @@ type MemberDeclsAsType<P extends Record<string, MemberDecl>> = {
|
|
|
64
64
|
type MemberDeclsAsDeepType<P extends Record<string, MemberDecl>> = {
|
|
65
65
|
[K in keyof P]: P[K] extends MemberDecl<Type, true> ? AsDeepType<P[K]["type"]> : AsDeepType<P[K]["type"]> | undefined;
|
|
66
66
|
};
|
|
67
|
-
export type AsDeepType<T extends Type> = T extends ArrayType<infer I> ? AsDeepType<I>[] : T extends ObjectType<infer P> ? MemberDeclsAsDeepType<P> : T extends BooleanType ? boolean : T extends DateType ? Date : T extends FloatType ? number : T extends IntegerType ? number : T extends StringType ? string : T extends TypeArgumentType ? unknown : T extends IncludeIdentifierType<TypeParameter[], infer
|
|
67
|
+
export type AsDeepType<T extends Type> = T extends ArrayType<infer I> ? AsDeepType<I>[] : T extends ObjectType<infer P> ? MemberDeclsAsDeepType<P> : T extends BooleanType ? boolean : T extends DateType ? Date : T extends FloatType ? number : T extends IntegerType ? number : T extends StringType ? string : T extends TypeArgumentType ? unknown : T extends IncludeIdentifierType<TypeParameter[], infer InnerDecl> ? InnerDecl extends TypeAliasDecl<string, infer TA> ? AsDeepType<TA> : InnerDecl extends EnumDecl<string, infer EC> ? AsDeepType<EnumType<EC>> : unknown : T extends NestedEntityMapType<string, infer TC> ? {
|
|
68
68
|
[id: string]: MemberDeclsAsDeepType<TC>;
|
|
69
69
|
} : T extends ReferenceIdentifierType ? string : T extends ChildEntitiesType ? never : T extends EnumType<infer EC> ? EC extends Record<string, EnumCaseDecl> ? {
|
|
70
70
|
[Case in keyof EC]: EnumCaseTypeAsDeepType<Case & string, EC[Case]["type"]>;
|
|
@@ -2,9 +2,6 @@ import { error, ok } from "@elyukai/utils/result";
|
|
|
2
2
|
import { assertExhaustive } from "@elyukai/utils/typeSafety";
|
|
3
3
|
import { NodeKind } from "../../shared/schema/Node.js";
|
|
4
4
|
import { getAtKeyPath, parseKeyPath } from "../../shared/schema/utils/keyPath.js";
|
|
5
|
-
import {} from "./dsl/index.js";
|
|
6
|
-
import {} from "./dsl/types/ChildEntitiesType.js";
|
|
7
|
-
import {} from "./dsl/types/TranslationObjectType.js";
|
|
8
5
|
import { isArrayType, isDecl, isIncludeIdentifierType, isObjectType, isTypeAliasDecl, } from "./guards.js";
|
|
9
6
|
export const isOfKind = (node, kind) => node.kind === kind;
|
|
10
7
|
export const reduceNodes = (reducer, nodes, options = {}) => {
|
|
@@ -118,11 +115,11 @@ export function walkTypeNodeTree(callbackFn, type, parentTypes, parentDecl) {
|
|
|
118
115
|
return assertExhaustive(type);
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
|
-
export const findTypeAtPath = (type, path, options = {}) => getAtKeyPath(type, [], parseKeyPath(path), options.throwOnPathMismatch ?? false,
|
|
122
|
-
? ok(
|
|
123
|
-
: error(previousPath => `Key path "${previousPath}" does not contain an array type.`), (
|
|
124
|
-
if (isObjectType(
|
|
125
|
-
const prop =
|
|
118
|
+
export const findTypeAtPath = (type, path, options = {}) => getAtKeyPath(type, [], parseKeyPath(path), options.throwOnPathMismatch ?? false, innerType => isArrayType(innerType)
|
|
119
|
+
? ok(innerType.items)
|
|
120
|
+
: error(previousPath => `Key path "${previousPath}" does not contain an array type.`), (innerType, name) => {
|
|
121
|
+
if (isObjectType(innerType)) {
|
|
122
|
+
const prop = innerType.properties[name];
|
|
126
123
|
if (prop) {
|
|
127
124
|
return ok(prop.type);
|
|
128
125
|
}
|
|
@@ -136,10 +133,10 @@ export const findTypeAtPath = (type, path, options = {}) => getAtKeyPath(type, [
|
|
|
136
133
|
},
|
|
137
134
|
// recursively resolves type aliases in includes as this is automatically
|
|
138
135
|
// called recursively if needed
|
|
139
|
-
|
|
136
|
+
innerType => isIncludeIdentifierType(innerType) &&
|
|
140
137
|
options.followTypeAliasIncludes &&
|
|
141
|
-
isTypeAliasDecl(
|
|
142
|
-
? ok([
|
|
138
|
+
isTypeAliasDecl(innerType.reference)
|
|
139
|
+
? ok([innerType.reference.type.value, true])
|
|
143
140
|
: error());
|
|
144
141
|
/**
|
|
145
142
|
* Tests whether a type is a child entity type, either directly or through an include.
|