@karmaniverous/entity-manager 6.14.3 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { EntityMap, TranscodeMap, ConditionalProperty, Exactify, PropertiesOfType, TranscodableProperties, FlattenEntityMap, Transcodes, MutuallyExclusive, NotNever, DefaultTranscodeMap, SortOrder } from '@karmaniverous/entity-tools';
2
- import { z } from 'zod';
1
+ import { EntityMap, TranscodeRegistry, ConditionalProperty, Exactify, PropertiesOfType, TranscodableProperties, FlattenEntityMap, Transcodes, MutuallyExclusive, NotNever, DefaultTranscodeRegistry, SortOrder } from '@karmaniverous/entity-tools';
2
+ import * as z from 'zod';
3
+ import { z as z$1, ZodType } from 'zod';
3
4
  import { BatchProcessOptions } from '@karmaniverous/batch-process';
4
5
 
5
6
  /**
@@ -14,7 +15,7 @@ interface BaseConfigMap {
14
15
  ShardedKeys: string;
15
16
  UnshardedKeys: string;
16
17
  TranscodedProperties: string;
17
- TranscodeMap: TranscodeMap;
18
+ TranscodeRegistry: TranscodeRegistry;
18
19
  }
19
20
 
20
21
  /**
@@ -48,7 +49,7 @@ interface ShardBump {
48
49
  /**
49
50
  * Configuration object for an {@link EntityManager | `EntityManager`} instance.
50
51
  *
51
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
52
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
52
53
  *
53
54
  * @category EntityManager
54
55
  */
@@ -57,18 +58,18 @@ type Config<C extends BaseConfigMap = BaseConfigMap> = ConditionalProperty<'enti
57
58
  defaultLimit?: number;
58
59
  defaultPageSize?: number;
59
60
  shardBumps?: ShardBump[];
60
- timestampProperty: C['TranscodedProperties'] & PropertiesOfType<C['EntityMap'][E], number> & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>;
61
- uniqueProperty: C['TranscodedProperties'] & keyof C['EntityMap'][E] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>;
61
+ timestampProperty: C['TranscodedProperties'] & PropertiesOfType<C['EntityMap'][E], number> & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>;
62
+ uniqueProperty: C['TranscodedProperties'] & keyof C['EntityMap'][E] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>;
62
63
  };
