@ftschopp/dynatable-core 1.4.2 → 1.4.3

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/builders/query/create-query-builder.d.ts.map +1 -1
  3. package/dist/builders/query/create-query-builder.js +19 -2
  4. package/dist/core/types.d.ts +5 -0
  5. package/dist/core/types.d.ts.map +1 -1
  6. package/package.json +11 -2
  7. package/eslint.config.mjs +0 -4
  8. package/jest.config.js +0 -11
  9. package/src/builders/README.md +0 -339
  10. package/src/builders/batch-get/README.md +0 -43
  11. package/src/builders/batch-get/create-batch-get-builder.test.ts +0 -193
  12. package/src/builders/batch-get/create-batch-get-builder.ts +0 -108
  13. package/src/builders/batch-get/index.ts +0 -2
  14. package/src/builders/batch-get/types.ts +0 -28
  15. package/src/builders/batch-write/README.md +0 -204
  16. package/src/builders/batch-write/create-batch-write-builder.test.ts +0 -173
  17. package/src/builders/batch-write/create-batch-write-builder.ts +0 -49
  18. package/src/builders/batch-write/index.ts +0 -2
  19. package/src/builders/batch-write/types.ts +0 -33
  20. package/src/builders/delete/create-delete-builder.test.ts +0 -294
  21. package/src/builders/delete/create-delete-builder.ts +0 -100
  22. package/src/builders/delete/index.ts +0 -2
  23. package/src/builders/delete/types.ts +0 -17
  24. package/src/builders/get/create-get-builder.test.ts +0 -272
  25. package/src/builders/get/create-get-builder.ts +0 -117
  26. package/src/builders/get/index.ts +0 -2
  27. package/src/builders/get/types.ts +0 -39
  28. package/src/builders/index.ts +0 -14
  29. package/src/builders/put/create-put-builder.test.ts +0 -213
  30. package/src/builders/put/create-put-builder.ts +0 -160
  31. package/src/builders/put/index.ts +0 -2
  32. package/src/builders/put/types.ts +0 -24
  33. package/src/builders/query/create-query-builder.test.ts +0 -770
  34. package/src/builders/query/create-query-builder.ts +0 -455
  35. package/src/builders/query/index.ts +0 -2
  36. package/src/builders/query/types.ts +0 -109
  37. package/src/builders/scan/create-scan-builder.test.ts +0 -416
  38. package/src/builders/scan/create-scan-builder.ts +0 -265
  39. package/src/builders/scan/index.ts +0 -2
  40. package/src/builders/scan/types.ts +0 -88
  41. package/src/builders/shared/conditions.ts +0 -58
  42. package/src/builders/shared/index.ts +0 -4
  43. package/src/builders/shared/operators.test.ts +0 -270
  44. package/src/builders/shared/operators.ts +0 -208
  45. package/src/builders/shared/projection.ts +0 -28
  46. package/src/builders/shared/types.ts +0 -101
  47. package/src/builders/transact-get/README.md +0 -167
  48. package/src/builders/transact-get/create-transact-get-builder.test.ts +0 -239
  49. package/src/builders/transact-get/create-transact-get-builder.ts +0 -67
  50. package/src/builders/transact-get/index.ts +0 -2
  51. package/src/builders/transact-get/types.ts +0 -31
  52. package/src/builders/transact-write/README.md +0 -202
  53. package/src/builders/transact-write/create-transact-write-builder.test.ts +0 -288
  54. package/src/builders/transact-write/create-transact-write-builder.ts +0 -124
  55. package/src/builders/transact-write/index.ts +0 -2
  56. package/src/builders/transact-write/types.ts +0 -71
  57. package/src/builders/update/create-update-builder.test.ts +0 -573
  58. package/src/builders/update/create-update-builder.ts +0 -375
  59. package/src/builders/update/index.ts +0 -2
  60. package/src/builders/update/types.ts +0 -63
  61. package/src/core/types.test.ts +0 -641
  62. package/src/core/types.ts +0 -366
  63. package/src/entity/create-entity-api.ts +0 -224
  64. package/src/entity/index.ts +0 -19
  65. package/src/entity/middleware/factories.ts +0 -15
  66. package/src/entity/middleware/types.ts +0 -7
  67. package/src/entity/middleware/with-middleware.ts +0 -37
  68. package/src/entity/types.ts +0 -79
  69. package/src/entity/validation/key-validation.ts +0 -34
  70. package/src/index.ts +0 -23
  71. package/src/table.ts +0 -116
  72. package/src/utils/dynamodb-logger.test.ts +0 -246
  73. package/src/utils/dynamodb-logger.ts +0 -175
  74. package/src/utils/model-utils.test.ts +0 -452
  75. package/src/utils/model-utils.ts +0 -188
  76. package/src/utils/zod-utils.test.ts +0 -363
  77. package/src/utils/zod-utils.ts +0 -56
  78. package/tests/integration/instagram-clone.integration.test.ts +0 -1019
  79. package/tests/integration/pagination-timestamps.integration.test.ts +0 -374
  80. package/tests/integration/transactions.integration.test.ts +0 -528
  81. package/tsconfig.json +0 -12
