effect-dynamodb 1.9.2 → 1.9.4
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/dist/Aggregate.d.ts +3 -2
- package/dist/Aggregate.d.ts.map +1 -1
- package/dist/Aggregate.js +150 -57
- package/dist/Aggregate.js.map +1 -1
- package/dist/DynamoClient.d.ts +17 -1
- package/dist/DynamoClient.d.ts.map +1 -1
- package/dist/DynamoClient.js +12 -2
- package/dist/DynamoClient.js.map +1 -1
- package/dist/Entity.d.ts +24 -7
- package/dist/Entity.d.ts.map +1 -1
- package/dist/Entity.js +102 -459
- package/dist/Entity.js.map +1 -1
- package/package.json +2 -2
package/dist/Aggregate.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Created via {@link make}. Sub-aggregates compose recursively via `.with()`.
|
|
10
10
|
*/
|
|
11
|
+
import { TypeId as SchemaAggregateTypeId } from "@effect-dynamodb/schema/Aggregate.js";
|
|
11
12
|
import type * as DynamoSchemaModule from "@effect-dynamodb/schema/DynamoSchema.js";
|
|
12
13
|
import { AggregateAssemblyError, type AggregateDecompositionError, AggregateTransactionOverflow, type ItemNotFound, RefNotFound, TransactionCancelled, ValidationError } from "@effect-dynamodb/schema/Errors.js";
|
|
13
14
|
import { type Context, Effect, Schema } from "effect";
|
|
@@ -20,8 +21,8 @@ export type { AggregateInputType, BoundSubAggregate, Input, Key, SubAggregate, T
|
|
|
20
21
|
import { type UpdateContext } from "@effect-dynamodb/schema/internal/AggregateCursor.js";
|
|
21
22
|
import type { AggregateEdge } from "@effect-dynamodb/schema/internal/AggregateEdges.js";
|
|
22
23
|
import type { AggregateInputType, BoundSubAggregate, SubAggregate } from "@effect-dynamodb/schema/internal/AggregateTypes.js";
|
|
23
|
-
export declare const TypeId:
|
|
24
|
-
export type TypeId = typeof
|
|
24
|
+
export declare const TypeId: typeof SchemaAggregateTypeId;
|
|
25
|
+
export type TypeId = typeof SchemaAggregateTypeId;
|
|
25
26
|
/** Options for paginated list queries */
|
|
26
27
|
export interface ListOptions {
|
|
27
28
|
/** Maximum number of root items (aggregates) to return */
|
package/dist/Aggregate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aggregate.d.ts","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"Aggregate.d.ts","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"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"}
|
package/dist/Aggregate.js
CHANGED
|
@@ -8,14 +8,16 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Created via {@link make}. Sub-aggregates compose recursively via `.with()`.
|
|
10
10
|
*/
|
|
11
|
+
import { TypeId as SchemaAggregateTypeId } from "@effect-dynamodb/schema/Aggregate.js";
|
|
11
12
|
import * as DynamoModel from "@effect-dynamodb/schema/DynamoModel.js";
|
|
12
13
|
import { composeCollectionKey, composeKey } from "@effect-dynamodb/schema/DynamoSchema.js";
|
|
13
14
|
import { AggregateAssemblyError, AggregateTransactionOverflow, RefNotFound, TransactionCancelled, ValidationError, } from "@effect-dynamodb/schema/Errors.js";
|
|
14
|
-
import { buildDateTransform, validateNoTransformOverride, } from "@effect-dynamodb/schema/internal/EntitySchemas.js";
|
|
15
|
+
import { buildDateTransform, substituteSchemaDeep, validateNoTransformOverride, } from "@effect-dynamodb/schema/internal/EntitySchemas.js";
|
|
15
16
|
import * as KeyComposer from "@effect-dynamodb/schema/KeyComposer.js";
|
|
16
17
|
import { Effect, Schema, SchemaAST } from "effect";
|
|
17
18
|
import * as Batch from "./Batch.js";
|
|
18
19
|
import { DynamoClient } from "./DynamoClient.js";
|
|
20
|
+
import { fromDefinition as entityFromDefinition } from "./Entity.js";
|
|
19
21
|
import { fromAttributeMap, toAttributeMap, toAttributeValue } from "./Marshaller.js";
|
|
20
22
|
// Internal modules (decomposed from Aggregate.ts)
|
|
21
23
|
export { isManyEdge, isOneEdge, isRefEdge, many, one, ref, } from "@effect-dynamodb/schema/internal/AggregateEdges.js";
|
|
@@ -25,7 +27,13 @@ import { deriveAggregateSchemas, deriveEntityFieldName, } from "@effect-dynamodb
|
|
|
25
27
|
// ---------------------------------------------------------------------------
|
|
26
28
|
// TypeId
|
|
27
29
|
// ---------------------------------------------------------------------------
|
|
28
|
-
export
|
|
30
|
+
// Re-export the schema package's TypeId rather than declaring a second
|
|
31
|
+
// `unique symbol`. Both resolve to the same registered `Symbol.for` at runtime,
|
|
32
|
+
// but two separate `unique symbol` declarations are NOMINALLY distinct types —
|
|
33
|
+
// which made the runtime `Aggregate` non-assignable to the pure
|
|
34
|
+
// `AggregateDefinition` it is meant to extend. Sharing one symbol type closes
|
|
35
|
+
// that dual-package hazard.
|
|
36
|
+
export const TypeId = SchemaAggregateTypeId;
|
|
29
37
|
export function make(schema, config) {
|
|
30
38
|
if (!("table" in config) || config.table === undefined) {
|
|
31
39
|
// Sub-aggregate form
|
|
@@ -122,6 +130,46 @@ const inferDateEncoding = (ast) => {
|
|
|
122
130
|
}
|
|
123
131
|
return undefined;
|
|
124
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* Build per-field date ENCODERS for a schema's own date fields. Encoders convert
|
|
135
|
+
* a domain date value to its wire primitive on the WRITE path — decompose works
|
|
136
|
+
* from the schema-decoded domain object, so EVERY date field (Pattern A self-date
|
|
137
|
+
* AND Pattern B transform) must serialize for storage. The READ path is handled
|
|
138
|
+
* entirely by the aggregate's tolerant `decodeSchema` (see `makeAggregate`), so
|
|
139
|
+
* no separate decoders are needed.
|
|
140
|
+
*/
|
|
141
|
+
const buildDateEncoders = (fields) => {
|
|
142
|
+
const encoders = {};
|
|
143
|
+
if (fields) {
|
|
144
|
+
for (const field of Object.keys(fields)) {
|
|
145
|
+
const fieldSchema = fields[field];
|
|
146
|
+
// Precedence: explicit `DynamoModel.storedAs` annotation > inferred default
|
|
147
|
+
// for standard Effect date schemas (handles `Schema.optional()` wrappers).
|
|
148
|
+
const encoding = DynamoModel.getEncoding(fieldSchema) ?? inferDateEncoding(fieldSchema.ast);
|
|
149
|
+
if (!encoding)
|
|
150
|
+
continue;
|
|
151
|
+
const encode = Schema.encodeUnknownSync(buildDateTransform(encoding));
|
|
152
|
+
encoders[field] = (value) => encode(value);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return encoders;
|
|
156
|
+
};
|
|
157
|
+
/** A schema's declared fields, if it exposes them (Schema.Struct / Schema.Class). */
|
|
158
|
+
const fieldsOf = (schema) => schema?.fields;
|
|
159
|
+
/**
|
|
160
|
+
* Apply a node's date encoders in place — converts the node entity's own domain
|
|
161
|
+
* date fields to their wire primitives before the decomposed item is marshalled
|
|
162
|
+
* (issue #72: without this, an edge's `DateTime` field marshals to `{M:{}}` and
|
|
163
|
+
* the subsequent `get`/assemble fails decoding it as a string).
|
|
164
|
+
*/
|
|
165
|
+
const applyNodeDateEncoders = (attrs, encoders) => {
|
|
166
|
+
if (!encoders)
|
|
167
|
+
return;
|
|
168
|
+
for (const [field, encode] of Object.entries(encoders)) {
|
|
169
|
+
if (field in attrs && attrs[field] != null)
|
|
170
|
+
attrs[field] = encode(attrs[field]);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
125
173
|
// ---------------------------------------------------------------------------
|
|
126
174
|
// Top-level aggregate construction
|
|
127
175
|
// ---------------------------------------------------------------------------
|
|
@@ -145,8 +193,6 @@ const makeAggregate = (schema, config) => {
|
|
|
145
193
|
// (e.g. `Schema.DateTimeUtcFromString`) cannot be combined with a
|
|
146
194
|
// `DynamoModel.storedAs(...)` annotation that conflicts with the
|
|
147
195
|
// transform's wire kind — same rule as Entity.
|
|
148
|
-
const dateEncoders = {};
|
|
149
|
-
const dateDecoders = {};
|
|
150
196
|
const schemaFields = schema.fields;
|
|
151
197
|
if (schemaFields) {
|
|
152
198
|
// Reject transform + storedAs annotation conflicts (Option (b) policy).
|
|
@@ -154,29 +200,46 @@ const makeAggregate = (schema, config) => {
|
|
|
154
200
|
// so we pass an empty `configuredAttributes` map — only the schema-level
|
|
155
201
|
// annotation conflict is checked.
|
|
156
202
|
validateNoTransformOverride(schemaFields, {});
|
|
157
|
-
for (const field of Object.keys(schemaFields)) {
|
|
158
|
-
const fieldSchema = schemaFields[field];
|
|
159
|
-
const explicit = DynamoModel.getEncoding(fieldSchema);
|
|
160
|
-
let encoding;
|
|
161
|
-
if (explicit) {
|
|
162
|
-
encoding = explicit;
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
// Infer for standard Effect date schemas (Schema.Date, DateTime, etc.)
|
|
166
|
-
// For optional fields (Union with Undefined), unwrap to find the inner type.
|
|
167
|
-
const inferred = inferDateEncoding(fieldSchema.ast);
|
|
168
|
-
if (inferred)
|
|
169
|
-
encoding = inferred;
|
|
170
|
-
}
|
|
171
|
-
if (encoding) {
|
|
172
|
-
const transform = buildDateTransform(encoding);
|
|
173
|
-
const encode = Schema.encodeUnknownSync(transform);
|
|
174
|
-
const decode = Schema.decodeUnknownSync(transform);
|
|
175
|
-
dateEncoders[field] = (value) => encode(value);
|
|
176
|
-
dateDecoders[field] = (stored) => decode(stored);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
203
|
}
|
|
204
|
+
// Date ENCODERS for the write path: decompose works from the schema-decoded
|
|
205
|
+
// domain object, so every root date field (Pattern A self-date AND Pattern B
|
|
206
|
+
// transform) is serialized to its wire primitive for storage.
|
|
207
|
+
const dateEncoders = buildDateEncoders(schemaFields);
|
|
208
|
+
// Decode schema for read/assemble + input validation. Mirrors the raw `schema`
|
|
209
|
+
// but recursively substitutes EVERY date / Redacted leaf — root and nested,
|
|
210
|
+
// Pattern A and Pattern B — with a TOLERANT transform. This is the single
|
|
211
|
+
// decode path for get / create / update:
|
|
212
|
+
// - reads supply the stored wire form (string/number) → lifted to domain;
|
|
213
|
+
// - update re-decodes the mutated state, which carries domain `DateTime`
|
|
214
|
+
// values → accepted as-is (a strict `*FromString` decoder would reject
|
|
215
|
+
// them). It is decode-only, so making transforms tolerant is safe — the
|
|
216
|
+
// stored wire format is still produced by `dateEncoders` / node encoders.
|
|
217
|
+
// Nested edge / ref classes round-trip with their class instance identity
|
|
218
|
+
// preserved (Option A). Returns the raw `schema` unchanged when it carries no
|
|
219
|
+
// date / Redacted leaf at all (zero overhead).
|
|
220
|
+
//
|
|
221
|
+
// SINGLE ref/one edge fields carry the opaque `DynamoModel.ref` annotation, so
|
|
222
|
+
// the substitution can't introspect them — `resolveRef` re-points each to its
|
|
223
|
+
// edge target model (unwrapping `DynamoModel.configure`). MANY edges are
|
|
224
|
+
// excluded: their model field is a `Schema.Array(...)` (or a wrapper class) that
|
|
225
|
+
// `substituteSchemaDeep` introspects directly — re-pointing it at the element
|
|
226
|
+
// model would drop the `Array` and yield "Expected object, got []" on assemble.
|
|
227
|
+
const edgeRefModels = new Map();
|
|
228
|
+
for (const [edgeName, edge] of Object.entries(config.edges)) {
|
|
229
|
+
if (!("_tag" in edge))
|
|
230
|
+
continue;
|
|
231
|
+
if (edge._tag !== "RefEdge" && edge._tag !== "OneEdge")
|
|
232
|
+
continue;
|
|
233
|
+
const entity = edge.entity;
|
|
234
|
+
const model = entity?.model;
|
|
235
|
+
if (!model)
|
|
236
|
+
continue;
|
|
237
|
+
edgeRefModels.set(edgeName, DynamoModel.isConfiguredModel(model) ? model.model : model);
|
|
238
|
+
}
|
|
239
|
+
const decodeSchema = substituteSchemaDeep(schema, {
|
|
240
|
+
tolerantTransforms: true,
|
|
241
|
+
resolveRef: (name) => edgeRefModels.get(name),
|
|
242
|
+
});
|
|
180
243
|
// Build optics at construction time (once per aggregate definition)
|
|
181
244
|
const classToPlain = Schema.toIso(schema);
|
|
182
245
|
const opticRoot = Schema.toIsoFocus(schema);
|
|
@@ -219,7 +282,7 @@ const makeAggregate = (schema, config) => {
|
|
|
219
282
|
key,
|
|
220
283
|
});
|
|
221
284
|
}
|
|
222
|
-
const result = yield* assembleAggregate(
|
|
285
|
+
const result = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
|
|
223
286
|
return result;
|
|
224
287
|
}),
|
|
225
288
|
create: (input) => Effect.gen(function* () {
|
|
@@ -227,8 +290,10 @@ const makeAggregate = (schema, config) => {
|
|
|
227
290
|
const tableConfig = yield* config.table.Tag;
|
|
228
291
|
// 1. Hydrate refs from edges
|
|
229
292
|
const hydrated = yield* hydrateAggregateRefs(input, config.edges, aggregateName);
|
|
230
|
-
// 2. Validate via schema decode
|
|
231
|
-
|
|
293
|
+
// 2. Validate via schema decode (decodeSchema substitutes nested edge
|
|
294
|
+
// self-date/Redacted leaves — Option A — and is identical to `schema`
|
|
295
|
+
// when no edge needs it).
|
|
296
|
+
const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(hydrated).pipe(Effect.mapError((cause) => new ValidationError({
|
|
232
297
|
entityType: aggregateName,
|
|
233
298
|
operation: "aggregate.create",
|
|
234
299
|
cause,
|
|
@@ -257,7 +322,7 @@ const makeAggregate = (schema, config) => {
|
|
|
257
322
|
});
|
|
258
323
|
}
|
|
259
324
|
// 1. Assemble current state
|
|
260
|
-
const current = yield* assembleAggregate(
|
|
325
|
+
const current = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
|
|
261
326
|
// 2. Apply mutation — provide optics context for composable updates
|
|
262
327
|
const state = classToPlain.get(current);
|
|
263
328
|
const updated = mutationFn({
|
|
@@ -266,8 +331,12 @@ const makeAggregate = (schema, config) => {
|
|
|
266
331
|
optic: opticRoot,
|
|
267
332
|
current: current,
|
|
268
333
|
});
|
|
269
|
-
// 3. Validate
|
|
270
|
-
|
|
334
|
+
// 3. Validate the mutated state via `decodeSchema` — its tolerant date
|
|
335
|
+
// transforms accept the domain `DateTime` values the mutation yields
|
|
336
|
+
// for every date field (root + nested edges, Pattern A and Pattern B),
|
|
337
|
+
// so update no longer trips the "Expected string, got DateTime" decode
|
|
338
|
+
// that a strict `*FromString` schema would raise (#72 update path).
|
|
339
|
+
const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(updated).pipe(Effect.mapError((cause) => new ValidationError({
|
|
271
340
|
entityType: aggregateName,
|
|
272
341
|
operation: "aggregate.update",
|
|
273
342
|
cause,
|
|
@@ -378,7 +447,7 @@ const makeAggregate = (schema, config) => {
|
|
|
378
447
|
const { allItems } = yield* fetchPartition(key);
|
|
379
448
|
if (allItems.length === 0)
|
|
380
449
|
return undefined;
|
|
381
|
-
const result = yield* assembleAggregate(
|
|
450
|
+
const result = yield* assembleAggregate(decodeSchema, rootNode, allItems, contextFields, key, aggregateName);
|
|
382
451
|
return result;
|
|
383
452
|
});
|
|
384
453
|
if (assembled !== undefined)
|
|
@@ -454,7 +523,7 @@ const deepEqualGroups = (a, b) => {
|
|
|
454
523
|
// ---------------------------------------------------------------------------
|
|
455
524
|
// Internal: Resolve the graph
|
|
456
525
|
// ---------------------------------------------------------------------------
|
|
457
|
-
const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, assemble, decompose, ownDiscriminator) => {
|
|
526
|
+
const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, assemble, decompose, ownDiscriminator, dateEncoders) => {
|
|
458
527
|
const children = [];
|
|
459
528
|
for (const [field, edge] of Object.entries(edges)) {
|
|
460
529
|
if ("_tag" in edge) {
|
|
@@ -463,14 +532,19 @@ const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, a
|
|
|
463
532
|
const mergedDisc = edge.discriminator
|
|
464
533
|
? { ...(discriminator ?? {}), ...edge.discriminator }
|
|
465
534
|
: discriminator;
|
|
466
|
-
children.push(resolveNode(field, edge.entityType, "one", {}, mergedDisc, undefined, undefined, edge.discriminator
|
|
535
|
+
children.push(resolveNode(field, edge.entityType, "one", {}, mergedDisc, undefined, undefined, edge.discriminator,
|
|
536
|
+
// Encode this edge entity's own date fields on write (issue #72).
|
|
537
|
+
buildDateEncoders(fieldsOf(edge.entity?.model))));
|
|
467
538
|
}
|
|
468
539
|
else if (edge._tag === "ManyEdge") {
|
|
469
|
-
children.push(resolveNode(field, edge.entityType, "many", {}, discriminator, edge.assemble, edge.decompose));
|
|
540
|
+
children.push(resolveNode(field, edge.entityType, "many", {}, discriminator, edge.assemble, edge.decompose, undefined, buildDateEncoders(fieldsOf(edge.entity?.model))));
|
|
470
541
|
}
|
|
471
542
|
else if (edge._tag === "BoundSubAggregate") {
|
|
472
543
|
const bound = edge;
|
|
473
|
-
const subChildren = resolveNode(field, bound.aggregate.root.entityType, "one", bound.aggregate.edges, bound.discriminator, undefined, undefined, bound.discriminator
|
|
544
|
+
const subChildren = resolveNode(field, bound.aggregate.root.entityType, "one", bound.aggregate.edges, bound.discriminator, undefined, undefined, bound.discriminator,
|
|
545
|
+
// The sub-aggregate root item carries the sub-schema's own (non-edge)
|
|
546
|
+
// date fields; its child edges get their own encoders via recursion.
|
|
547
|
+
buildDateEncoders(fieldsOf(bound.aggregate.schema)));
|
|
474
548
|
children.push(subChildren);
|
|
475
549
|
}
|
|
476
550
|
}
|
|
@@ -484,6 +558,7 @@ const resolveNode = (fieldName, entityType, cardinality, edges, discriminator, a
|
|
|
484
558
|
children,
|
|
485
559
|
assemble,
|
|
486
560
|
decompose,
|
|
561
|
+
dateEncoders,
|
|
487
562
|
};
|
|
488
563
|
};
|
|
489
564
|
// ---------------------------------------------------------------------------
|
|
@@ -514,7 +589,7 @@ const queryAllItems = (client, tableName, indexName, pkField, pkValue) => Effect
|
|
|
514
589
|
// ---------------------------------------------------------------------------
|
|
515
590
|
// Internal: Assembly algorithm
|
|
516
591
|
// ---------------------------------------------------------------------------
|
|
517
|
-
const assembleAggregate = (
|
|
592
|
+
const assembleAggregate = (decodeSchema, rootNode, allItems, _contextFields, key, aggregateName) => Effect.gen(function* () {
|
|
518
593
|
// Find the root item
|
|
519
594
|
const rootItems = allItems.filter((item) => item.__edd_e__ === rootNode.entityType);
|
|
520
595
|
if (rootItems.length === 0) {
|
|
@@ -567,19 +642,12 @@ const assembleAggregate = (schema, rootNode, allItems, _contextFields, dateDecod
|
|
|
567
642
|
continue;
|
|
568
643
|
rootFields[fieldKey] = value;
|
|
569
644
|
}
|
|
570
|
-
//
|
|
571
|
-
// Schema.decodeUnknownEffect expects domain types (Date, DateTime), not encoded strings.
|
|
572
|
-
// The decoder is the substituted bidirectional date schema built at make() time —
|
|
573
|
-
// identical wire format to the legacy `deserializeDateFromDynamo` helper.
|
|
574
|
-
for (const [field, decode] of Object.entries(dateDecoders)) {
|
|
575
|
-
if (field in rootFields && rootFields[field] != null) {
|
|
576
|
-
rootFields[field] = decode(rootFields[field]);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
// Merge root fields with assembled edge values
|
|
645
|
+
// Merge raw (wire-form) root fields with assembled edge items.
|
|
580
646
|
const assembled = { ...rootFields, ...edgeValues };
|
|
581
|
-
// Decode through the aggregate
|
|
582
|
-
|
|
647
|
+
// Decode through `decodeSchema` — a tolerant clone of the aggregate schema
|
|
648
|
+
// that lifts every date / Redacted leaf (root + nested edges) from the stored
|
|
649
|
+
// wire form to its domain value in a single pass (#72 + Option A).
|
|
650
|
+
const decoded = yield* Schema.decodeUnknownEffect(decodeSchema)(assembled).pipe(Effect.mapError((cause) => new ValidationError({
|
|
583
651
|
entityType: aggregateName,
|
|
584
652
|
operation: "aggregate.assemble",
|
|
585
653
|
cause,
|
|
@@ -709,15 +777,22 @@ const hydrateAggregateRefs = (input, edges, aggregateName) => Effect.gen(functio
|
|
|
709
777
|
const identifierName = idField?.name ?? "id";
|
|
710
778
|
// Deduplicate IDs for this entity type
|
|
711
779
|
const uniqueIds = [...new Set(reqs.map((r) => r.id))];
|
|
712
|
-
// `RefEntity` is the pure structural bound (no `get` — issue #66)
|
|
713
|
-
//
|
|
714
|
-
//
|
|
715
|
-
//
|
|
716
|
-
|
|
780
|
+
// `RefEntity` is the pure structural bound (no `get` — issue #66): aggregate
|
|
781
|
+
// edges can be authored from AWS-free `@effect-dynamodb/schema` definitions,
|
|
782
|
+
// which carry no runtime `.get`/operations. Ref hydration is a runtime
|
|
783
|
+
// operation, so promote a pure edge target to a full operational Entity (a
|
|
784
|
+
// thin op-attach over its retained `_data`); runtime-authored targets already
|
|
785
|
+
// carry `.get` and pass through untouched. Mirrors `DynamoClient.make()`'s
|
|
786
|
+
// entity binding. The promoted entity also exposes `.schemas`, used by the
|
|
787
|
+
// encode-back below (issue #72). The loop is already grouped by entity type,
|
|
788
|
+
// so this promotes once per distinct edge entity type per hydrate (issue #71).
|
|
789
|
+
const runtimeEntity = (typeof entity.get === "function"
|
|
790
|
+
? entity
|
|
791
|
+
: entityFromDefinition(entity));
|
|
717
792
|
// Build EntityGet intermediates for batch fetching
|
|
718
793
|
const getOps = uniqueIds.map((id) => runtimeEntity.get({ [identifierName]: id }));
|
|
719
794
|
const results = yield* Batch.get(getOps);
|
|
720
|
-
// Map results back to lookup, failing on missing refs
|
|
795
|
+
// Map results back to lookup, failing on missing refs.
|
|
721
796
|
for (let i = 0; i < uniqueIds.length; i++) {
|
|
722
797
|
const id = uniqueIds[i];
|
|
723
798
|
const result = results[i];
|
|
@@ -729,7 +804,19 @@ const hydrateAggregateRefs = (input, edges, aggregateName) => Effect.gen(functio
|
|
|
729
804
|
refId: id,
|
|
730
805
|
});
|
|
731
806
|
}
|
|
732
|
-
|
|
807
|
+
// `Batch.get` returns the DECODED record — transform fields are lifted to
|
|
808
|
+
// their domain form (e.g. `Schema.DateTimeUtcFromString` → `DateTime`). The
|
|
809
|
+
// denormalized ref is spliced into `input` and decoded again by the
|
|
810
|
+
// aggregate's strict `schema`, whose nested edge field is the ORIGINAL ref
|
|
811
|
+
// class expecting the wire form. Re-encode through the ref's substituted
|
|
812
|
+
// `recordSchema` so the spliced value is wire-form and decoded exactly once
|
|
813
|
+
// (issue #72) — this also keeps it marshall-safe for decompose.
|
|
814
|
+
const wire = yield* Schema.encodeUnknownEffect(runtimeEntity.schemas.recordSchema)(result).pipe(Effect.mapError((cause) => new ValidationError({
|
|
815
|
+
entityType: aggregateName,
|
|
816
|
+
operation: "aggregate.hydrateRefs.encode",
|
|
817
|
+
cause,
|
|
818
|
+
})));
|
|
819
|
+
hydratedLookup.set(`${entityType}:${id}`, wire);
|
|
733
820
|
}
|
|
734
821
|
}
|
|
735
822
|
// Walk the input again and replace IDs with hydrated data
|
|
@@ -956,6 +1043,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
|
|
|
956
1043
|
continue;
|
|
957
1044
|
subRootAttrs[key] = val;
|
|
958
1045
|
}
|
|
1046
|
+
// Serialize this node's own date fields to their wire primitive (#72).
|
|
1047
|
+
applyNodeDateEncoders(subRootAttrs, node.dateEncoders);
|
|
959
1048
|
// Inject context and discriminator
|
|
960
1049
|
mergeContextValues(subRootAttrs, contextValues);
|
|
961
1050
|
if (node.discriminator) {
|
|
@@ -979,6 +1068,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
|
|
|
979
1068
|
else if (node.cardinality === "one") {
|
|
980
1069
|
// Simple one-to-one edge (no children)
|
|
981
1070
|
const attrs = { ...value };
|
|
1071
|
+
// Serialize this edge entity's own date fields to their wire primitive (#72).
|
|
1072
|
+
applyNodeDateEncoders(attrs, node.dateEncoders);
|
|
982
1073
|
mergeContextValues(attrs, contextValues);
|
|
983
1074
|
if (node.discriminator) {
|
|
984
1075
|
for (const [k, v] of Object.entries(node.discriminator)) {
|
|
@@ -1008,6 +1099,8 @@ const decomposeNode = (items, node, value, contextValues, parentGroup, parentDis
|
|
|
1008
1099
|
: [];
|
|
1009
1100
|
for (const elem of arrayItems) {
|
|
1010
1101
|
const attrs = { ...elem };
|
|
1102
|
+
// Serialize this edge entity's own date fields to their wire primitive (#72).
|
|
1103
|
+
applyNodeDateEncoders(attrs, node.dateEncoders);
|
|
1011
1104
|
mergeContextValues(attrs, contextValues);
|
|
1012
1105
|
if (node.discriminator) {
|
|
1013
1106
|
for (const [k, v] of Object.entries(node.discriminator)) {
|