63
- }> & ConditionalProperty<'generatedProperties', C['ShardedKeys'] | C['UnshardedKeys'], ConditionalProperty<'sharded', C['ShardedKeys'], Record<C['ShardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>)[]>> & ConditionalProperty<'unsharded', C['UnshardedKeys'], Record<C['UnshardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>)[]>>> & ConditionalProperty<'propertyTranscodes', C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>, {
64
- [P in C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>]: PropertiesOfType<C['TranscodeMap'], FlattenEntityMap<C['EntityMap']>[P]>;
65
- }> & ConditionalProperty<'transcodes', keyof C['TranscodeMap'], Transcodes<C['TranscodeMap']>> & {
64
+ }> & ConditionalProperty<'generatedProperties', C['ShardedKeys'] | C['UnshardedKeys'], ConditionalProperty<'sharded', C['ShardedKeys'], Record<C['ShardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>)[]>> & ConditionalProperty<'unsharded', C['UnshardedKeys'], Record<C['UnshardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>)[]>>> & ConditionalProperty<'propertyTranscodes', C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>, {
65
+ [P in C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>]: PropertiesOfType<C['TranscodeRegistry'], FlattenEntityMap<C['EntityMap']>[P]>;
66
+ }> & ConditionalProperty<'transcodes', keyof C['TranscodeRegistry'], Transcodes<C['TranscodeRegistry']>> & {
66
67
  generatedKeyDelimiter?: string;
67
68
  generatedValueDelimiter?: string;
68
69
  hashKey: C['HashKey'];
69
70
  indexes?: Record<string, {
70
71
  hashKey: C['HashKey'] | C['ShardedKeys'];
71
- rangeKey: C['RangeKey'] | C['UnshardedKeys'] | (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>);
72
+ rangeKey: C['RangeKey'] | C['UnshardedKeys'] | (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeRegistry']>);
72
73
  projections?: string[];
73
74
  }>;
74
75
  rangeKey: C['RangeKey'];
@@ -79,27 +80,27 @@ type Config<C extends BaseConfigMap = BaseConfigMap> = ConditionalProperty<'enti
79
80
  /**
80
81
  * Validates a type derived from {@link BaseConfigMap | `BaseConfigMap`} to ensure HashKey and RangeKey are both defined and that all sets of special keys are mutually exclusive.
81
82
  *
82
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
83
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
83
84
  *
84
85
  * @category EntityManager
85
86
  * @protected
86
87
  */
87
- type ValidateConfigMap<C extends BaseConfigMap> = MutuallyExclusive<[
88
- C['HashKey'],
89
- C['RangeKey'],
90
- C['ShardedKeys'],
91
- C['UnshardedKeys'],
92
- keyof FlattenEntityMap<C['EntityMap']>
93
- ]> extends true ? NotNever<C, ['HashKey' | 'RangeKey']> extends true ? C : Exclude<NotNever<C, ['HashKey' | 'RangeKey']>, true> : Exclude<MutuallyExclusive<[
94
- C['HashKey'],
95
- C['RangeKey'],
96
- C['ShardedKeys'],
97
- C['UnshardedKeys'],
98
- keyof FlattenEntityMap<C['EntityMap']>
88
+ type ValidateConfigMap<CC extends BaseConfigMap> = MutuallyExclusive<[
89
+ CC['HashKey'],
90
+ CC['RangeKey'],
91
+ CC['ShardedKeys'],
92
+ CC['UnshardedKeys'],
93
+ keyof FlattenEntityMap<CC['EntityMap']>
94
+ ]> extends true ? NotNever<CC, ['HashKey' | 'RangeKey']> extends true ? CC : Exclude<NotNever<CC, ['HashKey' | 'RangeKey']>, true> : Exclude<MutuallyExclusive<[
95
+ CC['HashKey'],
96
+ CC['RangeKey'],
97
+ CC['ShardedKeys'],
98
+ CC['UnshardedKeys'],
99
+ keyof FlattenEntityMap<CC['EntityMap']>
99
100
  ]>, true>;
100
101
 
101
102
  /**
102
- * Generates & validates the map defining defines an {@link EntityManager | `EntityManager`} configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}.
103
+ * Generates & validates the map defining defines an {@link EntityManager | `EntityManager`} configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}.
103
104
  *
104
105
  * Unspecified properties will default to those defined in {@link BaseConfigMap | `BaseConfigMap`}.
105
106
  *
@@ -114,58 +115,48 @@ type ConfigMap<M extends Partial<BaseConfigMap> = Partial<BaseConfigMap>> = Vali
114
115
  ShardedKeys: 'ShardedKeys' extends keyof M ? NonNullable<M['ShardedKeys']> : never;
115
116
  UnshardedKeys: 'UnshardedKeys' extends keyof M ? NonNullable<M['UnshardedKeys']> : never;
116
117
  TranscodedProperties: 'TranscodedProperties' extends keyof M ? NonNullable<M['TranscodedProperties']> : never;
117
- TranscodeMap: 'TranscodeMap' extends keyof M ? NonNullable<M['TranscodeMap']> : DefaultTranscodeMap;
118
+ TranscodeRegistry: 'TranscodeRegistry' extends keyof M ? NonNullable<M['TranscodeRegistry']> : DefaultTranscodeRegistry;
118
119
  }>;
119
120
 
120
121
  /**
121
122
  * Extracts a database-facing partial item type from a {@link BaseConfigMap | `ConfigMap`}.
122
123
  *
123
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
124
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
124
125
  *
125
126
  * @category EntityManager
126
127
  * @protected
127
128
  */
128
- type EntityItem<C extends BaseConfigMap> = Partial<FlattenEntityMap<C['EntityMap']> & Record<C['HashKey'] | C['RangeKey'] | C['ShardedKeys'] | C['UnshardedKeys'], string>> & Record<string, unknown>;
129
+ type EntityItem<CC extends BaseConfigMap> = Partial<FlattenEntityMap<CC['EntityMap']> & Record<CC['HashKey'] | CC['RangeKey'] | CC['ShardedKeys'] | CC['UnshardedKeys'], string>> & Record<string, unknown>;
129
130
 
130
131
  /**
131
132
  * Database-facing record key type from a {@link BaseConfigMap | `ConfigMap`} with required hash & range keys.
132
133
  *
133
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
134
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
134
135
  *
135
136
  * @category EntityClient
136
137
  * @protected
137
138
  */
138
- type EntityKey<C extends BaseConfigMap> = Record<C['HashKey'] | C['RangeKey'], string>;
139
-
140
- /**
141
- * Database-facing record type from a {@link BaseConfigMap | `ConfigMap`} with required hash & range keys.
142
- *
143
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
144
- *
145
- * @category EntityManager
146
- * @protected
147
- */
148
- type EntityRecord<C extends BaseConfigMap> = EntityItem<C> & EntityKey<C>;
139
+ type EntityKey<CC extends BaseConfigMap> = Record<CC['HashKey'] | CC['RangeKey'], string>;
149
140
 
150
141
  /**
151
142
  * Extracts entity tokens from a {@link ConfigMap | `ConfigMap`}.
152
143
  *
153
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
144
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
154
145
  *
155
146
  * @category EntityManager
156
147
  * @protected
157
148
  */
158
- type EntityToken<C extends BaseConfigMap> = keyof Exactify<C['EntityMap']> & string;
149
+ type EntityToken<CC extends BaseConfigMap> = keyof Exactify<CC['EntityMap']> & string;
159
150
 
160
- declare const configSchema: z.ZodObject<{
161
- entities: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
162
- defaultLimit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
163
- defaultPageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
164
- shardBumps: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
165
- timestamp: z.ZodNumber;
166
- charBits: z.ZodNumber;
167
- chars: z.ZodNumber;
168
- }, z.core.$strict>>>>, z.ZodTransform<{
151
+ declare const configSchema: z$1.ZodObject<{
152
+ entities: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
153
+ defaultLimit: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodNumber>>;
154
+ defaultPageSize: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodNumber>>;
155
+ shardBumps: z$1.ZodPipe<z$1.ZodDefault<z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
156
+ timestamp: z$1.ZodNumber;
157
+ charBits: z$1.ZodNumber;
158
+ chars: z$1.ZodNumber;
159
+ }, z$1.core.$strict>>>>, z$1.ZodTransform<{
169
160
  timestamp: number;
170
161
  charBits: number;
171
162
  chars: number;
@@ -174,62 +165,116 @@ declare const configSchema: z.ZodObject<{
174
165
  charBits: number;
175
166
  chars: number;
176
167
  }[]>>;
177
- timestampProperty: z.ZodString;
178
- uniqueProperty: z.ZodString;
179
- }, z.core.$strict>>>>;
180
- generatedProperties: z.ZodDefault<z.ZodOptional<z.ZodObject<{
181
- sharded: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>>;
182
- unsharded: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>>;
183
- }, z.core.$strip>>>;
184
- hashKey: z.ZodString;
185
- indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
186
- hashKey: z.ZodString;
187
- rangeKey: z.ZodString;
188
- projections: z.ZodOptional<z.ZodArray<z.ZodString>>;
189
- }, z.core.$strip>>>>;
190
- generatedKeyDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
191
- generatedValueDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
192
- propertyTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
193
- rangeKey: z.ZodString;
194
- shardKeyDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
195
- throttle: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
196
- transcodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
197
- encode: z.ZodCustom<unknown, unknown>;
198
- decode: z.ZodCustom<unknown, unknown>;
199
- }, z.core.$strict>>>>;
200
- }, z.core.$strict>;
168
+ timestampProperty: z$1.ZodString;
169
+ uniqueProperty: z$1.ZodString;
170
+ }, z$1.core.$strict>>>>;
171
+ generatedProperties: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodObject<{
172
+ sharded: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodArray<z$1.ZodString>>>>;
173
+ unsharded: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodArray<z$1.ZodString>>>>;
174
+ }, z$1.core.$strip>>>;
175
+ hashKey: z$1.ZodString;
176
+ indexes: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
177
+ hashKey: z$1.ZodString;
178
+ rangeKey: z$1.ZodString;
179
+ projections: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
180
+ }, z$1.core.$strip>>>>;
181
+ generatedKeyDelimiter: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodString>>;
182
+ generatedValueDelimiter: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodString>>;
183
+ propertyTranscodes: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodString>>>;
184
+ rangeKey: z$1.ZodString;
185
+ shardKeyDelimiter: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodString>>;
186
+ throttle: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodNumber>>;
187
+ transcodes: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
188
+ encode: z$1.ZodCustom<unknown, unknown>;
189
+ decode: z$1.ZodCustom<unknown, unknown>;
190
+ }, z$1.core.$strict>>>>;
191
+ }, z$1.core.$strict>;
201
192
  /**
202
193
  * Simplified type taken on by a {@link Config | `Config`} object after parsing in the {@link EntityManager | `EntityManager`} constructor.
203
194
  *
204
195
  * @category EntityManager
205
196
  */
