@effect-dynamodb/schema 1.9.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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/Aggregate.d.ts +128 -0
  4. package/dist/Aggregate.d.ts.map +1 -0
  5. package/dist/Aggregate.js +69 -0
  6. package/dist/Aggregate.js.map +1 -0
  7. package/dist/DynamoModel.d.ts +370 -0
  8. package/dist/DynamoModel.d.ts.map +1 -0
  9. package/dist/DynamoModel.js +541 -0
  10. package/dist/DynamoModel.js.map +1 -0
  11. package/dist/DynamoSchema.d.ts +137 -0
  12. package/dist/DynamoSchema.d.ts.map +1 -0
  13. package/dist/DynamoSchema.js +188 -0
  14. package/dist/DynamoSchema.js.map +1 -0
  15. package/dist/Entity.d.ts +239 -0
  16. package/dist/Entity.d.ts.map +1 -0
  17. package/dist/Entity.js +558 -0
  18. package/dist/Entity.js.map +1 -0
  19. package/dist/Errors.d.ts +387 -0
  20. package/dist/Errors.d.ts.map +1 -0
  21. package/dist/Errors.js +218 -0
  22. package/dist/Errors.js.map +1 -0
  23. package/dist/KeyComposer.d.ts +264 -0
  24. package/dist/KeyComposer.d.ts.map +1 -0
  25. package/dist/KeyComposer.js +516 -0
  26. package/dist/KeyComposer.js.map +1 -0
  27. package/dist/Projection.d.ts +28 -0
  28. package/dist/Projection.d.ts.map +1 -0
  29. package/dist/Projection.js +39 -0
  30. package/dist/Projection.js.map +1 -0
  31. package/dist/index.d.ts +32 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +26 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/internal/AggregateCursor.d.ts +44 -0
  36. package/dist/internal/AggregateCursor.d.ts.map +1 -0
  37. package/dist/internal/AggregateCursor.js +18 -0
  38. package/dist/internal/AggregateCursor.js.map +1 -0
  39. package/dist/internal/AggregateEdges.d.ts +117 -0
  40. package/dist/internal/AggregateEdges.d.ts.map +1 -0
  41. package/dist/internal/AggregateEdges.js +51 -0
  42. package/dist/internal/AggregateEdges.js.map +1 -0
  43. package/dist/internal/AggregateSchemas.d.ts +76 -0
  44. package/dist/internal/AggregateSchemas.d.ts.map +1 -0
  45. package/dist/internal/AggregateSchemas.js +164 -0
  46. package/dist/internal/AggregateSchemas.js.map +1 -0
  47. package/dist/internal/AggregateTypes.d.ts +132 -0
  48. package/dist/internal/AggregateTypes.d.ts.map +1 -0
  49. package/dist/internal/AggregateTypes.js +7 -0
  50. package/dist/internal/AggregateTypes.js.map +1 -0
  51. package/dist/internal/DefaultCrypto.d.ts +26 -0
  52. package/dist/internal/DefaultCrypto.d.ts.map +1 -0
  53. package/dist/internal/DefaultCrypto.js +40 -0
  54. package/dist/internal/DefaultCrypto.js.map +1 -0
  55. package/dist/internal/EntityConfig.d.ts +152 -0
  56. package/dist/internal/EntityConfig.d.ts.map +1 -0
  57. package/dist/internal/EntityConfig.js +7 -0
  58. package/dist/internal/EntityConfig.js.map +1 -0
  59. package/dist/internal/EntitySchemas.d.ts +198 -0
  60. package/dist/internal/EntitySchemas.d.ts.map +1 -0
  61. package/dist/internal/EntitySchemas.js +798 -0
  62. package/dist/internal/EntitySchemas.js.map +1 -0
  63. package/dist/internal/EntityTypes.d.ts +233 -0
  64. package/dist/internal/EntityTypes.d.ts.map +1 -0
  65. package/dist/internal/EntityTypes.js +7 -0
  66. package/dist/internal/EntityTypes.js.map +1 -0
  67. package/dist/internal/SchemaAccessors.d.ts +90 -0
  68. package/dist/internal/SchemaAccessors.d.ts.map +1 -0
  69. package/dist/internal/SchemaAccessors.js +171 -0
  70. package/dist/internal/SchemaAccessors.js.map +1 -0
  71. package/package.json +70 -0
