rotorise 0.1.12 → 0.1.13
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.
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"char": 56
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
"count":
|
|
54
|
+
"count": 2133
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"location": {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"char": 56
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"count":
|
|
67
|
+
"count": 4930
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"location": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"char": 57
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
|
-
"count":
|
|
80
|
+
"count": 12160
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"location": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"char": 56
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
"count":
|
|
93
|
+
"count": 1816
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
"location": {
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"char": 57
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
|
-
"count":
|
|
106
|
+
"count": 66031
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
"location": {
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"char": 57
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
|
-
"count":
|
|
119
|
+
"count": 52491
|
|
120
120
|
}
|
|
121
121
|
]
|
|
122
122
|
}
|
package/dist/Rotorise.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Rotorise.ts"],"sourcesContent":["import type {\n DistributiveOmit,\n DistributivePick,\n Exact,\n NonEmptyArray,\n Replace,\n SliceFromStart,\n UnionToObject,\n ValueOf,\n evaluate,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity extends Record<string, unknown>,\n InputSpec extends InputSpecShape,\n skip extends number = 1,\n> = Entity extends unknown\n ? evaluate<\n Pick<\n Entity,\n extractHeadOrPass<\n SliceFromStart<\n InputSpec,\n number extends skip ? 1 : skip\n >[number]\n > &\n keyof Entity\n > &\n Partial<\n Pick<\n Entity,\n extractHeadOrPass<InputSpec[number]> & keyof Entity\n >\n >\n >\n : never\n\nexport type CompositeKeyParams<\n Entity extends Record<string, unknown>,\n FullSpec extends InputSpec<Entity>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = Entity extends unknown\n ? Join<\n CompositeKeyRec<\n Entity,\n number extends Deep ? Spec : SliceFromStart<Spec, Deep>\n >,\n Separator,\n (boolean extends isPartial ? false : isPartial) extends false\n ? false\n : true\n >\n : never\n\nexport type CompositeKeyBuilder<\n Entity extends Record<string, unknown>,\n Spec extends InputSpec<Entity>[],\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>\n\ntype joinable = string | number | bigint | boolean | null | undefined\ntype joinablePair = [joinable, joinable]\n\ntype Join<\n Pairs,\n Separator extends string,\n KeepIntermediate extends boolean = false,\n Acc extends string = '',\n AllAcc extends string = never,\n> = Pairs extends [infer Head extends joinablePair, ...infer Tail]\n ? Join<\n Tail,\n Separator,\n KeepIntermediate,\n Acc extends ''\n ? `${Head[0]}${Separator}${Head[1]}`\n : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`,\n KeepIntermediate extends true\n ? AllAcc | (Acc extends '' ? never : Acc)\n : never\n >\n : AllAcc | Acc\n\ntype ExtractPair<Entity extends Record<string, unknown>, Spec> = Spec extends [\n infer Key extends string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n (...key: any[]) => infer Value extends joinable,\n]\n ? [Uppercase<Key>, Value]\n : Spec extends keyof Entity & string\n ? [Uppercase<Spec>, Entity[Spec] & joinable]\n : never\n\ntype CompositeKeyRec<\n Entity extends Record<string, unknown>,\n Spec,\n Acc extends joinablePair[] = [],\n KeysCache extends string = keyof Entity & string,\n> = Spec extends [infer Head, ...infer Tail]\n ? CompositeKeyRec<\n Entity,\n Tail,\n [...Acc, ExtractPair<Entity, Head>],\n KeysCache\n >\n : Acc\n\ntype DiscriminatedSchemaShape = {\n discriminator: PropertyKey\n spec: {\n [k in PropertyKey]: unknown\n }\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\ntype InputSpecShape = ([string, (key: any) => unknown] | string)[]\n\ntype TableEntryImpl<\n Entity extends Record<string, unknown>,\n Schema,\n Separator extends string = '#',\n> = Entity extends unknown\n ? {\n [Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape\n ? ValueOf<{\n [K in Schema[Key]['discriminator']]: {\n [V in keyof Schema[Key]['spec']]: ProcessKey<\n Entity,\n Schema[Key]['spec'][V],\n Separator\n >\n }[Entity[K & keyof Entity] & keyof Schema[Key]['spec']]\n }>\n : ProcessKey<Entity, Schema[Key], Separator>\n } & Entity\n : never\n\nexport type TableEntry<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n> = TableEntryImpl<Entity, Schema, Separator>\n\ntype InputSpec<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]:\n | [key, (key: E[key]) => unknown]\n | (undefined extends E[key] ? never : null extends E[key] ? never : key)\n}[keyof E]\n\ntype extractHeadOrPass<T> = T extends unknown[] ? T[0] : T\n\ntype FullKeySpecSimple<Entity extends Record<string, unknown>> =\n | NonEmptyArray<InputSpec<Entity>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]: E[key] extends PropertyKey\n ? {\n discriminator: key\n spec: {\n [val in E[key]]: FullKeySpecSimple<\n Extract<\n Entity,\n {\n [k in key]: val\n }\n >\n >\n }\n }\n : never\n}[keyof E]\n\ntype FullKeySpec<Entity extends Record<string, unknown>> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity>\n\ntype FullKeySpecShape = FullKeySpecSimpleShape | DiscriminatedSchemaShape\n\nconst chainableNoOpProxy: unknown = new Proxy(() => chainableNoOpProxy, {\n get: () => chainableNoOpProxy,\n})\n\nconst createPathProxy = <T>(path = ''): T => {\n return new Proxy(() => {}, {\n get: (target, prop) => {\n if (typeof prop === 'string') {\n if (prop === 'toString') {\n return () => path\n }\n\n return createPathProxy(\n path === ''\n ? prop\n : !Number.isNaN(Number.parseInt(prop))\n ? `${path}[${prop}]`\n : `${path}.${prop}`,\n )\n }\n },\n }) as T\n}\n\nconst key =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <\n const Key extends keyof Schema,\n const Config extends { depth?: number; allowPartial?: boolean },\n const Attributes extends Partial<Entity>,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ): string | undefined => {\n const case_ = schema[key]\n\n if (case_ === undefined) {\n throw new Error(`Key ${key.toString()} not found in schema`)\n }\n let structure: InputSpec<Entity>[]\n\n if (Array.isArray(case_)) {\n structure = case_\n } else if (typeof case_ === 'object') {\n const discriminator =\n attributes[case_.discriminator as keyof Attributes]\n if (discriminator === undefined) {\n throw new Error(\n `Discriminator ${case_.discriminator.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n const val = case_.spec[discriminator as keyof typeof case_.spec]\n if (val === undefined) {\n throw new Error(\n `Discriminator value ${discriminator?.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n if (val === null) {\n return undefined\n }\n\n if (!Array.isArray(val)) {\n return attributes[val as keyof Attributes] as never\n }\n\n structure = val\n } else {\n const value = attributes[case_ as keyof Attributes]\n if (value == null) return undefined as never\n\n return value as never\n }\n\n if (config?.depth !== undefined) {\n structure = structure.slice(0, config.depth) as never\n }\n const composite: string[] = []\n\n for (const keySpec of structure) {\n const [key, transform] = Array.isArray(keySpec)\n ? keySpec\n : [keySpec]\n\n const value = attributes[key as keyof Attributes]\n if (\n (value !== undefined && value !== null && value !== '') ||\n transform\n ) {\n composite.push(key.toString().toUpperCase())\n composite.push(\n `${transform ? transform(value as never) : value}`,\n )\n } else if (config?.allowPartial) {\n break\n } else {\n throw new Error(\n `buildCompositeKey: Attribute ${key.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n }\n\n return composite.join(separator) as never\n }\n\nconst toEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <const ExactEntity extends Entity>(\n item: ExactEntity,\n ): ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never => {\n const entry = { ...item }\n\n for (const key_ in schema) {\n const val = key<Entity>()(schema, separator)(key_, item)\n if (val !== undefined) {\n entry[key_] = val satisfies string as never\n }\n }\n // console.log({ entry })\n return entry as never\n }\n\nconst fromEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpecShape>,\n Separator extends string = '#',\n >(\n schema: Schema,\n ) =>\n <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ): DistributiveOmit<Entry, keyof Schema> => {\n const item = { ...entry }\n\n for (const key_ in schema) {\n delete item[key_]\n }\n // console.log({ item })\n return item as never\n }\n\ntype ProcessSpecType<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends string\n ? DistributivePick<Entity, Spec>\n : Spec extends InputSpecShape\n ? CompositeKeyParamsImpl<\n Entity,\n Spec,\n Config['allowPartial'] extends true\n ? 1\n : Extract<Config['depth'], number>\n >\n : never\n\n// Cache commonly used conditional types\ntype SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape\n\ntype SpecConfigShape = {\n depth?: number\n allowPartial?: boolean\n}\n\n// Pre-compute discriminated variant types\ntype VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [\n Entity,\n] extends [never]\n ? { [k in K]: V }\n : Entity & { [k in K]: V }\n\n// Flatten nested type computation\ntype ProcessVariant<\n Entity extends Record<string, unknown>,\n K extends PropertyKey,\n V extends PropertyKey,\n Spec extends DiscriminatedSchemaShape,\n Config extends SpecConfigShape,\n> = VariantType<\n ProcessSpecType<\n VariantType<Entity, K, V>,\n Spec['spec'][V & keyof Spec['spec']],\n Config\n >,\n K,\n V\n>\n\n// Optimized attribute processing\ntype OptimizedAttributes<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessVariant<\n Entity,\n K,\n V,\n Spec,\n Config\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessSpecType<Entity, Spec, Config>\n\ntype ProcessKey<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n NullAs extends never | undefined = never,\n Config extends SpecConfigShape = SpecConfigShape,\n Attributes = Pick<Entity, Spec & keyof Entity>,\n> = Spec extends keyof Entity\n ? Replace<ValueOf<Attributes>, null, undefined>\n : Spec extends InputSpecShape\n ? CompositeKeyBuilderImpl<\n Entity,\n Spec,\n Separator,\n Exclude<Config['depth'], undefined>,\n Exclude<Config['allowPartial'], undefined>\n >\n : Spec extends null\n ? NullAs\n : never\n\ntype OptimizedBuildedKey<\n NarrowEntity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n Config extends SpecConfigShape,\n Attributes,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessKey<\n NarrowEntity,\n Spec['spec'][V],\n Separator,\n undefined,\n Config,\n Attributes\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>\n\ntype TableEntryDefinition<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpecShape>,\n Separator extends string,\n> = {\n toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(\n item: ExactEntity,\n ) => ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never\n fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ) => DistributiveOmit<Entry, keyof Schema>\n key: <\n const Key extends keyof Schema,\n const Config extends SpecConfig<Spec>,\n const Attributes extends OptimizedAttributes<Entity, Spec, Config_>,\n Spec = Schema[Key],\n Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] // exclude undefined param\n ? { depth?: undefined; allowPartial?: undefined }\n : Config,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ) => OptimizedBuildedKey<\n Entity & Attributes,\n Spec,\n Separator,\n Config_,\n Attributes\n >\n infer: TableEntryImpl<Entity, Schema, Separator>\n path: () => TableEntryImpl<Entity, Schema, Separator>\n}\n\nexport const tableEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ): TableEntryDefinition<Entity, Schema, Separator> => {\n return {\n toEntry: toEntry()(schema as never, separator) as never,\n fromEntry: fromEntry()(schema as never) as never,\n key: key()(schema as never, separator) as never,\n infer: chainableNoOpProxy as never,\n path: () => createPathProxy() as never,\n }\n }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsMA,IAAM,qBAA8B,IAAI,MAAM,MAAM,oBAAoB;AAAA,EACpE,KAAK,MAAM;AACf,CAAC;AAED,IAAM,kBAAkB,CAAI,OAAO,OAAU;AACzC,SAAO,IAAI,MAAM,MAAM;AAAA,EAAC,GAAG;AAAA,IACvB,KAAK,CAAC,QAAQ,SAAS;AACnB,UAAI,OAAO,SAAS,UAAU;AAC1B,YAAI,SAAS,YAAY;AACrB,iBAAO,MAAM;AAAA,QACjB;AAEA,eAAO;AAAA,UACH,SAAS,KACH,OACA,CAAC,OAAO,MAAM,OAAO,SAAS,IAAI,CAAC,IACjC,GAAG,IAAI,IAAI,IAAI,MACf,GAAG,IAAI,IAAI,IAAI;AAAA,QAC3B;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAC;AACL;AAEA,IAAM,MACF,MACA,CAcI,QACA,YAAuB,QAE3B,CAKIA,MACA,YACA,WACqB;AACrB,QAAM,QAAQ,OAAOA,IAAG;AAExB,MAAI,UAAU,QAAW;AACrB,UAAM,IAAI,MAAM,OAAOA,KAAI,SAAS,CAAC,sBAAsB;AAAA,EAC/D;AACA,MAAI;AAEJ,MAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,gBAAY;AAAA,EAChB,WAAW,OAAO,UAAU,UAAU;AAClC,UAAM,gBACF,WAAW,MAAM,aAAiC;AACtD,QAAI,kBAAkB,QAAW;AAC7B,YAAM,IAAI;AAAA,QACN,iBAAiB,MAAM,cAAc,SAAS,CAAC,iBAAiB,KAAK,UAAU,UAAU,CAAC;AAAA,MAC9F;AAAA,IACJ;AACA,UAAM,MAAM,MAAM,KAAK,aAAwC;AAC/D,QAAI,QAAQ,QAAW;AACnB,YAAM,IAAI;AAAA,QACN,uBAAuB,eAAe,SAAS,CAAC,iBAAiB,KAAK,UAAU,UAAU,CAAC;AAAA,MAC/F;AAAA,IACJ;AACA,QAAI,QAAQ,MAAM;AACd,aAAO;AAAA,IACX;AAEA,QAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACrB,aAAO,WAAW,GAAuB;AAAA,IAC7C;AAEA,gBAAY;AAAA,EAChB,OAAO;AACH,UAAM,QAAQ,WAAW,KAAyB;AAClD,QAAI,SAAS,KAAM,QAAO;AAE1B,WAAO;AAAA,EACX;AAEA,MAAI,QAAQ,UAAU,QAAW;AAC7B,gBAAY,UAAU,MAAM,GAAG,OAAO,KAAK;AAAA,EAC/C;AACA,QAAM,YAAsB,CAAC;AAE7B,aAAW,WAAW,WAAW;AAC7B,UAAM,CAACA,MAAK,SAAS,IAAI,MAAM,QAAQ,OAAO,IACxC,UACA,CAAC,OAAO;AAEd,UAAM,QAAQ,WAAWA,IAAuB;AAChD,QACK,UAAU,UAAa,UAAU,QAAQ,UAAU,MACpD,WACF;AACE,gBAAU,KAAKA,KAAI,SAAS,EAAE,YAAY,CAAC;AAC3C,gBAAU;AAAA,QACN,GAAG,YAAY,UAAU,KAAc,IAAI,KAAK;AAAA,MACpD;AAAA,IACJ,WAAW,QAAQ,cAAc;AAC7B;AAAA,IACJ,OAAO;AACH,YAAM,IAAI;AAAA,QACN,gCAAgCA,KAAI,SAAS,CAAC,iBAAiB,KAAK,UAAU,UAAU,CAAC;AAAA,MAC7F;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,UAAU,KAAK,SAAS;AACnC;AAEJ,IAAM,UACF,MACA,CAcI,QACA,YAAuB,QAE3B,CACI,SAGW;AACX,QAAM,QAAQ,EAAE,GAAG,KAAK;AAExB,aAAW,QAAQ,QAAQ;AACvB,UAAM,MAAM,IAAY,EAAE,QAAQ,SAAS,EAAE,MAAM,IAAI;AACvD,QAAI,QAAQ,QAAW;AACnB,YAAM,IAAI,IAAI;AAAA,IAClB;AAAA,EACJ;AAEA,SAAO;AACX;AAEJ,IAAM,YACF,MACA,CAII,WAEJ,CACI,UACwC;AACxC,QAAM,OAAO,EAAE,GAAG,MAAM;AAExB,aAAW,QAAQ,QAAQ;AACvB,WAAO,KAAK,IAAI;AAAA,EACpB;AAEA,SAAO;AACX;AAmJG,IAAM,aACT,MACA,CAII,QACA,YAAuB,QAC2B;AAClD,SAAO;AAAA,IACH,SAAS,QAAQ,EAAE,QAAiB,SAAS;AAAA,IAC7C,WAAW,UAAU,EAAE,MAAe;AAAA,IACtC,KAAK,IAAI,EAAE,QAAiB,SAAS;AAAA,IACrC,OAAO;AAAA,IACP,MAAM,MAAM,gBAAgB;AAAA,EAChC;AACJ;","names":["key"]}
|
|
1
|
+
{"version":3,"sources":["../src/Rotorise.ts"],"sourcesContent":["import type {\n DistributiveOmit,\n DistributivePick,\n Exact,\n NonEmptyArray,\n Replace,\n SliceFromStart,\n UnionToObject,\n ValueOf,\n evaluate,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity extends Record<string, unknown>,\n InputSpec extends InputSpecShape,\n skip extends number = 1,\n> = Entity extends unknown\n ? evaluate<\n Pick<\n Entity,\n extractHeadOrPass<\n SliceFromStart<\n InputSpec,\n number extends skip ? 1 : skip\n >[number]\n > &\n keyof Entity\n > &\n Partial<\n Pick<\n Entity,\n extractHeadOrPass<InputSpec[number]> & keyof Entity\n >\n >\n >\n : never\n\nexport type CompositeKeyParams<\n Entity extends Record<string, unknown>,\n FullSpec extends InputSpec<Entity>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = Entity extends unknown\n ? Join<\n CompositeKeyRec<\n Entity,\n number extends Deep ? Spec : SliceFromStart<Spec, Deep>\n >,\n Separator,\n (boolean extends isPartial ? false : isPartial) extends false\n ? false\n : true\n >\n : never\n\nexport type CompositeKeyBuilder<\n Entity extends Record<string, unknown>,\n Spec extends InputSpec<Entity>[],\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>\n\ntype joinable = string | number | bigint | boolean | null | undefined\ntype joinablePair = [joinable, joinable]\n\ntype Join<\n Pairs,\n Separator extends string,\n KeepIntermediate extends boolean = false,\n Acc extends string = '',\n AllAcc extends string = never,\n> = Pairs extends [infer Head extends joinablePair, ...infer Tail]\n ? Join<\n Tail,\n Separator,\n KeepIntermediate,\n Acc extends ''\n ? `${Head[0]}${Separator}${Head[1]}`\n : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`,\n KeepIntermediate extends true\n ? AllAcc | (Acc extends '' ? never : Acc)\n : never\n >\n : AllAcc | Acc\n\ntype ExtractPair<Entity extends Record<string, unknown>, Spec> = Spec extends [\n infer Key extends string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n (...key: any[]) => infer Value extends joinable,\n]\n ? [Uppercase<Key>, Value]\n : Spec extends keyof Entity & string\n ? [Uppercase<Spec>, Entity[Spec] & joinable]\n : never\n\ntype CompositeKeyRec<\n Entity extends Record<string, unknown>,\n Spec,\n Acc extends joinablePair[] = [],\n KeysCache extends string = keyof Entity & string,\n> = Spec extends [infer Head, ...infer Tail]\n ? CompositeKeyRec<\n Entity,\n Tail,\n [...Acc, ExtractPair<Entity, Head>],\n KeysCache\n >\n : Acc\n\ntype DiscriminatedSchemaShape = {\n discriminator: PropertyKey\n spec: {\n [k in PropertyKey]: unknown\n }\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\ntype InputSpecShape = ([string, (key: any) => unknown] | string)[]\n\ntype TableEntryImpl<\n Entity extends Record<string, unknown>,\n Schema,\n Separator extends string = '#',\n> = Entity extends unknown\n ? {\n [Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape\n ? ValueOf<{\n [K in Schema[Key]['discriminator']]: {\n [V in keyof Schema[Key]['spec']]: ProcessKey<\n Entity,\n Schema[Key]['spec'][V],\n Separator\n >\n }[Entity[K & keyof Entity] & keyof Schema[Key]['spec']]\n }>\n : ProcessKey<Entity, Schema[Key], Separator>\n } & Entity\n : never\n\nexport type TableEntry<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n> = TableEntryImpl<Entity, Schema, Separator>\n\ntype InputSpec<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]:\n | [key, (key: E[key]) => unknown]\n | (undefined extends E[key] ? never : null extends E[key] ? never : key)\n}[keyof E]\n\ntype extractHeadOrPass<T> = T extends unknown[] ? T[0] : T\n\ntype FullKeySpecSimple<Entity extends Record<string, unknown>> =\n | NonEmptyArray<InputSpec<Entity>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]: E[key] extends PropertyKey\n ? {\n discriminator: key\n spec: {\n [val in E[key]]: FullKeySpecSimple<\n Extract<\n Entity,\n {\n [k in key]: val\n }\n >\n >\n }\n }\n : never\n}[keyof E]\n\ntype FullKeySpec<Entity extends Record<string, unknown>> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity>\n\ntype FullKeySpecShape = FullKeySpecSimpleShape | DiscriminatedSchemaShape\n\nconst chainableNoOpProxy: unknown = new Proxy(() => chainableNoOpProxy, {\n get: () => chainableNoOpProxy,\n})\n\nconst createPathProxy = <T>(path = ''): T => {\n return new Proxy(() => {}, {\n get: (target, prop) => {\n if (typeof prop === 'string') {\n if (prop === 'toString') {\n return () => path\n }\n\n return createPathProxy(\n path === ''\n ? prop\n : !Number.isNaN(Number.parseInt(prop))\n ? `${path}[${prop}]`\n : `${path}.${prop}`,\n )\n }\n },\n }) as T\n}\n\nconst key =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <\n const Key extends keyof Schema,\n const Config extends { depth?: number; allowPartial?: boolean },\n const Attributes extends Partial<Entity>,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ): string | undefined => {\n const case_ = schema[key]\n\n if (case_ === undefined) {\n throw new Error(`Key ${key.toString()} not found in schema`)\n }\n let structure: InputSpec<Entity>[]\n\n if (Array.isArray(case_)) {\n structure = case_\n } else if (typeof case_ === 'object') {\n const discriminator =\n attributes[case_.discriminator as keyof Attributes]\n if (discriminator === undefined) {\n throw new Error(\n `Discriminator ${case_.discriminator.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n const val = case_.spec[discriminator as keyof typeof case_.spec]\n if (val === undefined) {\n throw new Error(\n `Discriminator value ${discriminator?.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n if (val === null) {\n return undefined\n }\n\n if (!Array.isArray(val)) {\n return attributes[val as keyof Attributes] as never\n }\n\n structure = val\n } else {\n const value = attributes[case_ as keyof Attributes]\n if (value == null) return undefined as never\n\n return value as never\n }\n\n if (config?.depth !== undefined) {\n structure = structure.slice(0, config.depth) as never\n }\n const composite: string[] = []\n\n for (const keySpec of structure) {\n const [key, transform] = Array.isArray(keySpec)\n ? keySpec\n : [keySpec]\n\n const value = attributes[key as keyof Attributes]\n if (\n (value !== undefined && value !== null && value !== '') ||\n transform\n ) {\n composite.push(key.toString().toUpperCase())\n composite.push(\n `${transform ? transform(value as never) : value}`,\n )\n } else if (config?.allowPartial) {\n break\n } else {\n throw new Error(\n `buildCompositeKey: Attribute ${key.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n }\n\n return composite.join(separator) as never\n }\n\nconst toEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <const ExactEntity extends Entity>(\n item: ExactEntity,\n ): ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never => {\n const entry = { ...item }\n\n for (const key_ in schema) {\n const val = key<Entity>()(schema, separator)(key_, item)\n if (val !== undefined) {\n entry[key_] = val satisfies string as never\n }\n }\n // console.log({ entry })\n return entry as never\n }\n\nconst fromEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpecShape>,\n Separator extends string = '#',\n >(\n schema: Schema,\n ) =>\n <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ): DistributiveOmit<Entry, keyof Schema> => {\n const item = { ...entry }\n\n for (const key_ in schema) {\n delete item[key_]\n }\n // console.log({ item })\n return item as never\n }\n\ntype ProcessSpecType<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends string\n ? DistributivePick<Entity, Spec>\n : Spec extends InputSpecShape\n ? CompositeKeyParamsImpl<\n Entity,\n Spec,\n Config['allowPartial'] extends true\n ? 1\n : Extract<Config['depth'], number>\n >\n : never\n\n// Cache commonly used conditional types\ntype SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape\n\ntype SpecConfigShape = {\n depth?: number\n allowPartial?: boolean\n}\n\n// Pre-compute discriminated variant types\ntype VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [\n Entity,\n] extends [never]\n ? { [k in K]: V }\n : Entity & { [k in K]: V }\n\n// Flatten nested type computation\ntype ProcessVariant<\n Entity extends Record<string, unknown>,\n K extends PropertyKey,\n V extends PropertyKey,\n Spec extends DiscriminatedSchemaShape,\n Config extends SpecConfigShape,\n> = VariantType<\n ProcessSpecType<\n VariantType<Entity, K, V>,\n Spec['spec'][V & keyof Spec['spec']],\n Config\n >,\n K,\n V\n>\n\n// Optimized attribute processing\ntype OptimizedAttributes<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessVariant<\n Entity,\n K,\n V,\n Spec,\n Config\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessSpecType<Entity, Spec, Config>\n\ntype ProcessKey<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n NullAs extends never | undefined = never,\n Config extends SpecConfigShape = SpecConfigShape,\n Attributes = Pick<Entity, Spec & keyof Entity>,\n> = [Entity] extends [never]\n ? never\n : Spec extends keyof Entity\n ? Replace<ValueOf<Attributes>, null, undefined>\n : Spec extends InputSpecShape\n ? CompositeKeyBuilderImpl<\n Entity,\n Spec,\n Separator,\n Exclude<Config['depth'], undefined>,\n Exclude<Config['allowPartial'], undefined>\n >\n : Spec extends null\n ? NullAs\n : never\n\ntype OptimizedBuildedKey<\n NarrowEntity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n Config extends SpecConfigShape,\n Attributes,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessKey<\n NarrowEntity extends { [k in K]: V } ? NarrowEntity : never,\n Spec['spec'][V],\n Separator,\n undefined,\n Config,\n Attributes\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>\n\ntype TableEntryDefinition<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpecShape>,\n Separator extends string,\n> = {\n toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(\n item: ExactEntity,\n ) => ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never\n fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ) => DistributiveOmit<Entry, keyof Schema>\n key: <\n const Key extends keyof Schema,\n const Config extends SpecConfig<Spec>,\n const Attributes extends OptimizedAttributes<Entity, Spec, Config_>,\n Spec = Schema[Key],\n Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] // exclude undefined param\n ? { depth?: undefined; allowPartial?: undefined }\n : Config,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ) => OptimizedBuildedKey<\n Entity & Attributes,\n Spec,\n Separator,\n Config_,\n Attributes\n >\n infer: TableEntryImpl<Entity, Schema, Separator>\n path: () => TableEntryImpl<Entity, Schema, Separator>\n}\n\nexport const tableEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ): TableEntryDefinition<Entity, Schema, Separator> => {\n return {\n toEntry: toEntry()(schema as never, separator) as never,\n fromEntry: fromEntry()(schema as never) as never,\n key: key()(schema as never, separator) as never,\n infer: chainableNoOpProxy as never,\n path: () => createPathProxy() as never,\n }\n }\n"],"mappings":"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","names":["key"]}
|
package/dist/Rotorise.d.cts
CHANGED
|
@@ -137,10 +137,12 @@ type OptimizedAttributes<Entity extends Record<string, unknown>, Spec, Config ex
|
|
|
137
137
|
[V in keyof Spec['spec']]: ProcessVariant<Entity, K, V, Spec, Config>;
|
|
138
138
|
}[keyof Spec['spec']];
|
|
139
139
|
}[Spec['discriminator']] : ProcessSpecType<Entity, Spec, Config>;
|
|
140
|
-
type ProcessKey<Entity extends Record<string, unknown>, Spec, Separator extends string, NullAs extends never | undefined = never, Config extends SpecConfigShape = SpecConfigShape, Attributes = Pick<Entity, Spec & keyof Entity>> = Spec extends keyof Entity ? Replace<ValueOf<Attributes>, null, undefined> : Spec extends InputSpecShape ? CompositeKeyBuilderImpl<Entity, Spec, Separator, Exclude<Config['depth'], undefined>, Exclude<Config['allowPartial'], undefined>> : Spec extends null ? NullAs : never;
|
|
140
|
+
type ProcessKey<Entity extends Record<string, unknown>, Spec, Separator extends string, NullAs extends never | undefined = never, Config extends SpecConfigShape = SpecConfigShape, Attributes = Pick<Entity, Spec & keyof Entity>> = [Entity] extends [never] ? never : Spec extends keyof Entity ? Replace<ValueOf<Attributes>, null, undefined> : Spec extends InputSpecShape ? CompositeKeyBuilderImpl<Entity, Spec, Separator, Exclude<Config['depth'], undefined>, Exclude<Config['allowPartial'], undefined>> : Spec extends null ? NullAs : never;
|
|
141
141
|
type OptimizedBuildedKey<NarrowEntity extends Record<string, unknown>, Spec, Separator extends string, Config extends SpecConfigShape, Attributes> = Spec extends DiscriminatedSchemaShape ? {
|
|
142
142
|
[K in Spec['discriminator']]: {
|
|
143
|
-
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity
|
|
143
|
+
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity extends {
|
|
144
|
+
[k in K]: V;
|
|
145
|
+
} ? NarrowEntity : never, Spec['spec'][V], Separator, undefined, Config, Attributes>;
|
|
144
146
|
}[keyof Spec['spec']];
|
|
145
147
|
}[Spec['discriminator']] : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>;
|
|
146
148
|
type TableEntryDefinition<Entity extends Record<string, unknown>, Schema extends Record<string, FullKeySpecShape>, Separator extends string> = {
|
package/dist/Rotorise.d.ts
CHANGED
|
@@ -137,10 +137,12 @@ type OptimizedAttributes<Entity extends Record<string, unknown>, Spec, Config ex
|
|
|
137
137
|
[V in keyof Spec['spec']]: ProcessVariant<Entity, K, V, Spec, Config>;
|
|
138
138
|
}[keyof Spec['spec']];
|
|
139
139
|
}[Spec['discriminator']] : ProcessSpecType<Entity, Spec, Config>;
|
|
140
|
-
type ProcessKey<Entity extends Record<string, unknown>, Spec, Separator extends string, NullAs extends never | undefined = never, Config extends SpecConfigShape = SpecConfigShape, Attributes = Pick<Entity, Spec & keyof Entity>> = Spec extends keyof Entity ? Replace<ValueOf<Attributes>, null, undefined> : Spec extends InputSpecShape ? CompositeKeyBuilderImpl<Entity, Spec, Separator, Exclude<Config['depth'], undefined>, Exclude<Config['allowPartial'], undefined>> : Spec extends null ? NullAs : never;
|
|
140
|
+
type ProcessKey<Entity extends Record<string, unknown>, Spec, Separator extends string, NullAs extends never | undefined = never, Config extends SpecConfigShape = SpecConfigShape, Attributes = Pick<Entity, Spec & keyof Entity>> = [Entity] extends [never] ? never : Spec extends keyof Entity ? Replace<ValueOf<Attributes>, null, undefined> : Spec extends InputSpecShape ? CompositeKeyBuilderImpl<Entity, Spec, Separator, Exclude<Config['depth'], undefined>, Exclude<Config['allowPartial'], undefined>> : Spec extends null ? NullAs : never;
|
|
141
141
|
type OptimizedBuildedKey<NarrowEntity extends Record<string, unknown>, Spec, Separator extends string, Config extends SpecConfigShape, Attributes> = Spec extends DiscriminatedSchemaShape ? {
|
|
142
142
|
[K in Spec['discriminator']]: {
|
|
143
|
-
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity
|
|
143
|
+
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity extends {
|
|
144
|
+
[k in K]: V;
|
|
145
|
+
} ? NarrowEntity : never, Spec['spec'][V], Separator, undefined, Config, Attributes>;
|
|
144
146
|
}[keyof Spec['spec']];
|
|
145
147
|
}[Spec['discriminator']] : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>;
|
|
146
148
|
type TableEntryDefinition<Entity extends Record<string, unknown>, Schema extends Record<string, FullKeySpecShape>, Separator extends string> = {
|
package/dist/Rotorise.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Rotorise.ts"],"sourcesContent":["import type {\n DistributiveOmit,\n DistributivePick,\n Exact,\n NonEmptyArray,\n Replace,\n SliceFromStart,\n UnionToObject,\n ValueOf,\n evaluate,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity extends Record<string, unknown>,\n InputSpec extends InputSpecShape,\n skip extends number = 1,\n> = Entity extends unknown\n ? evaluate<\n Pick<\n Entity,\n extractHeadOrPass<\n SliceFromStart<\n InputSpec,\n number extends skip ? 1 : skip\n >[number]\n > &\n keyof Entity\n > &\n Partial<\n Pick<\n Entity,\n extractHeadOrPass<InputSpec[number]> & keyof Entity\n >\n >\n >\n : never\n\nexport type CompositeKeyParams<\n Entity extends Record<string, unknown>,\n FullSpec extends InputSpec<Entity>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = Entity extends unknown\n ? Join<\n CompositeKeyRec<\n Entity,\n number extends Deep ? Spec : SliceFromStart<Spec, Deep>\n >,\n Separator,\n (boolean extends isPartial ? false : isPartial) extends false\n ? false\n : true\n >\n : never\n\nexport type CompositeKeyBuilder<\n Entity extends Record<string, unknown>,\n Spec extends InputSpec<Entity>[],\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>\n\ntype joinable = string | number | bigint | boolean | null | undefined\ntype joinablePair = [joinable, joinable]\n\ntype Join<\n Pairs,\n Separator extends string,\n KeepIntermediate extends boolean = false,\n Acc extends string = '',\n AllAcc extends string = never,\n> = Pairs extends [infer Head extends joinablePair, ...infer Tail]\n ? Join<\n Tail,\n Separator,\n KeepIntermediate,\n Acc extends ''\n ? `${Head[0]}${Separator}${Head[1]}`\n : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`,\n KeepIntermediate extends true\n ? AllAcc | (Acc extends '' ? never : Acc)\n : never\n >\n : AllAcc | Acc\n\ntype ExtractPair<Entity extends Record<string, unknown>, Spec> = Spec extends [\n infer Key extends string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n (...key: any[]) => infer Value extends joinable,\n]\n ? [Uppercase<Key>, Value]\n : Spec extends keyof Entity & string\n ? [Uppercase<Spec>, Entity[Spec] & joinable]\n : never\n\ntype CompositeKeyRec<\n Entity extends Record<string, unknown>,\n Spec,\n Acc extends joinablePair[] = [],\n KeysCache extends string = keyof Entity & string,\n> = Spec extends [infer Head, ...infer Tail]\n ? CompositeKeyRec<\n Entity,\n Tail,\n [...Acc, ExtractPair<Entity, Head>],\n KeysCache\n >\n : Acc\n\ntype DiscriminatedSchemaShape = {\n discriminator: PropertyKey\n spec: {\n [k in PropertyKey]: unknown\n }\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\ntype InputSpecShape = ([string, (key: any) => unknown] | string)[]\n\ntype TableEntryImpl<\n Entity extends Record<string, unknown>,\n Schema,\n Separator extends string = '#',\n> = Entity extends unknown\n ? {\n [Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape\n ? ValueOf<{\n [K in Schema[Key]['discriminator']]: {\n [V in keyof Schema[Key]['spec']]: ProcessKey<\n Entity,\n Schema[Key]['spec'][V],\n Separator\n >\n }[Entity[K & keyof Entity] & keyof Schema[Key]['spec']]\n }>\n : ProcessKey<Entity, Schema[Key], Separator>\n } & Entity\n : never\n\nexport type TableEntry<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n> = TableEntryImpl<Entity, Schema, Separator>\n\ntype InputSpec<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]:\n | [key, (key: E[key]) => unknown]\n | (undefined extends E[key] ? never : null extends E[key] ? never : key)\n}[keyof E]\n\ntype extractHeadOrPass<T> = T extends unknown[] ? T[0] : T\n\ntype FullKeySpecSimple<Entity extends Record<string, unknown>> =\n | NonEmptyArray<InputSpec<Entity>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]: E[key] extends PropertyKey\n ? {\n discriminator: key\n spec: {\n [val in E[key]]: FullKeySpecSimple<\n Extract<\n Entity,\n {\n [k in key]: val\n }\n >\n >\n }\n }\n : never\n}[keyof E]\n\ntype FullKeySpec<Entity extends Record<string, unknown>> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity>\n\ntype FullKeySpecShape = FullKeySpecSimpleShape | DiscriminatedSchemaShape\n\nconst chainableNoOpProxy: unknown = new Proxy(() => chainableNoOpProxy, {\n get: () => chainableNoOpProxy,\n})\n\nconst createPathProxy = <T>(path = ''): T => {\n return new Proxy(() => {}, {\n get: (target, prop) => {\n if (typeof prop === 'string') {\n if (prop === 'toString') {\n return () => path\n }\n\n return createPathProxy(\n path === ''\n ? prop\n : !Number.isNaN(Number.parseInt(prop))\n ? `${path}[${prop}]`\n : `${path}.${prop}`,\n )\n }\n },\n }) as T\n}\n\nconst key =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <\n const Key extends keyof Schema,\n const Config extends { depth?: number; allowPartial?: boolean },\n const Attributes extends Partial<Entity>,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ): string | undefined => {\n const case_ = schema[key]\n\n if (case_ === undefined) {\n throw new Error(`Key ${key.toString()} not found in schema`)\n }\n let structure: InputSpec<Entity>[]\n\n if (Array.isArray(case_)) {\n structure = case_\n } else if (typeof case_ === 'object') {\n const discriminator =\n attributes[case_.discriminator as keyof Attributes]\n if (discriminator === undefined) {\n throw new Error(\n `Discriminator ${case_.discriminator.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n const val = case_.spec[discriminator as keyof typeof case_.spec]\n if (val === undefined) {\n throw new Error(\n `Discriminator value ${discriminator?.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n if (val === null) {\n return undefined\n }\n\n if (!Array.isArray(val)) {\n return attributes[val as keyof Attributes] as never\n }\n\n structure = val\n } else {\n const value = attributes[case_ as keyof Attributes]\n if (value == null) return undefined as never\n\n return value as never\n }\n\n if (config?.depth !== undefined) {\n structure = structure.slice(0, config.depth) as never\n }\n const composite: string[] = []\n\n for (const keySpec of structure) {\n const [key, transform] = Array.isArray(keySpec)\n ? keySpec\n : [keySpec]\n\n const value = attributes[key as keyof Attributes]\n if (\n (value !== undefined && value !== null && value !== '') ||\n transform\n ) {\n composite.push(key.toString().toUpperCase())\n composite.push(\n `${transform ? transform(value as never) : value}`,\n )\n } else if (config?.allowPartial) {\n break\n } else {\n throw new Error(\n `buildCompositeKey: Attribute ${key.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n }\n\n return composite.join(separator) as never\n }\n\nconst toEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <const ExactEntity extends Entity>(\n item: ExactEntity,\n ): ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never => {\n const entry = { ...item }\n\n for (const key_ in schema) {\n const val = key<Entity>()(schema, separator)(key_, item)\n if (val !== undefined) {\n entry[key_] = val satisfies string as never\n }\n }\n // console.log({ entry })\n return entry as never\n }\n\nconst fromEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpecShape>,\n Separator extends string = '#',\n >(\n schema: Schema,\n ) =>\n <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ): DistributiveOmit<Entry, keyof Schema> => {\n const item = { ...entry }\n\n for (const key_ in schema) {\n delete item[key_]\n }\n // console.log({ item })\n return item as never\n }\n\ntype ProcessSpecType<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends string\n ? DistributivePick<Entity, Spec>\n : Spec extends InputSpecShape\n ? CompositeKeyParamsImpl<\n Entity,\n Spec,\n Config['allowPartial'] extends true\n ? 1\n : Extract<Config['depth'], number>\n >\n : never\n\n// Cache commonly used conditional types\ntype SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape\n\ntype SpecConfigShape = {\n depth?: number\n allowPartial?: boolean\n}\n\n// Pre-compute discriminated variant types\ntype VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [\n Entity,\n] extends [never]\n ? { [k in K]: V }\n : Entity & { [k in K]: V }\n\n// Flatten nested type computation\ntype ProcessVariant<\n Entity extends Record<string, unknown>,\n K extends PropertyKey,\n V extends PropertyKey,\n Spec extends DiscriminatedSchemaShape,\n Config extends SpecConfigShape,\n> = VariantType<\n ProcessSpecType<\n VariantType<Entity, K, V>,\n Spec['spec'][V & keyof Spec['spec']],\n Config\n >,\n K,\n V\n>\n\n// Optimized attribute processing\ntype OptimizedAttributes<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessVariant<\n Entity,\n K,\n V,\n Spec,\n Config\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessSpecType<Entity, Spec, Config>\n\ntype ProcessKey<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n NullAs extends never | undefined = never,\n Config extends SpecConfigShape = SpecConfigShape,\n Attributes = Pick<Entity, Spec & keyof Entity>,\n> = Spec extends keyof Entity\n ? Replace<ValueOf<Attributes>, null, undefined>\n : Spec extends InputSpecShape\n ? CompositeKeyBuilderImpl<\n Entity,\n Spec,\n Separator,\n Exclude<Config['depth'], undefined>,\n Exclude<Config['allowPartial'], undefined>\n >\n : Spec extends null\n ? NullAs\n : never\n\ntype OptimizedBuildedKey<\n NarrowEntity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n Config extends SpecConfigShape,\n Attributes,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessKey<\n NarrowEntity,\n Spec['spec'][V],\n Separator,\n undefined,\n Config,\n Attributes\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>\n\ntype TableEntryDefinition<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpecShape>,\n Separator extends string,\n> = {\n toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(\n item: ExactEntity,\n ) => ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never\n fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ) => DistributiveOmit<Entry, keyof Schema>\n key: <\n const Key extends keyof Schema,\n const Config extends SpecConfig<Spec>,\n const Attributes extends OptimizedAttributes<Entity, Spec, Config_>,\n Spec = Schema[Key],\n Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] // exclude undefined param\n ? { depth?: undefined; allowPartial?: undefined }\n : Config,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ) => OptimizedBuildedKey<\n Entity & Attributes,\n Spec,\n Separator,\n Config_,\n Attributes\n >\n infer: TableEntryImpl<Entity, Schema, Separator>\n path: () => TableEntryImpl<Entity, Schema, Separator>\n}\n\nexport const tableEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ): TableEntryDefinition<Entity, Schema, Separator> => {\n return {\n toEntry: toEntry()(schema as never, separator) as never,\n fromEntry: fromEntry()(schema as never) as never,\n key: key()(schema as never, separator) as never,\n infer: chainableNoOpProxy as never,\n path: () => createPathProxy() as never,\n }\n }\n"],"mappings":"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","names":["key"]}
|
|
1
|
+
{"version":3,"sources":["../src/Rotorise.ts"],"sourcesContent":["import type {\n DistributiveOmit,\n DistributivePick,\n Exact,\n NonEmptyArray,\n Replace,\n SliceFromStart,\n UnionToObject,\n ValueOf,\n evaluate,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity extends Record<string, unknown>,\n InputSpec extends InputSpecShape,\n skip extends number = 1,\n> = Entity extends unknown\n ? evaluate<\n Pick<\n Entity,\n extractHeadOrPass<\n SliceFromStart<\n InputSpec,\n number extends skip ? 1 : skip\n >[number]\n > &\n keyof Entity\n > &\n Partial<\n Pick<\n Entity,\n extractHeadOrPass<InputSpec[number]> & keyof Entity\n >\n >\n >\n : never\n\nexport type CompositeKeyParams<\n Entity extends Record<string, unknown>,\n FullSpec extends InputSpec<Entity>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = Entity extends unknown\n ? Join<\n CompositeKeyRec<\n Entity,\n number extends Deep ? Spec : SliceFromStart<Spec, Deep>\n >,\n Separator,\n (boolean extends isPartial ? false : isPartial) extends false\n ? false\n : true\n >\n : never\n\nexport type CompositeKeyBuilder<\n Entity extends Record<string, unknown>,\n Spec extends InputSpec<Entity>[],\n Separator extends string = '#',\n Deep extends number = number,\n isPartial extends boolean = false,\n> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>\n\ntype joinable = string | number | bigint | boolean | null | undefined\ntype joinablePair = [joinable, joinable]\n\ntype Join<\n Pairs,\n Separator extends string,\n KeepIntermediate extends boolean = false,\n Acc extends string = '',\n AllAcc extends string = never,\n> = Pairs extends [infer Head extends joinablePair, ...infer Tail]\n ? Join<\n Tail,\n Separator,\n KeepIntermediate,\n Acc extends ''\n ? `${Head[0]}${Separator}${Head[1]}`\n : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`,\n KeepIntermediate extends true\n ? AllAcc | (Acc extends '' ? never : Acc)\n : never\n >\n : AllAcc | Acc\n\ntype ExtractPair<Entity extends Record<string, unknown>, Spec> = Spec extends [\n infer Key extends string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n (...key: any[]) => infer Value extends joinable,\n]\n ? [Uppercase<Key>, Value]\n : Spec extends keyof Entity & string\n ? [Uppercase<Spec>, Entity[Spec] & joinable]\n : never\n\ntype CompositeKeyRec<\n Entity extends Record<string, unknown>,\n Spec,\n Acc extends joinablePair[] = [],\n KeysCache extends string = keyof Entity & string,\n> = Spec extends [infer Head, ...infer Tail]\n ? CompositeKeyRec<\n Entity,\n Tail,\n [...Acc, ExtractPair<Entity, Head>],\n KeysCache\n >\n : Acc\n\ntype DiscriminatedSchemaShape = {\n discriminator: PropertyKey\n spec: {\n [k in PropertyKey]: unknown\n }\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\ntype InputSpecShape = ([string, (key: any) => unknown] | string)[]\n\ntype TableEntryImpl<\n Entity extends Record<string, unknown>,\n Schema,\n Separator extends string = '#',\n> = Entity extends unknown\n ? {\n [Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape\n ? ValueOf<{\n [K in Schema[Key]['discriminator']]: {\n [V in keyof Schema[Key]['spec']]: ProcessKey<\n Entity,\n Schema[Key]['spec'][V],\n Separator\n >\n }[Entity[K & keyof Entity] & keyof Schema[Key]['spec']]\n }>\n : ProcessKey<Entity, Schema[Key], Separator>\n } & Entity\n : never\n\nexport type TableEntry<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n> = TableEntryImpl<Entity, Schema, Separator>\n\ntype InputSpec<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]:\n | [key, (key: E[key]) => unknown]\n | (undefined extends E[key] ? never : null extends E[key] ? never : key)\n}[keyof E]\n\ntype extractHeadOrPass<T> = T extends unknown[] ? T[0] : T\n\ntype FullKeySpecSimple<Entity extends Record<string, unknown>> =\n | NonEmptyArray<InputSpec<Entity>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<\n Entity extends Record<string, unknown>,\n E extends Record<string, unknown> = UnionToObject<Entity>,\n> = {\n [key in keyof E]: E[key] extends PropertyKey\n ? {\n discriminator: key\n spec: {\n [val in E[key]]: FullKeySpecSimple<\n Extract<\n Entity,\n {\n [k in key]: val\n }\n >\n >\n }\n }\n : never\n}[keyof E]\n\ntype FullKeySpec<Entity extends Record<string, unknown>> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity>\n\ntype FullKeySpecShape = FullKeySpecSimpleShape | DiscriminatedSchemaShape\n\nconst chainableNoOpProxy: unknown = new Proxy(() => chainableNoOpProxy, {\n get: () => chainableNoOpProxy,\n})\n\nconst createPathProxy = <T>(path = ''): T => {\n return new Proxy(() => {}, {\n get: (target, prop) => {\n if (typeof prop === 'string') {\n if (prop === 'toString') {\n return () => path\n }\n\n return createPathProxy(\n path === ''\n ? prop\n : !Number.isNaN(Number.parseInt(prop))\n ? `${path}[${prop}]`\n : `${path}.${prop}`,\n )\n }\n },\n }) as T\n}\n\nconst key =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <\n const Key extends keyof Schema,\n const Config extends { depth?: number; allowPartial?: boolean },\n const Attributes extends Partial<Entity>,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ): string | undefined => {\n const case_ = schema[key]\n\n if (case_ === undefined) {\n throw new Error(`Key ${key.toString()} not found in schema`)\n }\n let structure: InputSpec<Entity>[]\n\n if (Array.isArray(case_)) {\n structure = case_\n } else if (typeof case_ === 'object') {\n const discriminator =\n attributes[case_.discriminator as keyof Attributes]\n if (discriminator === undefined) {\n throw new Error(\n `Discriminator ${case_.discriminator.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n const val = case_.spec[discriminator as keyof typeof case_.spec]\n if (val === undefined) {\n throw new Error(\n `Discriminator value ${discriminator?.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n if (val === null) {\n return undefined\n }\n\n if (!Array.isArray(val)) {\n return attributes[val as keyof Attributes] as never\n }\n\n structure = val\n } else {\n const value = attributes[case_ as keyof Attributes]\n if (value == null) return undefined as never\n\n return value as never\n }\n\n if (config?.depth !== undefined) {\n structure = structure.slice(0, config.depth) as never\n }\n const composite: string[] = []\n\n for (const keySpec of structure) {\n const [key, transform] = Array.isArray(keySpec)\n ? keySpec\n : [keySpec]\n\n const value = attributes[key as keyof Attributes]\n if (\n (value !== undefined && value !== null && value !== '') ||\n transform\n ) {\n composite.push(key.toString().toUpperCase())\n composite.push(\n `${transform ? transform(value as never) : value}`,\n )\n } else if (config?.allowPartial) {\n break\n } else {\n throw new Error(\n `buildCompositeKey: Attribute ${key.toString()} not found in ${JSON.stringify(attributes)}`,\n )\n }\n }\n\n return composite.join(separator) as never\n }\n\nconst toEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<Entity>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]: InputSpec<Entity>[] | keyof Entity\n }\n }\n >,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ) =>\n <const ExactEntity extends Entity>(\n item: ExactEntity,\n ): ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never => {\n const entry = { ...item }\n\n for (const key_ in schema) {\n const val = key<Entity>()(schema, separator)(key_, item)\n if (val !== undefined) {\n entry[key_] = val satisfies string as never\n }\n }\n // console.log({ entry })\n return entry as never\n }\n\nconst fromEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpecShape>,\n Separator extends string = '#',\n >(\n schema: Schema,\n ) =>\n <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ): DistributiveOmit<Entry, keyof Schema> => {\n const item = { ...entry }\n\n for (const key_ in schema) {\n delete item[key_]\n }\n // console.log({ item })\n return item as never\n }\n\ntype ProcessSpecType<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends string\n ? DistributivePick<Entity, Spec>\n : Spec extends InputSpecShape\n ? CompositeKeyParamsImpl<\n Entity,\n Spec,\n Config['allowPartial'] extends true\n ? 1\n : Extract<Config['depth'], number>\n >\n : never\n\n// Cache commonly used conditional types\ntype SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape\n\ntype SpecConfigShape = {\n depth?: number\n allowPartial?: boolean\n}\n\n// Pre-compute discriminated variant types\ntype VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [\n Entity,\n] extends [never]\n ? { [k in K]: V }\n : Entity & { [k in K]: V }\n\n// Flatten nested type computation\ntype ProcessVariant<\n Entity extends Record<string, unknown>,\n K extends PropertyKey,\n V extends PropertyKey,\n Spec extends DiscriminatedSchemaShape,\n Config extends SpecConfigShape,\n> = VariantType<\n ProcessSpecType<\n VariantType<Entity, K, V>,\n Spec['spec'][V & keyof Spec['spec']],\n Config\n >,\n K,\n V\n>\n\n// Optimized attribute processing\ntype OptimizedAttributes<\n Entity extends Record<string, unknown>,\n Spec,\n Config extends SpecConfigShape,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessVariant<\n Entity,\n K,\n V,\n Spec,\n Config\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessSpecType<Entity, Spec, Config>\n\ntype ProcessKey<\n Entity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n NullAs extends never | undefined = never,\n Config extends SpecConfigShape = SpecConfigShape,\n Attributes = Pick<Entity, Spec & keyof Entity>,\n> = [Entity] extends [never]\n ? never\n : Spec extends keyof Entity\n ? Replace<ValueOf<Attributes>, null, undefined>\n : Spec extends InputSpecShape\n ? CompositeKeyBuilderImpl<\n Entity,\n Spec,\n Separator,\n Exclude<Config['depth'], undefined>,\n Exclude<Config['allowPartial'], undefined>\n >\n : Spec extends null\n ? NullAs\n : never\n\ntype OptimizedBuildedKey<\n NarrowEntity extends Record<string, unknown>,\n Spec,\n Separator extends string,\n Config extends SpecConfigShape,\n Attributes,\n> = Spec extends DiscriminatedSchemaShape\n ? {\n [K in Spec['discriminator']]: {\n [V in keyof Spec['spec']]: ProcessKey<\n NarrowEntity extends { [k in K]: V } ? NarrowEntity : never,\n Spec['spec'][V],\n Separator,\n undefined,\n Config,\n Attributes\n >\n }[keyof Spec['spec']]\n }[Spec['discriminator']]\n : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>\n\ntype TableEntryDefinition<\n Entity extends Record<string, unknown>,\n Schema extends Record<string, FullKeySpecShape>,\n Separator extends string,\n> = {\n toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(\n item: ExactEntity,\n ) => ExactEntity extends infer E extends Entity\n ? TableEntryImpl<E, Schema, Separator>\n : never\n fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(\n entry: Entry,\n ) => DistributiveOmit<Entry, keyof Schema>\n key: <\n const Key extends keyof Schema,\n const Config extends SpecConfig<Spec>,\n const Attributes extends OptimizedAttributes<Entity, Spec, Config_>,\n Spec = Schema[Key],\n Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] // exclude undefined param\n ? { depth?: undefined; allowPartial?: undefined }\n : Config,\n >(\n key: Key,\n attributes: Attributes,\n config?: Config,\n ) => OptimizedBuildedKey<\n Entity & Attributes,\n Spec,\n Separator,\n Config_,\n Attributes\n >\n infer: TableEntryImpl<Entity, Schema, Separator>\n path: () => TableEntryImpl<Entity, Schema, Separator>\n}\n\nexport const tableEntry =\n <const Entity extends Record<string, unknown>>() =>\n <\n const Schema extends Record<string, FullKeySpec<Entity>>,\n Separator extends string = '#',\n >(\n schema: Schema,\n separator: Separator = '#' as Separator,\n ): TableEntryDefinition<Entity, Schema, Separator> => {\n return {\n toEntry: toEntry()(schema as never, separator) as never,\n fromEntry: fromEntry()(schema as never) as never,\n key: key()(schema as never, separator) as never,\n infer: chainableNoOpProxy as never,\n path: () => createPathProxy() as never,\n }\n }\n"],"mappings":"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","names":["key"]}
|