tsondb 0.12.6 → 0.12.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.
@@ -5,5 +5,11 @@ export type TypeScriptRendererOptions = {
5
5
  preserveFiles: boolean;
6
6
  generateEntityMapType: boolean;
7
7
  addIdentifierToEntities: boolean;
8
+ /**
9
+ * Infer translation parameter types from the message strings in a {@link TranslationObjectType TranslationObject} as branded types.
10
+ */
11
+ inferTranslationParameters?: {
12
+ format: "mf2";
13
+ };
8
14
  };
9
15
  export declare const render: (options: Partial<TypeScriptRendererOptions> | undefined, declarations: readonly Decl[]) => string;
@@ -3,6 +3,7 @@ import { dirname, relative } from "node:path";
3
3
  import { discriminatorKey } from "../../../shared/enum.js";
4
4
  import { unique } from "../../../shared/utils/array.js";
5
5
  import { toCamelCase } from "../../../shared/utils/string.js";
6
+ import { extractParameterTypeNamesFromMessage, mapParameterTypeNames, } from "../../../shared/utils/translation.js";
6
7
  import { assertExhaustive } from "../../../shared/utils/typeSafety.js";
7
8
  import { asDecl } from "../../schema/declarations/Declaration.js";
8
9
  import { addEphemeralUUIDToType, createEntityIdentifierTypeAsDecl, isEntityDecl, } from "../../schema/declarations/EntityDecl.js";
@@ -14,7 +15,7 @@ import { getTypeOfKey } from "../../schema/types/generic/TranslationObjectType.j
14
15
  import { isNestedEntityMapType } from "../../schema/types/references/NestedEntityMapType.js";
15
16
  import { ReferenceIdentifierType } from "../../schema/types/references/ReferenceIdentifierType.js";
16
17
  import { ensureSpecialDirStart } from "../../utils/path.js";
17
- import { combineSyntaxes, emptyRenderResult, indent, prefixLines, syntax, } from "../../utils/render.js";
18
+ import { combineSyntaxes, emptyRenderResult, getIndentation, indent, prefixLines, syntax, } from "../../utils/render.js";
18
19
  const defaultOptions = {
19
20
  indentation: 2,
20
21
  objectTypeKeyword: "interface",
@@ -62,8 +63,34 @@ const renderEnumType = (options, type) => combineSyntaxes(Object.entries(type.va
62
63
  ? ""
63
64
  : syntax `${EOL}${caseName}: ${renderType(options, caseDef.type)}`}`)}${EOL}}`)));
64
65
  const renderChildEntitiesType = (options, type) => renderType(options, ArrayType(ReferenceIdentifierType(type.entity), { uniqueItems: true }));
66
+ const mapTypeNameToType = (typeName) => {
67
+ switch (typeName) {
68
+ case "string":
69
+ return "string";
70
+ case "number":
71
+ case "integer":
72
+ return "number";
73
+ case "date":
74
+ case "datetime":
75
+ case "time":
76
+ return "Date";
77
+ case null:
78
+ default:
79
+ return "StringableTranslationParameter";
80
+ }
81
+ };
82
+ const renderTranslationParameterBrand = (options, params) => {
83
+ if (options.inferTranslationParameters === undefined) {
84
+ return emptyRenderResult;
85
+ }
86
+ const entries = Object.entries(params);
87
+ if (entries.length === 0) {
88
+ return emptyRenderResult;
89
+ }
90
+ return syntax ` & { __params: { ${entries.map(([name, type]) => `"${name}": ${type}`).join("; ")} } }`;
91
+ };
65
92
  const renderTranslationObjectType = (options, type) => {
66
- return wrapAsObject(options, combineSyntaxes(Object.entries(type.properties).map(([name, config]) => syntax `"${name.replace('"', '\\"')}"${type.allKeysAreRequired ? "" : "?"}: ${renderType(options, getTypeOfKey(config, type))}`), EOL));
93
+ 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), mapTypeNameToType))}`), EOL));
67
94
  };
68
95
  const renderType = (options, type) => {
69
96
  switch (type.kind) {
@@ -135,6 +162,11 @@ const renderEntityMapType = (options, declarations) => syntax `export type Entit
135
162
  .filter(isEntityDecl)
