@exabugs/dynamodb-client 0.2.2 → 0.3.2

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 (65) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +92 -28
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/server/handler.cjs +137 -178
  8. package/dist/server/handler.cjs.map +4 -4
  9. package/dist/server/handler.d.ts.map +1 -1
  10. package/dist/server/handler.js +2 -15
  11. package/dist/server/handler.js.map +1 -1
  12. package/dist/server/operations/find.d.ts.map +1 -1
  13. package/dist/server/operations/find.js +5 -12
  14. package/dist/server/operations/find.js.map +1 -1
  15. package/dist/server/operations/findManyReference.d.ts.map +1 -1
  16. package/dist/server/operations/findManyReference.js +3 -10
  17. package/dist/server/operations/findManyReference.js.map +1 -1
  18. package/dist/server/operations/insertMany.d.ts.map +1 -1
  19. package/dist/server/operations/insertMany.js +3 -8
  20. package/dist/server/operations/insertMany.js.map +1 -1
  21. package/dist/server/operations/insertOne.d.ts.map +1 -1
  22. package/dist/server/operations/insertOne.js +3 -8
  23. package/dist/server/operations/insertOne.js.map +1 -1
  24. package/dist/server/operations/updateMany.d.ts.map +1 -1
  25. package/dist/server/operations/updateMany.js +3 -4
  26. package/dist/server/operations/updateMany.js.map +1 -1
  27. package/dist/server/operations/updateOne.d.ts.map +1 -1
  28. package/dist/server/operations/updateOne.js +3 -4
  29. package/dist/server/operations/updateOne.js.map +1 -1
  30. package/dist/server/shadow/config.d.ts +18 -112
  31. package/dist/server/shadow/config.d.ts.map +1 -1
  32. package/dist/server/shadow/config.js +33 -131
  33. package/dist/server/shadow/config.js.map +1 -1
  34. package/dist/server/shadow/generator.d.ts +92 -43
  35. package/dist/server/shadow/generator.d.ts.map +1 -1
  36. package/dist/server/shadow/generator.js +175 -56
  37. package/dist/server/shadow/generator.js.map +1 -1
  38. package/dist/server/shadow/index.d.ts +4 -3
  39. package/dist/server/shadow/index.d.ts.map +1 -1
  40. package/dist/server/shadow/index.js +4 -2
  41. package/dist/server/shadow/index.js.map +1 -1
  42. package/dist/server/shadow/typeInference.d.ts +61 -0
  43. package/dist/server/shadow/typeInference.d.ts.map +1 -0
  44. package/dist/server/shadow/typeInference.js +94 -0
  45. package/dist/server/shadow/typeInference.js.map +1 -0
  46. package/dist/server/shadow/types.d.ts +1 -1
  47. package/dist/server/shadow/types.d.ts.map +1 -1
  48. package/dist/server/utils/timestamps.d.ts.map +1 -1
  49. package/dist/server/utils/timestamps.js +3 -26
  50. package/dist/server/utils/timestamps.js.map +1 -1
  51. package/dist/server/utils/ttl.d.ts.map +1 -1
  52. package/dist/server/utils/ttl.js +11 -9
  53. package/dist/server/utils/ttl.js.map +1 -1
  54. package/dist/server/utils/validation.d.ts +14 -8
  55. package/dist/server/utils/validation.d.ts.map +1 -1
  56. package/dist/server/utils/validation.js +19 -26
  57. package/dist/server/utils/validation.js.map +1 -1
  58. package/package.json +1 -1
  59. package/terraform/README.md +3 -3
  60. package/terraform/main.tf +6 -2
  61. package/terraform/variables.tf +32 -2
  62. package/dist/scripts/generate-shadow-config.d.ts +0 -3
  63. package/dist/scripts/generate-shadow-config.d.ts.map +0 -1
  64. package/dist/scripts/generate-shadow-config.js +0 -159
  65. package/dist/scripts/generate-shadow-config.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2025-01-20
