effect-dynamodb 0.1.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -0
  3. package/dist/Aggregate.d.ts +210 -0
  4. package/dist/Aggregate.d.ts.map +1 -0
  5. package/dist/Aggregate.js +1169 -0
  6. package/dist/Aggregate.js.map +1 -0
  7. package/dist/Batch.d.ts +62 -0
  8. package/dist/Batch.d.ts.map +1 -0
  9. package/dist/Batch.js +218 -0
  10. package/dist/Batch.js.map +1 -0
  11. package/dist/Collection.d.ts +58 -0
  12. package/dist/Collection.d.ts.map +1 -0
  13. package/dist/Collection.js +195 -0
  14. package/dist/Collection.js.map +1 -0
  15. package/dist/Collections.d.ts +121 -0
  16. package/dist/Collections.d.ts.map +1 -0
  17. package/dist/Collections.js +121 -0
  18. package/dist/Collections.js.map +1 -0
  19. package/dist/DynamoClient.d.ts +317 -0
  20. package/dist/DynamoClient.d.ts.map +1 -0
  21. package/dist/DynamoClient.js +653 -0
  22. package/dist/DynamoClient.js.map +1 -0
  23. package/dist/DynamoModel.d.ts +278 -0
  24. package/dist/DynamoModel.d.ts.map +1 -0
  25. package/dist/DynamoModel.js +453 -0
  26. package/dist/DynamoModel.js.map +1 -0
  27. package/dist/DynamoSchema.d.ts +137 -0
  28. package/dist/DynamoSchema.d.ts.map +1 -0
  29. package/dist/DynamoSchema.js +188 -0
  30. package/dist/DynamoSchema.js.map +1 -0
  31. package/dist/Entity.d.ts +628 -0
  32. package/dist/Entity.d.ts.map +1 -0
  33. package/dist/Entity.js +2371 -0
  34. package/dist/Entity.js.map +1 -0
  35. package/dist/Errors.d.ts +227 -0
  36. package/dist/Errors.d.ts.map +1 -0
  37. package/dist/Errors.js +93 -0
  38. package/dist/Errors.js.map +1 -0
  39. package/dist/EventStore.d.ts +208 -0
  40. package/dist/EventStore.d.ts.map +1 -0
  41. package/dist/EventStore.js +333 -0
  42. package/dist/EventStore.js.map +1 -0
  43. package/dist/Expression.d.ts +50 -0
  44. package/dist/Expression.d.ts.map +1 -0
  45. package/dist/Expression.js +170 -0
  46. package/dist/Expression.js.map +1 -0
  47. package/dist/KeyComposer.d.ts +125 -0
  48. package/dist/KeyComposer.d.ts.map +1 -0
  49. package/dist/KeyComposer.js +257 -0
  50. package/dist/KeyComposer.js.map +1 -0
  51. package/dist/Marshaller.d.ts +30 -0
  52. package/dist/Marshaller.d.ts.map +1 -0
  53. package/dist/Marshaller.js +115 -0
  54. package/dist/Marshaller.js.map +1 -0
  55. package/dist/Projection.d.ts +28 -0
  56. package/dist/Projection.d.ts.map +1 -0
  57. package/dist/Projection.js +39 -0
  58. package/dist/Projection.js.map +1 -0
  59. package/dist/Query.d.ts +214 -0
  60. package/dist/Query.d.ts.map +1 -0
  61. package/dist/Query.js +397 -0
  62. package/dist/Query.js.map +1 -0
  63. package/dist/Table.d.ts +178 -0
  64. package/dist/Table.d.ts.map +1 -0
  65. package/dist/Table.js +211 -0
  66. package/dist/Table.js.map +1 -0
  67. package/dist/Transaction.d.ts +79 -0
  68. package/dist/Transaction.d.ts.map +1 -0
  69. package/dist/Transaction.js +215 -0
  70. package/dist/Transaction.js.map +1 -0
  71. package/dist/_AggregateCursor.d.ts +44 -0
  72. package/dist/_AggregateCursor.d.ts.map +1 -0
  73. package/dist/_AggregateCursor.js +18 -0
  74. package/dist/_AggregateCursor.js.map +1 -0
  75. package/dist/_AggregateEdges.d.ts +77 -0
  76. package/dist/_AggregateEdges.d.ts.map +1 -0
  77. package/dist/_AggregateEdges.js +41 -0
  78. package/dist/_AggregateEdges.js.map +1 -0
  79. package/dist/_AggregateSchemas.d.ts +69 -0
  80. package/dist/_AggregateSchemas.d.ts.map +1 -0
  81. package/dist/_AggregateSchemas.js +194 -0
  82. package/dist/_AggregateSchemas.js.map +1 -0
  83. package/dist/_AggregateTypes.d.ts +94 -0
  84. package/dist/_AggregateTypes.d.ts.map +1 -0
  85. package/dist/_AggregateTypes.js +7 -0
  86. package/dist/_AggregateTypes.js.map +1 -0
  87. package/dist/_EntityCombinators.d.ts +155 -0
  88. package/dist/_EntityCombinators.d.ts.map +1 -0
  89. package/dist/_EntityCombinators.js +158 -0
  90. package/dist/_EntityCombinators.js.map +1 -0
  91. package/dist/_EntityConfig.d.ts +100 -0
  92. package/dist/_EntityConfig.d.ts.map +1 -0
  93. package/dist/_EntityConfig.js +7 -0
  94. package/dist/_EntityConfig.js.map +1 -0
  95. package/dist/_EntityOps.d.ts +205 -0
  96. package/dist/_EntityOps.d.ts.map +1 -0
  97. package/dist/_EntityOps.js +137 -0
  98. package/dist/_EntityOps.js.map +1 -0
  99. package/dist/_EntitySchemas.d.ts +57 -0
  100. package/dist/_EntitySchemas.d.ts.map +1 -0
  101. package/dist/_EntitySchemas.js +298 -0
  102. package/dist/_EntitySchemas.js.map +1 -0
  103. package/dist/_EntityTypes.d.ts +81 -0
  104. package/dist/_EntityTypes.d.ts.map +1 -0
  105. package/dist/_EntityTypes.js +7 -0
  106. package/dist/_EntityTypes.js.map +1 -0
  107. package/dist/_sparse_check.d.ts +2 -0
  108. package/dist/_sparse_check.d.ts.map +1 -0
  109. package/dist/_sparse_check.js +193 -0
  110. package/dist/_sparse_check.js.map +1 -0
  111. package/dist/index.d.ts +35 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +20 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/internal/AggregateCursor.d.ts +44 -0
  116. package/dist/internal/AggregateCursor.d.ts.map +1 -0
  117. package/dist/internal/AggregateCursor.js +18 -0
  118. package/dist/internal/AggregateCursor.js.map +1 -0
  119. package/dist/internal/AggregateEdges.d.ts +77 -0
  120. package/dist/internal/AggregateEdges.d.ts.map +1 -0
  121. package/dist/internal/AggregateEdges.js +41 -0
  122. package/dist/internal/AggregateEdges.js.map +1 -0
  123. package/dist/internal/AggregateSchemas.d.ts +69 -0
  124. package/dist/internal/AggregateSchemas.d.ts.map +1 -0
  125. package/dist/internal/AggregateSchemas.js +193 -0
  126. package/dist/internal/AggregateSchemas.js.map +1 -0
  127. package/dist/internal/AggregateTypes.d.ts +94 -0
  128. package/dist/internal/AggregateTypes.d.ts.map +1 -0
  129. package/dist/internal/AggregateTypes.js +7 -0
  130. package/dist/internal/AggregateTypes.js.map +1 -0
  131. package/dist/internal/BoundQuery.d.ts +107 -0
  132. package/dist/internal/BoundQuery.d.ts.map +1 -0
  133. package/dist/internal/BoundQuery.js +111 -0
  134. package/dist/internal/BoundQuery.js.map +1 -0
  135. package/dist/internal/EntityCombinators.d.ts +173 -0
  136. package/dist/internal/EntityCombinators.d.ts.map +1 -0
  137. package/dist/internal/EntityCombinators.js +183 -0
  138. package/dist/internal/EntityCombinators.js.map +1 -0
  139. package/dist/internal/EntityConfig.d.ts +100 -0
  140. package/dist/internal/EntityConfig.d.ts.map +1 -0
  141. package/dist/internal/EntityConfig.js +7 -0
  142. package/dist/internal/EntityConfig.js.map +1 -0
  143. package/dist/internal/EntityOps.d.ts +268 -0
  144. package/dist/internal/EntityOps.d.ts.map +1 -0
  145. package/dist/internal/EntityOps.js +153 -0
  146. package/dist/internal/EntityOps.js.map +1 -0
  147. package/dist/internal/EntitySchemas.d.ts +57 -0
  148. package/dist/internal/EntitySchemas.d.ts.map +1 -0
  149. package/dist/internal/EntitySchemas.js +299 -0
  150. package/dist/internal/EntitySchemas.js.map +1 -0
  151. package/dist/internal/EntityTypes.d.ts +128 -0
  152. package/dist/internal/EntityTypes.d.ts.map +1 -0
  153. package/dist/internal/EntityTypes.js +7 -0
  154. package/dist/internal/EntityTypes.js.map +1 -0
  155. package/dist/internal/Expr.d.ts +141 -0
  156. package/dist/internal/Expr.d.ts.map +1 -0
  157. package/dist/internal/Expr.js +332 -0
  158. package/dist/internal/Expr.js.map +1 -0
  159. package/dist/internal/PathBuilder.d.ts +88 -0
  160. package/dist/internal/PathBuilder.d.ts.map +1 -0
  161. package/dist/internal/PathBuilder.js +100 -0
  162. package/dist/internal/PathBuilder.js.map +1 -0
  163. package/dist/internal/TransactableOps.d.ts +25 -0
  164. package/dist/internal/TransactableOps.d.ts.map +1 -0
  165. package/dist/internal/TransactableOps.js +58 -0
  166. package/dist/internal/TransactableOps.js.map +1 -0
  167. package/dist/internal/sparse_check.d.ts +2 -0
  168. package/dist/internal/sparse_check.d.ts.map +1 -0
  169. package/dist/internal/sparse_check.js +196 -0
  170. package/dist/internal/sparse_check.js.map +1 -0
  171. package/package.json +71 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @internal PathBuilder — Type-safe path proxy for DynamoDB expressions.