206
- type ParsedConfig = z.infer<typeof configSchema>;
197
+ type ParsedConfig = z$1.infer<typeof configSchema>;
207
198
 
208
199
  /**
209
200
  * A partial {@link EntityItem | `EntityItem`} restricted to keys defined in `C`.
210
201
  *
211
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
202
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
212
203
  *
213
204
  * @category QueryBuilder
214
205
  * @protected
215
206
  */
216
- type PageKey<C extends BaseConfigMap> = Pick<EntityItem<C>, C['HashKey'] | C['RangeKey'] | C['ShardedKeys'] | C['UnshardedKeys'] | C['TranscodedProperties']>;
207
+ type PageKey<CC extends BaseConfigMap> = Pick<EntityItem<CC>, CC['HashKey'] | CC['RangeKey'] | CC['ShardedKeys'] | CC['UnshardedKeys'] | CC['TranscodedProperties']>;
208
+ /**
209
+ * Internal helpers to safely derive index component tokens for an index IT.
210
+ *
211
+ * These helpers avoid direct generic indexing into `CF['indexes'][IT]` which can
212
+ * trigger TS2536. They guard presence and key membership before extracting
213
+ * literal types when available.
214
+ */
215
+ type IndexHashKeyOf<CF, IT extends string> = CF extends {
216
+ indexes?: infer I;
217
+ } ? I extends Record<string, unknown> ? IT extends keyof I ? I[IT] extends {
218
+ hashKey: infer HK;
219
+ } ? HK & string : never : never : never : never;
220
+ type IndexRangeKeyOf<CF, IT extends string> = CF extends {
221
+ indexes?: infer I;
222
+ } ? I extends Record<string, unknown> ? IT extends keyof I ? I[IT] extends {
223
+ rangeKey: infer RK;
224
+ } ? RK & string : never : never : never : never;
225
+ /**
226
+ * Derive the union of index token names from a values-first config literal.
227
+ *
228
+ * When CF carries an `indexes` object with preserved literal keys (prefer `as const`),
229
+ * this helper captures the index token union. Falls back to `string` if absent.
230
+ */
231
+ type IndexTokensOf<CF> = CF extends {
232
+ indexes?: infer I;
233
+ } ? I extends Record<string, unknown> ? keyof I & string : string : string;
234
+ type HasIndexFor<CF, IT extends string> = CF extends {
235
+ indexes?: infer I;
236
+ } ? I extends Record<string, unknown> ? IT extends keyof I ? true : false : false : false;
237
+ type IndexComponentTokens<CC extends BaseConfigMap, CF, IT extends string> = HasIndexFor<CF, IT> extends true ? CC['HashKey'] | CC['RangeKey'] | IndexHashKeyOf<CF, IT> | IndexRangeKeyOf<CF, IT> : CC['HashKey'] | CC['RangeKey'] | CC['ShardedKeys'] | CC['UnshardedKeys'] | CC['TranscodedProperties'];
238
+ /**
239
+ * Page key typed for a specific index token.
240
+ *
241
+ * - With CF (values-first config literal) present and carrying `indexes`, the
242
+ * shape narrows to exactly the component tokens of IT.
243
+ * - Without CF, falls back to the broad PageKey<CC> shape.
244
+ */
245
+ type PageKeyByIndex<CC extends BaseConfigMap, ET extends EntityToken<CC>, IT extends string = string, CF = unknown> = Pick<EntityItem<CC>, IndexComponentTokens<CC, CF, IT>>;
246
+
247
+ /** EntityOfToken — resolves the concrete entity shape for a specific entity token. */
248
+ type EntityOfToken<CC extends BaseConfigMap, ET extends EntityToken<CC>> = Exactify<CC['EntityMap']>[ET];
249
+ /**
250
+ * EntityItemByToken — database-facing partial item narrowed to a specific entity token.
251
+ * Mirrors `EntityItem<CC>` with the entity surface restricted to `EntityOfToken<CC, ET>`.
252
+ *
253
+ * Note: If using createEntityManager with entitiesSchema, the schema must declare
254
+ * only base (non-generated) properties. Generated keys/tokens are layered by EntityManager.
255
+ */
256
+ type EntityItemByToken<CC extends BaseConfigMap, ET extends EntityToken<CC>> = Partial<EntityOfToken<CC, ET> & Record<CC['HashKey'] | CC['RangeKey'] | CC['ShardedKeys'] | CC['UnshardedKeys'], string>> & Record<string, unknown>;
257
+ /** EntityRecordByToken — database-facing record (keys required) narrowed to a specific entity token. */
258
+ type EntityRecordByToken<CC extends BaseConfigMap, ET extends EntityToken<CC>> = EntityItemByToken<CC, ET> & EntityKey<CC>;
217
259
 
218
260
  /**
219
261
  * A result returned by a {@link ShardQueryFunction | `ShardQueryFunction`} querying an individual shard.
220
262
  *
221
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
263
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`}.
264
+ * @typeParam ET - Entity token narrowing the item type.
265
+ * @typeParam IT - Index token (for page key typing).
266
+ * @typeParam CF - Optional values-first config literal type for narrowing.
222
267
  *
223
268
  * @category EntityManager
224
269
  * @protected
225
270
  */