11
+
12
+ ### Added
13
+
14
+ - **Shadow Configuration**: Automatic field detection for all record types
15
+ - Support for 6 field types: string, number, boolean, datetime, array, object
16
+ - Automatic shadow generation for all fields in each record
17
+ - Environment variable-based configuration (4 variables)
18
+ - Comprehensive test suite (275 tests)
19
+ - Updated documentation with new configuration guide
20
+
21
+ ### Changed
22
+
23
+ - **Shadow Configuration**: Simplified configuration management
24
+ - Replaced JSON configuration files with environment variables
25
+ - `SHADOW_CREATED_AT_FIELD` (default: `createdAt`)
26
+ - `SHADOW_UPDATED_AT_FIELD` (default: `updatedAt`)
27
+ - `SHADOW_STRING_MAX_BYTES` (default: `100`)
28
+ - `SHADOW_NUMBER_PADDING` (default: `15`)
29
+ - Primitive types truncated at 100 bytes
30
+ - Complex types (array/object) truncated at 200 bytes
31
+ - Number range: -10^15 to +10^15
32
+
33
+ ### Removed
34
+
35
+ - **Shadow Configuration**: Removed schema-based configuration
36
+ - No longer requires `shadow.config.json` files
37
+ - No longer requires schema definitions for shadow fields
38
+ - Removed `generate-shadow-config` script
39
+ - Records are now independent and self-contained
40
+
41
+ ### Breaking Changes
42
+
43
+ - **Shadow Configuration**: Configuration method has changed
44
+ - Old: JSON configuration files with schema definitions
45
+ - New: Environment variables with automatic field detection
46
+ - Migration: Set environment variables and remove JSON config files
47
+ - All fields are now automatically shadowed (no schema required)
48
+
10
49
  ## [0.2.2] - 2024-12-01
11
50
 
12
51
  ### Added
package/README.md CHANGED
@@ -121,16 +121,22 @@ graph TB
121
121
 
122
122
  Get started in 3 steps: **Schema Definition → Deploy Infrastructure → Use Client**
123
123
 
124
- ### Complete Examples Available
124
+ ### Complete Example Project
125
125
 
126
- We provide complete, working examples for every step:
126
+ We provide a complete, working example project that demonstrates all features:
127
127
 