3
+ *
4
+ * Creates a recursive Proxy that tracks attribute path segments for use in
5
+ * condition, filter, update, and projection expressions.
6
+ */
7
+ export declare const PathTag: unique symbol;
8
+ export type PathTag = typeof PathTag;
9
+ /**
10
+ * A resolved attribute path tracking segments from root to leaf.
11
+ * Phantom types ensure type safety in expression builders.
12
+ *
13
+ * @typeParam Root - The root model type
14
+ * @typeParam Value - The value type at this path
15
+ * @typeParam Keys - Tuple of path segments
16
+ */
17
+ export interface Path<Root = unknown, Value = unknown, Keys extends ReadonlyArray<string | number> = ReadonlyArray<string | number>> {
18
+ readonly [PathTag]: PathTag;
19
+ readonly segments: ReadonlyArray<string | number>;
20
+ /** Phantom */ readonly _Root: (_: never) => Root;
21
+ /** Phantom */ readonly _Value: (_: never) => Value;
22
+ /** Phantom */ readonly _Keys: (_: never) => Keys;
23
+ /** Return a size operand for this path */
24
+ readonly size: () => SizeOperand<Root>;
25
+ }
26
+ /**
27
+ * A size() operand — represents the size of the attribute at the given path.
28
+ */
29
+ export interface SizeOperand<Root = unknown> {
30
+ readonly _tag: "size";
31
+ readonly segments: ReadonlyArray<string | number>;
32
+ /** Phantom */ readonly _Root: (_: never) => Root;
33
+ }
34
+ export interface ArrayPath<Root, Element, Keys extends ReadonlyArray<string | number> = ReadonlyArray<string | number>> extends Path<Root, ReadonlyArray<Element>, Keys> {
35
+ readonly at: (index: number) => NonNullable<Element> extends globalThis.Record<string, any> ? PathBuilder<Root, NonNullable<Element>> & Path<Root, NonNullable<Element>> : Path<Root, NonNullable<Element>>;
36
+ }
37
+ /**
38
+ * A recursive mapped type that provides type-safe path access to model attributes.
39
+ * Each property access returns either:
40
+ * - `Path<Root, V>` for leaf values (string, number, boolean, etc.)
41
+ * - `PathBuilder<Root, V> & Path<Root, V>` for nested objects
42
+ * - `ArrayPath<Root, E>` for arrays
43
+ */
44
+ export type PathBuilder<Root, Model, Keys extends ReadonlyArray<string | number> = []> = {
45
+ readonly [K in keyof Model]-?: NonNullable<Model[K]> extends ReadonlyArray<infer E> ? ArrayPath<Root, E, [...Keys, K & string]> : NonNullable<Model[K]> extends globalThis.Record<string, any> ? PathBuilder<Root, NonNullable<Model[K]>, [...Keys, K & string]> & Path<Root, NonNullable<Model[K]>, [...Keys, K & string]> : Path<Root, NonNullable<Model[K]>, [...Keys, K & string]>;
46
+ };
47
+ /** Check if a value is a Path */
48
+ export declare const isPath: (value: unknown) => value is Path;
49
+ /**
50
+ * Create a PathBuilder proxy that tracks attribute path segments.
51
+ *
52
+ * @param segments - Initial segments (default: [])
53
+ * @param resolveDbName - Optional function to resolve domain names to DynamoDB attribute names
54
+ */
55
+ export declare const createPathBuilder: <Model>(segments?: ReadonlyArray<string | number>, resolveDbName?: (name: string) => string) => PathBuilder<Model, Model>;
56
+ /**
57
+ * Compile path segments into DynamoDB ExpressionAttributeNames placeholders.
58
+ *
59
+ * @param segments - The path segments (e.g., ["address", "city"])
60
+ * @param names - Mutable names map to populate
61
+ * @param prefix - Placeholder prefix (e.g., "p" for paths, "e" for expressions)
62
+ * @param counter - Mutable counter object for unique placeholder generation
63
+ * @param resolveDbName - Optional function to resolve domain names to DynamoDB attribute names
64
+ * @returns The expression path string (e.g., "#p0.#p1" or "#p0[2].#p1")
65
+ */
66
+ export declare const compilePath: (segments: ReadonlyArray<string | number>, names: globalThis.Record<string, string>, prefix: string, counter: {
67
+ value: number;
68
+ }, resolveDbName?: (name: string) => string) => string;
69
+ /** Deep pick a single path from a type */
70
+ type DeepPickOne<T, Keys extends ReadonlyArray<string | number>> = Keys extends readonly [
71
+ infer Head extends keyof T,
72
+ ...infer Rest extends ReadonlyArray<string | number>
73
+ ] ? Rest extends readonly [] ? Pick<T, Head> : {
74
+ readonly [K in Head]: DeepPickOne<T[Head], Rest>;
75
+ } : T;
76
+ /** Convert a union to an intersection */
77
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
78
+ /**
79
+ * Deep pick from a type given an array of path tuples.
80
+ * Used by projections to narrow return types.
81
+ */
82
+ export type DeepPick<T, Paths extends ReadonlyArray<ReadonlyArray<string | number>>> = UnionToIntersection<{
83
+ [K in keyof Paths]: DeepPickOne<T, Paths[K]>;
84
+ }[number]>;
85
+ /** Extract the Keys tuple from a Path type */
86
+ export type PathKeys<P> = P extends Path<any, any, infer K> ? K : never;
87
+ export {};
88
+ //# sourceMappingURL=PathBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathBuilder.d.ts","sourceRoot":"","sources":["../../src/internal/PathBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @internal PathBuilder — Type-safe path proxy for DynamoDB expressions.
3
+ *
4
+ * Creates a recursive Proxy that tracks attribute path segments for use in
5
+ * condition, filter, update, and projection expressions.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Path interface — a resolved attribute path with phantom types
9
+ // ---------------------------------------------------------------------------
10
+ export const PathTag = Symbol.for("effect-dynamodb/Path");
11
+ // ---------------------------------------------------------------------------
12
+ // Runtime: createPathBuilder — single recursive Proxy handler
13
+ // ---------------------------------------------------------------------------
14
+ /** Check if a value is a Path */
15
+ export const isPath = (value) => typeof value === "object" && value !== null && PathTag in value;
16
+ /**
17
+ * Create a PathBuilder proxy that tracks attribute path segments.
18
+ *
19
+ * @param segments - Initial segments (default: [])
20
+ * @param resolveDbName - Optional function to resolve domain names to DynamoDB attribute names
21
+ */
22
+ export const createPathBuilder = (segments = [], resolveDbName) => {
23
+ const handler = {
24
+ get(_target, prop) {
25
+ if (prop === PathTag)
26
+ return PathTag;
27
+ if (prop === "_tag")
28
+ return "Path";
29
+ if (prop === "segments")
30
+ return segments;
31
+ if (prop === "_Root" || prop === "_Value")
32
+ return undefined;
33
+ if (prop === "size") {
34
+ return () => ({
35
+ _tag: "size",
36
+ _Root: undefined,
37
+ segments,
38
+ });
39
+ }
40
+ if (prop === "at") {
41
+ return (index) => createPathBuilder([...segments, index], resolveDbName);
42
+ }
43
+ // Pipe/iterator/Symbol access — return undefined to avoid interference
44
+ if (typeof prop === "symbol")
45
+ return undefined;
46
+ if (prop === "pipe" || prop === "toJSON" || prop === "then")
47
+ return undefined;
48
+ if (typeof prop === "string") {
49
+ return createPathBuilder([...segments, prop], resolveDbName);
50
+ }
51
+ return undefined;
52
+ },
53
+ has(_target, prop) {
54
+ return prop === PathTag || prop === "_tag" || prop === "segments";
55
+ },
56
+ };
57
+ return new Proxy({}, handler);
58
+ };
59
+ // ---------------------------------------------------------------------------
60
+ // compilePath — shared path→DynamoDB expression name compilation
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Compile path segments into DynamoDB ExpressionAttributeNames placeholders.
64
+ *
65
+ * @param segments - The path segments (e.g., ["address", "city"])
66
+ * @param names - Mutable names map to populate
67
+ * @param prefix - Placeholder prefix (e.g., "p" for paths, "e" for expressions)
68
+ * @param counter - Mutable counter object for unique placeholder generation
69
+ * @param resolveDbName - Optional function to resolve domain names to DynamoDB attribute names
70
+ * @returns The expression path string (e.g., "#p0.#p1" or "#p0[2].#p1")
71
+ */
72
+ export const compilePath = (segments, names, prefix, counter, resolveDbName) => {
73
+ const parts = [];
74
+ for (const seg of segments) {
75
+ if (typeof seg === "number") {
76
+ // Array index — append directly to previous part
77
+ parts.push(`[${seg}]`);
78
+ }
79
+ else {
80
+ const key = `#${prefix}${counter.value++}`;
81
+ names[key] = resolveDbName ? resolveDbName(seg) : seg;
82
+ parts.push(key);
83
+ }
84
+ }
85
+ // Join parts: string placeholders with ".", array indices attach directly
86
+ let result = "";
87
+ for (const part of parts) {
88
+ if (part.startsWith("[")) {
89
+ result += part;
90
+ }
91
+ else if (result === "") {
92
+ result = part;
93
+ }
94
+ else {
95
+ result += `.${part}`;
96
+ }
97
+ }
98
+ return result;
99
+ };
100
+ //# sourceMappingURL=PathBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathBuilder.js","sourceRoot":"","sources":["../../src/internal/PathBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @internal Shared helpers for Batch and Transaction operations.
3
+ *
4
+ * Extracts common patterns: table name resolution, primary key composition,
5
+ * and put-item construction (validation + key composition + system fields).
6
+ */
7
+ import { Effect, Schema } from "effect";
8
+ import type { Entity } from "../Entity.js";
9
+ import { ValidationError } from "../Errors.js";
10
+ import * as KeyComposer from "../KeyComposer.js";
11
+ /**
12
+ * Resolve table names for a set of entity infos, deduplicating by entity reference.
13
+ */
14
+ export declare const resolveTableNames: (infos: ReadonlyArray<{
15
+ readonly entity: Entity;
16
+ }>) => Effect.Effect<Map<Entity<Schema.Top, string, Record<string, KeyComposer.IndexDefinition>, import("./EntityConfig.js").TimestampsConfig | undefined, import("./EntityConfig.js").VersionedConfig | undefined, import("./EntityConfig.js").SoftDeleteConfig | undefined, import("./EntityConfig.js").UniqueConfig | undefined, undefined, undefined>, string>, never, import("../Table.js").TableConfig>;
17
+ /**
18
+ * Compose the primary key for an entity item.
19
+ */
20
+ export declare const composePrimaryKey: (entity: Entity, key: Record<string, unknown>) => Record<string, unknown>;
21
+ /**
22
+ * Validate input, compose all keys, and build a marshalled put item.
23
+ */
24
+ export declare const validateAndBuildPutItem: (entity: Entity, input: Record<string, unknown>, operation: string) => Effect.Effect<Record<string, import("@aws-sdk/client-dynamodb").AttributeValue>, ValidationError>;
25
+ //# sourceMappingURL=TransactableOps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactableOps.d.ts","sourceRoot":"","sources":["../../src/internal/TransactableOps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAA;AAGhD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,aAAa,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,2YAU/E,CAAA;AAEJ;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,EACd,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAOxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ,MAAM,EACd,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,MAAM,KAChB,MAAM,CAAC,MAAM,CACd,MAAM,CAAC,MAAM,EAAE,OAAO,0BAA0B,EAAE,cAAc,CAAC,EACjE,eAAe,CAiCb,CAAA"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @internal Shared helpers for Batch and Transaction operations.
3
+ *
4
+ * Extracts common patterns: table name resolution, primary key composition,
5
+ * and put-item construction (validation + key composition + system fields).
6
+ */
7
+ import { Effect, Schema } from "effect";
8
+ import { ValidationError } from "../Errors.js";
9
+ import * as KeyComposer from "../KeyComposer.js";
10
+ import { toAttributeMap } from "../Marshaller.js";
11
+ /**
12
+ * Resolve table names for a set of entity infos, deduplicating by entity reference.
13
+ */
14
+ export const resolveTableNames = (infos) => Effect.gen(function* () {
15
+ const tableNames = new Map();
16
+ for (const info of infos) {
17
+ if (!tableNames.has(info.entity)) {
18
+ const { name } = yield* info.entity._tableTag;
19
+ tableNames.set(info.entity, name);
20
+ }
21
+ }
22
+ return tableNames;
23
+ });
24
+ /**
25
+ * Compose the primary key for an entity item.
26
+ */
27
+ export const composePrimaryKey = (entity, key) => {
28
+ const primary = entity.indexes.primary;
29
+ const schema = entity._schema;
30
+ return {
31
+ [primary.pk.field]: KeyComposer.composePk(schema, entity.entityType, primary, key),
32
+ [primary.sk.field]: KeyComposer.composeSk(schema, entity.entityType, 1, primary, key),
33
+ };
34
+ };
35
+ /**
36
+ * Validate input, compose all keys, and build a marshalled put item.
37
+ */
38
+ export const validateAndBuildPutItem = (entity, input, operation) => Effect.gen(function* () {
39
+ const inputSchema = entity.schemas.inputSchema;
40
+ const validated = yield* Schema.decodeUnknownEffect(inputSchema)(input).pipe(Effect.mapError((cause) => new ValidationError({
41
+ entityType: entity.entityType,
42
+ operation,
43
+ cause,
44
+ })));
45
+ const item = { ...validated };
46
+ item.__edd_e__ = entity.entityType;
47
+ const keys = KeyComposer.composeAllKeys(entity._schema, entity.entityType, 1, entity.indexes, validated);
48
+ Object.assign(item, keys);
49
+ const now = new Date().toISOString();
50
+ if (entity.systemFields.createdAt)
51
+ item[entity.systemFields.createdAt] = now;
52
+ if (entity.systemFields.updatedAt)
53
+ item[entity.systemFields.updatedAt] = now;
54
+ if (entity.systemFields.version)
55
+ item[entity.systemFields.version] = 1;
56
+ return toAttributeMap(item);
57
+ });
58
+ //# sourceMappingURL=TransactableOps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactableOps.js","sourceRoot":"","sources":["../../src/internal/TransactableOps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sparse_check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparse_check.d.ts","sourceRoot":"","sources":["../../src/internal/sparse_check.ts"],"names":[],"mappings":""}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Type-level verification for sparse GSI all-or-none constraints.
3
+ * This file is NOT shipped — it exists solely for `pnpm check` validation.
4
+ *
5
+ * Enforcement:
6
+ * - Data-first: Entity.set(self, updates) — type error at the call site (NoInfer<U>)
7
+ * - Data-last: .pipe(Entity.set(updates)) — clean types, runtime validation catches
8
+ * partial GSI composites. Runtime is always active on all code paths.
9
+ *
10
+ * § Why data-last loses the constraint (with core Effect comparison):
11
+ *
12
+ * Core Effect duals like Ref.set and HashMap.set use a SHARED type parameter
13
+ * across the outer and inner functions:
14
+ *
15
+ * Ref.set: <A>(value: A) → (self: Ref<A>) → Effect<void>
16
+ * HashMap.set: <K, V>(key: K, v: V) → (self: HashMap<K, V>) → HashMap<K, V>
17
+ *
18
+ * In data-last, A/V are inferred from the arguments. When piped, `self` is
19
+ * checked against that inferred type. Because Ref and HashMap are INVARIANT
20
+ * in their type parameter, a mismatch between the inferred A and self's A
21
+ * produces a type error on self.
22
+ *
23
+ * Entity.set is different. The update constraint U is an all-or-none union:
24
+ *
25
+ * U = { tenantId: string; region: string } | { tenantId?: never; region?: never }
26
+ *
27
+ * If we used the same shared-parameter pattern:
28
+ *
29
+ * <U>(updates: U) → (self: EntityUpdate<..., U, ...>) → EntityUpdate<..., U, ...>
30
+ *
31
+ * Then Entity.set({ tenantId: "t-3" }) infers U = { tenantId: string }. When
32
+ * piped, self's U (the all-or-none union above) would need to extend
33
+ * { tenantId: string }. But it doesn't — the NoneAllowed branch has
34
+ * tenantId?: never. So this WOULD error, but at the self position, producing
35
+ * a confusing "EntityUpdate<...> is not assignable to EntityUpdate<...>" message
36
+ * rather than the clear "missing property 'region'" error from data-first.
37
+ *
38
+ * Worse: for non-constrained fields the error is reversed. Entity.set({ name: "Alice" })
39
+ * infers U = { name: string }, then self's U (the all-or-none union) would need
40
+ * to extend { name: string } — but { tenantId?: never; region?: never } doesn't
41
+ * have name at all, so it would ALSO error, even though the update is perfectly valid.
42
+ *
43
+ * The module-level Entity.set uses `Updates extends Record<string, unknown>` in
44
+ * data-last to avoid these false positives, accepting that the constraint is
45
+ * enforced only at runtime. Data-first uses NoInfer<U> for precise type-level
46
+ * enforcement.
47
+ *
48
+ * § Entity-scoped set (the solution):
49
+ *
50
+ * Each Entity instance exposes a `.set` dual where U is pre-bound from the
51
+ * entity definition — following the schemaBodyJson(schema) factory pattern
52
+ * from Effect HTTP. Because U is resolved at entity creation (not inferred
53
+ * from the updates argument), both data-first and data-last paths are type-safe.
54
+ */
55
+ import { Effect, HashMap, pipe, Ref, Schema } from "effect";
56
+ import * as Entity from "../Entity.js";
57
+ class Employee extends Schema.Class("Employee")({
58
+ employeeId: Schema.String,
59
+ name: Schema.NonEmptyString,
60
+ tenantId: Schema.String,
61
+ region: Schema.String,
62
+ }) {
63
+ }
64
+ const Employees = Entity.make({
65
+ model: Employee,
66
+ entityType: "Employee",
67
+ primaryKey: {
68
+ pk: { field: "pk", composite: ["employeeId"] },
69
+ sk: { field: "sk", composite: [] },
70
+ },
71
+ indexes: {
72
+ byTenant: {
73
+ name: "gsi1",
74
+ pk: { field: "gsi1pk", composite: ["tenantId"] },
75
+ sk: { field: "gsi1sk", composite: ["region"] },
76
+ },
77
+ },
78
+ });
79
+ // -----------------------------------------------------------------------
80
+ // DATA-FIRST: Entity.set(self, updates) — runtime validated
81
+ // GSI all-or-none is no longer enforced at the type level (TS 25-member
82
+ // union assignability limit). These all compile; partial composites
83
+ // produce a ValidationError at runtime.
84
+ // -----------------------------------------------------------------------
85
+ // Partial GSI composites: tenantId without region — caught at runtime
86
+ Entity.set(Employees.update({ employeeId: "e-1" }), { tenantId: "t-3" });
87
+ // All GSI composites
88
+ Entity.set(Employees.update({ employeeId: "e-1" }), { tenantId: "t-3", region: "us-east-1" });
89
+ // No GSI composites
90
+ Entity.set(Employees.update({ employeeId: "e-1" }), { name: "Alice" });
91
+ // -----------------------------------------------------------------------
92
+ // PIPE PATH: .pipe(Entity.set({ ... })) — clean types, runtime-validated
93
+ // -----------------------------------------------------------------------
94
+ // Partial GSI composites: no type error in pipe path (runtime catches it)
95
+ const _pipeBadRuntime = Effect.gen(function* () {
96
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Entity.set({ tenantId: "t-3" }), Entity.asModel);
97
+ });
98
+ // GOOD: all GSI composites in pipe
99
+ const _pipeGood1 = Effect.gen(function* () {
100
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Entity.set({ tenantId: "t-3", region: "us-east-1" }), Entity.asModel);
101
+ });
102
+ // GOOD: no GSI composites in pipe
103
+ const _pipeGood2 = Effect.gen(function* () {
104
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Entity.set({ name: "Alice" }), Entity.asModel);
105
+ });
106
+ // -----------------------------------------------------------------------
107
+ // PIPE CHAIN: Entity.set → Effect.map → Effect.catchTag composes cleanly
108
+ // -----------------------------------------------------------------------
109
+ // Partial GSI in pipe chain — no type error; runtime validation catches it.
110
+ // .asEffect() crosses the entity-op/Effect boundary before Effect combinators.
111
+ const _pipeChainPartial = Effect.gen(function* () {
112
+ const result = yield* Employees.update({ employeeId: "e-1" }).pipe(Entity.set({ tenantId: "t-3" }), (op) => op.asEffect(), Effect.map(() => "unexpected success"), Effect.catchTag("ValidationError", (e) => Effect.succeed(`Caught ValidationError: ${e.cause}`)));
113
+ return result;
114
+ });
115
+ // Full pipe chain with all GSI composites — .asEffect() at the boundary
116
+ const _pipeChainGood = Effect.gen(function* () {
117
+ const result = yield* Employees.update({ employeeId: "e-1" }).pipe(Entity.set({ tenantId: "t-3", region: "us-east-1" }), Entity.expectedVersion(1), (op) => op.asEffect(), Effect.map(() => "success"), Effect.catchTag("OptimisticLockError", () => Effect.succeed("lock failed")));
118
+ return result;
119
+ });
120
+ // -----------------------------------------------------------------------
121
+ // CORE EFFECT COMPARISON — why Ref.set / HashMap.set catch data-last
122
+ // mismatches but Entity.set cannot
123
+ // -----------------------------------------------------------------------
124
+ // Ref.set: shared type parameter A — invariant container catches mismatches
125
+ const _refExample = Effect.gen(function* () {
126
+ const ref = yield* Ref.make("red");
127
+ // Data-first: TYPE ERROR — "green" not in "red" | "blue"
128
+ // @ts-expect-error
129
+ yield* Ref.set(ref, "green");
130
+ // Data-last: ALSO TYPE ERROR — Ref<"red"|"blue"> not assignable to Ref<"green">
131
+ // The shared A is inferred as "green" from the argument, then self (Ref<"red"|"blue">)
132
+ // is checked — Ref is invariant, so the mismatch is caught.
133
+ // @ts-expect-error
134
+ yield* pipe(ref, Ref.set("green"));
135
+ });
136
+ // HashMap.set: shared type parameters K, V — invariant container catches mismatches
137
+ const _hashMapExample = Effect.gen(function* () {
138
+ const map = HashMap.make(["a", 1], ["b", 2]); // HashMap<string, number>
139
+ // Data-first: TYPE ERROR — "hello" is not number
140
+ // @ts-expect-error
141
+ HashMap.set(map, "c", "hello");
142
+ // Data-last: ALSO TYPE ERROR — HashMap<string, number> not assignable to HashMap<string, string>
143
+ // V is inferred as string from "hello", then self (HashMap<string, number>) is checked.
144
+ // @ts-expect-error
145
+ pipe(map, HashMap.set("c", "hello"));
146
+ });
147
+ // Entity.set: WHY it's different — the constraint is a union, not a simple type
148
+ //
149
+ // If Entity.set used the Ref/HashMap pattern (shared U parameter), then:
150
+ //
151
+ // Entity.set({ name: "Alice" }) // infers U = { name: string }
152
+ // // Returns: (self: EntityUpdate<..., { name: string }, ...>) => EntityUpdate<...>
153
+ //
154
+ // // When piped, self's U is the all-or-none union:
155
+ // // { tenantId: string; region: string } | { tenantId?: never; region?: never }
156
+ // // This union is NOT assignable to { name: string } — FALSE POSITIVE error.
157
+ // // A perfectly valid non-GSI update would be rejected.
158
+ //
159
+ // So the module-level Entity.set uses `Updates extends Record<string, unknown>`
160
+ // in data-last, accepting any record and deferring validation to runtime.
161
+ // -----------------------------------------------------------------------
162
+ // ENTITY-SCOPED SET: Employees.set() — runtime validated
163
+ // -----------------------------------------------------------------------
164
+ // Each Entity instance exposes a `.set` dual where U is pre-bound from the
165
+ // entity definition. GSI all-or-none is enforced at runtime.
166
+ // DATA-FIRST: partial GSI composites caught at runtime
167
+ Employees.set(Employees.update({ employeeId: "e-1" }), { tenantId: "t-3" });
168
+ // DATA-LAST: partial GSI composites caught at runtime
169
+ const _entityScopedBad = Effect.gen(function* () {
170
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Employees.set({ tenantId: "t-3" }), Entity.asModel);
171
+ });
172
+ // GOOD: all GSI composites in entity-scoped pipe
173
+ const _entityScopedGood1 = Effect.gen(function* () {
174
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Employees.set({ tenantId: "t-3", region: "us-east-1" }), Entity.asModel);
175
+ });
176
+ // GOOD: no GSI composites in entity-scoped pipe
177
+ const _entityScopedGood2 = Effect.gen(function* () {
178
+ yield* Employees.update({ employeeId: "e-1" }).pipe(Employees.set({ name: "Alice" }), Entity.asModel);
179
+ });
180
+ // PIPE CHAIN: Entity-scoped set composes with Effect.map/catchTag
181
+ const _entityScopedChain = Effect.gen(function* () {
182
+ const result = yield* Employees.update({ employeeId: "e-1" }).pipe(Employees.set({ tenantId: "t-3", region: "us-east-1" }), Employees.expectedVersion(1), (op) => op.asEffect(), Effect.map(() => "success"), Effect.catchTag("OptimisticLockError", () => Effect.succeed("lock failed")));
183
+ return result;
184
+ });
185
+ void _pipeBadRuntime;
186
+ void _pipeGood1;
187
+ void _pipeGood2;
188
+ void _pipeChainPartial;
189
+ void _pipeChainGood;
190
+ void _refExample;
191
+ void _hashMapExample;
192
+ void _entityScopedBad;
193
+ void _entityScopedGood1;
194
+ void _entityScopedGood2;
195
+ void _entityScopedChain;
196
+ //# sourceMappingURL=sparse_check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparse_check.js","sourceRoot":"","sources":["../../src/internal/sparse_check.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "effect-dynamodb",
3
+ "version": "0.1.0",
4
+ "description": "Effect TS ORM for DynamoDB — schema-driven entity modeling, single-table design, composite keys, transactions, and Stream-based pagination",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Justin Menga",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/jmenga/effect-dynamodb",
11
+ "directory": "packages/effect-dynamodb"
12
+ },
13
+ "homepage": "https://jmenga.github.io/effect-dynamodb",
14
+ "bugs": {
15
+ "url": "https://github.com/jmenga/effect-dynamodb/issues"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "keywords": [
21
+ "effect",
22
+ "effect-ts",
23
+ "dynamodb",
24
+ "orm",
25
+ "single-table",
26
+ "schema",
27
+ "typescript",
28
+ "aws",
29
+ "nosql",
30
+ "transactions",
31
+ "stream",
32
+ "pagination"
33
+ ],
34
+ "sideEffects": false,
35
+ "main": "dist/index.js",
36
+ "types": "dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "import": "./dist/index.js"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "README.md",
46
+ "LICENSE"
47
+ ],
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "test": "vitest run",
51
+ "test:watch": "vitest",
52
+ "test:connected": "vitest run --config vitest.connected.ts",
53
+ "check": "tsc --noEmit && tsc --noEmit -p tsconfig.examples.json",
54
+ "lint": "biome check .",
55
+ "lint:fix": "biome check --write ."
56
+ },
57
+ "dependencies": {
58
+ "@aws-sdk/client-dynamodb": "^3.700.0",
59
+ "@aws-sdk/util-dynamodb": "^3.700.0"
60
+ },
61
+ "peerDependencies": {
62
+ "effect": "^4.0.0-beta.48"
63
+ },
64
+ "devDependencies": {
65
+ "@effect/vitest": "4.0.0-beta.48",
66
+ "@types/node": "^25.5.0",
67
+ "effect": "4.0.0-beta.48",
68
+ "typescript": "^5.7.0",
69
+ "vitest": "^4.1.0"
70
+ }
71
+ }