@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.
- package/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/Aggregate.d.ts +128 -0
- package/dist/Aggregate.d.ts.map +1 -0
- package/dist/Aggregate.js +69 -0
- package/dist/Aggregate.js.map +1 -0
- package/dist/DynamoModel.d.ts +370 -0
- package/dist/DynamoModel.d.ts.map +1 -0
- package/dist/DynamoModel.js +541 -0
- package/dist/DynamoModel.js.map +1 -0
- package/dist/DynamoSchema.d.ts +137 -0
- package/dist/DynamoSchema.d.ts.map +1 -0
- package/dist/DynamoSchema.js +188 -0
- package/dist/DynamoSchema.js.map +1 -0
- package/dist/Entity.d.ts +239 -0
- package/dist/Entity.d.ts.map +1 -0
- package/dist/Entity.js +558 -0
- package/dist/Entity.js.map +1 -0
- package/dist/Errors.d.ts +387 -0
- package/dist/Errors.d.ts.map +1 -0
- package/dist/Errors.js +218 -0
- package/dist/Errors.js.map +1 -0
- package/dist/KeyComposer.d.ts +264 -0
- package/dist/KeyComposer.d.ts.map +1 -0
- package/dist/KeyComposer.js +516 -0
- package/dist/KeyComposer.js.map +1 -0
- package/dist/Projection.d.ts +28 -0
- package/dist/Projection.d.ts.map +1 -0
- package/dist/Projection.js +39 -0
- package/dist/Projection.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/AggregateCursor.d.ts +44 -0
- package/dist/internal/AggregateCursor.d.ts.map +1 -0
- package/dist/internal/AggregateCursor.js +18 -0
- package/dist/internal/AggregateCursor.js.map +1 -0
- package/dist/internal/AggregateEdges.d.ts +117 -0
- package/dist/internal/AggregateEdges.d.ts.map +1 -0
- package/dist/internal/AggregateEdges.js +51 -0
- package/dist/internal/AggregateEdges.js.map +1 -0
- package/dist/internal/AggregateSchemas.d.ts +76 -0
- package/dist/internal/AggregateSchemas.d.ts.map +1 -0
- package/dist/internal/AggregateSchemas.js +164 -0
- package/dist/internal/AggregateSchemas.js.map +1 -0
- package/dist/internal/AggregateTypes.d.ts +132 -0
- package/dist/internal/AggregateTypes.d.ts.map +1 -0
- package/dist/internal/AggregateTypes.js +7 -0
- package/dist/internal/AggregateTypes.js.map +1 -0
- package/dist/internal/DefaultCrypto.d.ts +26 -0
- package/dist/internal/DefaultCrypto.d.ts.map +1 -0
- package/dist/internal/DefaultCrypto.js +40 -0
- package/dist/internal/DefaultCrypto.js.map +1 -0
- package/dist/internal/EntityConfig.d.ts +152 -0
- package/dist/internal/EntityConfig.d.ts.map +1 -0
- package/dist/internal/EntityConfig.js +7 -0
- package/dist/internal/EntityConfig.js.map +1 -0
- package/dist/internal/EntitySchemas.d.ts +198 -0
- package/dist/internal/EntitySchemas.d.ts.map +1 -0
- package/dist/internal/EntitySchemas.js +798 -0
- package/dist/internal/EntitySchemas.js.map +1 -0
- package/dist/internal/EntityTypes.d.ts +233 -0
- package/dist/internal/EntityTypes.d.ts.map +1 -0
- package/dist/internal/EntityTypes.js +7 -0
- package/dist/internal/EntityTypes.js.map +1 -0
- package/dist/internal/SchemaAccessors.d.ts +90 -0
- package/dist/internal/SchemaAccessors.d.ts.map +1 -0
- package/dist/internal/SchemaAccessors.js +171 -0
- package/dist/internal/SchemaAccessors.js.map +1 -0
- package/package.json +70 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @effect-dynamodb/schema — Pure schema/relationship-derivation layer.
|
|
3
|
+
*
|
|
4
|
+
* This package contains the AWS-free core of effect-dynamodb: the domain-model
|
|
5
|
+
* annotation system (`DynamoModel`), the application namespace (`DynamoSchema`),
|
|
6
|
+
* composite key composition (`KeyComposer`), tagged errors, and the pure
|
|
7
|
+
* `Entity` / `Aggregate` definition builders with their derived `inputSchema` /
|
|
8
|
+
* `updateSchema` / `createSchema` codecs.
|
|
9
|
+
*
|
|
10
|
+
* It has ZERO dependency on the AWS SDK — neither at runtime nor in its emitted
|
|
11
|
+
* `.d.ts` surface — so consumers can import an entity/aggregate's derived schemas
|
|
12
|
+
* (e.g. for HttpApi payloads or validation) without pulling the AWS SDK into
|
|
13
|
+
* their dependency graph or type surface.
|
|
14
|
+
*
|
|
15
|
+
* The full `effect-dynamodb` package depends on and re-exports everything here,
|
|
16
|
+
* adding the AWS runtime (DynamoClient, CRUD operations, Batch/Transaction/
|
|
17
|
+
* Collection, Marshaller).
|
|
18
|
+
*/
|
|
19
|
+
export * as Aggregate from "./Aggregate.js";
|
|
20
|
+
export * as DynamoModel from "./DynamoModel.js";
|
|
21
|
+
export * as DynamoSchema from "./DynamoSchema.js";
|
|
22
|
+
export * as Entity from "./Entity.js";
|
|
23
|
+
export { AggregateAssemblyError, AggregateDecompositionError, AggregateTransactionOverflow, CascadePartialFailure, CompositeKeyHoleError, CompositeNullableError, ConditionalCheckFailed, DynamoError, DynamoValidationError, InternalServerError, ItemDeleted, ItemNotDeleted, ItemNotFound, makeCompositeKeyHoleError, makeCompositeNullableError, OptimisticLockError, RefNotFound, ResourceNotFoundError, StaleAppend, ThrottlingError, TransactionCancelled, TransactionOverflow, UniqueConstraintViolation, ValidationError, VersionConflict, } from "./Errors.js";
|
|
24
|
+
export * as KeyComposer from "./KeyComposer.js";
|
|
25
|
+
export * as Projection from "./Projection.js";
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAMjD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAA;AAmBpB,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate cursor and update context types.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
import type { Optic } from "effect";
|
|
7
|
+
/**
|
|
8
|
+
* A pre-bound optic rooted at the current aggregate state.
|
|
9
|
+
* Navigate with `.key()`, `.optionalKey()`, or `.at()`, then apply terminals
|
|
10
|
+
* `.get()`, `.replace()`, or `.modify()` — no need to pass the source explicitly.
|
|
11
|
+
* For composing externally-defined optics, use `optic` + `state`.
|
|
12
|
+
*/
|
|
13
|
+
export interface Cursor<S, A = S> {
|
|
14
|
+
/** Focus on a required key */
|
|
15
|
+
readonly key: <K extends keyof A & string>(k: K) => Cursor<S, A[K]>;
|
|
16
|
+
/** Focus on an optional key (narrows away `undefined`) */
|
|
17
|
+
readonly optionalKey: <K extends keyof A & string>(k: K) => Cursor<S, NonNullable<A[K]>>;
|
|
18
|
+
/** Focus on an array element by index (available when focused on an array) */
|
|
19
|
+
readonly at: A extends ReadonlyArray<infer E> ? (index: number) => Cursor<S, E> : never;
|
|
20
|
+
/** Read the focused value (returns `undefined` for absent optional/indexed focuses) */
|
|
21
|
+
readonly get: () => A;
|
|
22
|
+
/** Replace the focused value, returning the full updated state */
|
|
23
|
+
readonly replace: (value: A) => S;
|
|
24
|
+
/** Modify the focused value with a function, returning the full updated state */
|
|
25
|
+
readonly modify: (f: (a: A) => A) => S;
|
|
26
|
+
}
|
|
27
|
+
/** @internal Build a cursor by binding a source value into an optic */
|
|
28
|
+
export declare const makeCursor: <S>(source: S, optic: Optic.Iso<S, S>) => Cursor<S, S>;
|
|
29
|
+
/** Context provided to the aggregate update mutation function */
|
|
30
|
+
export interface UpdateContext<TIso, TClass = unknown> {
|
|
31
|
+
/** The current aggregate state as a plain object */
|
|
32
|
+
readonly state: TIso;
|
|
33
|
+
/** Pre-bound cursor — navigate with `.key()`, then `.get()` / `.replace()` / `.modify()` */
|
|
34
|
+
readonly cursor: Cursor<TIso>;
|
|
35
|
+
/** Composable optic rooted at the plain type — use with externally-defined lenses and `state` */
|
|
36
|
+
readonly optic: Optic.Iso<TIso, TIso>;
|
|
37
|
+
/** The current state as a Schema.Class instance (rarely needed) */
|
|
38
|
+
readonly current: TClass;
|
|
39
|
+
}
|
|
40
|
+
/** Discriminator config for binding a sub-aggregate */
|
|
41
|
+
export interface DiscriminatorConfig {
|
|
42
|
+
readonly discriminator: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=AggregateCursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateCursor.d.ts","sourceRoot":"","sources":["../../src/internal/AggregateCursor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAMnC;;;;;GAKG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxF,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAA;IACvF,uFAAuF;IACvF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IACrB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;IACjC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;CACvC;AAED,uEAAuE;AACvE,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAU5E,CAAA;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IACnD,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;IACpB,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACrC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate cursor and update context types.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
/** @internal Build a cursor by binding a source value into an optic */
|
|
7
|
+
export const makeCursor = (source, optic) => {
|
|
8
|
+
const build = (op) => ({
|
|
9
|
+
key: (k) => build(op.key(k)),
|
|
10
|
+
optionalKey: (k) => build(op.optionalKey(k)),
|
|
11
|
+
at: ((index) => build(op.at(index))),
|
|
12
|
+
get: () => (op.get ? op.get(source) : op.getResult(source)?.value),
|
|
13
|
+
replace: (value) => op.replace(value, source),
|
|
14
|
+
modify: (f) => op.modify(f)(source),
|
|
15
|
+
});
|
|
16
|
+
return build(optic);
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=AggregateCursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateCursor.js","sourceRoot":"","sources":["../../src/internal/AggregateCursor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH,uEAAuE;AACvE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAI,MAAS,EAAE,KAAsB,EAAgB,EAAE;IAC/E,MAAM,KAAK,GAAG,CAAI,EAAO,EAAgB,EAAE,CAAC,CAAC;QAC3C,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5B,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5C,EAAE,EAAE,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAQ;QACnD,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;QAClE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;QAC7C,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;KACpC,CAAC,CAAA;IACF,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;AACrB,CAAC,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate edge descriptor types and builders.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
import type { Schema } from "effect";
|
|
7
|
+
/**
|
|
8
|
+
* Structural entity type for refs — avoids import of Entity.
|
|
9
|
+
*
|
|
10
|
+
* Generic over `model` and `indexes` so the concrete entity (including its
|
|
11
|
+
* branded primary-key identifier type) flows through the edge builders into
|
|
12
|
+
* the derived aggregate input/update types. The defaults keep the bare
|
|
13
|
+
* `RefEntity` (no type arguments) usable as a non-generic structural bound for
|
|
14
|
+
* the edge descriptors and the runtime helpers in `AggregateSchemas.ts`.
|
|
15
|
+
*
|
|
16
|
+
* `indexes` mirrors `Entity.indexes` (`{ primary: { pk: { composite } }, ... }`);
|
|
17
|
+
* `RefEntityIdentifierValue` reads `indexes.primary.pk.composite` to recover the
|
|
18
|
+
* branded id type. A wider/looser `indexes` simply falls back to `string`.
|
|
19
|
+
*/
|
|
20
|
+
export interface RefEntity<M extends Schema.Top = Schema.Top, TIndexes = unknown> {
|
|
21
|
+
readonly _tag: "Entity";
|
|
22
|
+
readonly entityType: string;
|
|
23
|
+
readonly model: M;
|
|
24
|
+
readonly indexes: TIndexes;
|
|
25
|
+
readonly schemas: {
|
|
26
|
+
readonly recordSchema: Schema.Codec<any>;
|
|
27
|
+
};
|
|
28
|
+
/** Get an entity by key — uses `any` for structural compatibility with Entity's narrower key type */
|
|
29
|
+
readonly get: (key: any) => any;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A one-to-one edge: one member item per aggregate instance.
|
|
33
|
+
*
|
|
34
|
+
* Generic over the referenced entity `E` so its branded primary-key identifier
|
|
35
|
+
* type flows into the derived aggregate input/update types via
|
|
36
|
+
* `RefEntityIdentifierValue<E>`. `E = RefEntity` (the default) preserves the
|
|
37
|
+
* non-generic shape for edges without an associated entity.
|
|
38
|
+
*/
|
|
39
|
+
export interface OneEdge<E extends RefEntity = RefEntity> {
|
|
40
|
+
readonly _tag: "OneEdge";
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly entityType: string;
|
|
43
|
+
readonly entity?: E | undefined;
|
|
44
|
+
readonly discriminator?: Record<string, unknown> | undefined;
|
|
45
|
+
}
|
|
46
|
+
/** Configuration for a many edge */
|
|
47
|
+
export interface ManyEdgeConfig<E extends RefEntity = RefEntity> {
|
|
48
|
+
readonly entityType: string;
|
|
49
|
+
readonly entity?: E | undefined;
|
|
50
|
+
readonly inputField?: string | undefined;
|
|
51
|
+
readonly edgeAttributes?: ReadonlyArray<string> | undefined;
|
|
52
|
+
readonly sk?: {
|
|
53
|
+
readonly composite: ReadonlyArray<string>;
|
|
54
|
+
} | undefined;
|
|
55
|
+
readonly assemble?: ((items: ReadonlyArray<unknown>) => unknown) | undefined;
|
|
56
|
+
readonly decompose?: ((value: unknown) => ReadonlyArray<unknown>) | undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A one-to-many edge: multiple member items per aggregate instance.
|
|
60
|
+
*
|
|
61
|
+
* Generic over the referenced entity `E` so the array element id type can be
|
|
62
|
+
* recovered as the entity's branded identifier when the element IS the ref.
|
|
63
|
+
*/
|
|
64
|
+
export interface ManyEdge<E extends RefEntity = RefEntity> {
|
|
65
|
+
readonly _tag: "ManyEdge";
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly entityType: string;
|
|
68
|
+
readonly entity?: E | undefined;
|
|
69
|
+
readonly inputField?: string | undefined;
|
|
70
|
+
readonly edgeAttributes?: ReadonlyArray<string> | undefined;
|
|
71
|
+
readonly sk?: {
|
|
72
|
+
readonly composite: ReadonlyArray<string>;
|
|
73
|
+
} | undefined;
|
|
74
|
+
readonly assemble?: ((items: ReadonlyArray<unknown>) => unknown) | undefined;
|
|
75
|
+
readonly decompose?: ((value: unknown) => ReadonlyArray<unknown>) | undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A ref edge: no decomposition, hydrates via entity, data stays inline.
|
|
79
|
+
*
|
|
80
|
+
* Generic over the referenced entity `E` so its branded identifier flows into
|
|
81
|
+
* the derived aggregate input/update types.
|
|
82
|
+
*/
|
|
83
|
+
export interface RefEdge<E extends RefEntity = RefEntity> {
|
|
84
|
+
readonly _tag: "RefEdge";
|
|
85
|
+
readonly entity: E;
|
|
86
|
+
}
|
|
87
|
+
/** Union of edge types */
|
|
88
|
+
export type AggregateEdge = OneEdge<any> | ManyEdge<any> | RefEdge<any>;
|
|
89
|
+
/**
|
|
90
|
+
* Create a one-to-one edge descriptor.
|
|
91
|
+
*
|
|
92
|
+
* Generic over the referenced entity `E` so the entity's branded primary-key
|
|
93
|
+
* identifier flows into the derived aggregate input/update types. When `entity`
|
|
94
|
+
* is omitted, `E` defaults to `RefEntity` and the edge id falls back to `string`.
|
|
95
|
+
*/
|
|
96
|
+
export declare const one: <const E extends RefEntity = RefEntity>(name: string, config: {
|
|
97
|
+
readonly entityType: string;
|
|
98
|
+
readonly entity?: E;
|
|
99
|
+
readonly discriminator?: Record<string, unknown>;
|
|
100
|
+
}) => OneEdge<E>;
|
|
101
|
+
/** Create a one-to-many edge descriptor */
|
|
102
|
+
export declare function many<const E extends RefEntity, const IF extends string>(name: string, config: ManyEdgeConfig<E> & {
|
|
103
|
+
readonly inputField: IF;
|
|
104
|
+
}): ManyEdge<E> & {
|
|
105
|
+
readonly inputField: IF;
|
|
106
|
+
};
|
|
107
|
+
export declare function many<const E extends RefEntity>(name: string, config: ManyEdgeConfig<E>): ManyEdge<E>;
|
|
108
|
+
/**
|
|
109
|
+
* Create a ref edge descriptor — no decomposition, hydrates via entity, data
|
|
110
|
+
* stays inline. Generic over `E` so the entity's branded identifier flows into
|
|
111
|
+
* the derived aggregate input/update types.
|
|
112
|
+
*/
|
|
113
|
+
export declare const ref: <const E extends RefEntity>(entity: E) => RefEdge<E>;
|
|
114
|
+
export declare const isOneEdge: (edge: AggregateEdge) => edge is OneEdge<any>;
|
|
115
|
+
export declare const isManyEdge: (edge: AggregateEdge) => edge is ManyEdge<any>;
|
|
116
|
+
export declare const isRefEdge: (edge: AggregateEdge) => edge is RefEdge<any>;
|
|
117
|
+
//# sourceMappingURL=AggregateEdges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateEdges.d.ts","sourceRoot":"","sources":["../../src/internal/AggregateEdges.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAMpC;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO;IAC9E,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;KACzC,CAAA;IACD,qGAAqG;IACrG,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAA;CAChC;AAMD;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IACtD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CAC7D;AAED,oCAAoC;AACpC,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IAC3D,QAAQ,CAAC,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,GAAG,SAAS,CAAA;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;CAC9E;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IACvD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAA;IAC3D,QAAQ,CAAC,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,GAAG,SAAS,CAAA;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;CAC9E;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IACtD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;CACnB;AAED,0BAA0B;AAC1B,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;AAMvE;;;;;;GAMG;AACH,eAAO,MAAM,GAAG,GAAI,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvD,MAAM,MAAM,EACZ,QAAQ;IACN,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjD,KACA,OAAO,CAAC,CAAC,CAMV,CAAA;AAEF,2CAA2C;AAC3C,wBAAgB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,EACrE,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAA;CAAE,GACtD,QAAQ,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAA;CAAE,CAAA;AAC5C,wBAAgB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,QAAQ,CAAC,CAAC,CAAC,CAAA;AAed;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,QAAQ,CAAC,KAAG,OAAO,CAAC,CAAC,CAGlE,CAAA;AAMF,eAAO,MAAM,SAAS,GAAI,MAAM,aAAa,KAAG,IAAI,IAAI,OAAO,CAAC,GAAG,CAA4B,CAAA;AAC/F,eAAO,MAAM,UAAU,GAAI,MAAM,aAAa,KAAG,IAAI,IAAI,QAAQ,CAAC,GAAG,CAA6B,CAAA;AAClG,eAAO,MAAM,SAAS,GAAI,MAAM,aAAa,KAAG,IAAI,IAAI,OAAO,CAAC,GAAG,CAA4B,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate edge descriptor types and builders.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Edge builders
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
/**
|
|
10
|
+
* Create a one-to-one edge descriptor.
|
|
11
|
+
*
|
|
12
|
+
* Generic over the referenced entity `E` so the entity's branded primary-key
|
|
13
|
+
* identifier flows into the derived aggregate input/update types. When `entity`
|
|
14
|
+
* is omitted, `E` defaults to `RefEntity` and the edge id falls back to `string`.
|
|
15
|
+
*/
|
|
16
|
+
export const one = (name, config) => ({
|
|
17
|
+
_tag: "OneEdge",
|
|
18
|
+
name,
|
|
19
|
+
entityType: config.entityType,
|
|
20
|
+
entity: config.entity,
|
|
21
|
+
discriminator: config.discriminator,
|
|
22
|
+
});
|
|
23
|
+
export function many(name, config) {
|
|
24
|
+
return {
|
|
25
|
+
_tag: "ManyEdge",
|
|
26
|
+
name,
|
|
27
|
+
entityType: config.entityType,
|
|
28
|
+
entity: config.entity,
|
|
29
|
+
inputField: config.inputField,
|
|
30
|
+
edgeAttributes: config.edgeAttributes,
|
|
31
|
+
sk: config.sk,
|
|
32
|
+
assemble: config.assemble,
|
|
33
|
+
decompose: config.decompose,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a ref edge descriptor — no decomposition, hydrates via entity, data
|
|
38
|
+
* stays inline. Generic over `E` so the entity's branded identifier flows into
|
|
39
|
+
* the derived aggregate input/update types.
|
|
40
|
+
*/
|
|
41
|
+
export const ref = (entity) => ({
|
|
42
|
+
_tag: "RefEdge",
|
|
43
|
+
entity,
|
|
44
|
+
});
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Type guards
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
export const isOneEdge = (edge) => edge._tag === "OneEdge";
|
|
49
|
+
export const isManyEdge = (edge) => edge._tag === "ManyEdge";
|
|
50
|
+
export const isRefEdge = (edge) => edge._tag === "RefEdge";
|
|
51
|
+
//# sourceMappingURL=AggregateEdges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateEdges.js","sourceRoot":"","sources":["../../src/internal/AggregateEdges.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgGH,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CACjB,IAAY,EACZ,MAIC,EACW,EAAE,CAAC,CAAC;IAChB,IAAI,EAAE,SAAS;IACf,IAAI;IACJ,UAAU,EAAE,MAAM,CAAC,UAAU;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,aAAa,EAAE,MAAM,CAAC,aAAa;CACpC,CAAC,CAAA;AAWF,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,MAAsB;IACvD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAA4B,MAAS,EAAc,EAAE,CAAC,CAAC;IACxE,IAAI,EAAE,SAAS;IACf,MAAM;CACP,CAAC,CAAA;AAEF,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAmB,EAAwB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAA;AAC/F,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAmB,EAAyB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAA;AAClG,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAmB,EAAwB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate schema derivation — input and update schema building.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
import { Schema } from "effect";
|
|
7
|
+
import type { AggregateEdge, RefEntity } from "./AggregateEdges.js";
|
|
8
|
+
import type { BoundSubAggregate } from "./AggregateTypes.js";
|
|
9
|
+
/**
|
|
10
|
+
* Derive an input schema from an aggregate definition.
|
|
11
|
+
*
|
|
12
|
+
* Edge-driven: walks edges to determine field transformations.
|
|
13
|
+
* - OneEdge / RefEdge fields → `${field}Id: Schema.String`
|
|
14
|
+
* - Sub-aggregate edges are recursed
|
|
15
|
+
* - Many-edge array elements are recursed for ref replacement
|
|
16
|
+
* - PK composite fields are omitted (auto-generated)
|
|
17
|
+
* - `Schema.toCodecJson` is applied at the end so Date fields accept ISO strings
|
|
18
|
+
*/
|
|
19
|
+
export interface DerivedAggregateSchemas {
|
|
20
|
+
readonly inputSchema: Schema.Top;
|
|
21
|
+
readonly updateSchema: Schema.Top;
|
|
22
|
+
}
|
|
23
|
+
export declare const deriveAggregateSchemas: (schema: Schema.Top, edges: Record<string, AggregateEdge | BoundSubAggregate<any>>, pkComposites: ReadonlyArray<string>) => DerivedAggregateSchemas;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a field schema represents an optional field.
|
|
26
|
+
*
|
|
27
|
+
* Delegates to {@link SchemaAccessors.isFieldOptional}, which uses the stable
|
|
28
|
+
* `SchemaAST.isOptional` guard. Re-exported here (and from `Aggregate.ts`) for
|
|
29
|
+
* backwards-compatible access.
|
|
30
|
+
*/
|
|
31
|
+
export declare const isFieldOptional: (fieldSchema: Schema.Top) => boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Derive a field name from an entity's model identifier.
|
|
34
|
+
* E.g., entity with model identifier "Umpire" → "umpire" (lowercase first letter).
|
|
35
|
+
*/
|
|
36
|
+
export declare const deriveEntityFieldName: (entity: RefEntity) => string;
|
|
37
|
+
/**
|
|
38
|
+
* Derive input schema for a many-edge array element.
|
|
39
|
+
* Extracts the element type from the field schema (which may be an Array
|
|
40
|
+
* or optional(Array)). If the element IS the entity (matches the entity model),
|
|
41
|
+
* transforms to Schema.String. Otherwise, finds the entity-derived field within
|
|
42
|
+
* the element and transforms it.
|
|
43
|
+
*/
|
|
44
|
+
export declare const deriveElementInputSchema: (arrayFieldSchema: Schema.Top, entity?: RefEntity) => Schema.Top | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Unwrap a ConfiguredModel to get the raw Schema.Class model.
|
|
47
|
+
* ConfiguredModel wraps the original model with DynamoDB-specific overrides
|
|
48
|
+
* (field renaming, storage encoding) and has shape { model: M, attributes: ... }.
|
|
49
|
+
*/
|
|
50
|
+
export declare const unwrapModel: (model: Schema.Top) => Schema.Top;
|
|
51
|
+
/**
|
|
52
|
+
* Check if a schema matches an entity model (same Schema.Class identifier).
|
|
53
|
+
* This is used to detect when an array element IS the entity (e.g., Array<Umpire>),
|
|
54
|
+
* as opposed to wrapping the entity (e.g., Array<{ umpire: Umpire, role: string }>).
|
|
55
|
+
* Unwraps ConfiguredModel if the entity uses DynamoModel.configure.
|
|
56
|
+
*/
|
|
57
|
+
export declare const isSchemaMatchingEntity: (schema: Schema.Top, entity: RefEntity) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Extract the element schema from a field that is `Schema.Array(T)`,
|
|
60
|
+
* `Schema.NonEmptyArray(T)`, `Schema.optionalKey(Schema.Array(T))`, or
|
|
61
|
+
* `Schema.optional(Schema.Array(T))`. Returns `T`.
|
|
62
|
+
*
|
|
63
|
+
* Delegates to {@link SchemaAccessors.extractArrayElement}, which routes
|
|
64
|
+
* through `SchemaAST.isArrays`/`isUnion` guards and the typed `.value` /
|
|
65
|
+
* `.schema` / `.members` accessors. Re-exported here (and from `Aggregate.ts`)
|
|
66
|
+
* for backwards-compatible access.
|
|
67
|
+
*/
|
|
68
|
+
export declare const extractArrayElement: (fieldSchema: Schema.Top) => Schema.Top | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Access `.fields` on a Schema.Class or Schema.Struct.
|
|
71
|
+
*
|
|
72
|
+
* Delegates to {@link SchemaAccessors.getSchemaFields} (typed `.fields`).
|
|
73
|
+
* Re-exported here (and from `Aggregate.ts`) for backwards-compatible access.
|
|
74
|
+
*/
|
|
75
|
+
export declare const getSchemaFields: (schema: Schema.Top) => Record<string, Schema.Top> | undefined;
|
|
76
|
+
//# sourceMappingURL=AggregateSchemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateSchemas.d.ts","sourceRoot":"","sources":["../../src/internal/AggregateSchemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAY,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAW5D;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,CAAA;CAClC;AAED,eAAO,MAAM,sBAAsB,GACjC,QAAQ,MAAM,CAAC,GAAG,EAClB,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAC7D,cAAc,aAAa,CAAC,MAAM,CAAC,KAClC,uBAsDF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,CAAC,GAAG,KAAG,OACxB,CAAA;AAElC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,KAAG,MAKzD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GACnC,kBAAkB,MAAM,CAAC,GAAG,EAC5B,SAAS,SAAS,KACjB,MAAM,CAAC,GAAG,GAAG,SAkCf,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,CAAC,GAAG,KAAG,MAAM,CAAC,GAMtD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,CAAC,GAAG,EAAE,QAAQ,SAAS,KAAG,OAQ9E,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,CAAC,GAAG,KAAG,MAAM,CAAC,GAAG,GAAG,SACrC,CAAA;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,CAAC,GAAG,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SACrD,CAAA"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Aggregate schema derivation — input and update schema building.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from Aggregate.ts for decomposition. Not part of the public API.
|
|
5
|
+
*/
|
|
6
|
+
import { Schema } from "effect";
|
|
7
|
+
import { ConfiguredModelTag } from "../DynamoModel.js";
|
|
8
|
+
import { extractArrayElement as extractArrayElementImpl, getSchemaFields as getSchemaFieldsImpl, isFieldOptional as isFieldOptionalImpl, } from "./SchemaAccessors.js";
|
|
9
|
+
export const deriveAggregateSchemas = (schema, edges, pkComposites) => {
|
|
10
|
+
const fields = getSchemaFields(schema);
|
|
11
|
+
if (!fields)
|
|
12
|
+
return { inputSchema: schema, updateSchema: schema };
|
|
13
|
+
const omit = new Set(pkComposites);
|
|
14
|
+
const newFields = {};
|
|
15
|
+
for (const [name, fieldSchema] of Object.entries(fields)) {
|
|
16
|
+
if (omit.has(name))
|
|
17
|
+
continue;
|
|
18
|
+
const edge = edges[name];
|
|
19
|
+
if (edge && "_tag" in edge) {
|
|
20
|
+
const isOpt = isFieldOptional(fieldSchema);
|
|
21
|
+
if (edge._tag === "RefEdge" || edge._tag === "OneEdge") {
|
|
22
|
+
// RefEdge / OneEdge → ${name}Id: Schema.String
|
|
23
|
+
newFields[`${name}Id`] = isOpt ? Schema.optionalKey(Schema.String) : Schema.String;
|
|
24
|
+
}
|
|
25
|
+
else if (edge._tag === "BoundSubAggregate") {
|
|
26
|
+
const sub = edge.aggregate;
|
|
27
|
+
const subSchemas = deriveAggregateSchemas(sub.schema, sub.edges, []);
|
|
28
|
+
newFields[name] = isOpt
|
|
29
|
+
? Schema.optionalKey(subSchemas.inputSchema)
|
|
30
|
+
: subSchemas.inputSchema;
|
|
31
|
+
}
|
|
32
|
+
else if (edge._tag === "ManyEdge") {
|
|
33
|
+
const manyEdge = edge;
|
|
34
|
+
const fieldKey = manyEdge.inputField ?? name;
|
|
35
|
+
const elemSchema = deriveElementInputSchema(fieldSchema, manyEdge.entity);
|
|
36
|
+
if (elemSchema) {
|
|
37
|
+
newFields[fieldKey] = isOpt
|
|
38
|
+
? Schema.optionalKey(Schema.Array(elemSchema))
|
|
39
|
+
: Schema.Array(elemSchema);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
newFields[fieldKey] = fieldSchema;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Regular field → keep as-is (toCodecJson applied at the end handles Date)
|
|
48
|
+
newFields[name] = fieldSchema;
|
|
49
|
+
}
|
|
50
|
+
const inputSchema = Schema.toCodecJson(Schema.Struct(newFields));
|
|
51
|
+
// Update schema: all fields optional
|
|
52
|
+
const optionalFields = {};
|
|
53
|
+
for (const [name, fieldSchema] of Object.entries(newFields)) {
|
|
54
|
+
optionalFields[name] = isFieldOptional(fieldSchema)
|
|
55
|
+
? fieldSchema
|
|
56
|
+
: Schema.optional(fieldSchema);
|
|
57
|
+
}
|
|
58
|
+
const updateSchema = Schema.toCodecJson(Schema.Struct(optionalFields));
|
|
59
|
+
return { inputSchema, updateSchema };
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Check if a field schema represents an optional field.
|
|
63
|
+
*
|
|
64
|
+
* Delegates to {@link SchemaAccessors.isFieldOptional}, which uses the stable
|
|
65
|
+
* `SchemaAST.isOptional` guard. Re-exported here (and from `Aggregate.ts`) for
|
|
66
|
+
* backwards-compatible access.
|
|
67
|
+
*/
|
|
68
|
+
export const isFieldOptional = (fieldSchema) => isFieldOptionalImpl(fieldSchema);
|
|
69
|
+
/**
|
|
70
|
+
* Derive a field name from an entity's model identifier.
|
|
71
|
+
* E.g., entity with model identifier "Umpire" → "umpire" (lowercase first letter).
|
|
72
|
+
*/
|
|
73
|
+
export const deriveEntityFieldName = (entity) => {
|
|
74
|
+
const s = entity.model;
|
|
75
|
+
const identifier = "identifier" in s && typeof s.identifier === "string" ? s.identifier : entity.entityType;
|
|
76
|
+
return identifier.charAt(0).toLowerCase() + identifier.slice(1);
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Derive input schema for a many-edge array element.
|
|
80
|
+
* Extracts the element type from the field schema (which may be an Array
|
|
81
|
+
* or optional(Array)). If the element IS the entity (matches the entity model),
|
|
82
|
+
* transforms to Schema.String. Otherwise, finds the entity-derived field within
|
|
83
|
+
* the element and transforms it.
|
|
84
|
+
*/
|
|
85
|
+
export const deriveElementInputSchema = (arrayFieldSchema, entity) => {
|
|
86
|
+
const elemSchema = extractArrayElement(arrayFieldSchema);
|
|
87
|
+
if (!elemSchema)
|
|
88
|
+
return undefined;
|
|
89
|
+
const elemFields = getSchemaFields(elemSchema);
|
|
90
|
+
// Check if the element itself IS the entity model (e.g., Array<Umpire>)
|
|
91
|
+
if (entity && elemFields && isSchemaMatchingEntity(elemSchema, entity)) {
|
|
92
|
+
// Element IS the entity → array of IDs (Schema.String)
|
|
93
|
+
return Schema.String;
|
|
94
|
+
}
|
|
95
|
+
if (!elemFields)
|
|
96
|
+
return elemSchema;
|
|
97
|
+
// Element wraps entity + attributes — find the entity-derived field and transform it
|
|
98
|
+
if (entity) {
|
|
99
|
+
const entityFieldName = deriveEntityFieldName(entity);
|
|
100
|
+
let hasChanges = false;
|
|
101
|
+
const newFields = {};
|
|
102
|
+
for (const [name, fSchema] of Object.entries(elemFields)) {
|
|
103
|
+
if (name === entityFieldName) {
|
|
104
|
+
// This field references the entity — transform to ${name}Id: Schema.String
|
|
105
|
+
const isOpt = isFieldOptional(fSchema);
|
|
106
|
+
newFields[`${name}Id`] = isOpt ? Schema.optionalKey(Schema.String) : Schema.String;
|
|
107
|
+
hasChanges = true;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
newFields[name] = fSchema;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!hasChanges)
|
|
114
|
+
return elemSchema;
|
|
115
|
+
return Schema.Struct(newFields);
|
|
116
|
+
}
|
|
117
|
+
return elemSchema;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Unwrap a ConfiguredModel to get the raw Schema.Class model.
|
|
121
|
+
* ConfiguredModel wraps the original model with DynamoDB-specific overrides
|
|
122
|
+
* (field renaming, storage encoding) and has shape { model: M, attributes: ... }.
|
|
123
|
+
*/
|
|
124
|
+
export const unwrapModel = (model) => {
|
|
125
|
+
const m = model;
|
|
126
|
+
if (m[ConfiguredModelTag] === true && "model" in m) {
|
|
127
|
+
return m.model;
|
|
128
|
+
}
|
|
129
|
+
return model;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Check if a schema matches an entity model (same Schema.Class identifier).
|
|
133
|
+
* This is used to detect when an array element IS the entity (e.g., Array<Umpire>),
|
|
134
|
+
* as opposed to wrapping the entity (e.g., Array<{ umpire: Umpire, role: string }>).
|
|
135
|
+
* Unwraps ConfiguredModel if the entity uses DynamoModel.configure.
|
|
136
|
+
*/
|
|
137
|
+
export const isSchemaMatchingEntity = (schema, entity) => {
|
|
138
|
+
const s = schema;
|
|
139
|
+
const entityModel = unwrapModel(entity.model);
|
|
140
|
+
// Compare Schema.Class identifiers
|
|
141
|
+
if ("identifier" in s && "identifier" in entityModel) {
|
|
142
|
+
return s.identifier === entityModel.identifier;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Extract the element schema from a field that is `Schema.Array(T)`,
|
|
148
|
+
* `Schema.NonEmptyArray(T)`, `Schema.optionalKey(Schema.Array(T))`, or
|
|
149
|
+
* `Schema.optional(Schema.Array(T))`. Returns `T`.
|
|
150
|
+
*
|
|
151
|
+
* Delegates to {@link SchemaAccessors.extractArrayElement}, which routes
|
|
152
|
+
* through `SchemaAST.isArrays`/`isUnion` guards and the typed `.value` /
|
|
153
|
+
* `.schema` / `.members` accessors. Re-exported here (and from `Aggregate.ts`)
|
|
154
|
+
* for backwards-compatible access.
|
|
155
|
+
*/
|
|
156
|
+
export const extractArrayElement = (fieldSchema) => extractArrayElementImpl(fieldSchema);
|
|
157
|
+
/**
|
|
158
|
+
* Access `.fields` on a Schema.Class or Schema.Struct.
|
|
159
|
+
*
|
|
160
|
+
* Delegates to {@link SchemaAccessors.getSchemaFields} (typed `.fields`).
|
|
161
|
+
* Re-exported here (and from `Aggregate.ts`) for backwards-compatible access.
|
|
162
|
+
*/
|
|
163
|
+
export const getSchemaFields = (schema) => getSchemaFieldsImpl(schema);
|
|
164
|
+
//# sourceMappingURL=AggregateSchemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AggregateSchemas.js","sourceRoot":"","sources":["../../src/internal/AggregateSchemas.ts"],"names":[],"mappings":"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"}
|