128
- | Example | What You'll Learn | Time |
129
- | ------------------------------------------ | ---------------------------------------------------- | ------ |
130
- | **[Schema](./examples/schema/)** | Define TypeScript schemas and generate shadow config | 5 min |
131
- | **[Terraform](./examples/terraform/)** | Deploy Lambda + DynamoDB + Cognito to AWS | 10 min |
132
- | **[Client](./examples/client/)** | Node.js CRUD operations with MongoDB-like API | 10 min |
133
- | **[React Admin](./examples/react-admin/)** | Build complete admin UI with authentication | 15 min |
128
+ 👉 **[dynamodb-client-example](https://github.com/exabugs/dynamodb-client-example)** - Full-stack example with React Admin
129
+
130
+ This example includes:
131
+
132
+ - Complete TypeScript schemas (Articles, Tasks)
133
+ - Terraform infrastructure (DynamoDB, Lambda, Cognito)
134
+ - ✅ React Admin UI with authentication
135
+ - ✅ Shadow Records for efficient sorting
136
+ - ✅ Production-ready configuration
137
+ - ✅ Step-by-step QUICKSTART guide
138
+
139
+ **Use it as a template** for your own projects!
134
140
 
135
141
  ### Quick Example
136
142
 
@@ -138,6 +144,7 @@ We provide complete, working examples for every step:
138
144
  // 1. Define schema
139
145
  export const MySchema: SchemaRegistryConfig = {
140
146
  database: {
147
+ name: 'myapp',
141
148
  timestamps: {
142
149
  createdAt: 'createdAt',
143
150
  updatedAt: 'updatedAt',
@@ -152,7 +159,7 @@ export const MySchema: SchemaRegistryConfig = {
152
159
  },
153
160
  };
154
161
 
155
- // 2. Deploy with Terraform (see examples/terraform/)
162
+ // 2. Deploy with Terraform (see dynamodb-client-example)
156
163
  // terraform apply
157
164
 
158
165
  // 3. Use the client
@@ -163,16 +170,11 @@ await articles.insertOne({ title: 'Hello DynamoDB' });
163
170
  const article = await articles.findOne({ title: 'Hello DynamoDB' });
164
171
  ```
165
172
 
166
- ### 📚 Full Documentation
167
-
168
- 👉 **[Complete Examples Guide →](./examples/)** - Step-by-step tutorials with full source code
173
+ ### 📚 Getting Started
169
174
 
170
- Each example includes:
171
-
172
- - Complete source code
173
- - ✅ Step-by-step instructions
174
- - ✅ Terraform integration
175
- - ✅ Configuration templates
175
+ 1. **Clone the example project**: `git clone https://github.com/exabugs/dynamodb-client-example.git`
176
+ 2. **Follow the QUICKSTART guide**: See [QUICKSTART.md](https://github.com/exabugs/dynamodb-client-example/blob/main/QUICKSTART.md)
177
+ 3. **Customize for your needs**: Modify schemas, add resources, deploy to AWS
176
178
 
177
179
  ---
178
180
 
@@ -233,23 +235,85 @@ npm run clean # Clean build artifacts
233
235
 
234
236
  ## 🚢 Deployment
235
237
 
236
- ### Using Terraform
238
+ ### Using the Example Project
239
+
240
+ The easiest way to deploy is using the [dynamodb-client-example](https://github.com/exabugs/dynamodb-client-example) project:
237
241
 
238
242
  ```bash
239
- cd terraform
240
- terraform init
241
- terraform plan -var-file=envs/dev.tfvars
242
- terraform apply -var-file=envs/dev.tfvars
243
+ # Clone the example
244
+ git clone https://github.com/exabugs/dynamodb-client-example.git
245
+ cd dynamodb-client-example
246
+
247
+ # Deploy to dev environment
248
+ make deploy-dev
249
+
250
+ # Deploy to other environments
251
+ make deploy-stg # Staging
252
+ make deploy-prd # Production
243
253
  ```
244
254
 
245
- ### Using Make
255
+ See the [example project's documentation](https://github.com/exabugs/dynamodb-client-example) for detailed deployment instructions.
246
256
 
247
- ```bash
248
- make deploy-dev # Deploy to dev environment
249
- make deploy-stg # Deploy to staging
250
- make deploy-prd # Deploy to production
257
+ ---
258
+
259
+ ## 🔧 Shadow Configuration
260
+
261
+ ### Overview
262
+
263
+ The shadow feature automatically makes all fields sortable without requiring JSON configuration files. Configuration is managed entirely through environment variables.
264
+
265
+ ### Environment Variables
266
+
267
+ | Variable | Default | Description |
268
+ |----------|---------|-------------|
269
+ | `SHADOW_CREATED_AT_FIELD` | `createdAt` | Field name for creation timestamp |
270
+ | `SHADOW_UPDATED_AT_FIELD` | `updatedAt` | Field name for update timestamp |
271
+ | `SHADOW_STRING_MAX_BYTES` | `100` | Max bytes for primitive types (array/object use 2x) |
272
+ | `SHADOW_NUMBER_PADDING` | `15` | Padding digits for numbers |
273
+
274
+ ### Supported Types
275
+
276
+ - **string**: Strings (truncated at 100 bytes)
277
+ - **number**: Numbers (offset method, range: -10^15 to +10^15)
278
+ - **boolean**: Booleans (true=1, false=0)
279
+ - **datetime**: ISO 8601 datetime strings
280
+ - **array**: Arrays (JSON stringified, truncated at 200 bytes)
281
+ - **object**: Objects (JSON stringified, truncated at 200 bytes)
282
+
283
+ ### Automatic Shadow Generation
284
+
285
+ Only fields that exist in each record are automatically shadowed:
286
+
287
+ ```typescript
288
+ const record = {
289
+ id: '01HQXYZ123',
290
+ title: 'Article',
291
+ viewCount: 123,
292
+ published: true,
293
+ tags: ['tech', 'aws'],
294
+ metadata: { category: 'tech' }
295
+ };
296
+
297
+ // Automatically generates shadow records:
298
+ // - id#01HQXYZ123#id#01HQXYZ123
299
+ // - title#Article#id#01HQXYZ123
300
+ // - viewCount#1000000000000123#id#01HQXYZ123
301
+ // - published#1#id#01HQXYZ123
302
+ // - tags#["aws","tech"]#id#01HQXYZ123
303
+ // - metadata#{"category":"tech"}#id#01HQXYZ123
251
304
  ```
252
305
 
306
+ ### Exclusion Rules
307
+
308
+ - Fields starting with `__` are excluded (internal metadata)
309
+ - `null` or `undefined` values are excluded
310
+
311
+ ### Important Notes
312
+
313
+ - Records without a specific field won't appear in sort results for that field
314
+ - Primitive types are truncated at 100 bytes, complex types at 200 bytes
315
+ - Number range is -10^15 to +10^15 (within JavaScript's safe integer range)
316
+
253
317
  ---
254
318
 
255
319
  ## 🤝 Contributing
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@ export type { Logger, LoggerConfig, LogLevel, LogMetadata } from './logger.js';
6
6
  export { ErrorCode, AppError, AuthError, ConfigError, InvalidFilterError, InvalidTokenError, ItemNotFoundError, PartialFailureError, VersionConflictError, isAppError, getErrorClass, } from './errors.js';
7
7
  export type { FilterOperators, Filter, UpdateOperators, FindOptions, InsertOneResult, InsertManyResult, UpdateResult, DeleteResult, } from './types.js';
8
8
  export { Database, Collection } from './client/index.js';
9
- export { convertFilterToDynamo, type DynamoComparisonOperator, type DynamoCondition, type DynamoQuery, generateShadowRecords, type ShadowRecord, type ShadowSchema, getShadowConfig, getResourceSchema, clearShadowConfigCache, type ShadowConfig, } from './server/index.js';
9
+ export { convertFilterToDynamo, type DynamoComparisonOperator, type DynamoCondition, type DynamoQuery, generateShadowRecords, type ShadowRecord, getShadowConfig, clearShadowConfigCache, type ShadowConfig, } from './server/index.js';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,MAAM,EACN,eAAe,EACf,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,eAAe,EACf,MAAM,EACN,eAAe,EACf,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,qBAAqB,EACrB,KAAK,YAAY,EACjB,eAAe,EACf,sBAAsB,EACtB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -3,5 +3,5 @@ export { ulid, ulidWithTime, decodeTime } from './ulid.js';
3
3
  export { createLogger } from './logger.js';
4
4
  export { ErrorCode, AppError, AuthError, ConfigError, InvalidFilterError, InvalidTokenError, ItemNotFoundError, PartialFailureError, VersionConflictError, isAppError, getErrorClass, } from './errors.js';
5
5
  export { Database, Collection } from './client/index.js';
6
- export { convertFilterToDynamo, generateShadowRecords, getShadowConfig, getResourceSchema, clearShadowConfigCache, } from './server/index.js';
6
+ export { convertFilterToDynamo, generateShadowRecords, getShadowConfig, clearShadowConfigCache, } from './server/index.js';
7
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,qBAAqB,EAIrB,qBAAqB,EAGrB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,GAEvB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,qBAAqB,EAIrB,qBAAqB,EAErB,eAAe,EACf,sBAAsB,GAEvB,MAAM,mBAAmB,CAAC"}