226
- interface ShardQueryResult<C extends BaseConfigMap> {
271
+ interface ShardQueryResult<CC extends BaseConfigMap, ET extends EntityToken<CC>, IT extends string, CF = unknown> {
227
272
  /** The number of records returned. */
228
273
  count: number;
229
274
  /** The returned records. */
230
- items: EntityItem<C>[];
275
+ items: EntityItemByToken<CC, ET>[];
231
276
  /** The page key for the next query on this shard. */
232
- pageKey?: PageKey<C>;
277
+ pageKey?: PageKeyByIndex<CC, ET, IT, CF>;
233
278
  }
234
279
 
235
280
  /**
@@ -238,41 +283,81 @@ interface ShardQueryResult<C extends BaseConfigMap> {
238
283
  * This function will typically be composed dynamically to express a specific query index & logic. The arguments to this function will be provided by the {@link EntityManager.query | `EntityManager.query`} method, which assembles many returned pages queried across multiple shards into a single query result.
239
284
  *
240
285
  * @param hashKey - The hash key value of the shard being queried.
241
- * @param pageKey - The {@link PageKey | `PageKey`} returned by the previous query on this shard.
286
+ * @param pageKey - The typed page key for the index being queried.
242
287
  * @param pageSize - The maximum number of items to return from this query.
243
288
  *
244
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
289
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`}.
290
+ * @typeParam ET - Entity token narrowing the item/record types.
291
+ * @typeParam IT - Index token (inferred from shardQueryMap keys).
292
+ * @typeParam CF - Optional values-first config literal type for narrowing.
245
293
  *
246
294
  * @category EntityManager
247
295
  * @protected
248
296
  */
249
- type ShardQueryFunction<C extends BaseConfigMap> = (hashKey: string, pageKey?: PageKey<C>, pageSize?: number) => Promise<ShardQueryResult<C>>;
297
+ type ShardQueryFunction<CC extends BaseConfigMap, ET extends EntityToken<CC>, IT extends string, CF = unknown> = CF extends {
298
+ indexes?: infer I;
299
+ } ? I extends Record<string, unknown> ? IT extends keyof I & string ? (hashKey: string, pageKey?: PageKeyByIndex<CC, ET, IT, CF>, pageSize?: number) => Promise<ShardQueryResult<CC, ET, IT, CF>> : never : (hashKey: string, pageKey?: PageKeyByIndex<CC, ET, IT, CF>, pageSize?: number) => Promise<ShardQueryResult<CC, ET, IT, CF>> : (hashKey: string, pageKey?: PageKeyByIndex<CC, ET, IT, CF>, pageSize?: number) => Promise<ShardQueryResult<CC, ET, IT, CF>>;
250
300
 
251
301
  /**
252
302
  * Relates a specific index token to a {@link ShardQueryFunction | `ShardQueryFunction`} to be performed on that index.
253
303
  *
254
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
304
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`}.
305
+ * @typeParam ET - Entity token narrowing the function item types.
306
+ * @typeParam ITS - Index token subset (inferred from object keys).
307
+ * @typeParam CF - Optional values-first config literal type for narrowing. When
308
+ * provided and it carries an `indexes` object with preserved
309
+ * literal keys (prefer `as const` at call sites), the map keys
310
+ * are constrained to that set. Excess keys are rejected by
311
+ * excess property checks on object literals.
255
312
  *
256
313
  * @category EntityManager
257
314
  * @protected
258
315
  */
259
- type ShardQueryMap<C extends BaseConfigMap> = Record<string, ShardQueryFunction<C>>;
316
+ type ShardQueryMap<CC extends BaseConfigMap, ET extends EntityToken<CC>, ITS extends string, CF = unknown> = CF extends {
317
+ indexes?: infer I;
318
+ } ? I extends Record<string, unknown> ? Record<ITS & (keyof I & string), ShardQueryFunction<CC, ET, ITS & (keyof I & string), CF>> : Record<ITS, ShardQueryFunction<CC, ET, ITS, CF>> : Record<ITS, ShardQueryFunction<CC, ET, ITS, CF>>;
319
+ /**
320
+ * Convenience alias for ShardQueryMap that derives ITS (index token subset)
321
+ * from a values-first captured config CC (e.g., your config literal type).
322
+ *
323
+ * - If CC has `indexes`, ITS becomes the union of its keys.
324
+ * - Otherwise, ITS defaults to `string`.
325
+ *
326
+ * It also passes CC through the CF channel so per-index page-key narrowing
327
+ * applies consistently.
328
+ *
329
+ * This is optional DX sugar; it does not change runtime behavior.
330
+ */
331
+ type ShardQueryMapByCC<CC extends BaseConfigMap, ET extends EntityToken<CC>, CCLit = unknown> = ShardQueryMap<CC, ET, IndexTokensFrom<CCLit>, CCLit>;
332
+ /**
333
+ * Convenience alias for ShardQueryMap that derives ITS (index token subset)
334
+ * directly from a values-first config literal CF when it carries `indexes`.
335
+ *
336
+ * - If CF has `indexes`, ITS becomes the union of its keys.
337
+ * - Otherwise, ITS defaults to `string`.
338
+ *
339
+ * This is optional DX sugar; it does not change runtime behavior.
340
+ */
341
+ type ShardQueryMapByCF<CC extends BaseConfigMap, ET extends EntityToken<CC>, CF = unknown> = ShardQueryMap<CC, ET, IndexTokensOf<CF>, CF>;
260
342
 
261
343
  /**
262
344
  * Options passed to the {@link EntityManager.query | `EntityManager.query`} method.
263
345
  *
264
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
346
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
347
+ * @typeParam ET - Entity token narrowing the item types.
348
+ * @typeParam ITS - Index token subset (inferred from shardQueryMap keys).
349
+ * @typeParam CF - Optional values-first config literal type used for index-aware narrowing.
265
350
  *
266
351
  * @category EntityManager
267
352
  * @protected
268
353
  */
269
- interface QueryOptions<C extends BaseConfigMap> {
354
+ interface QueryOptions<CC extends BaseConfigMap, ET extends EntityToken<CC> = EntityToken<CC>, ITS extends string = string, CF = unknown> {
270
355
  /** Identifies the entity to be queried. Key of {@link Config | `Config`} `entities`. */
271
- entityToken: EntityToken<C>;
356
+ entityToken: ET;
272
357
  /**
273
358
  * Partial item object sufficiently populated to generate index hash keys.
274
359
  */
275
- item: EntityItem<C>;
360
+ item: EntityItemByToken<CC, ET>;
276
361
  /**
277
362
  * The target maximum number of records to be returned by the query across
278
363
  * all shards.
@@ -304,11 +389,11 @@ interface QueryOptions<C extends BaseConfigMap> {
304
389
  * page key, e.g. to match the same string against `firstName` and `lastName`
305
390
  * properties without performing a table scan for either.
306
391
  */
307
- shardQueryMap: ShardQueryMap<C>;
392
+ shardQueryMap: ShardQueryMap<CC, ET, ITS, CF>;
308
393
  /**
309
394
  * A {@link SortOrder | `SortOrder`} object specifying the sort order of the result set. Defaults to `[]`.
310
395
  */
311
- sortOrder?: SortOrder<EntityItem<C>>;
396
+ sortOrder?: SortOrder<EntityItemByToken<CC, ET>>;
312
397
  /**
313
398
  * Lower limit to query shard space.
314
399
  *
@@ -336,20 +421,45 @@ interface QueryOptions<C extends BaseConfigMap> {
336
421
  */
337
422
  throttle?: number;
338
423
  }
424
+ /**
425
+ * Convenience alias for QueryOptions that derives ITS (index token subset)
426
+ * directly from a values-first config literal CF when it carries `indexes`.
427
+ *
428
+ * - If CF has `indexes`, ITS becomes the union of its keys.
429
+ * - Otherwise, ITS defaults to `string`.
430
+ *
431
+ * This is optional DX sugar; it does not change runtime behavior.
432
+ */
433
+ type QueryOptionsByCF<CC extends BaseConfigMap, ET extends EntityToken<CC> = EntityToken<CC>, CF = unknown> = QueryOptions<CC, ET, IndexTokensOf<CF>, CF>;
434
+ /**
435
+ * Convenience alias for QueryOptions that derives ITS (index token subset)
436
+ * from a values-first captured config CC (e.g., your config literal type).
437
+ *
438
+ * - If CC has `indexes`, ITS becomes the union of its keys.
439
+ * - Otherwise, ITS defaults to `string`.
440
+ *
441
+ * It also passes CC through the CF channel so page-key narrowing and other
442
+ * CF-aware typing applies consistently.
443
+ *
444
+ * This is optional DX sugar; it does not change runtime behavior.
445
+ */
446
+ type QueryOptionsByCC<CCMap extends BaseConfigMap, ET extends EntityToken<CCMap> = EntityToken<CCMap>, CC = unknown> = QueryOptions<CCMap, ET, IndexTokensFrom<CC>, CC>;
339
447
 
340
448
  /**
341
449
  * A result returned by a query across multiple shards, where each shard may receive multiple page queries via a dynamically-generated {@link ShardQueryFunction | `ShardQueryFunction`}.
342
450
  *
343
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
451
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`}.
452
+ * @typeParam ET - Entity token narrowing the result item type.
453
+ * @typeParam ITS - Index token subset (carried for symmetry; not represented in the shape).
344
454
  *
345
455
  * @category EntityManager
346
456
  * @protected
347
457
  */
348
- interface QueryResult<C extends BaseConfigMap> {
458
+ interface QueryResult<CC extends BaseConfigMap, ET extends EntityToken<CC>, ITS extends string> {
349
459
  /** Total number of records returned across all shards. */
350
460
  count: number;
351
461
  /** The returned records. */
352
- items: EntityItem<C>[];
462
+ items: EntityItemByToken<CC, ET>[];
353
463
  /**
354
464
  * A compressed, two-layer map of page keys, used to query the next page of
355
465
  * data for a given sort key on each shard of a given hash key.
@@ -361,14 +471,14 @@ interface QueryResult<C extends BaseConfigMap> {
361
471
  * The EntityManager class applies a configuration-driven sharded data model &
362
472
  * query strategy to NoSql data.
363
473
  *
364
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
474
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
365
475
  *
366
476
  * @remarks
367
477
  * While the {@link EntityManager.query | `query`} method is `public`, normally it should not be called directly. The `query` method is used by a platform-specific {@link BaseQueryBuilder.query | `QueryBuilder.query`} method to provide a fluent query API.
368
478
  *
369
479
  * @category EntityManager
370
480
  */
371
- declare class EntityManager<C extends BaseConfigMap> {
481
+ declare class EntityManager<CC extends BaseConfigMap> {
372
482
  #private;
373
483
  /** Logger object (defaults to `console`, must support `debug` & `error` methods). */
374
484
  readonly logger: Pick<Console, 'debug' | 'error'>;
@@ -378,7 +488,7 @@ declare class EntityManager<C extends BaseConfigMap> {
378
488
  * @param config - EntityManager {@link Config | `Config`} object.
379
489
  * @param logger - Logger object (defaults to `console`, must support `debug` & `error` methods).
380
490
  */
381
- constructor(config: Config<C>, logger?: Pick<Console, 'debug' | 'error'>);
491
+ constructor(config: Config<CC>, logger?: Pick<Console, 'debug' | 'error'>);
382
492
  /**
383
493
  * Get the current EntityManager {@link Config | `Config`} object.
384
494
  *
@@ -401,7 +511,7 @@ declare class EntityManager<C extends BaseConfigMap> {
401
511
  *
402
512
  * @throws `Error` if `property` is not a {@link Config | Config} `generatedProperties` key.
403
513
  */
404
- encodeGeneratedProperty<C extends BaseConfigMap>(property: C['ShardedKeys'] | C['UnshardedKeys'], item: EntityItem<C>): string | undefined;
514
+ encodeGeneratedProperty(property: CC['ShardedKeys'] | CC['UnshardedKeys'], item: EntityItem<CC>): string | undefined;
405
515
  /**
406
516
  * Update generated properties, hash key, and range key on an {@link EntityItem | `EntityItem`} object.
407
517
  *
@@ -415,21 +525,11 @@ declare class EntityManager<C extends BaseConfigMap> {
415
525
  *
416
526
  * @overload
417
527
  */
418
- addKeys(entityToken: EntityToken<C>, item: EntityItem<C>, overwrite?: boolean): EntityRecord<C>;
528
+ addKeys<ET extends EntityToken<CC>>(entityToken: ET, item: EntityItemByToken<CC, ET>, overwrite?: boolean): EntityRecordByToken<CC, ET>;
419
529
  /**
420
- * Update generated properties, hash key, and range key on an array of {@link EntityItem | `EntityItem`} objects.
421
- *
422
- * @param entityToken - {@link Config | `Config`} `entities` key.
423
- * @param item - Array of {@link EntityItem | `EntityItem`} objects.
424
- * @param overwrite - Overwrite existing properties (default `false`).
425
- *
426
- * @returns An array of {@link EntityRecord | `EntityRecord`} objects with updated properties.
427
- *
428
- * @throws `Error` if `entityToken` is invalid.
429
- *
430
530
  * @overload
431
531
  */
432
- addKeys(entityToken: EntityToken<C>, item: EntityItem<C>[], overwrite?: boolean): EntityRecord<C>[];
532
+ addKeys<ET extends EntityToken<CC>>(entityToken: ET, item: EntityItemByToken<CC, ET>[], overwrite?: boolean): EntityRecordByToken<CC, ET>[];
433
533
  /**
434
534
  * Convert one or more {@link EntityItem | `EntityItem`} objects into an array of {@link EntityKey | `EntityKey`} values.
435
535
  *
@@ -442,8 +542,11 @@ declare class EntityManager<C extends BaseConfigMap> {
442
542
  *
443
543
  * @throws `Error` if `entityToken` is invalid.
444
544
  */
445
- getPrimaryKey(entityToken: EntityToken<C>, item: EntityItem<C>, overwrite?: boolean): EntityKey<C>[];
446
- getPrimaryKey(entityToken: EntityToken<C>, items: EntityItem<C>[], overwrite?: boolean): EntityKey<C>[];
545
+ getPrimaryKey<ET extends EntityToken<CC>>(entityToken: ET, item: EntityItemByToken<CC, ET>, overwrite?: boolean): EntityKey<CC>[];
546
+ /**
547
+ * @overload
548
+ */
549
+ getPrimaryKey<ET extends EntityToken<CC>>(entityToken: ET, items: EntityItemByToken<CC, ET>[], overwrite?: boolean): EntityKey<CC>[];
447
550
  /**
448
551
  * Strips generated properties, hash key, and range key from an {@link EntityRecord | `EntityRecord`} object.
449
552
  *
@@ -456,20 +559,11 @@ declare class EntityManager<C extends BaseConfigMap> {
456
559
  *
457
560
  * @overload
458
561
  */
459
- removeKeys(entityToken: EntityToken<C>, item: EntityRecord<C>): EntityItem<C>;
562
+ removeKeys<ET extends EntityToken<CC>>(entityToken: ET, item: EntityRecordByToken<CC, ET>): EntityItemByToken<CC, ET>;
460
563
  /**
461
- * Strips generated properties, hash key, and range key from an array of {@link EntityRecord | `EntityRecord`} objects.
462
- *
463
- * @param entityToken - {@link Config | `Config`} `entities` key.
464
- * @param items - Array of {@link EntityRecord | `EntityRecord`} objects.
465
- *
466
- * @returns Array of {@link EntityItem | `EntityItem`} objects with generated properties, hash key & range key removed.
467
- *
468
- * @throws `Error` if `entityToken` is invalid.
469
- *
470
564
  * @overload
471
565
  */
472
- removeKeys(entityToken: EntityToken<C>, items: EntityRecord<C>[]): EntityItem<C>[];
566
+ removeKeys<ET extends EntityToken<CC>>(entityToken: ET, items: EntityRecordByToken<CC, ET>[]): EntityItemByToken<CC, ET>[];
473
567
  /**
474
568
  * Find an index token in a {@link Config | `Config`} object based on the index `hashKey` and `rangeKey`.
475
569
  *
@@ -504,21 +598,128 @@ declare class EntityManager<C extends BaseConfigMap> {
504
598
  *
505
599
  * @protected
506
600
  */
507
- query(options: QueryOptions<C>): Promise<QueryResult<C>>;
601
+ query<ET extends EntityToken<CC>, ITS extends string, CF = unknown>(options: QueryOptions<CC, ET, ITS, CF>): Promise<QueryResult<CC, ET, ITS>>;
602
+ }
603
+
604
+ /**
605
+ * Values-first config input used to capture literal tokens from the provided
606
+ * configuration value. This does not enforce full Config shape at compile
607
+ * time; runtime validation still occurs via Zod in the EntityManager.
608
+ *
609
+ * Keep this intentionally permissive to maximize inference from `as const`.
610
+ */
611
+ interface ConfigInput {
612
+ hashKey: string;
613
+ rangeKey: string;
614
+ generatedProperties?: {
615
+ sharded?: Record<string, readonly string[]>;
616
+ unsharded?: Record<string, readonly string[]>;
617
+ };
618
+ propertyTranscodes?: Record<string, string>;
619
+ indexes?: Record<string, {
620
+ hashKey: string;
621
+ rangeKey: string;
622
+ projections?: string[];
623
+ }>;
624
+ entities?: Record<string, unknown>;
625
+ /**
626
+ * Optional Zod schemas for per-entity domain shapes (non-generated fields only).
627
+ *
628
+ * Important: Schemas MUST declare only base (non-generated) properties. Do not include
629
+ * global keys (hashKey/rangeKey) or any generated tokens (sharded/unsharded).
630
+ */
631
+ entitiesSchema?: Record<string, ZodType>;
632
+ generatedKeyDelimiter?: string;
633
+ generatedValueDelimiter?: string;
634
+ shardKeyDelimiter?: string;
635
+ transcodes?: unknown;
636
+ throttle?: number;
508
637
  }
638
+ type HashKeyFrom<CC> = CC extends {
639
+ hashKey: infer H;
640
+ } ? H & string : 'hashKey';
641
+ type RangeKeyFrom<CC> = CC extends {
642
+ rangeKey: infer R;
643
+ } ? R & string : 'rangeKey';
644
+ type ShardedKeysFrom<CC> = CC extends {
645
+ generatedProperties?: infer GP;
646
+ } ? GP extends {
647
+ sharded?: infer S;
648
+ } ? keyof S & string : never : never;
649
+ type UnshardedKeysFrom<CC> = CC extends {
650
+ generatedProperties?: infer GP;
651
+ } ? GP extends {
652
+ unsharded?: infer U;
653
+ } ? keyof U & string : never : never;
654
+ type TranscodedPropertiesFrom<CC> = CC extends {
655
+ propertyTranscodes?: infer PT;
656
+ } ? keyof PT & string : never;
657
+ /**
658
+ * Derive an EntityMap from CC.entitiesSchema when provided (values-first, no generics).
659
+ * Fallback to broad EntityMap if schemas are absent.
660
+ */
661
+ type EntitiesFromSchema<CC> = CC extends {
662
+ entitiesSchema?: infer S;
663
+ } ? S extends Record<string, ZodType> ? {
664
+ [K in keyof S & string]: z.infer<S[K]>;
665
+ } & EntityMap : EntityMap : EntityMap;
666
+ /**
667
+ * Derive the union of index token names from a values-first config input.
668
+ *
669
+ * When the provided config literal carries an `indexes` object with preserved
670
+ * literal keys (prefer `as const` at call sites), this helper captures the
671
+ * index token union. Falls back to `string` if absent.
672
+ */
673
+ type IndexTokensFrom<CC> = CC extends {
674
+ indexes?: infer I;
675
+ } ? keyof I & string : string;
676
+ /**
677
+ * Captures a BaseConfigMap-compatible type from a literal ConfigInput value
678
+ * and an EntityMap (defaults to MinimalEntityMapFrom<CC>).
679
+ */
680
+ type CapturedConfigMapFrom<CC, EM extends EntityMap> = {
681
+ EntityMap: EM;
682
+ HashKey: HashKeyFrom<CC>;
683
+ RangeKey: RangeKeyFrom<CC>;
684
+ ShardedKeys: ShardedKeysFrom<CC>;
685
+ UnshardedKeys: UnshardedKeysFrom<CC>;
686
+ TranscodedProperties: TranscodedPropertiesFrom<CC>;
687
+ TranscodeRegistry: DefaultTranscodeRegistry;
688
+ } & BaseConfigMap;
689
+ /**
690
+ * Values-first factory that captures literal tokens and index names directly
691
+ * from the provided config value. Runtime config parsing/validation is
692
+ * unchanged (performed in the EntityManager constructor).
693
+ *
694
+ * @typeParam CC - Captured config input (values-first). Prefer `as const` and
695
+ * `satisfies` at call sites to preserve literal keys.
696
+ * @typeParam EM - EntityMap for the manager. Defaults to a minimal derived map
697
+ * from `CC.entitiesSchema` when present; otherwise falls back to EntityMap.
698
+ */
699
+ declare function createEntityManager<const CC extends ConfigInput, EM extends EntityMap = EntitiesFromSchema<CC>>(config: CC, logger?: Pick<Console, 'debug' | 'error'>): EntityManager<CapturedConfigMapFrom<CC, EM>>;
700
+
701
+ /**
702
+ * Database-facing record type from a {@link BaseConfigMap | `ConfigMap`} with required hash & range keys.
703
+ *
704
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
705
+ *
706
+ * @category EntityManager
707
+ * @protected
708
+ */
709
+ type EntityRecord<CC extends BaseConfigMap> = EntityItem<CC> & EntityKey<CC>;
509
710
 
510
711
  /**
511
712
  * Base EntityClient options.
512
713
  *
513
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
714
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
514
715
  *
515
716
  * @category EntityClient
516
717
  */
517
- interface BaseEntityClientOptions<C extends BaseConfigMap> {
718
+ interface BaseEntityClientOptions<CC extends BaseConfigMap> {
518
719
  /** Default batch process options. */
519
720
  batchProcessOptions?: Omit<BatchProcessOptions<unknown, unknown>, 'batchHandler' | 'unprocessedItemExtractor'>;
520
721
  /** {@link EntityManager | `EntityManager`} instance. */
521
- entityManager: EntityManager<C>;
722
+ entityManager: EntityManager<CC>;
522
723
  /** Injected logger object. Must support `debug` and `error` methods. Default: `console` */
523
724
  logger?: Pick<Console, 'debug' | 'error'>;
524
725
  }
@@ -526,40 +727,40 @@ interface BaseEntityClientOptions<C extends BaseConfigMap> {
526
727
  /**
527
728
  * Base EntityClient class. Integrates {@link EntityManager | `EntityManager`} with injected logging & enhanced batch processing.
528
729
  *
529
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
730
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
530
731
  *
531
732
  * @category EntityClient
532
733
  */
533
- declare abstract class BaseEntityClient<C extends BaseConfigMap> {
734
+ declare abstract class BaseEntityClient<CC extends BaseConfigMap> {
534
735
  /** Default batch process options. */
535
- readonly batchProcessOptions: NonNullable<BaseEntityClientOptions<C>['batchProcessOptions']>;
736
+ readonly batchProcessOptions: NonNullable<BaseEntityClientOptions<CC>['batchProcessOptions']>;
536
737
  /** {@link EntityManager | `EntityManager`} instance. */
537
- readonly entityManager: EntityManager<C>;
738
+ readonly entityManager: EntityManager<CC>;
538
739
  /** Injected logger object. Must support `debug` and `error` methods. Default: `console` */
539
- readonly logger: NonNullable<BaseEntityClientOptions<C>['logger']>;
740
+ readonly logger: NonNullable<BaseEntityClientOptions<CC>['logger']>;
540
741
  /**
541
742
  * DynamoDB EntityClient constructor.
542
743
  *
543
744
  * @param options - {@link BaseEntityClientOptions | `BaseEntityClientOptions`} object.
544
745
  */
545
- constructor(options: BaseEntityClientOptions<C>);
746
+ constructor(options: BaseEntityClientOptions<CC>);
546
747
  }
547
748
 
548
749
  /**
549
750
  * Constructor options for {@link BaseQueryBuilder | `BaseQueryBuilder`}.
550
751
  *
551
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
752
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
552
753
  * @typeParam EntityClient - {@link BaseEntityClient | `BaseEntityClient`} derived class instance.
553
754
  *
554
755
  * @category QueryBuilder
555
756
  */
556
- interface BaseQueryBuilderOptions<C extends BaseConfigMap, EntityClient extends BaseEntityClient<C>> {
757
+ interface BaseQueryBuilderOptions<CC extends BaseConfigMap, EntityClient extends BaseEntityClient<CC>> {
557
758
  /** {@link BaseEntityClient | `EntityClient`} instance. */
558
759
  entityClient: EntityClient;
559
760
  /** Entity token. */
560
- entityToken: EntityToken<C>;
761
+ entityToken: EntityToken<CC>;
561
762
  /** Hash key token. */
562
- hashKeyToken: C['HashKey'] | C['ShardedKeys'];
763
+ hashKeyToken: CC['HashKey'] | CC['ShardedKeys'];
563
764
  /** Dehydrated page key map. */
564
765
  pageKeyMap?: string;
565
766
  }
@@ -569,28 +770,29 @@ interface BaseQueryBuilderOptions<C extends BaseConfigMap, EntityClient extends
569
770
  *
570
771
  * Same as {@link QueryOptions | `QueryOptions`} for {@link EntityManager.query | `EntityManager.query`}, excluding `entityToken`, `pageKeyMap`, and `shardQueryMap`.
571
772
  *
572
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
773
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
573
774
  *
574
775
  * @category QueryBuilder
575
776
  */
576
- type QueryBuilderQueryOptions<C extends BaseConfigMap> = Omit<QueryOptions<C>, 'entityToken' | 'pageKeyMap' | 'shardQueryMap'>;
777
+ type QueryBuilderQueryOptions<CC extends BaseConfigMap, CF = unknown> = Omit<QueryOptions<CC, never, string, CF>, 'entityToken' | 'pageKeyMap' | 'shardQueryMap'>;
577
778
 
578
779
  /**
579
780
  * Abstract base class supporting a fluent API for building a {@link ShardQueryMap | `ShardQueryMap`} using a database client.
580
781
  *
581
- * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
782
+ * @typeParam CC - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeRegistry | `TranscodeRegistry`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
582
783
  * @typeParam EntityClient - {@link BaseEntityClient | `BaseEntityClient`} derived class instance.
583
784
  * @typeParam IndexParams - Database platform-specific, index-specific query parameters.
785
+ * @typeParam CF - Optional values-first config literal type for page key narrowing.
584
786
  *
585
787
  * @category QueryBuilder
586
788
  */
587
- declare abstract class BaseQueryBuilder<C extends BaseConfigMap, EntityClient extends BaseEntityClient<C>, IndexParams> {
789
+ declare abstract class BaseQueryBuilder<CC extends BaseConfigMap, EntityClient extends BaseEntityClient<CC>, IndexParams, ET extends EntityToken<CC> = EntityToken<CC>, ITS extends string = string, CF = unknown> {
588
790
  /** {@link BaseEntityClient | `EntityClient`} instance. */
589
791
  readonly entityClient: EntityClient;
590
792
  /** Entity token. */
591
- readonly entityToken: EntityToken<C>;
793
+ readonly entityToken: EntityToken<CC>;
592
794
  /** Hash key token. */
593
- readonly hashKeyToken: C['HashKey'] | C['ShardedKeys'];
795
+ readonly hashKeyToken: CC['HashKey'] | CC['ShardedKeys'];
594
796
  /** Dehydrated page key map. */
595
797
  readonly pageKeyMap?: string;
596
798
  /**
@@ -598,18 +800,18 @@ declare abstract class BaseQueryBuilder<C extends BaseConfigMap, EntityClient ex
598
800
  *
599
801
  * @protected
600
802
  */
601
- readonly indexParamsMap: Record<string, IndexParams>;
803
+ readonly indexParamsMap: Record<ITS, IndexParams>;
602
804
  /** BaseQueryBuilder constructor. */
603
- constructor(options: BaseQueryBuilderOptions<C, EntityClient>);
604
- protected abstract getShardQueryFunction(indexToken: string): ShardQueryFunction<C>;
805
+ constructor(options: BaseQueryBuilderOptions<CC, EntityClient>);
806
+ protected abstract getShardQueryFunction(indexToken: ITS): ShardQueryFunction<CC, ET, ITS, CF>;
605
807
  /**
606
808
  * Builds a {@link ShardQueryMap | `ShardQueryMap`} object.
607
809
  *
608
810
  * @returns - The {@link ShardQueryMap | `ShardQueryMap`} object.
609
811
  */
610
- build(): ShardQueryMap<C>;
611
- query(options: QueryBuilderQueryOptions<C>): Promise<QueryResult<C>>;
812
+ build(): ShardQueryMap<CC, ET, ITS, CF>;
813
+ query(options: QueryBuilderQueryOptions<CC, CF>): Promise<QueryResult<CC, ET, ITS>>;
612
814
  }
613
815
 
614
- export { BaseEntityClient, BaseQueryBuilder, EntityManager, configSchema };
615
- export type { BaseConfigMap, BaseEntityClientOptions, BaseQueryBuilderOptions, Config, ConfigMap, EntityItem, EntityKey, EntityRecord, EntityToken, PageKey, ParsedConfig, QueryBuilderQueryOptions, QueryOptions, QueryResult, ShardBump, ShardQueryFunction, ShardQueryMap, ShardQueryResult, ValidateConfigMap };
816
+ export { BaseEntityClient, BaseQueryBuilder, EntityManager, configSchema, createEntityManager };
817
+ export type { BaseConfigMap, BaseEntityClientOptions, BaseQueryBuilderOptions, CapturedConfigMapFrom, Config, ConfigInput, ConfigMap, EntitiesFromSchema, EntityItem, EntityItemByToken, EntityKey, EntityOfToken, EntityRecord, EntityRecordByToken, EntityToken, HasIndexFor, HashKeyFrom, IndexComponentTokens, IndexHashKeyOf, IndexRangeKeyOf, IndexTokensFrom, IndexTokensOf, PageKey, PageKeyByIndex, ParsedConfig, QueryBuilderQueryOptions, QueryOptions, QueryOptionsByCC, QueryOptionsByCF, QueryResult, RangeKeyFrom, ShardBump, ShardQueryFunction, ShardQueryMap, ShardQueryMapByCC, ShardQueryMapByCF, ShardQueryResult, ShardedKeysFrom, TranscodedPropertiesFrom, UnshardedKeysFrom, ValidateConfigMap };