rotorise 0.1.12 → 0.1.14
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/.attest/assertions/typescript.json +6 -6
- package/dist/Rotorise.cjs.map +1 -1
- package/dist/Rotorise.d.cts +26 -23
- package/dist/Rotorise.d.ts +26 -23
- package/dist/Rotorise.js.map +1 -1
- package/package.json +1 -1
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"char": 56
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
"count":
|
|
54
|
+
"count": 2012
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"location": {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"char": 56
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"count":
|
|
67
|
+
"count": 4652
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"location": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"char": 57
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
|
-
"count":
|
|
80
|
+
"count": 11620
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"location": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"char": 56
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
"count":
|
|
93
|
+
"count": 1358
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
"location": {
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"char": 57
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
|
-
"count":
|
|
106
|
+
"count": 64802
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
"location": {
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"char": 57
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
|
-
"count":
|
|
119
|
+
"count": 48910
|
|
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":"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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 ValueOf,\n evaluate,\n MergeIntersectionObject,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity,\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<MergeIntersectionObject<Entity>>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity,\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<MergeIntersectionObject<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, 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,\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 = ([PropertyKey, (key: any) => unknown] | PropertyKey)[]\n\ntype TableEntryImpl<\n Entity,\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<E> = {\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> =\n | NonEmptyArray<InputSpec<MergeIntersectionObject<Entity>>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<Entity, E> = {\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> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity, MergeIntersectionObject<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>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]:\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | 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<MergeIntersectionObject<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<MergeIntersectionObject<Entity>>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]:\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | 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,\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,\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,\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,\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,\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<Entity, Schema, Separator extends string> = {\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;AAgMA,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,CAgBI,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,CAgBI,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;AAiJG,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"]}
|
package/dist/Rotorise.d.cts
CHANGED
|
@@ -62,26 +62,29 @@ type SliceFromStart<
|
|
|
62
62
|
: Acc
|
|
63
63
|
: never
|
|
64
64
|
|
|
65
|
-
type
|
|
66
|
-
[K in
|
|
65
|
+
type MergeIntersectionObject<T, Keys = keyof T> = {
|
|
66
|
+
[K in Keys]: T[K]
|
|
67
67
|
}
|
|
68
|
+
// type t = MergeIntersectionObject<
|
|
69
|
+
// { a: 'a1'; b: 1n; extra: 'extra' } | { a: 'a2'; b: 2 }
|
|
70
|
+
// >
|
|
68
71
|
|
|
69
72
|
type NonEmptyArray<T> = [T, ...T[]]
|
|
70
73
|
|
|
71
74
|
type Replace<T, U, V> = T extends U ? V : T
|
|
72
75
|
|
|
73
|
-
type CompositeKeyParamsImpl<Entity
|
|
74
|
-
type CompositeKeyParams<Entity extends Record<string, unknown>, FullSpec extends InputSpec<Entity
|
|
75
|
-
type CompositeKeyBuilderImpl<Entity
|
|
76
|
-
type CompositeKeyBuilder<Entity extends Record<string, unknown>, Spec extends InputSpec<Entity
|
|
76
|
+
type CompositeKeyParamsImpl<Entity, InputSpec extends InputSpecShape, skip extends number = 1> = Entity extends unknown ? evaluate<Pick<Entity, extractHeadOrPass<SliceFromStart<InputSpec, number extends skip ? 1 : skip>[number]> & keyof Entity> & Partial<Pick<Entity, extractHeadOrPass<InputSpec[number]> & keyof Entity>>> : never;
|
|
77
|
+
type CompositeKeyParams<Entity extends Record<string, unknown>, FullSpec extends InputSpec<MergeIntersectionObject<Entity>>[], skip extends number = 1> = CompositeKeyParamsImpl<Entity, FullSpec, skip>;
|
|
78
|
+
type CompositeKeyBuilderImpl<Entity, Spec, Separator extends string = '#', Deep extends number = number, isPartial extends boolean = false> = Entity extends unknown ? Join<CompositeKeyRec<Entity, number extends Deep ? Spec : SliceFromStart<Spec, Deep>>, Separator, (boolean extends isPartial ? false : isPartial) extends false ? false : true> : never;
|
|
79
|
+
type CompositeKeyBuilder<Entity extends Record<string, unknown>, Spec extends InputSpec<MergeIntersectionObject<Entity>>[], Separator extends string = '#', Deep extends number = number, isPartial extends boolean = false> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>;
|
|
77
80
|
type joinable = string | number | bigint | boolean | null | undefined;
|
|
78
81
|
type joinablePair = [joinable, joinable];
|
|
79
82
|
type Join<Pairs, Separator extends string, KeepIntermediate extends boolean = false, Acc extends string = '', AllAcc extends string = never> = Pairs extends [infer Head extends joinablePair, ...infer Tail] ? Join<Tail, Separator, KeepIntermediate, Acc extends '' ? `${Head[0]}${Separator}${Head[1]}` : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`, KeepIntermediate extends true ? AllAcc | (Acc extends '' ? never : Acc) : never> : AllAcc | Acc;
|
|
80
|
-
type ExtractPair<Entity
|
|
83
|
+
type ExtractPair<Entity, Spec> = Spec extends [
|
|
81
84
|
infer Key extends string,
|
|
82
85
|
(...key: any[]) => infer Value extends joinable
|
|
83
86
|
] ? [Uppercase<Key>, Value] : Spec extends keyof Entity & string ? [Uppercase<Spec>, Entity[Spec] & joinable] : never;
|
|
84
|
-
type CompositeKeyRec<Entity
|
|
87
|
+
type CompositeKeyRec<Entity, Spec, Acc extends joinablePair[] = [], KeysCache extends string = keyof Entity & string> = Spec extends [infer Head, ...infer Tail] ? CompositeKeyRec<Entity, Tail, [
|
|
85
88
|
...Acc,
|
|
86
89
|
ExtractPair<Entity, Head>
|
|
87
90
|
], KeysCache> : Acc;
|
|
@@ -91,8 +94,8 @@ type DiscriminatedSchemaShape = {
|
|
|
91
94
|
[k in PropertyKey]: unknown;
|
|
92
95
|
};
|
|
93
96
|
};
|
|
94
|
-
type InputSpecShape = ([
|
|
95
|
-
type TableEntryImpl<Entity
|
|
97
|
+
type InputSpecShape = ([PropertyKey, (key: any) => unknown] | PropertyKey)[];
|
|
98
|
+
type TableEntryImpl<Entity, Schema, Separator extends string = '#'> = Entity extends unknown ? {
|
|
96
99
|
[Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape ? ValueOf<{
|
|
97
100
|
[K in Schema[Key]['discriminator']]: {
|
|
98
101
|
[V in keyof Schema[Key]['spec']]: ProcessKey<Entity, Schema[Key]['spec'][V], Separator>;
|
|
@@ -100,13 +103,12 @@ type TableEntryImpl<Entity extends Record<string, unknown>, Schema, Separator ex
|
|
|
100
103
|
}> : ProcessKey<Entity, Schema[Key], Separator>;
|
|
101
104
|
} & Entity : never;
|
|
102
105
|
type TableEntry<Entity extends Record<string, unknown>, Schema extends Record<string, FullKeySpec<Entity>>, Separator extends string = '#'> = TableEntryImpl<Entity, Schema, Separator>;
|
|
103
|
-
type InputSpec<
|
|
106
|
+
type InputSpec<E> = {
|
|
104
107
|
[key in keyof E]: [key, (key: E[key]) => unknown] | (undefined extends E[key] ? never : null extends E[key] ? never : key);
|
|
105
108
|
}[keyof E];
|
|
106
109
|
type extractHeadOrPass<T> = T extends unknown[] ? T[0] : T;
|
|
107
|
-
type FullKeySpecSimple<Entity
|
|
108
|
-
type
|
|
109
|
-
type DiscriminatedSchema<Entity extends Record<string, unknown>, E extends Record<string, unknown> = UnionToObject<Entity>> = {
|
|
110
|
+
type FullKeySpecSimple<Entity> = NonEmptyArray<InputSpec<MergeIntersectionObject<Entity>>> | (keyof Entity & string) | null;
|
|
111
|
+
type DiscriminatedSchema<Entity, E> = {
|
|
110
112
|
[key in keyof E]: E[key] extends PropertyKey ? {
|
|
111
113
|
discriminator: key;
|
|
112
114
|
spec: {
|
|
@@ -116,9 +118,8 @@ type DiscriminatedSchema<Entity extends Record<string, unknown>, E extends Recor
|
|
|
116
118
|
};
|
|
117
119
|
} : never;
|
|
118
120
|
}[keyof E];
|
|
119
|
-
type FullKeySpec<Entity
|
|
120
|
-
type
|
|
121
|
-
type ProcessSpecType<Entity extends Record<string, unknown>, Spec, Config extends SpecConfigShape> = Spec extends string ? DistributivePick<Entity, Spec> : Spec extends InputSpecShape ? CompositeKeyParamsImpl<Entity, Spec, Config['allowPartial'] extends true ? 1 : Extract<Config['depth'], number>> : never;
|
|
121
|
+
type FullKeySpec<Entity> = FullKeySpecSimple<Entity> | DiscriminatedSchema<Entity, MergeIntersectionObject<Entity>>;
|
|
122
|
+
type ProcessSpecType<Entity, Spec, Config extends SpecConfigShape> = Spec extends string ? DistributivePick<Entity, Spec> : Spec extends InputSpecShape ? CompositeKeyParamsImpl<Entity, Spec, Config['allowPartial'] extends true ? 1 : Extract<Config['depth'], number>> : never;
|
|
122
123
|
type SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape;
|
|
123
124
|
type SpecConfigShape = {
|
|
124
125
|
depth?: number;
|
|
@@ -131,19 +132,21 @@ type VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [
|
|
|
131
132
|
} : Entity & {
|
|
132
133
|
[k in K]: V;
|
|
133
134
|
};
|
|
134
|
-
type ProcessVariant<Entity
|
|
135
|
-
type OptimizedAttributes<Entity
|
|
135
|
+
type ProcessVariant<Entity, K extends PropertyKey, V extends PropertyKey, Spec extends DiscriminatedSchemaShape, Config extends SpecConfigShape> = VariantType<ProcessSpecType<VariantType<Entity, K, V>, Spec['spec'][V & keyof Spec['spec']], Config>, K, V>;
|
|
136
|
+
type OptimizedAttributes<Entity, Spec, Config extends SpecConfigShape> = Spec extends DiscriminatedSchemaShape ? {
|
|
136
137
|
[K in Spec['discriminator']]: {
|
|
137
138
|
[V in keyof Spec['spec']]: ProcessVariant<Entity, K, V, Spec, Config>;
|
|
138
139
|
}[keyof Spec['spec']];
|
|
139
140
|
}[Spec['discriminator']] : ProcessSpecType<Entity, Spec, Config>;
|
|
140
|
-
type ProcessKey<Entity
|
|
141
|
-
type OptimizedBuildedKey<NarrowEntity
|
|
141
|
+
type ProcessKey<Entity, 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;
|
|
142
|
+
type OptimizedBuildedKey<NarrowEntity, Spec, Separator extends string, Config extends SpecConfigShape, Attributes> = Spec extends DiscriminatedSchemaShape ? {
|
|
142
143
|
[K in Spec['discriminator']]: {
|
|
143
|
-
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity
|
|
144
|
+
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity extends {
|
|
145
|
+
[k in K]: V;
|
|
146
|
+
} ? NarrowEntity : never, Spec['spec'][V], Separator, undefined, Config, Attributes>;
|
|
144
147
|
}[keyof Spec['spec']];
|
|
145
148
|
}[Spec['discriminator']] : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>;
|
|
146
|
-
type TableEntryDefinition<Entity
|
|
149
|
+
type TableEntryDefinition<Entity, Schema, Separator extends string> = {
|
|
147
150
|
toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(item: ExactEntity) => ExactEntity extends infer E extends Entity ? TableEntryImpl<E, Schema, Separator> : never;
|
|
148
151
|
fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(entry: Entry) => DistributiveOmit<Entry, keyof Schema>;
|
|
149
152
|
key: <const Key extends keyof Schema, const Config extends SpecConfig<Spec>, const Attributes extends OptimizedAttributes<Entity, Spec, Config_>, Spec = Schema[Key], Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] ? {
|
package/dist/Rotorise.d.ts
CHANGED
|
@@ -62,26 +62,29 @@ type SliceFromStart<
|
|
|
62
62
|
: Acc
|
|
63
63
|
: never
|
|
64
64
|
|
|
65
|
-
type
|
|
66
|
-
[K in
|
|
65
|
+
type MergeIntersectionObject<T, Keys = keyof T> = {
|
|
66
|
+
[K in Keys]: T[K]
|
|
67
67
|
}
|
|
68
|
+
// type t = MergeIntersectionObject<
|
|
69
|
+
// { a: 'a1'; b: 1n; extra: 'extra' } | { a: 'a2'; b: 2 }
|
|
70
|
+
// >
|
|
68
71
|
|
|
69
72
|
type NonEmptyArray<T> = [T, ...T[]]
|
|
70
73
|
|
|
71
74
|
type Replace<T, U, V> = T extends U ? V : T
|
|
72
75
|
|
|
73
|
-
type CompositeKeyParamsImpl<Entity
|
|
74
|
-
type CompositeKeyParams<Entity extends Record<string, unknown>, FullSpec extends InputSpec<Entity
|
|
75
|
-
type CompositeKeyBuilderImpl<Entity
|
|
76
|
-
type CompositeKeyBuilder<Entity extends Record<string, unknown>, Spec extends InputSpec<Entity
|
|
76
|
+
type CompositeKeyParamsImpl<Entity, InputSpec extends InputSpecShape, skip extends number = 1> = Entity extends unknown ? evaluate<Pick<Entity, extractHeadOrPass<SliceFromStart<InputSpec, number extends skip ? 1 : skip>[number]> & keyof Entity> & Partial<Pick<Entity, extractHeadOrPass<InputSpec[number]> & keyof Entity>>> : never;
|
|
77
|
+
type CompositeKeyParams<Entity extends Record<string, unknown>, FullSpec extends InputSpec<MergeIntersectionObject<Entity>>[], skip extends number = 1> = CompositeKeyParamsImpl<Entity, FullSpec, skip>;
|
|
78
|
+
type CompositeKeyBuilderImpl<Entity, Spec, Separator extends string = '#', Deep extends number = number, isPartial extends boolean = false> = Entity extends unknown ? Join<CompositeKeyRec<Entity, number extends Deep ? Spec : SliceFromStart<Spec, Deep>>, Separator, (boolean extends isPartial ? false : isPartial) extends false ? false : true> : never;
|
|
79
|
+
type CompositeKeyBuilder<Entity extends Record<string, unknown>, Spec extends InputSpec<MergeIntersectionObject<Entity>>[], Separator extends string = '#', Deep extends number = number, isPartial extends boolean = false> = CompositeKeyBuilderImpl<Entity, Spec, Separator, Deep, isPartial>;
|
|
77
80
|
type joinable = string | number | bigint | boolean | null | undefined;
|
|
78
81
|
type joinablePair = [joinable, joinable];
|
|
79
82
|
type Join<Pairs, Separator extends string, KeepIntermediate extends boolean = false, Acc extends string = '', AllAcc extends string = never> = Pairs extends [infer Head extends joinablePair, ...infer Tail] ? Join<Tail, Separator, KeepIntermediate, Acc extends '' ? `${Head[0]}${Separator}${Head[1]}` : `${Acc}${Separator}${Head[0]}${Separator}${Head[1]}`, KeepIntermediate extends true ? AllAcc | (Acc extends '' ? never : Acc) : never> : AllAcc | Acc;
|
|
80
|
-
type ExtractPair<Entity
|
|
83
|
+
type ExtractPair<Entity, Spec> = Spec extends [
|
|
81
84
|
infer Key extends string,
|
|
82
85
|
(...key: any[]) => infer Value extends joinable
|
|
83
86
|
] ? [Uppercase<Key>, Value] : Spec extends keyof Entity & string ? [Uppercase<Spec>, Entity[Spec] & joinable] : never;
|
|
84
|
-
type CompositeKeyRec<Entity
|
|
87
|
+
type CompositeKeyRec<Entity, Spec, Acc extends joinablePair[] = [], KeysCache extends string = keyof Entity & string> = Spec extends [infer Head, ...infer Tail] ? CompositeKeyRec<Entity, Tail, [
|
|
85
88
|
...Acc,
|
|
86
89
|
ExtractPair<Entity, Head>
|
|
87
90
|
], KeysCache> : Acc;
|
|
@@ -91,8 +94,8 @@ type DiscriminatedSchemaShape = {
|
|
|
91
94
|
[k in PropertyKey]: unknown;
|
|
92
95
|
};
|
|
93
96
|
};
|
|
94
|
-
type InputSpecShape = ([
|
|
95
|
-
type TableEntryImpl<Entity
|
|
97
|
+
type InputSpecShape = ([PropertyKey, (key: any) => unknown] | PropertyKey)[];
|
|
98
|
+
type TableEntryImpl<Entity, Schema, Separator extends string = '#'> = Entity extends unknown ? {
|
|
96
99
|
[Key in keyof Schema]: Schema[Key] extends DiscriminatedSchemaShape ? ValueOf<{
|
|
97
100
|
[K in Schema[Key]['discriminator']]: {
|
|
98
101
|
[V in keyof Schema[Key]['spec']]: ProcessKey<Entity, Schema[Key]['spec'][V], Separator>;
|
|
@@ -100,13 +103,12 @@ type TableEntryImpl<Entity extends Record<string, unknown>, Schema, Separator ex
|
|
|
100
103
|
}> : ProcessKey<Entity, Schema[Key], Separator>;
|
|
101
104
|
} & Entity : never;
|
|
102
105
|
type TableEntry<Entity extends Record<string, unknown>, Schema extends Record<string, FullKeySpec<Entity>>, Separator extends string = '#'> = TableEntryImpl<Entity, Schema, Separator>;
|
|
103
|
-
type InputSpec<
|
|
106
|
+
type InputSpec<E> = {
|
|
104
107
|
[key in keyof E]: [key, (key: E[key]) => unknown] | (undefined extends E[key] ? never : null extends E[key] ? never : key);
|
|
105
108
|
}[keyof E];
|
|
106
109
|
type extractHeadOrPass<T> = T extends unknown[] ? T[0] : T;
|
|
107
|
-
type FullKeySpecSimple<Entity
|
|
108
|
-
type
|
|
109
|
-
type DiscriminatedSchema<Entity extends Record<string, unknown>, E extends Record<string, unknown> = UnionToObject<Entity>> = {
|
|
110
|
+
type FullKeySpecSimple<Entity> = NonEmptyArray<InputSpec<MergeIntersectionObject<Entity>>> | (keyof Entity & string) | null;
|
|
111
|
+
type DiscriminatedSchema<Entity, E> = {
|
|
110
112
|
[key in keyof E]: E[key] extends PropertyKey ? {
|
|
111
113
|
discriminator: key;
|
|
112
114
|
spec: {
|
|
@@ -116,9 +118,8 @@ type DiscriminatedSchema<Entity extends Record<string, unknown>, E extends Recor
|
|
|
116
118
|
};
|
|
117
119
|
} : never;
|
|
118
120
|
}[keyof E];
|
|
119
|
-
type FullKeySpec<Entity
|
|
120
|
-
type
|
|
121
|
-
type ProcessSpecType<Entity extends Record<string, unknown>, Spec, Config extends SpecConfigShape> = Spec extends string ? DistributivePick<Entity, Spec> : Spec extends InputSpecShape ? CompositeKeyParamsImpl<Entity, Spec, Config['allowPartial'] extends true ? 1 : Extract<Config['depth'], number>> : never;
|
|
121
|
+
type FullKeySpec<Entity> = FullKeySpecSimple<Entity> | DiscriminatedSchema<Entity, MergeIntersectionObject<Entity>>;
|
|
122
|
+
type ProcessSpecType<Entity, Spec, Config extends SpecConfigShape> = Spec extends string ? DistributivePick<Entity, Spec> : Spec extends InputSpecShape ? CompositeKeyParamsImpl<Entity, Spec, Config['allowPartial'] extends true ? 1 : Extract<Config['depth'], number>> : never;
|
|
122
123
|
type SpecConfig<Spec> = Spec extends string ? never : SpecConfigShape;
|
|
123
124
|
type SpecConfigShape = {
|
|
124
125
|
depth?: number;
|
|
@@ -131,19 +132,21 @@ type VariantType<Entity, K extends PropertyKey, V extends PropertyKey> = [
|
|
|
131
132
|
} : Entity & {
|
|
132
133
|
[k in K]: V;
|
|
133
134
|
};
|
|
134
|
-
type ProcessVariant<Entity
|
|
135
|
-
type OptimizedAttributes<Entity
|
|
135
|
+
type ProcessVariant<Entity, K extends PropertyKey, V extends PropertyKey, Spec extends DiscriminatedSchemaShape, Config extends SpecConfigShape> = VariantType<ProcessSpecType<VariantType<Entity, K, V>, Spec['spec'][V & keyof Spec['spec']], Config>, K, V>;
|
|
136
|
+
type OptimizedAttributes<Entity, Spec, Config extends SpecConfigShape> = Spec extends DiscriminatedSchemaShape ? {
|
|
136
137
|
[K in Spec['discriminator']]: {
|
|
137
138
|
[V in keyof Spec['spec']]: ProcessVariant<Entity, K, V, Spec, Config>;
|
|
138
139
|
}[keyof Spec['spec']];
|
|
139
140
|
}[Spec['discriminator']] : ProcessSpecType<Entity, Spec, Config>;
|
|
140
|
-
type ProcessKey<Entity
|
|
141
|
-
type OptimizedBuildedKey<NarrowEntity
|
|
141
|
+
type ProcessKey<Entity, 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;
|
|
142
|
+
type OptimizedBuildedKey<NarrowEntity, Spec, Separator extends string, Config extends SpecConfigShape, Attributes> = Spec extends DiscriminatedSchemaShape ? {
|
|
142
143
|
[K in Spec['discriminator']]: {
|
|
143
|
-
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity
|
|
144
|
+
[V in keyof Spec['spec']]: ProcessKey<NarrowEntity extends {
|
|
145
|
+
[k in K]: V;
|
|
146
|
+
} ? NarrowEntity : never, Spec['spec'][V], Separator, undefined, Config, Attributes>;
|
|
144
147
|
}[keyof Spec['spec']];
|
|
145
148
|
}[Spec['discriminator']] : ProcessKey<NarrowEntity, Spec, Separator, undefined, Config, Attributes>;
|
|
146
|
-
type TableEntryDefinition<Entity
|
|
149
|
+
type TableEntryDefinition<Entity, Schema, Separator extends string> = {
|
|
147
150
|
toEntry: <const ExactEntity extends Exact<Entity, ExactEntity>>(item: ExactEntity) => ExactEntity extends infer E extends Entity ? TableEntryImpl<E, Schema, Separator> : never;
|
|
148
151
|
fromEntry: <const Entry extends TableEntryImpl<Entity, Schema, Separator>>(entry: Entry) => DistributiveOmit<Entry, keyof Schema>;
|
|
149
152
|
key: <const Key extends keyof Schema, const Config extends SpecConfig<Spec>, const Attributes extends OptimizedAttributes<Entity, Spec, Config_>, Spec = Schema[Key], Config_ extends SpecConfigShape = [SpecConfigShape] extends [Config] ? {
|
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 ValueOf,\n evaluate,\n MergeIntersectionObject,\n} from './utils'\n\nexport type CompositeKeyParamsImpl<\n Entity,\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<MergeIntersectionObject<Entity>>[],\n skip extends number = 1,\n> = CompositeKeyParamsImpl<Entity, FullSpec, skip>\n\ntype CompositeKeyBuilderImpl<\n Entity,\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<MergeIntersectionObject<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, 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,\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 = ([PropertyKey, (key: any) => unknown] | PropertyKey)[]\n\ntype TableEntryImpl<\n Entity,\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<E> = {\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> =\n | NonEmptyArray<InputSpec<MergeIntersectionObject<Entity>>>\n | (keyof Entity & string)\n | null\n\ntype FullKeySpecSimpleShape = InputSpecShape | string | null\n\ntype DiscriminatedSchema<Entity, E> = {\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> =\n | FullKeySpecSimple<Entity>\n | DiscriminatedSchema<Entity, MergeIntersectionObject<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>() =>\n <\n const Schema extends Record<\n string,\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]:\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | 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<MergeIntersectionObject<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<MergeIntersectionObject<Entity>>[]\n | keyof Entity\n | {\n discriminator: keyof Entity\n spec: {\n [val in string]:\n | InputSpec<MergeIntersectionObject<Entity>>[]\n | 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,\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,\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,\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,\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,\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<Entity, Schema, Separator extends string> = {\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"]}
|