@karmaniverous/entity-manager 6.4.10 → 6.5.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/cjs/ParsedConfig.js +52 -12
- package/dist/cjs/getIndexComponents.js +25 -0
- package/dist/cjs/rehydratePageKeyMap.js +2 -1
- package/dist/cjs/unwrapIndex.js +2 -1
- package/dist/index.d.ts +75 -14
- package/dist/mjs/ParsedConfig.js +52 -12
- package/dist/mjs/getIndexComponents.js +23 -0
- package/dist/mjs/rehydratePageKeyMap.js +2 -1
- package/dist/mjs/unwrapIndex.js +2 -1
- package/package.json +1 -1
package/dist/cjs/ParsedConfig.js
CHANGED
|
@@ -23,6 +23,10 @@ const validateKeyExclusive = (key, label, ref, ctx) => {
|
|
|
23
23
|
message: `${label} '${key}' is not exclusive`,
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
|
+
const componentArray = zod.z
|
|
27
|
+
.array(zod.z.string().min(1))
|
|
28
|
+
.nonempty()
|
|
29
|
+
.superRefine(validateArrayUnique);
|
|
26
30
|
const configSchema = zod.z
|
|
27
31
|
.object({
|
|
28
32
|
entities: zod.z
|
|
@@ -46,10 +50,7 @@ const configSchema = zod.z
|
|
|
46
50
|
.record(zod.z
|
|
47
51
|
.object({
|
|
48
52
|
atomic: zod.z.boolean().optional().default(false),
|
|
49
|
-
elements:
|
|
50
|
-
.array(zod.z.string().min(1))
|
|
51
|
-
.nonempty()
|
|
52
|
-
.superRefine(validateArrayUnique),
|
|
53
|
+
elements: componentArray,
|
|
53
54
|
sharded: zod.z.boolean().optional().default(false),
|
|
54
55
|
})
|
|
55
56
|
.optional())
|
|
@@ -57,10 +58,11 @@ const configSchema = zod.z
|
|
|
57
58
|
.default({}),
|
|
58
59
|
elementTranscodes: zod.z.record(zod.z.string()).optional().default({}),
|
|
59
60
|
indexes: zod.z
|
|
60
|
-
.record(zod.z
|
|
61
|
-
|
|
62
|
-
.
|
|
63
|
-
.
|
|
61
|
+
.record(zod.z.object({
|
|
62
|
+
hashKey: zod.z.string().min(1),
|
|
63
|
+
rangeKey: zod.z.string().min(1),
|
|
64
|
+
projections: componentArray.optional(),
|
|
65
|
+
}))
|
|
64
66
|
.optional()
|
|
65
67
|
.default({}),
|
|
66
68
|
shardBumps: zod.z
|
|
@@ -209,18 +211,56 @@ const configSchema = zod.z
|
|
|
209
211
|
],
|
|
210
212
|
received: element,
|
|
211
213
|
});
|
|
212
|
-
// validate
|
|
214
|
+
// validate indexes.
|
|
213
215
|
const generatedProperties = Object.keys(entity.generated);
|
|
214
|
-
for (const [indexKey,
|
|
215
|
-
|
|
216
|
+
for (const [indexKey, { hashKey, rangeKey, projections },] of Object.entries(entity.indexes)) {
|
|
217
|
+
// validate index hash key is sharded
|
|
218
|
+
if (hashKey !== data.hashKey && !entity.generated[hashKey]?.sharded)
|
|
219
|
+
ctx.addIssue({
|
|
220
|
+
code: zod.z.ZodIssueCode.custom,
|
|
221
|
+
message: 'index hash key is not sharded',
|
|
222
|
+
path: ['entities', entityToken, 'indexes', indexKey, 'hashKey'],
|
|
223
|
+
});
|
|
224
|
+
// validate index range key is unsharded
|
|
225
|
+
if (rangeKey !== data.rangeKey && entity.generated[rangeKey]?.sharded)
|
|
226
|
+
ctx.addIssue({
|
|
227
|
+
code: zod.z.ZodIssueCode.custom,
|
|
228
|
+
message: 'index range key is sharded',
|
|
229
|
+
path: ['entities', entityToken, 'indexes', indexKey, 'rangeKey'],
|
|
230
|
+
});
|
|
231
|
+
// validate all ungenerated entity index components have a corresponding entity element type
|
|
232
|
+
for (const component of [hashKey, rangeKey])
|
|
216
233
|
if (![data.hashKey, data.rangeKey, ...generatedProperties].includes(component) &&
|
|
217
234
|
!typedElements.includes(component))
|
|
218
235
|
ctx.addIssue({
|
|
219
236
|
code: zod.z.ZodIssueCode.invalid_enum_value,
|
|
220
237
|
options: typedElements,
|
|
221
|
-
path: [
|
|
238
|
+
path: [
|
|
239
|
+
'entities',
|
|
240
|
+
entityToken,
|
|
241
|
+
'indexes',
|
|
242
|
+
indexKey,
|
|
243
|
+
'components',
|
|
244
|
+
],
|
|
222
245
|
received: component,
|
|
223
246
|
});
|
|
247
|
+
// validate no index projections are index components, hashKey, or rangeKey
|
|
248
|
+
if (projections)
|
|
249
|
+
for (const projection of projections) {
|
|
250
|
+
if ([data.hashKey, data.rangeKey, hashKey, rangeKey].includes(projection))
|
|
251
|
+
ctx.addIssue({
|
|
252
|
+
code: zod.z.ZodIssueCode.custom,
|
|
253
|
+
message: 'index projection is an index component, hash key, or range key',
|
|
254
|
+
path: [
|
|
255
|
+
'entities',
|
|
256
|
+
entityToken,
|
|
257
|
+
'indexes',
|
|
258
|
+
indexKey,
|
|
259
|
+
'projections',
|
|
260
|
+
],
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
224
264
|
}
|
|
225
265
|
});
|
|
226
266
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var radash = require('radash');
|
|
4
|
+
var validateEntityIndexToken = require('./validateEntityIndexToken.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get the index components of an entity index. Adds the hash and range keys to the index components.
|
|
8
|
+
*
|
|
9
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
10
|
+
* @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
|
|
11
|
+
* @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
|
|
12
|
+
*
|
|
13
|
+
* @returns Array of index components.
|
|
14
|
+
*
|
|
15
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
16
|
+
* @throws `Error` if `indexToken` is invalid.
|
|
17
|
+
*/
|
|
18
|
+
function getIndexComponents(entityManager, entityToken, indexToken) {
|
|
19
|
+
validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
|
|
20
|
+
const { hashKey, rangeKey, entities } = entityManager.config;
|
|
21
|
+
const { hashKey: indexHashKey, rangeKey: indexRangeKey } = entities[entityToken].indexes[indexToken];
|
|
22
|
+
return radash.unique([hashKey, rangeKey, indexHashKey, indexRangeKey]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.getIndexComponents = getIndexComponents;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var radash = require('radash');
|
|
4
4
|
var encodeGeneratedProperty = require('./encodeGeneratedProperty.js');
|
|
5
5
|
var getHashKeySpace = require('./getHashKeySpace.js');
|
|
6
|
+
var getIndexComponents = require('./getIndexComponents.js');
|
|
6
7
|
var rehydrateIndexItem = require('./rehydrateIndexItem.js');
|
|
7
8
|
var updateItemRangeKey = require('./updateItemRangeKey.js');
|
|
8
9
|
var validateEntityIndexToken = require('./validateEntityIndexToken.js');
|
|
@@ -51,7 +52,7 @@ function rehydratePageKeyMap(entityManager, dehydrated, entityToken, indexTokens
|
|
|
51
52
|
...rehydrateIndexItem.rehydrateIndexItem(entityManager, dehydratedIndexPageKeyMaps[i], entityToken, index, [entityManager.config.hashKey]),
|
|
52
53
|
};
|
|
53
54
|
item = updateItemRangeKey.updateItemRangeKey(entityManager, item, entityToken);
|
|
54
|
-
return radash.zipToObject(entityManager
|
|
55
|
+
return radash.zipToObject(getIndexComponents.getIndexComponents(entityManager, entityToken, index), (component) => entityManager.config.entities[entityToken].generated[component]
|
|
55
56
|
? encodeGeneratedProperty.encodeGeneratedProperty(entityManager, item, entityToken, component)
|
|
56
57
|
: item[component]);
|
|
57
58
|
}));
|
package/dist/cjs/unwrapIndex.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var radash = require('radash');
|
|
4
|
+
var getIndexComponents = require('./getIndexComponents.js');
|
|
4
5
|
var validateEntityIndexToken = require('./validateEntityIndexToken.js');
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -21,7 +22,7 @@ function unwrapIndex(entityManager, entityToken, indexToken) {
|
|
|
21
22
|
validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
|
|
22
23
|
const generated = entityManager.config.entities[entityToken].generated;
|
|
23
24
|
const generatedKeys = Object.keys(radash.shake(generated));
|
|
24
|
-
return entityManager
|
|
25
|
+
return getIndexComponents.getIndexComponents(entityManager, entityToken, indexToken)
|
|
25
26
|
.map((component) => component === entityManager.config.hashKey
|
|
26
27
|
? entityManager.config.hashKey
|
|
27
28
|
: component === entityManager.config.rangeKey
|
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,19 @@ interface ShardBump {
|
|
|
80
80
|
*/
|
|
81
81
|
chars: number;
|
|
82
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Returns a Config entity index components type.
|
|
85
|
+
*
|
|
86
|
+
* @typeParam EntityToken - The {@link Entity | `Entity`} token.
|
|
87
|
+
* @typeParam M - The {@link EntityMap | `EntityMap`}.
|
|
88
|
+
* @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property.
|
|
89
|
+
* @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property.
|
|
90
|
+
* @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}.
|
|
91
|
+
|
|
92
|
+
* @category Config
|
|
93
|
+
* @protected
|
|
94
|
+
*/
|
|
95
|
+
type ConfigEntityIndexComponent<EntityToken extends keyof Exactify<M>, M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> = TranscodableProperties<M[EntityToken], T> | PropertiesOfType<M[EntityToken], never> | HashKey | RangeKey;
|
|
83
96
|
/**
|
|
84
97
|
* Returns a Config entity type.
|
|
85
98
|
*
|
|
@@ -171,11 +184,15 @@ type ConfigEntity<EntityToken extends keyof Exactify<M>, M extends EntityMap, Ha
|
|
|
171
184
|
/**
|
|
172
185
|
* Indexes defined for the {@link Entity | `Entity`}. Should reflect the underlying database table indexes.
|
|
173
186
|
*
|
|
174
|
-
* Each key is the name of an index, and each value
|
|
187
|
+
* Each key is the name of an index, and each value defines the hash key, range key, and projected properties of the index.
|
|
175
188
|
*
|
|
176
|
-
*
|
|
189
|
+
* hashKey and rangeKey types must align with the {@link Config | `Config`} `T` type parameter. Note that all {@link ConfigEntityGenerated | generated property} types are transcodable by definition.
|
|
177
190
|
*/
|
|
178
|
-
indexes?: Record<string,
|
|
191
|
+
indexes?: Record<string, {
|
|
192
|
+
hashKey: ConfigEntityIndexComponent<EntityToken, M, HashKey, RangeKey, T>;
|
|
193
|
+
rangeKey: ConfigEntityIndexComponent<EntityToken, M, HashKey, RangeKey, T>;
|
|
194
|
+
projections?: (keyof M[EntityToken])[];
|
|
195
|
+
}>;
|
|
179
196
|
/**
|
|
180
197
|
* An array of {@link ShardBump | `ShardBump`} objects representing the {@link Entity | `Entity`}'s sharding strategy.
|
|
181
198
|
*
|
|
@@ -377,7 +394,19 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
377
394
|
sharded?: boolean | undefined;
|
|
378
395
|
}>>>>>;
|
|
379
396
|
elementTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
380
|
-
indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
397
|
+
indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
398
|
+
hashKey: z.ZodString;
|
|
399
|
+
rangeKey: z.ZodString;
|
|
400
|
+
projections: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>;
|
|
401
|
+
}, "strip", z.ZodTypeAny, {
|
|
402
|
+
hashKey: string;
|
|
403
|
+
rangeKey: string;
|
|
404
|
+
projections?: [string, ...string[]] | undefined;
|
|
405
|
+
}, {
|
|
406
|
+
hashKey: string;
|
|
407
|
+
rangeKey: string;
|
|
408
|
+
projections?: [string, ...string[]] | undefined;
|
|
409
|
+
}>>>>;
|
|
381
410
|
shardBumps: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
382
411
|
timestamp: z.ZodNumber;
|
|
383
412
|
charBits: z.ZodNumber;
|
|
@@ -421,7 +450,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
421
450
|
defaultLimit: number;
|
|
422
451
|
defaultPageSize: number;
|
|
423
452
|
elementTranscodes: Record<string, string>;
|
|
424
|
-
indexes: Record<string,
|
|
453
|
+
indexes: Record<string, {
|
|
454
|
+
hashKey: string;
|
|
455
|
+
rangeKey: string;
|
|
456
|
+
projections?: [string, ...string[]] | undefined;
|
|
457
|
+
}>;
|
|
425
458
|
shardBumps: {
|
|
426
459
|
timestamp: number;
|
|
427
460
|
charBits: number;
|
|
@@ -440,7 +473,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
440
473
|
defaultLimit?: number | undefined;
|
|
441
474
|
defaultPageSize?: number | undefined;
|
|
442
475
|
elementTranscodes?: Record<string, string> | undefined;
|
|
443
|
-
indexes?: Record<string,
|
|
476
|
+
indexes?: Record<string, {
|
|
477
|
+
hashKey: string;
|
|
478
|
+
rangeKey: string;
|
|
479
|
+
projections?: [string, ...string[]] | undefined;
|
|
480
|
+
}> | undefined;
|
|
444
481
|
shardBumps?: {
|
|
445
482
|
timestamp: number;
|
|
446
483
|
charBits: number;
|
|
@@ -455,7 +492,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
455
492
|
defaultLimit: number;
|
|
456
493
|
defaultPageSize: number;
|
|
457
494
|
elementTranscodes: Record<string, string>;
|
|
458
|
-
indexes: Record<string,
|
|
495
|
+
indexes: Record<string, {
|
|
496
|
+
hashKey: string;
|
|
497
|
+
rangeKey: string;
|
|
498
|
+
projections?: [string, ...string[]] | undefined;
|
|
499
|
+
}>;
|
|
459
500
|
shardBumps: {
|
|
460
501
|
timestamp: number;
|
|
461
502
|
charBits: number;
|
|
@@ -474,7 +515,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
474
515
|
defaultLimit?: number | undefined;
|
|
475
516
|
defaultPageSize?: number | undefined;
|
|
476
517
|
elementTranscodes?: Record<string, string> | undefined;
|
|
477
|
-
indexes?: Record<string,
|
|
518
|
+
indexes?: Record<string, {
|
|
519
|
+
hashKey: string;
|
|
520
|
+
rangeKey: string;
|
|
521
|
+
projections?: [string, ...string[]] | undefined;
|
|
522
|
+
}> | undefined;
|
|
478
523
|
shardBumps?: {
|
|
479
524
|
timestamp: number;
|
|
480
525
|
charBits: number;
|
|
@@ -509,7 +554,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
509
554
|
defaultLimit: number;
|
|
510
555
|
defaultPageSize: number;
|
|
511
556
|
elementTranscodes: Record<string, string>;
|
|
512
|
-
indexes: Record<string,
|
|
557
|
+
indexes: Record<string, {
|
|
558
|
+
hashKey: string;
|
|
559
|
+
rangeKey: string;
|
|
560
|
+
projections?: [string, ...string[]] | undefined;
|
|
561
|
+
}>;
|
|
513
562
|
shardBumps: {
|
|
514
563
|
timestamp: number;
|
|
515
564
|
charBits: number;
|
|
@@ -540,7 +589,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
540
589
|
defaultLimit?: number | undefined;
|
|
541
590
|
defaultPageSize?: number | undefined;
|
|
542
591
|
elementTranscodes?: Record<string, string> | undefined;
|
|
543
|
-
indexes?: Record<string,
|
|
592
|
+
indexes?: Record<string, {
|
|
593
|
+
hashKey: string;
|
|
594
|
+
rangeKey: string;
|
|
595
|
+
projections?: [string, ...string[]] | undefined;
|
|
596
|
+
}> | undefined;
|
|
544
597
|
shardBumps?: {
|
|
545
598
|
timestamp: number;
|
|
546
599
|
charBits: number;
|
|
@@ -567,7 +620,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
567
620
|
defaultLimit: number;
|
|
568
621
|
defaultPageSize: number;
|
|
569
622
|
elementTranscodes: Record<string, string>;
|
|
570
|
-
indexes: Record<string,
|
|
623
|
+
indexes: Record<string, {
|
|
624
|
+
hashKey: string;
|
|
625
|
+
rangeKey: string;
|
|
626
|
+
projections?: [string, ...string[]] | undefined;
|
|
627
|
+
}>;
|
|
571
628
|
shardBumps: {
|
|
572
629
|
timestamp: number;
|
|
573
630
|
charBits: number;
|
|
@@ -598,7 +655,11 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
598
655
|
defaultLimit?: number | undefined;
|
|
599
656
|
defaultPageSize?: number | undefined;
|
|
600
657
|
elementTranscodes?: Record<string, string> | undefined;
|
|
601
|
-
indexes?: Record<string,
|
|
658
|
+
indexes?: Record<string, {
|
|
659
|
+
hashKey: string;
|
|
660
|
+
rangeKey: string;
|
|
661
|
+
projections?: [string, ...string[]] | undefined;
|
|
662
|
+
}> | undefined;
|
|
602
663
|
shardBumps?: {
|
|
603
664
|
timestamp: number;
|
|
604
665
|
charBits: number;
|
|
@@ -620,7 +681,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
620
681
|
}> | undefined;
|
|
621
682
|
}>;
|
|
622
683
|
/**
|
|
623
|
-
*
|
|
684
|
+
* Simplified type taken on by a {@link Config | `Config`} object after parsing in the {@link EntityManager | `EntityManager`} constructor.
|
|
624
685
|
*
|
|
625
686
|
* @category Config
|
|
626
687
|
*/
|
|
@@ -828,4 +889,4 @@ declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKe
|
|
|
828
889
|
query<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(options: QueryOptions<Item, EntityToken, M, HashKey, RangeKey>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
|
|
829
890
|
}
|
|
830
891
|
|
|
831
|
-
export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryMap, type ShardQueryResult, type Unwrap, conditionalize };
|
|
892
|
+
export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigEntityIndexComponent, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryMap, type ShardQueryResult, type Unwrap, conditionalize };
|
package/dist/mjs/ParsedConfig.js
CHANGED
|
@@ -21,6 +21,10 @@ const validateKeyExclusive = (key, label, ref, ctx) => {
|
|
|
21
21
|
message: `${label} '${key}' is not exclusive`,
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
|
+
const componentArray = z
|
|
25
|
+
.array(z.string().min(1))
|
|
26
|
+
.nonempty()
|
|
27
|
+
.superRefine(validateArrayUnique);
|
|
24
28
|
const configSchema = z
|
|
25
29
|
.object({
|
|
26
30
|
entities: z
|
|
@@ -44,10 +48,7 @@ const configSchema = z
|
|
|
44
48
|
.record(z
|
|
45
49
|
.object({
|
|
46
50
|
atomic: z.boolean().optional().default(false),
|
|
47
|
-
elements:
|
|
48
|
-
.array(z.string().min(1))
|
|
49
|
-
.nonempty()
|
|
50
|
-
.superRefine(validateArrayUnique),
|
|
51
|
+
elements: componentArray,
|
|
51
52
|
sharded: z.boolean().optional().default(false),
|
|
52
53
|
})
|
|
53
54
|
.optional())
|
|
@@ -55,10 +56,11 @@ const configSchema = z
|
|
|
55
56
|
.default({}),
|
|
56
57
|
elementTranscodes: z.record(z.string()).optional().default({}),
|
|
57
58
|
indexes: z
|
|
58
|
-
.record(z
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
.
|
|
59
|
+
.record(z.object({
|
|
60
|
+
hashKey: z.string().min(1),
|
|
61
|
+
rangeKey: z.string().min(1),
|
|
62
|
+
projections: componentArray.optional(),
|
|
63
|
+
}))
|
|
62
64
|
.optional()
|
|
63
65
|
.default({}),
|
|
64
66
|
shardBumps: z
|
|
@@ -207,18 +209,56 @@ const configSchema = z
|
|
|
207
209
|
],
|
|
208
210
|
received: element,
|
|
209
211
|
});
|
|
210
|
-
// validate
|
|
212
|
+
// validate indexes.
|
|
211
213
|
const generatedProperties = Object.keys(entity.generated);
|
|
212
|
-
for (const [indexKey,
|
|
213
|
-
|
|
214
|
+
for (const [indexKey, { hashKey, rangeKey, projections },] of Object.entries(entity.indexes)) {
|
|
215
|
+
// validate index hash key is sharded
|
|
216
|
+
if (hashKey !== data.hashKey && !entity.generated[hashKey]?.sharded)
|
|
217
|
+
ctx.addIssue({
|
|
218
|
+
code: z.ZodIssueCode.custom,
|
|
219
|
+
message: 'index hash key is not sharded',
|
|
220
|
+
path: ['entities', entityToken, 'indexes', indexKey, 'hashKey'],
|
|
221
|
+
});
|
|
222
|
+
// validate index range key is unsharded
|
|
223
|
+
if (rangeKey !== data.rangeKey && entity.generated[rangeKey]?.sharded)
|
|
224
|
+
ctx.addIssue({
|
|
225
|
+
code: z.ZodIssueCode.custom,
|
|
226
|
+
message: 'index range key is sharded',
|
|
227
|
+
path: ['entities', entityToken, 'indexes', indexKey, 'rangeKey'],
|
|
228
|
+
});
|
|
229
|
+
// validate all ungenerated entity index components have a corresponding entity element type
|
|
230
|
+
for (const component of [hashKey, rangeKey])
|
|
214
231
|
if (![data.hashKey, data.rangeKey, ...generatedProperties].includes(component) &&
|
|
215
232
|
!typedElements.includes(component))
|
|
216
233
|
ctx.addIssue({
|
|
217
234
|
code: z.ZodIssueCode.invalid_enum_value,
|
|
218
235
|
options: typedElements,
|
|
219
|
-
path: [
|
|
236
|
+
path: [
|
|
237
|
+
'entities',
|
|
238
|
+
entityToken,
|
|
239
|
+
'indexes',
|
|
240
|
+
indexKey,
|
|
241
|
+
'components',
|
|
242
|
+
],
|
|
220
243
|
received: component,
|
|
221
244
|
});
|
|
245
|
+
// validate no index projections are index components, hashKey, or rangeKey
|
|
246
|
+
if (projections)
|
|
247
|
+
for (const projection of projections) {
|
|
248
|
+
if ([data.hashKey, data.rangeKey, hashKey, rangeKey].includes(projection))
|
|
249
|
+
ctx.addIssue({
|
|
250
|
+
code: z.ZodIssueCode.custom,
|
|
251
|
+
message: 'index projection is an index component, hash key, or range key',
|
|
252
|
+
path: [
|
|
253
|
+
'entities',
|
|
254
|
+
entityToken,
|
|
255
|
+
'indexes',
|
|
256
|
+
indexKey,
|
|
257
|
+
'projections',
|
|
258
|
+
],
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
222
262
|
}
|
|
223
263
|
});
|
|
224
264
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { unique } from 'radash';
|
|
2
|
+
import { validateEntityIndexToken } from './validateEntityIndexToken.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the index components of an entity index. Adds the hash and range keys to the index components.
|
|
6
|
+
*
|
|
7
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
8
|
+
* @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
|
|
9
|
+
* @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
|
|
10
|
+
*
|
|
11
|
+
* @returns Array of index components.
|
|
12
|
+
*
|
|
13
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
14
|
+
* @throws `Error` if `indexToken` is invalid.
|
|
15
|
+
*/
|
|
16
|
+
function getIndexComponents(entityManager, entityToken, indexToken) {
|
|
17
|
+
validateEntityIndexToken(entityManager, entityToken, indexToken);
|
|
18
|
+
const { hashKey, rangeKey, entities } = entityManager.config;
|
|
19
|
+
const { hashKey: indexHashKey, rangeKey: indexRangeKey } = entities[entityToken].indexes[indexToken];
|
|
20
|
+
return unique([hashKey, rangeKey, indexHashKey, indexRangeKey]);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { getIndexComponents };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { range, mapValues, zipToObject, cluster } from 'radash';
|
|
2
2
|
import { encodeGeneratedProperty } from './encodeGeneratedProperty.js';
|
|
3
3
|
import { getHashKeySpace } from './getHashKeySpace.js';
|
|
4
|
+
import { getIndexComponents } from './getIndexComponents.js';
|
|
4
5
|
import { rehydrateIndexItem } from './rehydrateIndexItem.js';
|
|
5
6
|
import { updateItemRangeKey } from './updateItemRangeKey.js';
|
|
6
7
|
import { validateEntityIndexToken } from './validateEntityIndexToken.js';
|
|
@@ -49,7 +50,7 @@ function rehydratePageKeyMap(entityManager, dehydrated, entityToken, indexTokens
|
|
|
49
50
|
...rehydrateIndexItem(entityManager, dehydratedIndexPageKeyMaps[i], entityToken, index, [entityManager.config.hashKey]),
|
|
50
51
|
};
|
|
51
52
|
item = updateItemRangeKey(entityManager, item, entityToken);
|
|
52
|
-
return zipToObject(entityManager
|
|
53
|
+
return zipToObject(getIndexComponents(entityManager, entityToken, index), (component) => entityManager.config.entities[entityToken].generated[component]
|
|
53
54
|
? encodeGeneratedProperty(entityManager, item, entityToken, component)
|
|
54
55
|
: item[component]);
|
|
55
56
|
}));
|
package/dist/mjs/unwrapIndex.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { shake } from 'radash';
|
|
2
|
+
import { getIndexComponents } from './getIndexComponents.js';
|
|
2
3
|
import { validateEntityIndexToken } from './validateEntityIndexToken.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -19,7 +20,7 @@ function unwrapIndex(entityManager, entityToken, indexToken) {
|
|
|
19
20
|
validateEntityIndexToken(entityManager, entityToken, indexToken);
|
|
20
21
|
const generated = entityManager.config.entities[entityToken].generated;
|
|
21
22
|
const generatedKeys = Object.keys(shake(generated));
|
|
22
|
-
return entityManager
|
|
23
|
+
return getIndexComponents(entityManager, entityToken, indexToken)
|
|
23
24
|
.map((component) => component === entityManager.config.hashKey
|
|
24
25
|
? entityManager.config.hashKey
|
|
25
26
|
: component === entityManager.config.rangeKey
|
package/package.json
CHANGED