@@ -0,0 +1,387 @@
1
+ import { type Option } from "effect";
2
+ declare const DynamoError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
3
+ readonly _tag: "DynamoError";
4
+ } & Readonly<A>;
5
+ /** Wraps AWS SDK errors from DynamoDB operations */
6
+ export declare class DynamoError extends DynamoError_base<{
7
+ readonly operation: string;
8
+ readonly cause: unknown;
9
+ }> {
10
+ }
11
+ declare const ThrottlingError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
12
+ readonly _tag: "ThrottlingError";
13
+ } & Readonly<A>;
14
+ /** DynamoDB throttling — request rate too high */
15
+ export declare class ThrottlingError extends ThrottlingError_base<{
16
+ readonly operation: string;
17
+ readonly cause: unknown;
18
+ }> {
19
+ }
20
+ declare const DynamoValidationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
21
+ readonly _tag: "DynamoValidationError";
22
+ } & Readonly<A>;
23
+ /** DynamoDB validation error — malformed request */
24
+ export declare class DynamoValidationError extends DynamoValidationError_base<{
25
+ readonly operation: string;
26
+ readonly cause: unknown;
27
+ }> {
28
+ }
29
+ declare const InternalServerError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
30
+ readonly _tag: "InternalServerError";
31
+ } & Readonly<A>;
32
+ /** DynamoDB internal server error — transient failure */
33
+ export declare class InternalServerError extends InternalServerError_base<{
34
+ readonly operation: string;
35
+ readonly cause: unknown;
36
+ }> {
37
+ }
38
+ declare const ResourceNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
39
+ readonly _tag: "ResourceNotFoundError";
40
+ } & Readonly<A>;
41
+ /** DynamoDB resource not found — table doesn't exist */
42
+ export declare class ResourceNotFoundError extends ResourceNotFoundError_base<{
43
+ readonly operation: string;
44
+ readonly cause: unknown;
45
+ }> {
46
+ }
47
+ declare const ItemNotFound_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
48
+ readonly _tag: "ItemNotFound";
49
+ } & Readonly<A>;
50
+ /** GetItem returned no item for the given key */
51
+ export declare class ItemNotFound extends ItemNotFound_base<{
52
+ readonly entityType: string;
53
+ readonly key: Record<string, unknown>;
54
+ }> {
55
+ }
56
+ declare const ConditionalCheckFailed_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
57
+ readonly _tag: "ConditionalCheckFailed";
58
+ } & Readonly<A>;
59
+ /**
60
+ * PutItem/DeleteItem/UpdateItem conditional check failed.
61
+ *
62
+ * On `Entity.append()` (time-series), this is surfaced when a user-supplied
63
+ * `condition` rejected the write while the CAS predicate held. In that case
64
+ * `current` is `Option.some(<decoded post-state>)` carrying the live current
65
+ * item snapshot read via the follow-up GetItem. For non-append paths and for
66
+ * append calls that opted out via `.skipFollowUp()`, `current` is omitted /
67
+ * `Option.none()` (no follow-up GetItem was issued).
68
+ *
69
+ * On the `.skipFollowUp()` path of `.append()`, user-condition failures cannot
70
+ * be distinguished from CAS failures, so they are reported as
71
+ * {@link StaleAppend} instead — see that error's docs.
72
+ */
73
+ export declare class ConditionalCheckFailed extends ConditionalCheckFailed_base<{
74
+ readonly entityType: string;
75
+ readonly key: Record<string, unknown>;
76
+ readonly current?: Option.Option<unknown>;
77
+ }> {
78
+ }
79
+ declare const StaleAppend_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
80
+ readonly _tag: "StaleAppend";
81
+ } & Readonly<A>;
82
+ /**
83
+ * `Entity.append()` was rejected because the CAS predicate
84
+ * (`attribute_not_exists(pk) OR <orderBy> < :newOrderBy`) did not hold —
85
+ * i.e. another writer has already advanced the current item past
86
+ * `attemptedOrderBy`. This is an EXPECTED outcome under newer-wins
87
+ * concurrency; callers typically `Effect.catchTag("StaleAppend", ...)` and
88
+ * treat it as a no-op.
89
+ *
90
+ * `current` carries the winning state when the follow-up GetItem ran:
91
+ * - `Option.some(<raw decoded item>)` on the default path.
92
+ * - `Option.none()` when the caller opted out via `.skipFollowUp()`.
93
+ *
94
+ * The value is typed as `unknown` because `StaleAppend` has no model
95
+ * generic; callers that need a typed value can decode it with the entity's
96
+ * record schema themselves.
97
+ *
98
+ * NOTE on the `skipFollowUp` path: a user-supplied `.condition()` failure
99
+ * also raises `StaleAppend` (not {@link ConditionalCheckFailed}) because no
100
+ * follow-up GetItem ran, so the two cancellation modes are
101
+ * indistinguishable. If you need the disambiguation, do not call
102
+ * `.skipFollowUp()`.
103
+ */
104
+ export declare class StaleAppend extends StaleAppend_base<{
105
+ readonly entityType: string;
106
+ readonly orderByField: string;
107
+ readonly attemptedOrderBy: unknown;
108
+ readonly current: Option.Option<unknown>;
109
+ }> {
110
+ }
111
+ declare const ValidationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
112
+ readonly _tag: "ValidationError";
113
+ } & Readonly<A>;
114
+ /** Schema decode/encode validation failed */
115
+ export declare class ValidationError extends ValidationError_base<{
116
+ readonly entityType: string;
117
+ readonly operation: string;
118
+ readonly cause: unknown;
119
+ }> {
120
+ }
121
+ declare const TransactionCancelled_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
122
+ readonly _tag: "TransactionCancelled";
123
+ } & Readonly<A>;
124
+ /** TransactWriteItems or TransactGetItems cancelled by DynamoDB */
125
+ export declare class TransactionCancelled extends TransactionCancelled_base<{
126
+ readonly operation: string;
127
+ readonly reasons: ReadonlyArray<{
128
+ readonly code?: string | undefined;
129
+ readonly message?: string | undefined;
130
+ }>;
131
+ readonly cause: unknown;
132
+ }> {
133
+ }
134
+ declare const UniqueConstraintViolation_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
135
+ readonly _tag: "UniqueConstraintViolation";
136
+ } & Readonly<A>;
137
+ /** Unique constraint violation — field value already exists */
138
+ export declare class UniqueConstraintViolation extends UniqueConstraintViolation_base<{
139
+ readonly entityType: string;
140
+ readonly constraint: string;
141
+ readonly fields: Record<string, string>;
142
+ }> {
143
+ }
144
+ declare const OptimisticLockError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
145
+ readonly _tag: "OptimisticLockError";
146
+ } & Readonly<A>;
147
+ /** Optimistic concurrency conflict — item was modified since last read */
148
+ export declare class OptimisticLockError extends OptimisticLockError_base<{
149
+ readonly entityType: string;
150
+ readonly key: Record<string, unknown>;
151
+ readonly expectedVersion: number;
152
+ readonly actualVersion: number;
153
+ }> {
154
+ }
155
+ /** @internal Shape of AWS SDK TransactionCanceledException */
156
+ export interface AwsTransactionCancelled {
157
+ readonly name: "TransactionCanceledException";
158
+ readonly CancellationReasons?: ReadonlyArray<{
159
+ readonly Code?: string;
160
+ readonly Message?: string;
161
+ }>;
162
+ }
163
+ /** @internal Shape of AWS SDK ConditionalCheckFailedException */
164
+ export interface AwsConditionalCheckFailed {
165
+ readonly name: "ConditionalCheckFailedException";
166
+ }
167
+ /** @internal */
168
+ export declare const isAwsTransactionCancelled: (cause: unknown) => cause is AwsTransactionCancelled;
169
+ /** @internal */
170
+ export declare const isAwsConditionalCheckFailed: (cause: unknown) => cause is AwsConditionalCheckFailed;
171
+ /** @internal */
172
+ export declare const isAwsThrottling: (cause: unknown) => boolean;
173
+ /** @internal */
174
+ export declare const isAwsValidationError: (cause: unknown) => boolean;
175
+ /** @internal */
176
+ export declare const isAwsInternalServerError: (cause: unknown) => boolean;
177
+ /** @internal */
178
+ export declare const isAwsResourceNotFound: (cause: unknown) => boolean;
179
+ declare const TransactionOverflow_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
180
+ readonly _tag: "TransactionOverflow";
181
+ } & Readonly<A>;
182
+ /** Entity-level transactWriteItems would exceed DynamoDB's 100-item limit */
183
+ export declare class TransactionOverflow extends TransactionOverflow_base<{
184
+ readonly entityType: string;
185
+ readonly operation: string;
186
+ readonly itemCount: number;
187
+ readonly limit: number;
188
+ }> {
189
+ }
190
+ declare const RefNotFound_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
191
+ readonly _tag: "RefNotFound";
192
+ } & Readonly<A>;
193
+ /** Referenced entity not found during ref hydration */
194
+ export declare class RefNotFound extends RefNotFound_base<{
195
+ readonly entity: string;
196
+ readonly field: string;
197
+ readonly refEntity: string;
198
+ readonly refId: string;
199
+ }> {
200
+ }
201
+ declare const ItemDeleted_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
202
+ readonly _tag: "ItemDeleted";
203
+ } & Readonly<A>;
204
+ /** Item is soft-deleted and cannot be modified without restore */
205
+ export declare class ItemDeleted extends ItemDeleted_base<{
206
+ readonly entityType: string;
207
+ readonly key: Record<string, unknown>;
208
+ readonly deletedAt: string;
209
+ }> {
210
+ }
211
+ declare const ItemNotDeleted_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
212
+ readonly _tag: "ItemNotDeleted";
213
+ } & Readonly<A>;
214
+ /** Item is not soft-deleted — restore requires a deleted item */
215
+ export declare class ItemNotDeleted extends ItemNotDeleted_base<{
216
+ readonly entityType: string;
217
+ readonly key: Record<string, unknown>;
218
+ }> {
219
+ }
220
+ declare const AggregateAssemblyError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
221
+ readonly _tag: "AggregateAssemblyError";
222
+ } & Readonly<A>;
223
+ /** Aggregate assembly failed — missing items, structural violations, or decode errors */
224
+ export declare class AggregateAssemblyError extends AggregateAssemblyError_base<{
225
+ readonly aggregate: string;
226
+ readonly reason: string;
227
+ readonly key: Record<string, unknown>;
228
+ }> {
229
+ }
230
+ declare const AggregateDecompositionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
231
+ readonly _tag: "AggregateDecompositionError";
232
+ } & Readonly<A>;
233
+ /** Aggregate decomposition failed — schema validation or structural error during write path */
234
+ export declare class AggregateDecompositionError extends AggregateDecompositionError_base<{
235
+ readonly aggregate: string;
236
+ readonly member: string;
237
+ readonly reason: string;
238
+ }> {
239
+ }
240
+ declare const AggregateTransactionOverflow_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
241
+ readonly _tag: "AggregateTransactionOverflow";
242
+ } & Readonly<A>;
243
+ /** Sub-aggregate exceeds DynamoDB's 100-item transaction limit */
244
+ export declare class AggregateTransactionOverflow extends AggregateTransactionOverflow_base<{
245
+ readonly aggregate: string;
246
+ readonly subgraph: string;
247
+ readonly itemCount: number;
248
+ readonly limit: number;
249
+ }> {
250
+ }
251
+ declare const CascadePartialFailure_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
252
+ readonly _tag: "CascadePartialFailure";
253
+ } & Readonly<A>;
254
+ /** Cascade update partially failed (eventual mode) */
255
+ export declare class CascadePartialFailure extends CascadePartialFailure_base<{
256
+ readonly sourceEntity: string;
257
+ readonly sourceId: string;
258
+ readonly succeeded: number;
259
+ readonly failed: number;
260
+ readonly errors: ReadonlyArray<unknown>;
261
+ }> {
262
+ }
263
+ declare const VersionConflict_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
264
+ readonly _tag: "VersionConflict";
265
+ } & Readonly<A>;
266
+ /** Optimistic concurrency conflict — stream version did not match */
267
+ export declare class VersionConflict extends VersionConflict_base<{
268
+ readonly streamName: string;
269
+ readonly streamId: string;
270
+ readonly expectedVersion: number;
271
+ }> {
272
+ }
273
+ declare const CompositeKeyHoleError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
274
+ readonly _tag: "CompositeKeyHoleError";
275
+ } & Readonly<A>;
276
+ /**
277
+ * EDD-9024 — DEPRECATED in v1.7.1.
278
+ *
279
+ * @deprecated Since v1.7.1, this error is no longer thrown at runtime. It is
280
+ * kept as an exported class for back-compat with consumers who type-imported
281
+ * it (e.g. inside `Effect.catchTag("CompositeKeyHoleError", ...)` blocks).
282
+ * No code path constructs or throws this error anymore.
283
+ *
284
+ * **Why deprecated.** v1.7.0's "throw under preserve on hole pattern" was a
285
+ * defensive runtime safety net for a case the type system already catches:
286
+ * required composites can't be omitted under `exactOptionalPropertyTypes`
287
+ * since v1.7.0 reverted the v1.6 NullishOr widening. The only remaining
288
+ * runtime "hole" shape is "optional leading composite absent + present
289
+ * trailing composite," which is a normal write the consumer expressly chose.
290
+ *
291
+ * **What replaces it.** Hole patterns now collapse into the unified per-half
292
+ * can't-compose rule:
293
+ * - `'sparse'` half → REMOVE that half's key (drops the half).
294
+ * - `'preserve'` half + composite of the half is in `Entity.remove([...])`
295
+ * → REMOVE that half's key (cascade override fires).
296
+ * - `'preserve'` half + no composite in `Entity.remove([...])` → noop (the
297
+ * stored key is left untouched; may be stale until the next write that
298
+ * touches the half supplies enough composites to recompose, or an
299
+ * `Entity.remove` cascade fires).
300
+ *
301
+ * See `DESIGN.md §7 Policy-Aware GSI Composition` (v1.7.1 unified rule).
302
+ *
303
+ * **Migration.** Remove any `Effect.catchTag("CompositeKeyHoleError", ...)`
304
+ * handlers — the throw site is gone and the catch is dead code. If you were
305
+ * relying on the throw to detect bad payloads, switch to declaring the
306
+ * relevant GSI half as `'sparse'` (the consumer-side semantic that always
307
+ * matches the throw's intent — drop the index entry on can't-compose) or
308
+ * supply the surviving composites via `set` in the same update.
309
+ */
310
+ export declare class CompositeKeyHoleError extends CompositeKeyHoleError_base<{
311
+ readonly entityType: string;
312
+ readonly indexName: string;
313
+ readonly clearedComposite: string;
314
+ readonly trailingComposite: string;
315
+ readonly clearedPosition: number;
316
+ readonly trailingPosition: number;
317
+ /** Which GSI key attribute the hole is in — `"pk"` (gsiNpk) or `"sk"` (gsiNsk). */
318
+ readonly key: "pk" | "sk";
319
+ /** Human-readable description, prefixed with `EDD-9024`. */
320
+ readonly message: string;
321
+ }> {
322
+ }
323
+ /**
324
+ * Build a {@link CompositeKeyHoleError} with a formatted message.
325
+ *
326
+ * @deprecated Since v1.7.1 this builder is unused — no code path raises EDD-9024
327
+ * at runtime. Kept exported only for back-compat with consumers who imported
328
+ * the helper. See {@link CompositeKeyHoleError} for the migration path.
329
+ */
330
+ export declare const makeCompositeKeyHoleError: (params: {
331
+ readonly entityType: string;
332
+ readonly indexName: string;
333
+ readonly clearedComposite: string;
334
+ readonly trailingComposite: string;
335
+ readonly clearedPosition: number;
336
+ readonly trailingPosition: number;
337
+ readonly key: "pk" | "sk";
338
+ }) => CompositeKeyHoleError;
339
+ declare const CompositeNullableError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
340
+ readonly _tag: "CompositeNullableError";
341
+ } & Readonly<A>;
342
+ /**
343
+ * EDD-9025 — A composite attribute on `primaryKey`, `indexes`, or a `unique`
344
+ * constraint has a Schema whose type union includes `null`. Composites
345
+ * participate in string composition (`acc#X#alert#Y`); `null` is not a
346
+ * meaningful slot value — only present-with-value or absent. Allowing
347
+ * `Schema.NullOr` / `Schema.NullishOr` / `Schema.Union([..., Schema.Null])`
348
+ * on a composite would let `set({ composite: null })` typecheck, then either
349
+ * blow up at runtime or silently produce a key with the literal string
350
+ * `"null"` as a slot.
351
+ *
352
+ * Raised at `Entity.make()` time. The error names the entity, the
353
+ * surface where the composite is declared (primary key / a GSI / a unique
354
+ * constraint), the offending composite attribute, and the resolved Schema
355
+ * path that contains `null`.
356
+ *
357
+ * Resolution: declare the attribute as `Schema.optional(...)` (which
358
+ * produces `T | undefined` without `null`). Sparse-pattern usage is fully
359
+ * supported under v3's two-way payload classification — `undefined` is
360
+ * "absent" for GSI composition purposes.
361
+ *
362
+ * See `DESIGN.md §7 Policy-Aware GSI Composition` (EDD-9025 footgun gate).
363
+ */
364
+ export declare class CompositeNullableError extends CompositeNullableError_base<{
365
+ readonly entityType: string;
366
+ /** "primaryKey" | "index:<name>" | "unique:<name>" */
367
+ readonly surface: string;
368
+ readonly compositeAttribute: string;
369
+ /** Resolved schema path that revealed the `null` branch. */
370
+ readonly schemaPath: string;
371
+ /** Human-readable description, prefixed with `EDD-9025`. */
372
+ readonly message: string;
373
+ }> {
374
+ }
375
+ /**
376
+ * Build a {@link CompositeNullableError} with a formatted message. Centralises
377
+ * the message format so call sites (Entity.make validation paths) stay
378
+ * consistent.
379
+ */
380
+ export declare const makeCompositeNullableError: (params: {
381
+ readonly entityType: string;
382
+ readonly surface: string;
383
+ readonly compositeAttribute: string;
384
+ readonly schemaPath: string;
385
+ }) => CompositeNullableError;
386
+ export {};
387
+ //# sourceMappingURL=Errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Errors.d.ts","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"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"}
package/dist/Errors.js ADDED
@@ -0,0 +1,218 @@
1
+ import { Data } from "effect";
2
+ /** Wraps AWS SDK errors from DynamoDB operations */
3
+ export class DynamoError extends Data.TaggedError("DynamoError") {
4
+ }
5
+ /** DynamoDB throttling — request rate too high */
6
+ export class ThrottlingError extends Data.TaggedError("ThrottlingError") {
7
+ }
8
+ /** DynamoDB validation error — malformed request */
9
+ export class DynamoValidationError extends Data.TaggedError("DynamoValidationError") {
10
+ }
11
+ /** DynamoDB internal server error — transient failure */
12
+ export class InternalServerError extends Data.TaggedError("InternalServerError") {
13
+ }
14
+ /** DynamoDB resource not found — table doesn't exist */
15
+ export class ResourceNotFoundError extends Data.TaggedError("ResourceNotFoundError") {
16
+ }
17
+ /** GetItem returned no item for the given key */
18
+ export class ItemNotFound extends Data.TaggedError("ItemNotFound") {
19
+ }
20
+ /**
21
+ * PutItem/DeleteItem/UpdateItem conditional check failed.
22
+ *
23
+ * On `Entity.append()` (time-series), this is surfaced when a user-supplied
24
+ * `condition` rejected the write while the CAS predicate held. In that case
25
+ * `current` is `Option.some(<decoded post-state>)` carrying the live current
26
+ * item snapshot read via the follow-up GetItem. For non-append paths and for
27
+ * append calls that opted out via `.skipFollowUp()`, `current` is omitted /
28
+ * `Option.none()` (no follow-up GetItem was issued).
29
+ *
30
+ * On the `.skipFollowUp()` path of `.append()`, user-condition failures cannot
31
+ * be distinguished from CAS failures, so they are reported as
32
+ * {@link StaleAppend} instead — see that error's docs.
33
+ */
34
+ export class ConditionalCheckFailed extends Data.TaggedError("ConditionalCheckFailed") {
35
+ }
36
+ /**
37
+ * `Entity.append()` was rejected because the CAS predicate
38
+ * (`attribute_not_exists(pk) OR <orderBy> < :newOrderBy`) did not hold —
39
+ * i.e. another writer has already advanced the current item past
40
+ * `attemptedOrderBy`. This is an EXPECTED outcome under newer-wins
41
+ * concurrency; callers typically `Effect.catchTag("StaleAppend", ...)` and
42
+ * treat it as a no-op.
43
+ *
44
+ * `current` carries the winning state when the follow-up GetItem ran:
45
+ * - `Option.some(<raw decoded item>)` on the default path.
46
+ * - `Option.none()` when the caller opted out via `.skipFollowUp()`.
47
+ *
48
+ * The value is typed as `unknown` because `StaleAppend` has no model
49
+ * generic; callers that need a typed value can decode it with the entity's
50
+ * record schema themselves.
51
+ *
52
+ * NOTE on the `skipFollowUp` path: a user-supplied `.condition()` failure
53
+ * also raises `StaleAppend` (not {@link ConditionalCheckFailed}) because no
54
+ * follow-up GetItem ran, so the two cancellation modes are
55
+ * indistinguishable. If you need the disambiguation, do not call
56
+ * `.skipFollowUp()`.
57
+ */
58
+ export class StaleAppend extends Data.TaggedError("StaleAppend") {
59
+ }
60
+ /** Schema decode/encode validation failed */
61
+ export class ValidationError extends Data.TaggedError("ValidationError") {
62
+ }
63
+ /** TransactWriteItems or TransactGetItems cancelled by DynamoDB */
64
+ export class TransactionCancelled extends Data.TaggedError("TransactionCancelled") {
65
+ }
66
+ /** Unique constraint violation — field value already exists */
67
+ export class UniqueConstraintViolation extends Data.TaggedError("UniqueConstraintViolation") {
68
+ }
69
+ /** Optimistic concurrency conflict — item was modified since last read */
70
+ export class OptimisticLockError extends Data.TaggedError("OptimisticLockError") {
71
+ }
72
+ /** @internal */
73
+ export const isAwsTransactionCancelled = (cause) => cause != null &&
74
+ typeof cause === "object" &&
75
+ "name" in cause &&
76
+ cause.name === "TransactionCanceledException";
77
+ /** @internal */
78
+ export const isAwsConditionalCheckFailed = (cause) => cause != null &&
79
+ typeof cause === "object" &&
80
+ "name" in cause &&
81
+ cause.name === "ConditionalCheckFailedException";
82
+ /** @internal */
83
+ export const isAwsThrottling = (cause) => cause != null &&
84
+ typeof cause === "object" &&
85
+ "name" in cause &&
86
+ (cause.name === "ThrottlingException" ||
87
+ cause.name === "ProvisionedThroughputExceededException");
88
+ /** @internal */
89
+ export const isAwsValidationError = (cause) => cause != null &&
90
+ typeof cause === "object" &&
91
+ "name" in cause &&
92
+ cause.name === "ValidationException";
93
+ /** @internal */
94
+ export const isAwsInternalServerError = (cause) => cause != null &&
95
+ typeof cause === "object" &&
96
+ "name" in cause &&
97
+ cause.name === "InternalServerError";
98
+ /** @internal */
99
+ export const isAwsResourceNotFound = (cause) => cause != null &&
100
+ typeof cause === "object" &&
101
+ "name" in cause &&
102
+ cause.name === "ResourceNotFoundException";
103
+ /** Entity-level transactWriteItems would exceed DynamoDB's 100-item limit */
104
+ export class TransactionOverflow extends Data.TaggedError("TransactionOverflow") {
105
+ }
106
+ /** Referenced entity not found during ref hydration */
107
+ export class RefNotFound extends Data.TaggedError("RefNotFound") {
108
+ }
109
+ /** Item is soft-deleted and cannot be modified without restore */
110
+ export class ItemDeleted extends Data.TaggedError("ItemDeleted") {
111
+ }
112
+ /** Item is not soft-deleted — restore requires a deleted item */
113
+ export class ItemNotDeleted extends Data.TaggedError("ItemNotDeleted") {
114
+ }
115
+ /** Aggregate assembly failed — missing items, structural violations, or decode errors */
116
+ export class AggregateAssemblyError extends Data.TaggedError("AggregateAssemblyError") {
117
+ }
118
+ /** Aggregate decomposition failed — schema validation or structural error during write path */
119
+ export class AggregateDecompositionError extends Data.TaggedError("AggregateDecompositionError") {
120
+ }
121
+ /** Sub-aggregate exceeds DynamoDB's 100-item transaction limit */
122
+ export class AggregateTransactionOverflow extends Data.TaggedError("AggregateTransactionOverflow") {
123
+ }
124
+ /** Cascade update partially failed (eventual mode) */
125
+ export class CascadePartialFailure extends Data.TaggedError("CascadePartialFailure") {
126
+ }
127
+ /** Optimistic concurrency conflict — stream version did not match */
128
+ export class VersionConflict extends Data.TaggedError("VersionConflict") {
129
+ }
130
+ /**
131
+ * EDD-9024 — DEPRECATED in v1.7.1.
132
+ *
133
+ * @deprecated Since v1.7.1, this error is no longer thrown at runtime. It is
134
+ * kept as an exported class for back-compat with consumers who type-imported
135
+ * it (e.g. inside `Effect.catchTag("CompositeKeyHoleError", ...)` blocks).
136
+ * No code path constructs or throws this error anymore.
137
+ *
138
+ * **Why deprecated.** v1.7.0's "throw under preserve on hole pattern" was a
139
+ * defensive runtime safety net for a case the type system already catches:
140
+ * required composites can't be omitted under `exactOptionalPropertyTypes`
141
+ * since v1.7.0 reverted the v1.6 NullishOr widening. The only remaining
142
+ * runtime "hole" shape is "optional leading composite absent + present
143
+ * trailing composite," which is a normal write the consumer expressly chose.
144
+ *
145
+ * **What replaces it.** Hole patterns now collapse into the unified per-half
146
+ * can't-compose rule:
147
+ * - `'sparse'` half → REMOVE that half's key (drops the half).
148
+ * - `'preserve'` half + composite of the half is in `Entity.remove([...])`
149
+ * → REMOVE that half's key (cascade override fires).
150
+ * - `'preserve'` half + no composite in `Entity.remove([...])` → noop (the
151
+ * stored key is left untouched; may be stale until the next write that
152
+ * touches the half supplies enough composites to recompose, or an
153
+ * `Entity.remove` cascade fires).
154
+ *
155
+ * See `DESIGN.md §7 Policy-Aware GSI Composition` (v1.7.1 unified rule).
156
+ *
157
+ * **Migration.** Remove any `Effect.catchTag("CompositeKeyHoleError", ...)`
158
+ * handlers — the throw site is gone and the catch is dead code. If you were
159
+ * relying on the throw to detect bad payloads, switch to declaring the
160
+ * relevant GSI half as `'sparse'` (the consumer-side semantic that always
161
+ * matches the throw's intent — drop the index entry on can't-compose) or
162
+ * supply the surviving composites via `set` in the same update.
163
+ */
164
+ export class CompositeKeyHoleError extends Data.TaggedError("CompositeKeyHoleError") {
165
+ }
166
+ /**
167
+ * Build a {@link CompositeKeyHoleError} with a formatted message.
168
+ *
169
+ * @deprecated Since v1.7.1 this builder is unused — no code path raises EDD-9024
170
+ * at runtime. Kept exported only for back-compat with consumers who imported
171
+ * the helper. See {@link CompositeKeyHoleError} for the migration path.
172
+ */
173
+ export const makeCompositeKeyHoleError = (params) => new CompositeKeyHoleError({
174
+ ...params,
175
+ message: `[EDD-9024 — DEPRECATED] Composite key hole on GSI "${params.indexName}" of entity "${params.entityType}": ` +
176
+ `composite "${params.clearedComposite}" at ${params.key} position ${params.clearedPosition} is absent, ` +
177
+ `but composite "${params.trailingComposite}" at ${params.key} position ${params.trailingPosition} is still present. ` +
178
+ `Since v1.7.1 this error is no longer thrown — hole patterns collapse into the unified per-half can't-compose rule ` +
179
+ `(REMOVE the half under 'sparse' or removedSet cascade; noop under 'preserve' without removedSet).`,
180
+ });
181
+ /**
182
+ * EDD-9025 — A composite attribute on `primaryKey`, `indexes`, or a `unique`
183
+ * constraint has a Schema whose type union includes `null`. Composites
184
+ * participate in string composition (`acc#X#alert#Y`); `null` is not a
185
+ * meaningful slot value — only present-with-value or absent. Allowing
186
+ * `Schema.NullOr` / `Schema.NullishOr` / `Schema.Union([..., Schema.Null])`
187
+ * on a composite would let `set({ composite: null })` typecheck, then either
188
+ * blow up at runtime or silently produce a key with the literal string
189
+ * `"null"` as a slot.
190
+ *
191
+ * Raised at `Entity.make()` time. The error names the entity, the
192
+ * surface where the composite is declared (primary key / a GSI / a unique
193
+ * constraint), the offending composite attribute, and the resolved Schema
194
+ * path that contains `null`.
195
+ *
196
+ * Resolution: declare the attribute as `Schema.optional(...)` (which
197
+ * produces `T | undefined` without `null`). Sparse-pattern usage is fully
198
+ * supported under v3's two-way payload classification — `undefined` is
199
+ * "absent" for GSI composition purposes.
200
+ *
201
+ * See `DESIGN.md §7 Policy-Aware GSI Composition` (EDD-9025 footgun gate).
202
+ */
203
+ export class CompositeNullableError extends Data.TaggedError("CompositeNullableError") {
204
+ }
205
+ /**
206
+ * Build a {@link CompositeNullableError} with a formatted message. Centralises
207
+ * the message format so call sites (Entity.make validation paths) stay
208
+ * consistent.
209
+ */
210
+ export const makeCompositeNullableError = (params) => new CompositeNullableError({
211
+ ...params,
212
+ message: `[EDD-9025] Entity "${params.entityType}": composite attribute "${params.compositeAttribute}" ` +
213
+ `on ${params.surface} resolves to a Schema that includes \`null\` (${params.schemaPath}). ` +
214
+ `Composites participate in string composition and cannot be null — only present-with-value or absent. ` +
215
+ `Replace the nullable wrapper with \`Schema.optional(...)\` (T | undefined) to express the sparse ` +
216
+ `pattern, or supply a non-nullable schema for "${params.compositeAttribute}".`,
217
+ });
218
+ //# sourceMappingURL=Errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Errors.js","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"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"}