@ftschopp/dynatable-core 1.0.0
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/CHANGELOG.md +62 -0
- package/README.md +17 -0
- package/dist/builders/batch-get/create-batch-get-builder.d.ts +18 -0
- package/dist/builders/batch-get/create-batch-get-builder.d.ts.map +1 -0
- package/dist/builders/batch-get/create-batch-get-builder.js +71 -0
- package/dist/builders/batch-get/index.d.ts +3 -0
- package/dist/builders/batch-get/index.d.ts.map +1 -0
- package/dist/builders/batch-get/index.js +18 -0
- package/dist/builders/batch-get/types.d.ts +25 -0
- package/dist/builders/batch-get/types.d.ts.map +1 -0
- package/dist/builders/batch-get/types.js +2 -0
- package/dist/builders/batch-write/create-batch-write-builder.d.ts +12 -0
- package/dist/builders/batch-write/create-batch-write-builder.d.ts.map +1 -0
- package/dist/builders/batch-write/create-batch-write-builder.js +35 -0
- package/dist/builders/batch-write/index.d.ts +3 -0
- package/dist/builders/batch-write/index.d.ts.map +1 -0
- package/dist/builders/batch-write/index.js +18 -0
- package/dist/builders/batch-write/types.d.ts +30 -0
- package/dist/builders/batch-write/types.d.ts.map +1 -0
- package/dist/builders/batch-write/types.js +2 -0
- package/dist/builders/delete/create-delete-builder.d.ts +9 -0
- package/dist/builders/delete/create-delete-builder.d.ts.map +1 -0
- package/dist/builders/delete/create-delete-builder.js +72 -0
- package/dist/builders/delete/index.d.ts +3 -0
- package/dist/builders/delete/index.d.ts.map +1 -0
- package/dist/builders/delete/index.js +18 -0
- package/dist/builders/delete/types.d.ts +11 -0
- package/dist/builders/delete/types.d.ts.map +1 -0
- package/dist/builders/delete/types.js +2 -0
- package/dist/builders/get/create-get-builder.d.ts +12 -0
- package/dist/builders/get/create-get-builder.d.ts.map +1 -0
- package/dist/builders/get/create-get-builder.js +95 -0
- package/dist/builders/get/index.d.ts +3 -0
- package/dist/builders/get/index.d.ts.map +1 -0
- package/dist/builders/get/index.js +18 -0
- package/dist/builders/get/types.d.ts +28 -0
- package/dist/builders/get/types.d.ts.map +1 -0
- package/dist/builders/get/types.js +2 -0
- package/dist/builders/index.d.ts +12 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +29 -0
- package/dist/builders/put/create-put-builder.d.ts +9 -0
- package/dist/builders/put/create-put-builder.d.ts.map +1 -0
- package/dist/builders/put/create-put-builder.js +104 -0
- package/dist/builders/put/index.d.ts +3 -0
- package/dist/builders/put/index.d.ts.map +1 -0
- package/dist/builders/put/index.js +18 -0
- package/dist/builders/put/types.d.ts +17 -0
- package/dist/builders/put/types.d.ts.map +1 -0
- package/dist/builders/put/types.js +2 -0
- package/dist/builders/query/create-query-builder.d.ts +9 -0
- package/dist/builders/query/create-query-builder.d.ts.map +1 -0
- package/dist/builders/query/create-query-builder.js +283 -0
- package/dist/builders/query/index.d.ts +3 -0
- package/dist/builders/query/index.d.ts.map +1 -0
- package/dist/builders/query/index.js +18 -0
- package/dist/builders/query/types.d.ts +79 -0
- package/dist/builders/query/types.d.ts.map +1 -0
- package/dist/builders/query/types.js +2 -0
- package/dist/builders/scan/create-scan-builder.d.ts +12 -0
- package/dist/builders/scan/create-scan-builder.d.ts.map +1 -0
- package/dist/builders/scan/create-scan-builder.js +103 -0
- package/dist/builders/scan/index.d.ts +3 -0
- package/dist/builders/scan/index.d.ts.map +1 -0
- package/dist/builders/scan/index.js +18 -0
- package/dist/builders/scan/types.d.ts +43 -0
- package/dist/builders/scan/types.d.ts.map +1 -0
- package/dist/builders/scan/types.js +2 -0
- package/dist/builders/shared/conditions.d.ts +18 -0
- package/dist/builders/shared/conditions.d.ts.map +1 -0
- package/dist/builders/shared/conditions.js +48 -0
- package/dist/builders/shared/index.d.ts +4 -0
- package/dist/builders/shared/index.d.ts.map +1 -0
- package/dist/builders/shared/index.js +19 -0
- package/dist/builders/shared/operators.d.ts +12 -0
- package/dist/builders/shared/operators.d.ts.map +1 -0
- package/dist/builders/shared/operators.js +197 -0
- package/dist/builders/shared/types.d.ts +77 -0
- package/dist/builders/shared/types.d.ts.map +1 -0
- package/dist/builders/shared/types.js +6 -0
- package/dist/builders/transact-get/create-transact-get-builder.d.ts +18 -0
- package/dist/builders/transact-get/create-transact-get-builder.d.ts.map +1 -0
- package/dist/builders/transact-get/create-transact-get-builder.js +60 -0
- package/dist/builders/transact-get/index.d.ts +3 -0
- package/dist/builders/transact-get/index.d.ts.map +1 -0
- package/dist/builders/transact-get/index.js +18 -0
- package/dist/builders/transact-get/types.d.ts +28 -0
- package/dist/builders/transact-get/types.d.ts.map +1 -0
- package/dist/builders/transact-get/types.js +2 -0
- package/dist/builders/transact-write/create-transact-write-builder.d.ts +18 -0
- package/dist/builders/transact-write/create-transact-write-builder.d.ts.map +1 -0
- package/dist/builders/transact-write/create-transact-write-builder.js +97 -0
- package/dist/builders/transact-write/index.d.ts +3 -0
- package/dist/builders/transact-write/index.d.ts.map +1 -0
- package/dist/builders/transact-write/index.js +18 -0
- package/dist/builders/transact-write/types.d.ts +34 -0
- package/dist/builders/transact-write/types.d.ts.map +1 -0
- package/dist/builders/transact-write/types.js +2 -0
- package/dist/builders/update/create-update-builder.d.ts +14 -0
- package/dist/builders/update/create-update-builder.d.ts.map +1 -0
- package/dist/builders/update/create-update-builder.js +180 -0
- package/dist/builders/update/index.d.ts +3 -0
- package/dist/builders/update/index.d.ts.map +1 -0
- package/dist/builders/update/index.js +18 -0
- package/dist/builders/update/types.d.ts +35 -0
- package/dist/builders/update/types.d.ts.map +1 -0
- package/dist/builders/update/types.js +2 -0
- package/dist/core/types.d.ts +224 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/entity.d.ts +73 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/entity.js +161 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/table.d.ts +70 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +69 -0
- package/dist/utils/dynamodb-logger.d.ts +118 -0
- package/dist/utils/dynamodb-logger.d.ts.map +1 -0
- package/dist/utils/dynamodb-logger.js +125 -0
- package/dist/utils/model-utils.d.ts +24 -0
- package/dist/utils/model-utils.d.ts.map +1 -0
- package/dist/utils/model-utils.js +88 -0
- package/dist/utils/zod-utils.d.ts +13 -0
- package/dist/utils/zod-utils.d.ts.map +1 -0
- package/dist/utils/zod-utils.js +35 -0
- package/eslint.config.mjs +4 -0
- package/jest.config.js +11 -0
- package/package.json +36 -0
- package/src/builders/README.md +272 -0
- package/src/builders/batch-get/README.md +98 -0
- package/src/builders/batch-get/create-batch-get-builder.test.ts +165 -0
- package/src/builders/batch-get/create-batch-get-builder.ts +106 -0
- package/src/builders/batch-get/index.ts +2 -0
- package/src/builders/batch-get/types.ts +29 -0
- package/src/builders/batch-write/README.md +204 -0
- package/src/builders/batch-write/create-batch-write-builder.test.ts +173 -0
- package/src/builders/batch-write/create-batch-write-builder.ts +49 -0
- package/src/builders/batch-write/index.ts +2 -0
- package/src/builders/batch-write/types.ts +33 -0
- package/src/builders/delete/create-delete-builder.test.ts +294 -0
- package/src/builders/delete/create-delete-builder.ts +100 -0
- package/src/builders/delete/index.ts +2 -0
- package/src/builders/delete/types.ts +11 -0
- package/src/builders/get/create-get-builder.test.ts +272 -0
- package/src/builders/get/create-get-builder.ts +140 -0
- package/src/builders/get/index.ts +2 -0
- package/src/builders/get/types.ts +30 -0
- package/src/builders/index.ts +14 -0
- package/src/builders/put/create-put-builder.test.ts +213 -0
- package/src/builders/put/create-put-builder.ts +151 -0
- package/src/builders/put/index.ts +2 -0
- package/src/builders/put/types.ts +18 -0
- package/src/builders/query/create-query-builder.test.ts +230 -0
- package/src/builders/query/create-query-builder.ts +353 -0
- package/src/builders/query/index.ts +2 -0
- package/src/builders/query/types.ts +95 -0
- package/src/builders/scan/create-scan-builder.test.ts +260 -0
- package/src/builders/scan/create-scan-builder.ts +217 -0
- package/src/builders/scan/index.ts +2 -0
- package/src/builders/scan/types.ts +49 -0
- package/src/builders/shared/conditions.ts +58 -0
- package/src/builders/shared/index.ts +3 -0
- package/src/builders/shared/operators.test.ts +270 -0
- package/src/builders/shared/operators.ts +200 -0
- package/src/builders/shared/types.ts +100 -0
- package/src/builders/transact-get/README.md +167 -0
- package/src/builders/transact-get/create-transact-get-builder.test.ts +239 -0
- package/src/builders/transact-get/create-transact-get-builder.ts +67 -0
- package/src/builders/transact-get/index.ts +2 -0
- package/src/builders/transact-get/types.ts +31 -0
- package/src/builders/transact-write/README.md +166 -0
- package/src/builders/transact-write/create-transact-write-builder.test.ts +288 -0
- package/src/builders/transact-write/create-transact-write-builder.ts +118 -0
- package/src/builders/transact-write/index.ts +2 -0
- package/src/builders/transact-write/types.ts +33 -0
- package/src/builders/update/create-update-builder.test.ts +333 -0
- package/src/builders/update/create-update-builder.ts +284 -0
- package/src/builders/update/index.ts +2 -0
- package/src/builders/update/types.ts +42 -0
- package/src/core/types.test.ts +506 -0
- package/src/core/types.ts +290 -0
- package/src/entity.ts +337 -0
- package/src/index.ts +22 -0
- package/src/table.ts +109 -0
- package/src/utils/dynamodb-logger.test.ts +246 -0
- package/src/utils/dynamodb-logger.ts +175 -0
- package/src/utils/model-utils.test.ts +232 -0
- package/src/utils/model-utils.ts +101 -0
- package/src/utils/zod-utils.test.ts +272 -0
- package/src/utils/zod-utils.ts +36 -0
- package/tests/integration/instagram-clone.integration.test.ts +966 -0
- package/tests/integration/pagination-timestamps.integration.test.ts +375 -0
- package/tests/integration/transactions.integration.test.ts +529 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for DynamoDB schema and model inference
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive type utilities for:
|
|
5
|
+
* - Defining DynamoDB table schemas with primary and secondary indexes
|
|
6
|
+
* - Inferring strongly-typed input and output models from schema definitions
|
|
7
|
+
* - Automatic key generation and template variable extraction
|
|
8
|
+
* - Type-safe attribute handling with support for defaults and auto-generation
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const schema: SchemaDefinition = {
|
|
13
|
+
* format: 'dynatable:1.0.0',
|
|
14
|
+
* version: '1.0.0',
|
|
15
|
+
* indexes: { primary: { hash: "PK", sort: "SK" } },
|
|
16
|
+
* models: {
|
|
17
|
+
* User: {
|
|
18
|
+
* key: { PK: { type: String, value: "USER#${id}" }, SK: { type: String, value: "PROFILE" } },
|
|
19
|
+
* attributes: { id: { type: String, required: true }, name: { type: String } }
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Attribute definition for model attributes
|
|
27
|
+
*
|
|
28
|
+
* @property type - The JavaScript constructor for the attribute type
|
|
29
|
+
* @property [required] - Whether the attribute is required
|
|
30
|
+
* @property [generate] - Auto-generation strategy ('ulid', 'uuid')
|
|
31
|
+
* @property [default] - Default value or generator function
|
|
32
|
+
*/
|
|
33
|
+
export type AttributeDefinition = {
|
|
34
|
+
type: StringConstructor | NumberConstructor | BooleanConstructor | DateConstructor;
|
|
35
|
+
required?: boolean;
|
|
36
|
+
generate?: 'ulid' | 'uuid';
|
|
37
|
+
default?: any;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Key definition for primary and secondary indexes
|
|
41
|
+
*
|
|
42
|
+
* @property type - Always String for DynamoDB keys
|
|
43
|
+
* @property value - Template string for key generation
|
|
44
|
+
*/
|
|
45
|
+
export type KeyDefinition = {
|
|
46
|
+
type: StringConstructor;
|
|
47
|
+
value: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Primary key definition - requires both PK and SK (uppercase)
|
|
51
|
+
*/
|
|
52
|
+
export type PrimaryKeyDefinition = {
|
|
53
|
+
PK: KeyDefinition;
|
|
54
|
+
SK: KeyDefinition;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Index definition with hash and optional sort key
|
|
58
|
+
*/
|
|
59
|
+
export type IndexDefinition = {
|
|
60
|
+
hash: string;
|
|
61
|
+
sort?: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Indexes configuration - requires at least a primary index
|
|
65
|
+
*/
|
|
66
|
+
export type IndexesDefinition = {
|
|
67
|
+
primary: IndexDefinition;
|
|
68
|
+
[indexName: string]: IndexDefinition;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Model definition containing keys, indexes, and attributes
|
|
72
|
+
* - key: REQUIRED, must have pk and sk
|
|
73
|
+
* - attributes: REQUIRED, model attributes
|
|
74
|
+
* - index: OPTIONAL, secondary index keys
|
|
75
|
+
*/
|
|
76
|
+
export type ModelDefinition = {
|
|
77
|
+
key: PrimaryKeyDefinition;
|
|
78
|
+
index?: Record<string, KeyDefinition>;
|
|
79
|
+
attributes: Record<string, AttributeDefinition>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Schema parameters configuration
|
|
83
|
+
*/
|
|
84
|
+
export type SchemaParams = {
|
|
85
|
+
isoDates?: boolean;
|
|
86
|
+
timestamps?: boolean;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Complete schema definition for a DynamoDB table
|
|
90
|
+
* - format: Table schema format version (e.g., "dynatable:1.0.0")
|
|
91
|
+
* - version: Schema version (e.g., "1.0.0")
|
|
92
|
+
* - indexes: Index definitions (requires at least 'primary')
|
|
93
|
+
* - models: Model definitions (each requires 'key' and 'attributes')
|
|
94
|
+
* - params: Optional schema parameters
|
|
95
|
+
*/
|
|
96
|
+
export type SchemaDefinition = {
|
|
97
|
+
format: string;
|
|
98
|
+
version: string;
|
|
99
|
+
indexes: IndexesDefinition;
|
|
100
|
+
models: Record<string, ModelDefinition>;
|
|
101
|
+
params?: SchemaParams;
|
|
102
|
+
};
|
|
103
|
+
type InferAttr<T> = T extends StringConstructor ? string : T extends NumberConstructor ? number : T extends BooleanConstructor ? boolean : T extends DateConstructor ? Date : unknown;
|
|
104
|
+
/**
|
|
105
|
+
* Non-generated attributes for input
|
|
106
|
+
* Splits into required and optional based on the 'required' field
|
|
107
|
+
*/
|
|
108
|
+
type NonGeneratedAttributes<M extends ModelDefinition> = {
|
|
109
|
+
[K in keyof M['attributes'] as M['attributes'][K] extends {
|
|
110
|
+
generate: string;
|
|
111
|
+
} ? never : M['attributes'][K] extends {
|
|
112
|
+
required: true;
|
|
113
|
+
} ? K : never]: InferAttr<M['attributes'][K]['type']>;
|
|
114
|
+
} & {
|
|
115
|
+
[K in keyof M['attributes'] as M['attributes'][K] extends {
|
|
116
|
+
generate: string;
|
|
117
|
+
} ? never : M['attributes'][K] extends {
|
|
118
|
+
required: false;
|
|
119
|
+
} ? K : M['attributes'][K] extends {
|
|
120
|
+
required: true;
|
|
121
|
+
} ? never : K]?: InferAttr<M['attributes'][K]['type']>;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Generated-only attributes for internal use
|
|
125
|
+
*/
|
|
126
|
+
type GeneratedAttributes<M extends ModelDefinition> = {
|
|
127
|
+
[K in keyof M['attributes'] as M['attributes'][K] extends {
|
|
128
|
+
generate: string;
|
|
129
|
+
} ? K : never]: InferAttr<M['attributes'][K]['type']>;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Template string variable extraction
|
|
133
|
+
*/
|
|
134
|
+
type ExtractTemplateVars<S extends string> = S extends `${string}\${${infer Var}}${infer Rest}` ? Var | ExtractTemplateVars<Rest> : never;
|
|
135
|
+
/**
|
|
136
|
+
* Extract template variables from primary keys (PK and SK)
|
|
137
|
+
*/
|
|
138
|
+
type PrimaryKeyVars<M extends ModelDefinition> = ExtractTemplateVars<M['key']['PK']['value']> | ExtractTemplateVars<M['key']['SK']['value']>;
|
|
139
|
+
/**
|
|
140
|
+
* Extract template variables from index keys (if they exist)
|
|
141
|
+
*/
|
|
142
|
+
type IndexKeyVars<M extends ModelDefinition> = M['index'] extends Record<string, KeyDefinition> ? {
|
|
143
|
+
[K in keyof M['index']]: ExtractTemplateVars<M['index'][K]['value']>;
|
|
144
|
+
}[keyof M['index']] : never;
|
|
145
|
+
/**
|
|
146
|
+
* Extract all template variables from primary and index keys
|
|
147
|
+
*/
|
|
148
|
+
type KeyVars<M extends ModelDefinition> = PrimaryKeyVars<M> | IndexKeyVars<M>;
|
|
149
|
+
type IsGenerated<M extends ModelDefinition, K extends string> = K extends keyof M['attributes'] ? M['attributes'][K] extends {
|
|
150
|
+
generate: string;
|
|
151
|
+
} ? true : false : false;
|
|
152
|
+
type FilterNonGeneratedKeyVars<M extends ModelDefinition, K extends string = KeyVars<M>> = K extends string ? (IsGenerated<M, K> extends true ? never : K) : never;
|
|
153
|
+
/**
|
|
154
|
+
* Keys required in input
|
|
155
|
+
*/
|
|
156
|
+
type RequiredKeys<M extends ModelDefinition> = {
|
|
157
|
+
[K in keyof NonGeneratedAttributes<M>]: M['attributes'][K] extends {
|
|
158
|
+
required: true;
|
|
159
|
+
} ? K : never;
|
|
160
|
+
}[keyof NonGeneratedAttributes<M>];
|
|
161
|
+
/**
|
|
162
|
+
* Input type used for put/update
|
|
163
|
+
*
|
|
164
|
+
* @deprecated Use InferInputFromSchema when possible to get timestamp inference
|
|
165
|
+
*/
|
|
166
|
+
export type InferInput<M extends ModelDefinition> = {
|
|
167
|
+
[K in keyof NonGeneratedAttributes<M> as K extends RequiredKeys<M> ? K : never]: NonGeneratedAttributes<M>[K];
|
|
168
|
+
} & {
|
|
169
|
+
[K in keyof NonGeneratedAttributes<M> as K extends RequiredKeys<M> ? never : K]?: NonGeneratedAttributes<M>[K];
|
|
170
|
+
} & {
|
|
171
|
+
[K in FilterNonGeneratedKeyVars<M>]: string;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Infers the input type from a complete schema definition
|
|
175
|
+
* When timestamps are enabled, createdAt and updatedAt are NOT included (auto-generated)
|
|
176
|
+
*/
|
|
177
|
+
export type InferInputFromSchema<S extends SchemaDefinition, ModelName extends keyof S['models']> = InferInput<S['models'][ModelName]>;
|
|
178
|
+
/**
|
|
179
|
+
* Full model type after applying defaults and keys
|
|
180
|
+
*/
|
|
181
|
+
type ModelAttributes<M extends ModelDefinition> = NonGeneratedAttributes<M> & GeneratedAttributes<M>;
|
|
182
|
+
/**
|
|
183
|
+
* Timestamp fields that are automatically added when timestamps are enabled
|
|
184
|
+
*/
|
|
185
|
+
export type TimestampFields = {
|
|
186
|
+
createdAt: string;
|
|
187
|
+
updatedAt: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Infers the model type without exposing internal DynamoDB keys (PK, SK, GSI1PK, etc.)
|
|
191
|
+
* Only includes business attributes and generated fields
|
|
192
|
+
*
|
|
193
|
+
* @deprecated Use InferModelFromSchema when possible to get timestamp inference
|
|
194
|
+
*/
|
|
195
|
+
export type InferModel<M extends ModelDefinition> = ModelAttributes<M>;
|
|
196
|
+
/**
|
|
197
|
+
* Infers the model type from a complete schema definition
|
|
198
|
+
* Automatically includes timestamp fields (createdAt, updatedAt) when params.timestamps is true
|
|
199
|
+
*/
|
|
200
|
+
export type InferModelFromSchema<S extends SchemaDefinition, ModelName extends keyof S['models']> = S['params'] extends {
|
|
201
|
+
timestamps: true;
|
|
202
|
+
} ? ModelAttributes<S['models'][ModelName]> & TimestampFields : ModelAttributes<S['models'][ModelName]>;
|
|
203
|
+
/**
|
|
204
|
+
* Internal type that includes DynamoDB keys - used internally by builders
|
|
205
|
+
* Includes pk, sk, and any index keys
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
export type InferModelWithKeys<M extends ModelDefinition> = ModelAttributes<M> & {
|
|
209
|
+
[K in keyof M['key']]: string;
|
|
210
|
+
} & (M['index'] extends Record<string, KeyDefinition> ? {
|
|
211
|
+
[K in keyof M['index']]: string;
|
|
212
|
+
} : Record<string, never>);
|
|
213
|
+
/**
|
|
214
|
+
* Extract template variables from primary keys only
|
|
215
|
+
*/
|
|
216
|
+
type KeyTemplateVars<M extends ModelDefinition> = PrimaryKeyVars<M>;
|
|
217
|
+
/**
|
|
218
|
+
* Input for get/delete operations (only key template vars)
|
|
219
|
+
*/
|
|
220
|
+
export type InferKeyInput<M extends ModelDefinition> = {
|
|
221
|
+
[K in KeyTemplateVars<M>]: string;
|
|
222
|
+
};
|
|
223
|
+
export {};
|
|
224
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/entity.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { InferInput, InferKeyInput, InferModel, ModelDefinition } from './core/types';
|
|
3
|
+
import { GetBuilder, PutBuilder, QueryBuilder, UpdateBuilder, DeleteBuilder, ScanBuilder, BatchGetBuilder, BatchWriteBuilder } from './builders';
|
|
4
|
+
import { DynamoDBLogger } from './utils/dynamodb-logger';
|
|
5
|
+
/**
|
|
6
|
+
* Options for creating the Entity API
|
|
7
|
+
*/
|
|
8
|
+
export type EntityAPIOptions = {
|
|
9
|
+
logger?: DynamoDBLogger;
|
|
10
|
+
timestamps?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Entity API interface for a model
|
|
14
|
+
*/
|
|
15
|
+
export type EntityAPI<Model, Input, KeyInput, ModelDef extends ModelDefinition = any> = {
|
|
16
|
+
/**
|
|
17
|
+
* Retrieves an item by its key.
|
|
18
|
+
* @param key - Partial or full key object to identify the item
|
|
19
|
+
* @returns GetBuilder configured for the item
|
|
20
|
+
*/
|
|
21
|
+
get: (key: KeyInput) => GetBuilder<KeyInput, Model>;
|
|
22
|
+
/**
|
|
23
|
+
* Puts an item into the table after validation and applying defaults.
|
|
24
|
+
* @param item - The input data to put
|
|
25
|
+
* @returns PutBuilder configured for the item
|
|
26
|
+
*/
|
|
27
|
+
put: (item: Input) => PutBuilder<Model>;
|
|
28
|
+
/**
|
|
29
|
+
* Queries items using key conditions.
|
|
30
|
+
* @returns QueryBuilder for building and executing the query
|
|
31
|
+
*/
|
|
32
|
+
query: () => QueryBuilder<Model, ModelDef>;
|
|
33
|
+
/**
|
|
34
|
+
* Scans the entire table or index without key conditions.
|
|
35
|
+
* @returns ScanBuilder for building and executing the scan
|
|
36
|
+
*/
|
|
37
|
+
scan: () => ScanBuilder<Model>;
|
|
38
|
+
/**
|
|
39
|
+
* Updates an item by its key.
|
|
40
|
+
* @param key - Partial or full key object to identify the item
|
|
41
|
+
* @returns UpdateBuilder configured for the item
|
|
42
|
+
*/
|
|
43
|
+
update: (key: KeyInput) => UpdateBuilder<Model>;
|
|
44
|
+
/**
|
|
45
|
+
* Deletes an item by its key.
|
|
46
|
+
* @param key - Partial or full key object to identify the item
|
|
47
|
+
* @returns DeleteBuilder configured for the item
|
|
48
|
+
*/
|
|
49
|
+
delete: (key: KeyInput) => DeleteBuilder<Model>;
|
|
50
|
+
/**
|
|
51
|
+
* Retrieves multiple items by their keys in a single batch operation.
|
|
52
|
+
* @param keys - Array of key objects to retrieve
|
|
53
|
+
* @returns BatchGetBuilder configured for the items
|
|
54
|
+
*/
|
|
55
|
+
batchGet: (keys: KeyInput[]) => BatchGetBuilder<Model>;
|
|
56
|
+
/**
|
|
57
|
+
* Writes multiple items in a single batch operation (puts or deletes).
|
|
58
|
+
* @param items - Array of items to put
|
|
59
|
+
* @returns BatchWriteBuilder configured for the items
|
|
60
|
+
*/
|
|
61
|
+
batchWrite: (items: Input[]) => BatchWriteBuilder;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Creates an entity API instance with validation, key resolution, and builder creation.
|
|
65
|
+
*
|
|
66
|
+
* @param modelName - The name of the model/entity
|
|
67
|
+
* @param model - The model definition
|
|
68
|
+
* @param client - DynamoDB client instance
|
|
69
|
+
* @param options - Optional configuration (logger, timestamps)
|
|
70
|
+
* @returns EntityAPI with get and put methods
|
|
71
|
+
*/
|
|
72
|
+
export declare const createEntityAPI: <Model extends ModelDefinition>(tableName: string, modelName: string, model: Model, client: DynamoDBClient, options?: EntityAPIOptions) => EntityAPI<InferModel<Model>, InferInput<Model>, InferKeyInput<Model>, Model>;
|
|
73
|
+
//# sourceMappingURL=entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGtF,OAAO,EASL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,SAAS,eAAe,GAAG,GAAG,IAAI;IACtF;;;;OAIG;IACH,GAAG,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAEpD;;;;OAIG;IACH,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;IAExC;;;OAGG;IACH,KAAK,EAAE,MAAM,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE3C;;;OAGG;IACH,IAAI,EAAE,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;IAE/B;;;;OAIG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC;IAEhD;;;;OAIG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC;IAEhD;;;;OAIG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,eAAe,CAAC,KAAK,CAAC,CAAC;IAEvD;;;;OAIG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,iBAAiB,CAAC;CACnD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,eAAe,EAC3D,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,OAAO,KAAK,EACZ,QAAQ,cAAc,EACtB,UAAS,gBAAqB,KAC7B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK,CAqO7E,CAAC"}
|
package/dist/entity.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEntityAPI = void 0;
|
|
4
|
+
const model_utils_1 = require("./utils/model-utils");
|
|
5
|
+
const zod_utils_1 = require("./utils/zod-utils");
|
|
6
|
+
const builders_1 = require("./builders");
|
|
7
|
+
/**
|
|
8
|
+
* Creates an entity API instance with validation, key resolution, and builder creation.
|
|
9
|
+
*
|
|
10
|
+
* @param modelName - The name of the model/entity
|
|
11
|
+
* @param model - The model definition
|
|
12
|
+
* @param client - DynamoDB client instance
|
|
13
|
+
* @param options - Optional configuration (logger, timestamps)
|
|
14
|
+
* @returns EntityAPI with get and put methods
|
|
15
|
+
*/
|
|
16
|
+
const createEntityAPI = (tableName, modelName, model, client, options = {}) => {
|
|
17
|
+
const { logger, timestamps = false } = options;
|
|
18
|
+
// Build a Zod schema from the model
|
|
19
|
+
const zodSchema = (0, zod_utils_1.modelToZod)(model);
|
|
20
|
+
return {
|
|
21
|
+
get(key) {
|
|
22
|
+
// Extract required fields from key templates
|
|
23
|
+
const requiredFields = new Set();
|
|
24
|
+
if (model.key) {
|
|
25
|
+
for (const keyDef of Object.values(model.key)) {
|
|
26
|
+
(0, model_utils_1.extractTemplateVars)(keyDef.value).forEach((field) => requiredFields.add(field));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Check if all required fields are present
|
|
30
|
+
const keyRecord = key;
|
|
31
|
+
const missingFields = Array.from(requiredFields).filter((field) => keyRecord[field] === undefined);
|
|
32
|
+
if (missingFields.length > 0) {
|
|
33
|
+
throw new Error(`[${modelName}] Missing required key field(s) for get(): ${missingFields.join(', ')}. ` +
|
|
34
|
+
`Required fields: ${Array.from(requiredFields).join(', ')}`);
|
|
35
|
+
}
|
|
36
|
+
// Resolve any key defaults or computed keys
|
|
37
|
+
const fullKey = (0, model_utils_1.resolveKeys)(model, key);
|
|
38
|
+
return (0, builders_1.createGetBuilder)(tableName, fullKey, client, undefined, logger);
|
|
39
|
+
},
|
|
40
|
+
put(item) {
|
|
41
|
+
// Validate full input data
|
|
42
|
+
const parsed = zodSchema.parse(item);
|
|
43
|
+
// Apply post-processing defaults from the model (including timestamps for new items)
|
|
44
|
+
const withDefaults = (0, model_utils_1.applyPostDefaults)(model, parsed, {
|
|
45
|
+
isUpdate: false,
|
|
46
|
+
timestamps,
|
|
47
|
+
});
|
|
48
|
+
// Resolve keys again with defaults
|
|
49
|
+
const fullKey = (0, model_utils_1.resolveKeys)(model, withDefaults);
|
|
50
|
+
// Combine keys and data into full item, adding _type field
|
|
51
|
+
const fullItem = {
|
|
52
|
+
...withDefaults,
|
|
53
|
+
...fullKey,
|
|
54
|
+
_type: modelName, // Add entity type identifier
|
|
55
|
+
};
|
|
56
|
+
return (0, builders_1.createPutBuilder)(tableName, fullItem, client, [], false, 'NONE', false, logger);
|
|
57
|
+
},
|
|
58
|
+
query() {
|
|
59
|
+
return (0, builders_1.createQueryBuilder)(tableName, client, model, logger);
|
|
60
|
+
},
|
|
61
|
+
scan() {
|
|
62
|
+
return (0, builders_1.createScanBuilder)(tableName, client, [], [], undefined, false, undefined, undefined, undefined, logger);
|
|
63
|
+
},
|
|
64
|
+
update(key) {
|
|
65
|
+
// Extract required fields from key templates
|
|
66
|
+
const requiredFields = new Set();
|
|
67
|
+
if (model.key) {
|
|
68
|
+
for (const keyDef of Object.values(model.key)) {
|
|
69
|
+
(0, model_utils_1.extractTemplateVars)(keyDef.value).forEach((field) => requiredFields.add(field));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Check if all required fields are present
|
|
73
|
+
const keyRecord = key;
|
|
74
|
+
const missingFields = Array.from(requiredFields).filter((field) => keyRecord[field] === undefined);
|
|
75
|
+
if (missingFields.length > 0) {
|
|
76
|
+
throw new Error(`[${modelName}] Missing required key field(s) for update(): ${missingFields.join(', ')}. ` +
|
|
77
|
+
`Required fields: ${Array.from(requiredFields).join(', ')}`);
|
|
78
|
+
}
|
|
79
|
+
// Resolve any key defaults or computed keys
|
|
80
|
+
const fullKey = (0, model_utils_1.resolveKeys)(model, key);
|
|
81
|
+
return (0, builders_1.createUpdateBuilder)(tableName, fullKey, client, [], { set: [], remove: [], add: [], delete: [] }, 'NONE', 0, timestamps, logger);
|
|
82
|
+
},
|
|
83
|
+
delete(key) {
|
|
84
|
+
// Extract required fields from key templates
|
|
85
|
+
const requiredFields = new Set();
|
|
86
|
+
if (model.key) {
|
|
87
|
+
for (const keyDef of Object.values(model.key)) {
|
|
88
|
+
(0, model_utils_1.extractTemplateVars)(keyDef.value).forEach((field) => requiredFields.add(field));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Check if all required fields are present
|
|
92
|
+
const keyRecord = key;
|
|
93
|
+
const missingFields = Array.from(requiredFields).filter((field) => keyRecord[field] === undefined);
|
|
94
|
+
if (missingFields.length > 0) {
|
|
95
|
+
throw new Error(`[${modelName}] Missing required key field(s) for delete(): ${missingFields.join(', ')}. ` +
|
|
96
|
+
`Required fields: ${Array.from(requiredFields).join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
// Resolve any key defaults or computed keys
|
|
99
|
+
const fullKey = (0, model_utils_1.resolveKeys)(model, key);
|
|
100
|
+
return (0, builders_1.createDeleteBuilder)(tableName, fullKey, client, [], 'NONE', logger);
|
|
101
|
+
},
|
|
102
|
+
batchGet(keys) {
|
|
103
|
+
// Extract required fields from key templates
|
|
104
|
+
const requiredFields = new Set();
|
|
105
|
+
if (model.key) {
|
|
106
|
+
for (const keyDef of Object.values(model.key)) {
|
|
107
|
+
(0, model_utils_1.extractTemplateVars)(keyDef.value).forEach((field) => requiredFields.add(field));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Process all keys and validate them
|
|
111
|
+
const resolvedKeys = keys.map((key) => {
|
|
112
|
+
// Check if all required fields are present
|
|
113
|
+
const keyRecord = key;
|
|
114
|
+
const missingFields = Array.from(requiredFields).filter((field) => keyRecord[field] === undefined);
|
|
115
|
+
if (missingFields.length > 0) {
|
|
116
|
+
throw new Error(`[${modelName}] Missing required key field(s) for batchGet(): ${missingFields.join(', ')}. ` +
|
|
117
|
+
`Required fields: ${Array.from(requiredFields).join(', ')}`);
|
|
118
|
+
}
|
|
119
|
+
// Resolve any key defaults or computed keys
|
|
120
|
+
return (0, model_utils_1.resolveKeys)(model, key);
|
|
121
|
+
});
|
|
122
|
+
// Create the request items in the format expected by BatchGetItem
|
|
123
|
+
const requestItems = {
|
|
124
|
+
[tableName]: {
|
|
125
|
+
Keys: resolvedKeys,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
return (0, builders_1.createBatchGetBuilder)(requestItems, client, undefined, logger);
|
|
129
|
+
},
|
|
130
|
+
batchWrite(items) {
|
|
131
|
+
// Validate and process all items
|
|
132
|
+
const processedItems = items.map((item) => {
|
|
133
|
+
// Validate full input data
|
|
134
|
+
const parsed = zodSchema.parse(item);
|
|
135
|
+
// Apply post-processing defaults from the model (including timestamps for new items)
|
|
136
|
+
const withDefaults = (0, model_utils_1.applyPostDefaults)(model, parsed, {
|
|
137
|
+
isUpdate: false,
|
|
138
|
+
timestamps,
|
|
139
|
+
});
|
|
140
|
+
// Resolve keys again with defaults
|
|
141
|
+
const fullKey = (0, model_utils_1.resolveKeys)(model, withDefaults);
|
|
142
|
+
// Combine keys and data into full item, adding _type field
|
|
143
|
+
return {
|
|
144
|
+
...withDefaults,
|
|
145
|
+
...fullKey,
|
|
146
|
+
_type: modelName, // Add entity type identifier
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
// Create the request items in the format expected by BatchWriteItem
|
|
150
|
+
const requestItems = {
|
|
151
|
+
[tableName]: processedItems.map((item) => ({
|
|
152
|
+
PutRequest: {
|
|
153
|
+
Item: item,
|
|
154
|
+
},
|
|
155
|
+
})),
|
|
156
|
+
};
|
|
157
|
+
return (0, builders_1.createBatchWriteBuilder)(requestItems, client, logger);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
exports.createEntityAPI = createEntityAPI;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './table';
|
|
2
|
+
export { type SchemaDefinition, type ModelDefinition, type PrimaryKeyDefinition, type KeyDefinition, type AttributeDefinition, type IndexDefinition, type IndexesDefinition, type SchemaParams, type InferInput, type InferModel, type InferKeyInput, type InferModelFromSchema, type InferInputFromSchema, type TimestampFields, } from './core/types';
|
|
3
|
+
export { createDynamoDBLogger, type DynamoDBLogger, type DynamoDBLoggerConfig, } from './utils/dynamodb-logger';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.createDynamoDBLogger = void 0;
|
|
18
|
+
__exportStar(require("./table"), exports);
|
|
19
|
+
var dynamodb_logger_1 = require("./utils/dynamodb-logger");
|
|
20
|
+
Object.defineProperty(exports, "createDynamoDBLogger", { enumerable: true, get: function () { return dynamodb_logger_1.createDynamoDBLogger; } });
|
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { InferKeyInput, InferModelFromSchema, InferInputFromSchema, SchemaDefinition } from './core/types';
|
|
3
|
+
import { EntityAPI } from './entity';
|
|
4
|
+
import { TransactWriteBuilder } from './builders/transact-write';
|
|
5
|
+
import { TransactGetBuilder } from './builders/transact-get';
|
|
6
|
+
import { DynamoDBLogger } from './utils/dynamodb-logger';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for the Table instance
|
|
9
|
+
*/
|
|
10
|
+
export type TableConfig<S extends SchemaDefinition> = {
|
|
11
|
+
/** The DynamoDB table name */
|
|
12
|
+
name: string;
|
|
13
|
+
/** AWS DynamoDB client instance */
|
|
14
|
+
client: DynamoDBClient;
|
|
15
|
+
/** Optional logger instance for DynamoDB operations */
|
|
16
|
+
logger?: DynamoDBLogger;
|
|
17
|
+
/** The schema definition for all models in the table */
|
|
18
|
+
schema: S;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Internal helper type to infer all entity APIs from schema definition
|
|
22
|
+
*/
|
|
23
|
+
type EntityMap<S extends SchemaDefinition> = {
|
|
24
|
+
[K in keyof S['models']]: EntityAPI<InferModelFromSchema<S, K>, InferInputFromSchema<S, K>, InferKeyInput<S['models'][K]>>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Represents a typed DynamoDB Table with entity APIs
|
|
28
|
+
*
|
|
29
|
+
* Provides access to all entity operations (get, put, delete, etc.)
|
|
30
|
+
* via `table.entities.<EntityName>`.
|
|
31
|
+
*/
|
|
32
|
+
export declare class Table<S extends SchemaDefinition> {
|
|
33
|
+
/** Generated entity APIs */
|
|
34
|
+
readonly entities: EntityMap<S>;
|
|
35
|
+
/** DynamoDB client */
|
|
36
|
+
private readonly client;
|
|
37
|
+
constructor(config: TableConfig<S>);
|
|
38
|
+
/**
|
|
39
|
+
* Creates a new TransactWrite builder for atomic multi-item write operations
|
|
40
|
+
*
|
|
41
|
+
* @returns A TransactWriteBuilder instance
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* // Like a photo atomically
|
|
46
|
+
* await table.transactWrite()
|
|
47
|
+
* .addPut(table.entities.Like.put({ photoId: "123", likingUsername: "alice" }).dbParams())
|
|
48
|
+
* .addUpdate(table.entities.Photo.update({ username: "bob", photoId: "123" }).add("likesCount", 1).dbParams())
|
|
49
|
+
* .execute();
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
transactWrite(): TransactWriteBuilder;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new TransactGet builder for atomic multi-item read operations
|
|
55
|
+
*
|
|
56
|
+
* @returns A TransactGetBuilder instance
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // Get user and photo atomically
|
|
61
|
+
* const [user, photo] = await table.transactGet()
|
|
62
|
+
* .addGet(table.entities.User.get({ username: "alice" }).dbParams())
|
|
63
|
+
* .addGet(table.entities.Photo.get({ username: "alice", photoId: "123" }).dbParams())
|
|
64
|
+
* .execute();
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
transactGet(): TransactGetBuilder;
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAmB,SAAS,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAA8B,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAA4B,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,gBAAgB,IAAI;IACpD,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,cAAc,CAAC;IACvB,uDAAuD;IACvD,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,wDAAwD;IACxD,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,KAAK,SAAS,CAAC,CAAC,SAAS,gBAAgB,IAAI;KAC1C,CAAC,IAAI,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,SAAS,CACjC,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAC9B;CACF,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,KAAK,CAAC,CAAC,SAAS,gBAAgB;IAC3C,4BAA4B;IAC5B,SAAgB,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAEvC,sBAAsB;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAsBlC;;;;;;;;;;;;;OAaG;IACH,aAAa,IAAI,oBAAoB;IAIrC;;;;;;;;;;;;;OAaG;IACH,WAAW,IAAI,kBAAkB;CAGlC"}
|
package/dist/table.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Table = void 0;
|
|
4
|
+
const entity_1 = require("./entity");
|
|
5
|
+
const transact_write_1 = require("./builders/transact-write");
|
|
6
|
+
const transact_get_1 = require("./builders/transact-get");
|
|
7
|
+
/**
|
|
8
|
+
* Represents a typed DynamoDB Table with entity APIs
|
|
9
|
+
*
|
|
10
|
+
* Provides access to all entity operations (get, put, delete, etc.)
|
|
11
|
+
* via `table.entities.<EntityName>`.
|
|
12
|
+
*/
|
|
13
|
+
class Table {
|
|
14
|
+
/** Generated entity APIs */
|
|
15
|
+
entities;
|
|
16
|
+
/** DynamoDB client */
|
|
17
|
+
client;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
const { client, schema, logger, name: tableName } = config;
|
|
20
|
+
this.client = client;
|
|
21
|
+
const rawEntities = {};
|
|
22
|
+
for (const modelName in schema.models) {
|
|
23
|
+
const model = schema.models[modelName];
|
|
24
|
+
if (!model) {
|
|
25
|
+
throw new Error(`Model '${modelName}' is missing in schema`);
|
|
26
|
+
}
|
|
27
|
+
rawEntities[modelName] = (0, entity_1.createEntityAPI)(tableName, modelName, model, client, {
|
|
28
|
+
logger,
|
|
29
|
+
timestamps: schema.params?.timestamps ?? false,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
this.entities = rawEntities;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new TransactWrite builder for atomic multi-item write operations
|
|
36
|
+
*
|
|
37
|
+
* @returns A TransactWriteBuilder instance
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Like a photo atomically
|
|
42
|
+
* await table.transactWrite()
|
|
43
|
+
* .addPut(table.entities.Like.put({ photoId: "123", likingUsername: "alice" }).dbParams())
|
|
44
|
+
* .addUpdate(table.entities.Photo.update({ username: "bob", photoId: "123" }).add("likesCount", 1).dbParams())
|
|
45
|
+
* .execute();
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
transactWrite() {
|
|
49
|
+
return (0, transact_write_1.createTransactWriteBuilder)(this.client);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new TransactGet builder for atomic multi-item read operations
|
|
53
|
+
*
|
|
54
|
+
* @returns A TransactGetBuilder instance
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Get user and photo atomically
|
|
59
|
+
* const [user, photo] = await table.transactGet()
|
|
60
|
+
* .addGet(table.entities.User.get({ username: "alice" }).dbParams())
|
|
61
|
+
* .addGet(table.entities.Photo.get({ username: "alice", photoId: "123" }).dbParams())
|
|
62
|
+
* .execute();
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
transactGet() {
|
|
66
|
+
return (0, transact_get_1.createTransactGetBuilder)(this.client);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Table = Table;
|