package/src/core/types.ts DELETED
@@ -1,366 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
-
3
- /**
4
- * Type definitions for DynamoDB schema and model inference
5
- *
6
- * Provides comprehensive type utilities for:
7
- * - Defining DynamoDB table schemas with primary and secondary indexes
8
- * - Inferring strongly-typed input and output models from schema definitions
9
- * - Automatic key generation and template variable extraction
10
- * - Type-safe attribute handling with support for defaults and auto-generation
11
- *
12
- * @example
13
- * ```typescript
14
- * const schema: SchemaDefinition = {
15
- * format: 'dynatable:1.0.0',
16
- * version: '1.0.0',
17
- * indexes: { primary: { hash: "PK", sort: "SK" } },
18
- * models: {
19
- * User: {
20
- * key: { PK: { type: String, value: "USER#${id}" }, SK: { type: String, value: "PROFILE" } },
21
- * attributes: { id: { type: String, required: true }, name: { type: String } }
22
- * }
23
- * }
24
- * };
25
- * ```
26
- */
27
-
28
- // -------------------- Type Definitions --------------------
29
-
30
- /**
31
- * Scalar attribute definition (String, Number, Boolean, Date)
32
- */
33
- export type ScalarAttributeDefinition = {
34
- type: StringConstructor | NumberConstructor | BooleanConstructor | DateConstructor;
35
- required?: boolean;
36
- generate?: 'ulid' | 'uuid';
37
- default?: any;
38
- nulls?: boolean;
39
- };
40
-
41
- /**
42
- * Object attribute definition with a nested schema
43
- *
44
- * @example
45
- * address: {
46
- * type: Object,
47
- * schema: {
48
- * street: { type: String },
49
- * city: { type: String, required: true },
50
- * }
51
- * }
52
- */
53
- export type ObjectAttributeDefinition = {
54
- type: ObjectConstructor;
55
- schema: Record<string, AttributeDefinition>;
56
- required?: boolean;
57
- default?: any;
58
- nulls?: boolean;
59
- };
60
-
61
- /**
62
- * Array attribute definition with a typed items schema
63
- *
64
- * @example
65
- * history: {
66
- * type: Array,
67
- * default: [],
68
- * items: {
69
- * type: Object,
70
- * schema: {
71
- * date: { type: String },
72
- * status: { type: String },
73
- * }
74
- * }
75
- * }
76
- */
77
- export type ArrayAttributeDefinition = {
78
- type: ArrayConstructor;
79
- items: AttributeDefinition;
80
- required?: boolean;
81
- default?: any;
82
- nulls?: boolean;
83
- };
84
-
85
- /**
86
- * Attribute definition for model attributes — supports scalars, nested objects, and arrays
87
- */
88
- export type AttributeDefinition =
89
- | ScalarAttributeDefinition
90
- | ObjectAttributeDefinition
91
- | ArrayAttributeDefinition;
92
-
93
- /**
94
- * Key definition for primary and secondary indexes
95
- *
96
- * @property type - Always String for DynamoDB keys
97
- * @property value - Template string for key generation
98
- */
99
- export type KeyDefinition = {
100
- type: StringConstructor;
101
- value: string;
102
- };
103
-
104
- /**
105
- * Primary key definition - requires both PK and SK (uppercase)
106
- */
107
- export type PrimaryKeyDefinition = {
108
- PK: KeyDefinition;
109
- SK: KeyDefinition;
110
- };
111
-
112
- /**
113
- * Index definition with hash and optional sort key
114
- */
115
- export type IndexDefinition = {
116
- hash: string;
117
- sort?: string;
118
- };
119
-
120
- /**
121
- * Indexes configuration - requires at least a primary index
122
- */
123
- export type IndexesDefinition = {
124
- primary: IndexDefinition;
125
- [indexName: string]: IndexDefinition;
126
- };
127
-
128
- /**
129
- * Model definition containing keys, indexes, and attributes
130
- * - key: REQUIRED, must have pk and sk
131
- * - attributes: REQUIRED, model attributes
132
- * - index: OPTIONAL, secondary index keys
133
- */
134
- export type ModelDefinition = {
135
- key: PrimaryKeyDefinition;
136
- index?: Record<string, KeyDefinition>;
137
- attributes: Record<string, AttributeDefinition>;
138
- };
139
-
140
- /**
141
- * Schema parameters configuration
142
- */
143
- export type SchemaParams = {
144
- timestamps?: boolean;
145
- cleanInternalKeys?: boolean;
146
- };
147
-
148
- /**
149
- * Complete schema definition for a DynamoDB table
150
- * - format: Table schema format version (e.g., "dynatable:1.0.0")
151
- * - version: Schema version (e.g., "1.0.0")
152
- * - indexes: Index definitions (requires at least 'primary')
153
- * - models: Model definitions (each requires 'key' and 'attributes')
154
- * - params: Optional schema parameters
155
- */
156
- export type SchemaDefinition = {
157
- format: string;
158
- version: string;
159
- indexes: IndexesDefinition;
160
- models: Record<string, ModelDefinition>;
161
- params?: SchemaParams;
162
- };
163
-
164
- /**
165
- * Recursively infers the TypeScript type from an AttributeDefinition.
166
- * - Object → infers the nested schema shape
167
- * - Array → infers an array of the items type
168
- * - Scalars → maps to the corresponding primitive
169
- */
170
- type InferAttr<A> = A extends { type: ObjectConstructor; schema: infer S }
171
- ? InferObjectSchema<S>
172
- : A extends { type: ArrayConstructor; items: infer I }
173
- ? Array<InferAttr<I>>
174
- : A extends { type: StringConstructor }
175
- ? string
176
- : A extends { type: NumberConstructor }
177
- ? number
178
- : A extends { type: BooleanConstructor }
179
- ? boolean
180
- : A extends { type: DateConstructor }
181
- ? Date
182
- : unknown;
183
-
184
- /**
185
- * Infers the shape of a nested object schema, respecting required/optional fields.
186
- */
187
- type InferObjectSchema<S> = {
188
- [K in keyof S as S[K] extends { required: true } ? K : never]: InferAttr<S[K]>;
189
- } & {
190
- [K in keyof S as S[K] extends { required: true } ? never : K]?: InferAttr<S[K]>;
191
- };
192
-
193
- /**
194
- * Non-generated attributes for input
195
- * Splits into required and optional based on the 'required' field
196
- */
197
- type NonGeneratedAttributes<M extends ModelDefinition> = {
198
- [K in keyof M['attributes'] as M['attributes'][K] extends { generate: string }
199
- ? never
200
- : M['attributes'][K] extends { required: true }
201
- ? K
202
- : never]: InferAttr<M['attributes'][K]>;
203
- } & {
204
- [K in keyof M['attributes'] as M['attributes'][K] extends { generate: string }
205
- ? never
206
- : M['attributes'][K] extends { required: false }
207
- ? K
208
- : M['attributes'][K] extends { required: true }
209
- ? never
210
- : K]?: InferAttr<M['attributes'][K]>;
211
- };
212
-
213
- /**
214
- * Generated-only attributes for internal use
215
- */
216
- type GeneratedAttributes<M extends ModelDefinition> = {
217
- [K in keyof M['attributes'] as M['attributes'][K] extends { generate: string }
218
- ? K
219
- : never]: InferAttr<M['attributes'][K]>;
220
- };
221
-
222
- /**
223
- * Template string variable extraction
224
- */
225
- type ExtractTemplateVars<S extends string> = S extends `${string}\${${infer Var}}${infer Rest}`
226
- ? Var | ExtractTemplateVars<Rest>
227
- : never;
228
-
229
- /**
230
- * Extract template variables from primary keys (PK and SK)
231
- */
232
- type PrimaryKeyVars<M extends ModelDefinition> =
233
- | ExtractTemplateVars<M['key']['PK']['value']>
234
- | ExtractTemplateVars<M['key']['SK']['value']>;
235
-
236
- /**
237
- * Extract template variables from index keys (if they exist)
238
- */
239
- type IndexKeyVars<M extends ModelDefinition> =
240
- M['index'] extends Record<string, KeyDefinition>
241
- ? {
242
- [K in keyof M['index']]: ExtractTemplateVars<M['index'][K]['value']>;
243
- }[keyof M['index']]
244
- : never;
245
-
246
- /**
247
- * Extract all template variables from primary and index keys
248
- */
249
- type KeyVars<M extends ModelDefinition> = PrimaryKeyVars<M> | IndexKeyVars<M>;
250
-
251
- type IsGenerated<M extends ModelDefinition, K extends string> = K extends keyof M['attributes']
252
- ? M['attributes'][K] extends { generate: string }
253
- ? true
254
- : false
255
- : false;
256
-
257
- type FilterNonGeneratedKeyVars<
258
- M extends ModelDefinition,
259
- K extends string = KeyVars<M>,
260
- > = K extends string ? (IsGenerated<M, K> extends true ? never : K) : never;
261
-
262
- /**
263
- * Keys required in input
264
- */
265
- type RequiredKeys<M extends ModelDefinition> = {
266
- [K in keyof NonGeneratedAttributes<M>]: M['attributes'][K] extends {
267
- required: true;
268
- }
269
- ? K
270
- : never;
271
- }[keyof NonGeneratedAttributes<M>];
272
-
273
- /**
274
- * Input type used for put/update
275
- *
276
- * @deprecated Use InferInputFromSchema when possible to get timestamp inference
277
- */
278
- export type InferInput<M extends ModelDefinition> = {
279
- [K in keyof NonGeneratedAttributes<M> as K extends RequiredKeys<M>
280
- ? K
281
- : never]: NonGeneratedAttributes<M>[K];
282
- } & {
283
- [K in keyof NonGeneratedAttributes<M> as K extends RequiredKeys<M>
284
- ? never
285
- : K]?: NonGeneratedAttributes<M>[K];
286
- } & {
287
- [K in FilterNonGeneratedKeyVars<M>]: string;
288
- };
289
-
290
- /**
291
- * Infers the input type from a complete schema definition
292
- * When timestamps are enabled, createdAt and updatedAt are NOT included (auto-generated)
293
- */
294
- export type InferInputFromSchema<
295
- S extends SchemaDefinition,
296
- ModelName extends keyof S['models'],
297
- > = InferInput<S['models'][ModelName]>;
298
-
299
- /**
300
- * Full model type after applying defaults and keys
301
- */
302
- type ModelAttributes<M extends ModelDefinition> = NonGeneratedAttributes<M> &
303
- GeneratedAttributes<M>;
304
-
305
- /**
306
- * Timestamp fields that are automatically added when timestamps are enabled
307
- */
308
- export type TimestampFields = {
309
- createdAt: string;
310
- updatedAt: string;
311
- };
312
-
313
- /**
314
- * Infers the model type without exposing internal DynamoDB keys (PK, SK, GSI1PK, etc.)
315
- * Only includes business attributes and generated fields
316
- *
317
- * @deprecated Use InferModelFromSchema when possible to get timestamp inference
318
- */
319
- export type InferModel<M extends ModelDefinition> = ModelAttributes<M>;
320
-
321
- /**
322
- * Infers the model type from a complete schema definition
323
- * Automatically includes timestamp fields (createdAt, updatedAt) when params.timestamps is true
324
- */
325
- export type InferModelFromSchema<
326
- S extends SchemaDefinition,
327
- ModelName extends keyof S['models'],
328
- > = S['params'] extends { timestamps: true }
329
- ? ModelAttributes<S['models'][ModelName]> & TimestampFields
330
- : ModelAttributes<S['models'][ModelName]>;
331
-
332
- /**
333
- * Internal type that includes DynamoDB keys - used internally by builders
334
- * Includes pk, sk, and any index keys
335
- * @internal
336
- */
337
- export type InferModelWithKeys<M extends ModelDefinition> = ModelAttributes<M> & {
338
- [K in keyof M['key']]: string;
339
- } & (M['index'] extends Record<string, KeyDefinition>
340
- ? {
341
- [K in keyof M['index']]: string;
342
- }
343
- : Record<string, never>);
344
-
345
- /**
346
- * Extract template variables from primary keys only
347
- */
348
- type KeyTemplateVars<M extends ModelDefinition> = PrimaryKeyVars<M>;
349
-
350
- /**
351
- * Input for get/delete operations (only key template vars)
352
- */
353
- export type InferKeyInput<M extends ModelDefinition> = {
354
- [K in KeyTemplateVars<M>]: string;
355
- };
356
-
357
- /**
358
- * Extracts the item type from an array attribute.
359
- *
360
- * @example
361
- * type StoryFrame = ArrayItem<StoryEntity['frames']>;
362
- * // → { url: string; duration?: number; mediaType?: string }
363
- *
364
- * type HistoryEntry = ArrayItem<TransactionEntity['history']>;
365
- */
366
- export type ArrayItem<T extends readonly unknown[] | undefined> = NonNullable<T>[number];
@@ -1,224 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
3
- import { InferInput, InferKeyInput, InferModel, ModelDefinition } from '@/core/types';
4
- import { applyPostDefaults, resolveKeys } from '@/utils/model-utils';
5
- import { modelToZod } from '@/utils/zod-utils';
6
- import {
7
- createGetBuilder,
8
- createPutBuilder,
9
- createQueryBuilder,
10
- createUpdateBuilder,
11
- createDeleteBuilder,
12
- createScanBuilder,
13
- createBatchGetBuilder,
14
- createBatchWriteBuilder,
15
- WriteRequest,
16
- } from '@/builders';
17
- import { EntityAPI, EntityAPIOptions } from './types';
18
- import { withMiddleware } from './middleware/with-middleware';
19
- import { createCleanKeysMiddleware } from './middleware/factories';
20
- import { validateKeyFields } from './validation/key-validation';
21
- import { Condition } from '@/builders/shared/types';
22
-
23
- /**
24
- * Creates an entity API instance with validation, key resolution, and builder creation.
25
- *
26
- * @param tableName - The name of the DynamoDB table
27
- * @param modelName - The name of the model/entity
28
- * @param model - The model definition
29
- * @param client - DynamoDB client instance
30
- * @param options - Optional configuration (logger, timestamps, cleanInternalKeys)
31
- * @returns EntityAPI with get, put, query, scan, update, delete, batchGet, and batchWrite methods
32
- */
33
- export const createEntityAPI = <Model extends ModelDefinition>(
34
- tableName: string,
35
- modelName: string,
36
- model: Model,
37
- client: DynamoDBClient,
38
- options: EntityAPIOptions = {}
39
- ): EntityAPI<InferModel<Model>, InferInput<Model>, InferKeyInput<Model>> => {
40
- const { logger, timestamps = false, cleanInternalKeys = false } = options;
41
-
42
- // Build a Zod schema from the model
43
- const zodSchema = modelToZod(model);
44
-
45
- return {
46
- get(key) {
47
- // Validate key fields
48
- validateKeyFields(modelName, model, key as Record<string, unknown>, 'get()');
49
-
50
- // Resolve any key defaults or computed keys
51
- const fullKey = resolveKeys(model, key);
52
-
53
- const builder = createGetBuilder<InferKeyInput<Model>, InferModel<Model>>(
54
- tableName,
55
- fullKey,
56
- client,
57
- undefined,
58
- logger
59
- );
60
-
61
- return withMiddleware(builder, createCleanKeysMiddleware(cleanInternalKeys));
62
- },
63
-
64
- put(item) {
65
- // Validate full input data
66
- const parsed = zodSchema.parse(item);
67
-
68
- // Apply post-processing defaults from the model (including timestamps for new items)
69
- const withDefaults = applyPostDefaults(model, parsed, {
70
- isUpdate: false,
71
- timestamps,
72
- });
73
-
74
- // Resolve keys again with defaults (including GSI index keys)
75
- const fullKey = resolveKeys(model, withDefaults, 'both');
76
-
77
- // Combine keys and data into full item, adding _type field
78
- const fullItem = {
79
- ...withDefaults,
80
- ...fullKey,
81
- _type: modelName, // Add entity type identifier
82
- };
83
-
84
- return createPutBuilder(tableName, fullItem, client, [], false, 'NONE', false, logger);
85
- },
86
-
87
- query() {
88
- // Auto-filter by entity type so query() only returns items for this
89
- // entity. Without this, queries on shared GSIs return items from other
90
- // entities that share the same partition key.
91
- return createQueryBuilder<InferModel<Model>>(tableName, client, model, logger, modelName);
92
- },
93
-
94
- scan() {
95
- // Auto-filter by entity type so scan only returns items for this entity
96
- const typeFilter: Condition = {
97
- expression: '#_type = :_type',
98
- names: { '#_type': '_type' },
99
- values: { ':_type': modelName },
100
- };
101
-
102
- const builder = createScanBuilder<InferModel<Model>>(
103
- tableName,
104
- client,
105
- [typeFilter],
106
- [],
107
- undefined,
108
- false,
109
- undefined,
110
- undefined,
111
- undefined,
112
- logger
113
- );
114
-
115
- return withMiddleware(builder, createCleanKeysMiddleware(cleanInternalKeys));
116
- },
117
-
118
- update(key) {
119
- // Validate key fields
120
- validateKeyFields(modelName, model, key as Record<string, unknown>, 'update()');
121
-
122
- // Resolve any key defaults or computed keys
123
- const fullKey = resolveKeys(model, key);
124
-
125
- const builder = createUpdateBuilder<InferModel<Model>>(
126
- tableName,
127
- fullKey as Partial<InferModel<Model>>,
128
- client,
129
- [],
130
- { set: [], remove: [], add: [], delete: [] },
131
- 'NONE',
132
- 0,
133
- timestamps,
134
- logger,
135
- // Carry the original template-vars-bearing key (e.g. { username: 'jane' })
136
- // so the builder can recompute index keys when .set() touches their template fields.
137
- { model, keyVars: key as Record<string, unknown> }
138
- );
139
-
140
- return withMiddleware(builder, createCleanKeysMiddleware(cleanInternalKeys));
141
- },
142
-
143
- delete(key) {
144
- // Validate key fields
145
- validateKeyFields(modelName, model, key as Record<string, unknown>, 'delete()');
146
-
147
- // Resolve any key defaults or computed keys
148
- const fullKey = resolveKeys(model, key);
149
-
150
- const builder = createDeleteBuilder<InferModel<Model>>(
151
- tableName,
152
- fullKey as Partial<InferModel<Model>>,
153
- client,
154
- [],
155
- 'NONE',
156
- logger
157
- );
158
-
159
- return withMiddleware(builder, createCleanKeysMiddleware(cleanInternalKeys));
160
- },
161
-
162
- batchGet(keys) {
163
- // Process all keys and validate them
164
- const resolvedKeys = keys.map((key) => {
165
- // Validate key fields
166
- validateKeyFields(modelName, model, key as Record<string, unknown>, 'batchGet()');
167
-
168
- // Resolve any key defaults or computed keys
169
- return resolveKeys(model, key);
170
- });
171
-
172
- // Create the request items in the format expected by BatchGetItem
173
- const requestItems = {
174
- [tableName]: {
175
- Keys: resolvedKeys,
176
- },
177
- };
178
-
179
- const builder = createBatchGetBuilder<InferModel<Model>>(
180
- requestItems,
181
- client,
182
- undefined,
183
- logger
184
- );
185
-
186
- return withMiddleware(builder, createCleanKeysMiddleware(cleanInternalKeys));
187
- },
188
-
189
- batchWrite(items) {
190
- // Validate and process all items
191
- const processedItems = items.map((item) => {
192
- // Validate full input data
193
- const parsed = zodSchema.parse(item);
194
-
195
- // Apply post-processing defaults from the model (including timestamps for new items)
196
- const withDefaults = applyPostDefaults(model, parsed, {
197
- isUpdate: false,
198
- timestamps,
199
- });
200
-
201
- // Resolve keys again with defaults (including GSI index keys)
202
- const fullKey = resolveKeys(model, withDefaults, 'both');
203
-
204
- // Combine keys and data into full item, adding _type field
205
- return {
206
- ...withDefaults,
207
- ...fullKey,
208
- _type: modelName, // Add entity type identifier
209
- };
210
- });
211
-
212
- // Create the request items in the format expected by BatchWriteItem
213
- const requestItems: Record<string, WriteRequest[]> = {
214
- [tableName]: processedItems.map((item) => ({
215
- PutRequest: {
216
- Item: item,
217
- },
218
- })),
219
- };
220
-
221
- return createBatchWriteBuilder(requestItems, client, logger);
222
- },
223
- };
224
- };
@@ -1,19 +0,0 @@
1
- /**
2
- * Entity API module
3
- *
4
- * Provides high-level entity management with validation, key resolution, and builder creation.
5
- */
6
-
7
- // Core types
8
- export type { EntityAPI, EntityAPIOptions } from './types';
9
-
10
- // Middleware types and utilities
11
- export type { ExecutionMiddleware } from './middleware/types';
12
- export { withMiddleware } from './middleware/with-middleware';
13
- export { createCleanKeysMiddleware } from './middleware/factories';
14
-
15
- // Validation utilities
16
- export { validateKeyFields } from './validation/key-validation';
17
-
18
- // Main entity API factory
19
- export { createEntityAPI } from './create-entity-api';
@@ -1,15 +0,0 @@
1
- import { stripInternalKeys } from '@/utils/model-utils';
2
- import { ExecutionMiddleware } from './types';
3
-
4
- /**
5
- * Creates middleware configuration for cleaning internal keys
6
- */
7
- export function createCleanKeysMiddleware(shouldClean: boolean): ExecutionMiddleware {
8
- if (!shouldClean) {
9
- return {};
10
- }
11
-
12
- return {
13
- after: (result) => stripInternalKeys(result),
14
- };
15
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Middleware hooks for builder execution
3
- */
4
- export type ExecutionMiddleware<T = any> = {
5
- before?: () => void | Promise<void>;
6
- after?: (result: T) => T | Promise<T>;
7
- };
@@ -1,37 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { ExecutionMiddleware } from './types';
3
-
4
- /**
5
- * Applies middleware hooks to a builder's execute method
6
- */
7
- export function withMiddleware<B extends { execute: () => Promise<any> }>(
8
- builder: B,
9
- middleware: ExecutionMiddleware
10
- ): B {
11
- const { before, after } = middleware;
12
-
13
- // If no middleware hooks provided, return builder as-is
14
- if (!before && !after) {
15
- return builder;
16
- }
17
-
18
- return {
19
- ...builder,
20
- execute: async () => {
21
- // Before execution hook
22
- if (before) {
23
- await before();
24
- }
25
-
26
- // Execute original builder
27
- const result = await builder.execute();
28
-
29
- // After execution hook
30
- if (after) {
31
- return await after(result);
32
- }
33
-
34
- return result;
35
- },
36
- };
37
- }