136
163
  .sort((a, b) => a.name.localeCompare(b.name))
137
164
  .map(decl => syntax `${decl.name}: ${decl.name}`), EOL))}${EOL}}${EOL + EOL}`;
165
+ const renderStringableTranslationParameterType = (options) => options.inferTranslationParameters?.format === "mf2"
166
+ ? "export type StringableTranslationParameter = {\n" +
167
+ prefixLines(getIndentation(options.indentation, 1), "toString(): string") +
168
+ "\n}\n\n"
169
+ : "";
138
170
  export const render = (options = defaultOptions, declarations) => {
139
171
  const finalOptions = { ...defaultOptions, ...options };
140
172
  const [_, entityMap] = finalOptions.generateEntityMapType
@@ -154,6 +186,7 @@ export const render = (options = defaultOptions, declarations) => {
154
186
  return undefined;
155
187
  }, declarations));
156
188
  return (entityMap +
189
+ renderStringableTranslationParameterType(finalOptions) +
157
190
  (finalOptions.preserveFiles
158
191
  ? (declarations[0] === undefined ? "" : renderImports(declarations[0].sourceUrl, imports)) +
159
192
  content
@@ -20,6 +20,13 @@ const checkDuplicateIdentifier = (existingDecls, decl) => {
20
20
  throw new Error(`Duplicate declaration name "${decl.name}" in "${decl.sourceUrl}" and "${existingDeclWithSameName.sourceUrl}". Make sure declaration names are globally unique.`);
21
21
  }
22
22
  };
23
+ // const checkReservedIdentifier = (decl: NestedDecl) => {
24
+ // if (RESERVED_DECLARATION_IDENTIFIER.includes(decl.name)) {
25
+ // throw new Error(
26
+ // `Declaration "${decl.name}" in "${decl.sourceUrl}" uses a reserved identifier name.`,
27
+ // )
28
+ // }
29
+ // }
23
30
  const checkParameterNamesShadowing = (decls) => {
24
31
  for (const decl of decls) {
25
32
  for (const param of getParameterNames(decl)) {
@@ -219,9 +226,10 @@ export const Schema = (declarations, localeEntity) => {
219
226
  debug("collecting nested declarations ...");
220
227
  const allDecls = addDeclarations([], localeEntity ? declarations.concat(localeEntity) : declarations);
221
228
  debug("found %d nested declarations", allDecls.length);
222
- debug("checking for duplicate identifiers ...");
229
+ debug("checking for duplicate identifiers ..."); // debug("checking for duplicate or reserved identifiers ...")
223
230
  allDecls.forEach((decl, declIndex) => {
224
231
  checkDuplicateIdentifier(allDecls.slice(0, declIndex), decl);
232
+ // checkReservedIdentifier(decl)
225
233
  });
226
234
  const allDeclsWithoutNestedEntities = allDecls.filter(decl => decl.kind !== "NestedEntity");
227
235
  debug("checking name shadowing ...");
@@ -1,28 +1,30 @@
1
1
  import { Lazy } from "../../../shared/utils/lazy.ts";
2
- import type { Leaves } from "../../../shared/utils/object.ts";
3
2
  import type { DisplayNameCustomizer } from "../../utils/displayName.ts";
4
- import type { GetNestedDeclarations, GetReferences, Predicate, Serializer, TypeArgumentsResolver, Validator } from "../Node.ts";
3
+ import type { GetNestedDeclarations, GetReferences, Predicate, Serialized, TypeArgumentsResolver, Validator } from "../Node.ts";
5
4
  import { NodeKind } from "../Node.ts";
6
5
  import type { MemberDecl, ObjectType } from "../types/generic/ObjectType.ts";
7
6
  import { StringType } from "../types/primitives/StringType.ts";
8
- import type { AsType } from "../types/Type.ts";
7
+ import type { NestedEntityMapType } from "../types/references/NestedEntityMapType.ts";
9
8
  import type { BaseDecl } from "./Declaration.ts";
10
9
  import { TypeAliasDecl } from "./TypeAliasDecl.ts";
11
10
  export type GenericEntityDisplayName = string | {
12
11
  pathToLocaleMap?: string;
13
12
  pathInLocaleMap?: string;
14
13
  } | null;
15
- export type EntityDisplayName<T extends TConstraint> = Leaves<AsType<ObjectType<T>>> | {
14
+ export type EntityDisplayName<T extends TConstraint> = PathTo<T, StringType> | {
16
15
  /**
17
16
  * @default "translations"
18
17
  */
19
- pathToLocaleMap?: Leaves<AsType<ObjectType<T>>>;
18
+ pathToLocaleMap?: PathTo<T, NestedEntityMapType>;
20
19
  /**
21
20
  * @default "name"
22
21
  */
23
22
  pathInLocaleMap?: string;
24
23
  } | null;
25
24
  type TConstraint = Record<string, MemberDecl>;
25
+ type PathTo<T extends TConstraint, R> = {
26
+ [K in keyof T]: T[K] extends MemberDecl<infer V> ? V extends R ? K : R extends V ? string : T[K] extends ObjectType<infer P> ? `${Extract<K, string>}.${PathTo<P, R>}` : never : never;
27
+ }[Extract<keyof T, string>];
26
28
  export interface EntityDecl<Name extends string = string, T extends TConstraint = TConstraint, FK extends Extract<keyof T, string> | undefined = Extract<keyof T, string> | undefined> extends BaseDecl<Name, []> {
27
29
  kind: NodeKind["EntityDecl"];
28
30
  namePlural: string;
@@ -31,7 +33,7 @@ export interface EntityDecl<Name extends string = string, T extends TConstraint
31
33
  /**
32
34
  * @default "name"
33
35
  */
34
- displayName?: EntityDisplayName<T>;
36
+ displayName?: GenericEntityDisplayName;
35
37
  displayNameCustomizer?: DisplayNameCustomizer<ObjectType<T>>;
36
38
  isDeprecated?: boolean;
37
39
  }
@@ -75,5 +77,5 @@ export declare const addEphemeralUUIDToType: <T extends TConstraint>(decl: Entit
75
77
  }>;
76
78
  export declare const createEntityIdentifierType: () => StringType;
77
79
  export declare const createEntityIdentifierTypeAsDecl: <Name extends string>(decl: EntityDecl<Name>) => TypeAliasDecl<`${Name}_ID`, StringType, []>;
78
- export declare const serializeEntityDecl: Serializer<EntityDecl>;
80
+ export declare const serializeEntityDecl: <Name extends string, T extends TConstraint, FK extends Extract<keyof T, string> | undefined>(type: EntityDecl<Name, T, FK>) => Serialized<EntityDecl<Name, T, FK>>;
79
81
  export declare const getReferencesForEntityDecl: GetReferences<EntityDecl>;
@@ -49,12 +49,12 @@ export const createEntityIdentifierTypeAsDecl = (decl) => TypeAliasDecl(decl.sou
49
49
  name: (decl.name + "_ID"),
50
50
  type: createEntityIdentifierType,
51
51
  });
52
- export const serializeEntityDecl = (type) => ({
52
+ export const serializeEntityDecl = ((type) => ({
53
53
  ...type,
54
54
  type: serializeObjectType(type.type.value),
55
55
  displayName: typeof type.displayName === "function"
56
56
  ? null
57
57
  : type.displayName,
58
58
  displayNameCustomizer: type.displayNameCustomizer !== undefined,
59
- });
59
+ }));
60
60
  export const getReferencesForEntityDecl = (decl, value, inDecl) => getReferencesForObjectType(decl.type.value, value, [...inDecl, decl]);
@@ -1,3 +1,4 @@
1
+ import { type EnumValue } from "../../../shared/schema/declarations/EnumDecl.ts";
1
2
  import { Lazy } from "../../../shared/utils/lazy.ts";
2
3
  import type { GetNestedDeclarations, GetReferences, Predicate, Serializer, TypeArgumentsResolver, ValidatorOfParamDecl } from "../Node.ts";
3
4
  import { NodeKind } from "../Node.ts";
@@ -33,3 +34,4 @@ export declare const resolveTypeArgumentsInEnumDecl: TypeArgumentsResolver<EnumD
33
34
  export declare const serializeEnumDecl: Serializer<EnumDecl>;
34
35
  export declare const getReferencesForEnumDecl: GetReferences<EnumDecl>;
35
36
  export declare const cases: <T extends TConstraint>(decl: EnumDecl<string, T>) => EnumCaseDecl<T[keyof T]["type"]>[];
37
+ export declare const getAnyEnumCaseValue: <K extends string, V>(enumValue: { [Key in K]: EnumValue<Key, V>; }[K]) => V;
@@ -1,3 +1,4 @@
1
+ import { ENUM_DISCRIMINATOR_KEY, } from "../../../shared/schema/declarations/EnumDecl.js";
1
2
  import { Lazy } from "../../../shared/utils/lazy.js";
2
3
  import { onlyKeys } from "../../../shared/utils/object.js";
3
4
  import { NodeKind } from "../Node.js";
@@ -46,3 +47,4 @@ export const serializeEnumDecl = decl => ({
46
47
  });
47
48
  export const getReferencesForEnumDecl = (decl, value, inDecl) => getReferencesForEnumType(decl.type.value, value, [...inDecl, decl]);
48
49
  export const cases = (decl) => Object.values(decl.type.value.values);
50
+ export const getAnyEnumCaseValue = (enumValue) => enumValue[enumValue[ENUM_DISCRIMINATOR_KEY]];
@@ -25,14 +25,28 @@ type EnumCaseTypeAsType<Case extends string, T extends Type | null> = T extends
25
25
  } : {
26
26
  kind: Case;
27
27
  };
28
- export type AsDeepType<T extends Type> = T extends ArrayType<infer I> ? AsType<I>[] : T extends ObjectType<infer P> ? {
28
+ type EnumCaseTypeAsDeepType<Case extends string, T extends Type | null> = T extends object ? {
29
+ kind: Case;
30
+ } & {
31
+ [AV in Case]: AsDeepType<T>;
32
+ } : {
33
+ kind: Case;
34
+ };
35
+ type MemberDeclsAsType<P extends Record<string, MemberDecl>> = {
29
36
  [K in keyof P]: P[K] extends MemberDecl<Type, true> ? AsType<P[K]["type"]> : AsType<P[K]["type"]> | undefined;
30
- } : 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 Decl> ? Decl extends TypeAliasDecl<string, infer TA> ? AsType<TA> : Decl extends EnumDecl<string, infer EC> ? AsType<EnumType<EC>> : unknown : T extends NestedEntityMapType ? unknown : T extends ReferenceIdentifierType ? string : T extends ChildEntitiesType ? string[] : T extends EnumType<infer EC> ? EC extends Record<string, EnumCaseDecl> ? {
31
- [Case in keyof EC]: EnumCaseTypeAsType<Case & string, EC[Case]["type"]>;
37
+ };
38
+ type MemberDeclsAsDeepType<P extends Record<string, MemberDecl>> = {
39
+ [K in keyof P]: P[K] extends MemberDecl<Type, true> ? AsDeepType<P[K]["type"]> : // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- it does make a difference here
40
+ AsDeepType<P[K]["type"]> | undefined;
41
+ };
42
+ 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 Decl> ? Decl extends TypeAliasDecl<string, infer TA> ? AsDeepType<TA> : Decl extends EnumDecl<string, infer EC> ? AsDeepType<EnumType<EC>> : unknown : T extends NestedEntityMapType<string, infer TC> ? {
43
+ [id: string]: MemberDeclsAsDeepType<TC>;
44
+ } : T extends ReferenceIdentifierType ? string : T extends ChildEntitiesType ? never : T extends EnumType<infer EC> ? EC extends Record<string, EnumCaseDecl> ? {
45
+ [Case in keyof EC]: EnumCaseTypeAsDeepType<Case & string, EC[Case]["type"]>;
32
46
  }[keyof EC] : never : never;
33
- export type AsType<T extends Type> = T extends ArrayType<infer I> ? AsType<I>[] : T extends ObjectType<infer P> ? {
34
- [K in keyof P]: P[K] extends MemberDecl<Type, true> ? AsType<P[K]["type"]> : AsType<P[K]["type"]> | undefined;
35
- } : 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 ? unknown : T extends NestedEntityMapType ? unknown : T extends ReferenceIdentifierType ? string : T extends ChildEntitiesType ? string[] : T extends EnumType<infer EC> ? EC extends Record<string, EnumCaseDecl> ? {
47
+ export type AsType<T extends Type> = T extends ArrayType<infer I> ? AsType<I>[] : T extends ObjectType<infer P> ? MemberDeclsAsType<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 ? unknown : T extends NestedEntityMapType<string, infer TC> ? {
48
+ [id: string]: MemberDeclsAsType<TC>;
49
+ } : T extends ReferenceIdentifierType ? string : T extends ChildEntitiesType ? string[] : T extends EnumType<infer EC> ? EC extends Record<string, EnumCaseDecl> ? {
36
50
  [Case in keyof EC]: EnumCaseTypeAsType<Case & string, EC[Case]["type"]>;
37
51
  }[keyof EC] : never : never;
38
52
  export type AsNode<T> = T extends (infer I)[] ? ArrayType<AsNode<I>> : T extends Record<string, unknown> ? ObjectType<{
@@ -4,6 +4,7 @@ export const getDisplayNameFromEntityInstance = (entity, instanceContainer, getI
4
4
  if (useCustomizer && entity.displayNameCustomizer) {
5
5
  const calculatedName = getDisplayNameFromEntityInstance(entity, instanceContainer, getInstanceById, getChildInstancesForInstanceId, locales, defaultName, false);
6
6
  return entity.displayNameCustomizer({
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment -- otherwise type instiatiation too deep
7
8
  instance: instanceContainer.content,
8
9
  instanceId: instanceContainer.id,
9
10
  instanceDisplayName: calculatedName.name,
@@ -7,4 +7,5 @@ export type RenderResult = [imports: {
7
7
  export declare const emptyRenderResult: RenderResult;
8
8
  export declare const combineSyntaxes: (syntaxes: (RenderResult | string | undefined)[], separator?: string) => RenderResult;
9
9
  export declare const syntax: (strings: TemplateStringsArray, ...values: (RenderResult | string | undefined)[]) => RenderResult;
10
+ export declare const getIndentation: (spaces: number, indentLevel: number) => string;
10
11
  export declare const indent: (spaces: number, indentLevel: number, text: RenderResult) => RenderResult;
@@ -28,7 +28,8 @@ export const syntax = (strings, ...values) => strings.reduce((acc, str, i) => {
28
28
  return [acc[0], acc[1] + str.replace(/\n/g, EOL)];
29
29
  }
30
30
  }, emptyRenderResult);
31
+ export const getIndentation = (spaces, indentLevel) => " ".repeat(spaces * indentLevel);
31
32
  export const indent = (spaces, indentLevel, text) => [
32
33
  text[0],
33
- prefixLines(" ".repeat(spaces * indentLevel), text[1]),
34
+ prefixLines(getIndentation(spaces, indentLevel), text[1]),
34
35
  ];
@@ -1,20 +1,24 @@
1
- import type { Leaves } from "../../../shared/utils/object.ts";
1
+ import type { GenericEntityDisplayName } from "../../../node/schema/index.ts";
2
2
  import { NodeKind, type GetReferencesSerialized, type SerializedNode, type SerializedTypeArgumentsResolver } from "../Node.ts";
3
+ import type { SerializedNestedEntityMapType } from "../types/NestedEntityMapType.ts";
3
4
  import { type SerializedMemberDecl, type SerializedObjectType } from "../types/ObjectType.ts";
4
- import type { SerializedAsType } from "../types/Type.ts";
5
+ import type { SerializedStringType } from "../types/StringType.ts";
5
6
  import type { SerializedBaseDecl } from "./Declaration.ts";
6
- export type SerializedEntityDisplayName<T extends SerializedObjectType> = Leaves<SerializedAsType<T>> | {
7
+ export type SerializedEntityDisplayName<T extends TSerializedConstraint> = SerializedPathTo<T, SerializedStringType> | {
7
8
  /**
8
9
  * @default "translations"
9
10
  */
10
- pathToLocaleMap?: Leaves<SerializedAsType<T>>;
11
+ pathToLocaleMap?: SerializedPathTo<T, SerializedNestedEntityMapType>;
11
12
  /**
12
13
  * @default "name"
13
14
  */
14
15
  pathInLocaleMap?: string;
15
16
  } | null;
16
- type TConstraint = Record<string, SerializedMemberDecl>;
17
- export interface SerializedEntityDecl<Name extends string = string, T extends TConstraint = TConstraint, FK extends Extract<keyof T, string> | undefined = Extract<keyof T, string> | undefined> extends SerializedBaseDecl<Name, []> {
17
+ type TSerializedConstraint = Record<string, SerializedMemberDecl>;
18
+ type SerializedPathTo<T extends TSerializedConstraint, R> = {
19
+ [K in keyof T]: T[K] extends SerializedMemberDecl<infer V> ? V extends R ? K : R extends V ? string : T[K] extends SerializedObjectType<infer P> ? `${Extract<K, string>}.${SerializedPathTo<P, R>}` : never : never;
20
+ }[Extract<keyof T, string>];
21
+ export interface SerializedEntityDecl<Name extends string = string, T extends TSerializedConstraint = TSerializedConstraint, FK extends Extract<keyof T, string> | undefined = Extract<keyof T, string> | undefined> extends SerializedBaseDecl<Name, []> {
18
22
  kind: NodeKind["EntityDecl"];
19
23
  namePlural: string;
20
24
  type: SerializedObjectType<T>;
@@ -22,13 +26,13 @@ export interface SerializedEntityDecl<Name extends string = string, T extends TC
22
26
  /**
23
27
  * @default "name"
24
28
  */
25
- displayName?: SerializedEntityDisplayName<SerializedObjectType<T>>;
29
+ displayName?: GenericEntityDisplayName;
26
30
  displayNameCustomizer: boolean;
27
31
  isDeprecated?: boolean;
28
32
  }
29
33
  export declare const isSerializedEntityDecl: (node: SerializedNode) => node is SerializedEntityDecl;
30
- export declare const isSerializedEntityDeclWithParentReference: <Name extends string, T extends TConstraint, FK extends Extract<keyof T, string> | undefined>(decl: SerializedEntityDecl<Name, T, FK>) => decl is SerializedEntityDecl<Name, T, NonNullable<FK>>;
31
- export declare const isSerializedEntityDeclWithoutParentReference: <Name extends string, T extends TConstraint>(decl: SerializedEntityDecl<Name, T>) => decl is SerializedEntityDecl<Name, T, undefined>;
34
+ export declare const isSerializedEntityDeclWithParentReference: <Name extends string, T extends TSerializedConstraint, FK extends Extract<keyof T, string> | undefined>(decl: SerializedEntityDecl<Name, T, FK>) => decl is SerializedEntityDecl<Name, T, NonNullable<FK>>;
35
+ export declare const isSerializedEntityDeclWithoutParentReference: <Name extends string, T extends TSerializedConstraint>(decl: SerializedEntityDecl<Name, T>) => decl is SerializedEntityDecl<Name, T, undefined>;
32
36
  export declare const resolveTypeArgumentsInSerializedEntityDecl: SerializedTypeArgumentsResolver<SerializedEntityDecl>;
33
37
  export declare const getReferencesForSerializedEntityDecl: GetReferencesSerialized<SerializedEntityDecl>;
34
38
  export {};
@@ -2,7 +2,7 @@ export declare const sortObjectKeys: (obj: Record<string, unknown>, keys: string
2
2
  export declare const sortObjectKeysAlphabetically: (obj: Record<string, unknown>) => Record<string, unknown>;
3
3
  export declare const mergeObjects: <T>(obj1: Record<string, T>, obj2: Record<string, T>, solveConflict: (a: T, b: T) => T) => Record<string, T>;
4
4
  export type Leaves<T> = T extends object ? {
5
- [K in keyof T]: T[K] extends unknown[] ? never : `${Exclude<K, symbol>}${Leaves<T[K]> extends never ? "" : `.${Leaves<T[K]>}`}`;
5
+ [K in keyof T]: T[K] extends unknown[] ? never : `${Extract<K, string>}${Leaves<T[K]> extends never ? "" : `.${Leaves<T[K]>}`}`;
6
6
  }[keyof T] : never;
7
7
  export declare const onlyKeys: <T extends object, K extends keyof T>(obj: T, ...keys: K[]) => Pick<T, K>;
8
8
  export declare const hasKey: <T extends object, K extends PropertyKey>(obj: T, key: K) => obj is T & { [k in K]: unknown; };
@@ -0,0 +1,2 @@
1
+ export declare const extractParameterTypeNamesFromMessage: (message: string) => Record<string, string | null>;
2
+ export declare const mapParameterTypeNames: <T>(typeMap: Record<string, string | null>, map: (typeName: string | null) => T) => Record<string, T>;
@@ -0,0 +1,66 @@
1
+ import { MessageError, parseMessage } from "messageformat";
2
+ import { assertExhaustive } from "./typeSafety.js";
3
+ const mergeAssoc = (acc, key, value) => {
4
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- if there is a previous value and the current result is null, keep the more specific one
5
+ return { ...acc, [key]: value ?? acc[key] };
6
+ };
7
+ const reduceMapAssoc = (map, acc, item) => {
8
+ const result = map(item);
9
+ if (result) {
10
+ return mergeAssoc(acc, result[0], result[1]);
11
+ }
12
+ return acc;
13
+ };
14
+ const reduceADT = (cases, acc, item) => {
15
+ const caseFn = cases[item.type];
16
+ return caseFn?.(acc, item) ?? acc;
17
+ };
18
+ const extractParameterFromDeclaration = (decl) => {
19
+ switch (decl.type) {
20
+ case "input":
21
+ return [decl.name, decl.value.functionRef?.name ?? null];
22
+ case "local":
23
+ return undefined;
24
+ default:
25
+ return assertExhaustive(decl);
26
+ }
27
+ };
28
+ const extractParametersFromDeclarations = (decls) => decls.reduce((acc, decl) => reduceMapAssoc(extractParameterFromDeclaration, acc, decl), {});
29
+ const reduceParametersFromPattern = (acc, pattern) => pattern.reduce((acc, element) => {
30
+ if (typeof element === "string") {
31
+ return acc;
32
+ }
33
+ return reduceADT({
34
+ expression: (acc, element) => {
35
+ if (!element.arg) {
36
+ return acc;
37
+ }
38
+ return reduceADT({
39
+ variable: (acc, variable) => mergeAssoc(acc, variable.name, element.functionRef?.name ?? null),
40
+ }, acc, element.arg);
41
+ },
42
+ }, acc, element);
43
+ }, acc);
44
+ export const extractParameterTypeNamesFromMessage = (message) => {
45
+ try {
46
+ const dataModel = parseMessage(message);
47
+ switch (dataModel.type) {
48
+ case "message":
49
+ return reduceParametersFromPattern(extractParametersFromDeclarations(dataModel.declarations), dataModel.pattern);
50
+ case "select": {
51
+ return dataModel.selectors.reduce((acc, variable) => mergeAssoc(acc, variable.name, null), dataModel.variants.reduce((acc, variant) => reduceParametersFromPattern(acc, variant.value), extractParametersFromDeclarations(dataModel.declarations)));
52
+ }
53
+ default:
54
+ return assertExhaustive(dataModel);
55
+ }
56
+ }
57
+ catch (error) {
58
+ if (error instanceof MessageError) {
59
+ throw new MessageError(error.message, message);
60
+ }
61
+ else {
62
+ throw error;
63
+ }
64
+ }
65
+ };
66
+ export const mapParameterTypeNames = (typeMap, map) => Object.fromEntries(Object.entries(typeMap).map(([key, typeName]) => [key, map(typeName)]));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsondb",
3
- "version": "0.12.6",
3
+ "version": "0.12.8",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "Lukas Obermann",
@@ -50,6 +50,7 @@
50
50
  "@preact/signals": "^2.5.1",
51
51
  "debug": "^4.4.3",
52
52
  "express": "^5.1.0",
53
+ "messageformat": "^4.0.0",
53
54
  "preact": "^10.27.2",
54
55
  "preact-iso": "^2.11.0",
55
56
  "simple-cli-args": "^0.1.3",