@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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Justin Menga
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @effect-dynamodb/schema
|
|
2
|
+
|
|
3
|
+
The pure, AWS-free schema and relationship-derivation layer of [`effect-dynamodb`](https://www.npmjs.com/package/effect-dynamodb).
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@effect-dynamodb/schema)
|
|
6
|
+
|
|
7
|
+
This package contains the parts of `effect-dynamodb` that do **not** touch the AWS SDK:
|
|
8
|
+
|
|
9
|
+
- `DynamoModel` — Schema annotations (`Hidden`, `identifier`, `ref`) and `configure()` field overrides.
|
|
10
|
+
- `DynamoSchema` — the application namespace (name + version) used for key prefixing.
|
|
11
|
+
- `KeyComposer` — composite key composition from index definitions.
|
|
12
|
+
- `Errors` — the tagged error hierarchy.
|
|
13
|
+
- `Entity.make` / `Aggregate.make` — **pure definition builders** that derive an entity/aggregate's
|
|
14
|
+
`inputSchema` / `updateSchema` / `createSchema` codecs.
|
|
15
|
+
|
|
16
|
+
It has **zero dependency on `@aws-sdk/*`** — neither in its runtime import graph nor in its emitted
|
|
17
|
+
`.d.ts` surface. Import it when you only need an entity/aggregate's derived schemas (for example, as
|
|
18
|
+
HTTP API payload schemas or for validation) without pulling the AWS SDK into your dependency graph or
|
|
19
|
+
type surface.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { Entity } from "@effect-dynamodb/schema"
|
|
23
|
+
import { Schema } from "effect"
|
|
24
|
+
|
|
25
|
+
class Team extends Schema.Class<Team>("Team")({
|
|
26
|
+
teamId: Schema.String,
|
|
27
|
+
name: Schema.NonEmptyString,
|
|
28
|
+
}) {}
|
|
29
|
+
|
|
30
|
+
const Teams = Entity.make({
|
|
31
|
+
model: Team,
|
|
32
|
+
entityType: "Team",
|
|
33
|
+
primaryKey: {
|
|
34
|
+
pk: { field: "pk", composite: ["teamId"] },
|
|
35
|
+
sk: { field: "sk", composite: [] },
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// The derived, fully-typed input schema — no AWS SDK in sight.
|
|
40
|
+
type TeamInput = typeof Teams.inputSchema.Type
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Relationship to `effect-dynamodb`
|
|
44
|
+
|
|
45
|
+
The full [`effect-dynamodb`](https://www.npmjs.com/package/effect-dynamodb) package **depends on and
|
|
46
|
+
re-exports** everything here, then adds the AWS runtime (DynamoClient, CRUD/query operations,
|
|
47
|
+
Batch/Transaction/Collection, Marshaller). If you need to actually read from or write to DynamoDB, use
|
|
48
|
+
`effect-dynamodb` — `import { Entity, Aggregate, DynamoModel, DynamoSchema } from "effect-dynamodb"`
|
|
49
|
+
gives you the same definition builders **plus** the operational layer.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
MIT
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregate (pure definition layer) — builds the AWS-free half of an Aggregate:
|
|
3
|
+
* the Schema.Class hierarchy binding, edge graph, partition/collection key
|
|
4
|
+
* configuration, and the derived `inputSchema` / `updateSchema` / `createSchema`.
|
|
5
|
+
*
|
|
6
|
+
* This module is AWS-SDK-free in BOTH its runtime import graph and its
|
|
7
|
+
* emitted `.d.ts` surface. The full `effect-dynamodb` package provides the
|
|
8
|
+
* operational `Aggregate.make` (with `get` / `create` / `update` / `delete` /
|
|
9
|
+
* `list`) that additionally carries the AWS runtime (DynamoClient, Marshaller,
|
|
10
|
+
* Batch/Transaction). Both reuse the pure {@link deriveAggregateSchemas}
|
|
11
|
+
* derivation so the schemas have a single source of truth.
|
|
12
|
+
*
|
|
13
|
+
* `Aggregate.make()` here returns a pure {@link AggregateDefinition} (top-level
|
|
14
|
+
* form) or a {@link SubAggregate} (sub-aggregate form). Consumers who only need
|
|
15
|
+
* the derived schemas can import it from `@effect-dynamodb/schema` without
|
|
16
|
+
* pulling the AWS SDK into their dependency graph or type surface.
|
|
17
|
+
*/
|
|
18
|
+
import type { Schema } from "effect";
|
|
19
|
+
import type * as DynamoSchemaModule from "./DynamoSchema.js";
|
|
20
|
+
import type { AggregateEdge } from "./internal/AggregateEdges.js";
|
|
21
|
+
import type { AggregateInputType, BoundSubAggregate, SubAggregate } from "./internal/AggregateTypes.js";
|
|
22
|
+
export type { Cursor, DiscriminatorConfig, UpdateContext } from "./internal/AggregateCursor.js";
|
|
23
|
+
export { type AggregateEdge, isManyEdge, isOneEdge, isRefEdge, type ManyEdge, type ManyEdgeConfig, many, type OneEdge, one, type RefEdge, type RefEntity, ref, } from "./internal/AggregateEdges.js";
|
|
24
|
+
export { type DerivedAggregateSchemas, deriveAggregateSchemas, deriveElementInputSchema, deriveEntityFieldName, extractArrayElement, getSchemaFields, isFieldOptional, isSchemaMatchingEntity, unwrapModel, } from "./internal/AggregateSchemas.js";
|
|
25
|
+
export type { AggregateInputType, BoundSubAggregate, Input, Key, SubAggregate, Type, UpdateFn, } from "./internal/AggregateTypes.js";
|
|
26
|
+
export declare const TypeId: unique symbol;
|
|
27
|
+
export type TypeId = typeof TypeId;
|
|
28
|
+
/** A minimal table tag reference — the pure layer never executes against it. */
|
|
29
|
+
export interface AggregateTableLike {
|
|
30
|
+
readonly Tag: unknown;
|
|
31
|
+
}
|
|
32
|
+
interface SubAggregateConfig<TEdges extends Record<string, AggregateEdge | BoundSubAggregate<any, any>> = Record<string, AggregateEdge | BoundSubAggregate<any, any>>> {
|
|
33
|
+
readonly root: {
|
|
34
|
+
readonly entityType: string;
|
|
35
|
+
};
|
|
36
|
+
readonly edges: TEdges;
|
|
37
|
+
}
|
|
38
|
+
interface CollectionConfig {
|
|
39
|
+
readonly index: string;
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly sk: {
|
|
42
|
+
readonly field: string;
|
|
43
|
+
readonly composite: ReadonlyArray<string>;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
interface ListCollectionConfig extends CollectionConfig {
|
|
47
|
+
readonly pk: {
|
|
48
|
+
readonly field: string;
|
|
49
|
+
readonly composite: ReadonlyArray<string>;
|
|
50
|
+
};
|
|
51
|
+
readonly cardinality?: number | undefined;
|
|
52
|
+
}
|
|
53
|
+
interface AggregateConfig<_TSchema extends Schema.Top, TEdges extends Record<string, AggregateEdge | BoundSubAggregate<any, any>> = Record<string, AggregateEdge | BoundSubAggregate<any, any>>, TPK extends ReadonlyArray<string> = ReadonlyArray<string>> {
|
|
54
|
+
readonly table: AggregateTableLike;
|
|
55
|
+
readonly schema: DynamoSchemaModule.DynamoSchema;
|
|
56
|
+
readonly pk: {
|
|
57
|
+
readonly field: string;
|
|
58
|
+
readonly composite: TPK;
|
|
59
|
+
};
|
|
60
|
+
readonly collection: CollectionConfig;
|
|
61
|
+
readonly list?: ListCollectionConfig | undefined;
|
|
62
|
+
readonly context?: ReadonlyArray<string> | undefined;
|
|
63
|
+
readonly root: {
|
|
64
|
+
readonly entityType: string;
|
|
65
|
+
};
|
|
66
|
+
readonly edges: TEdges;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The pure aggregate definition produced by the top-level form of {@link make}.
|
|
70
|
+
* Carries the schema binding, partition/collection key configuration, and the
|
|
71
|
+
* derived `inputSchema` / `updateSchema` / `createSchema`. Does NOT carry the
|
|
72
|
+
* AWS-coupled CRUD operations — those live on the runtime `effect-dynamodb`
|
|
73
|
+
* `Aggregate` type.
|
|
74
|
+
*/
|
|
75
|
+
export interface AggregateDefinition<TSchema extends Schema.Top, TInput = unknown> {
|
|
76
|
+
readonly [TypeId]: TypeId;
|
|
77
|
+
readonly _tag: "Aggregate";
|
|
78
|
+
readonly schema: TSchema;
|
|
79
|
+
/** @internal Tag of the table this aggregate is bound to. */
|
|
80
|
+
readonly _tableTag: unknown;
|
|
81
|
+
/** Primary key field name (e.g., "pk") */
|
|
82
|
+
readonly pkField: string;
|
|
83
|
+
/** Collection GSI config */
|
|
84
|
+
readonly collection: {
|
|
85
|
+
readonly index: string;
|
|
86
|
+
readonly sk: {
|
|
87
|
+
readonly field: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/** List GSI config — undefined when not configured */
|
|
91
|
+
readonly listIndex: {
|
|
92
|
+
readonly index: string;
|
|
93
|
+
readonly pk: {
|
|
94
|
+
readonly field: string;
|
|
95
|
+
};
|
|
96
|
+
readonly sk: {
|
|
97
|
+
readonly field: string;
|
|
98
|
+
};
|
|
99
|
+
} | undefined;
|
|
100
|
+
/** Derived input schema for `create()`. */
|
|
101
|
+
readonly inputSchema: Schema.Codec<TInput>;
|
|
102
|
+
/** Alias for `inputSchema`. */
|
|
103
|
+
readonly createSchema: Schema.Codec<TInput>;
|
|
104
|
+
/** Derived update schema — all `inputSchema` fields made optional. */
|
|
105
|
+
readonly updateSchema: Schema.Codec<Partial<TInput>>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create a pure aggregate definition.
|
|
109
|
+
*
|
|
110
|
+
* **Sub-aggregate form** — `Aggregate.make(Schema, { root, edges })`:
|
|
111
|
+
* Returns a composable {@link SubAggregate} with `.with()` for discriminator binding.
|
|
112
|
+
*
|
|
113
|
+
* **Top-level form** — `Aggregate.make(Schema, { table, schema, pk, collection, ... })`:
|
|
114
|
+
* Returns a pure {@link AggregateDefinition} carrying the derived schemas.
|
|
115
|
+
*
|
|
116
|
+
* This pure form is AWS-SDK-free. The full operational `Aggregate.make` (with
|
|
117
|
+
* `get` / `create` / `update` / `delete` / `list`) is exported from
|
|
118
|
+
* `effect-dynamodb`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function make<TSchema extends Schema.Top, const TEdges extends Record<string, AggregateEdge | BoundSubAggregate<any, any>>>(schema: TSchema, config: SubAggregateConfig<TEdges> & {
|
|
121
|
+
readonly table?: undefined;
|
|
122
|
+
}): SubAggregate<TSchema, TEdges>;
|
|
123
|
+
export declare function make<TSchema extends Schema.Top, const TEdges extends Record<string, AggregateEdge | BoundSubAggregate<any, any>>, const TPK extends ReadonlyArray<string>>(schema: TSchema, config: AggregateConfig<TSchema, TEdges, TPK>): AggregateDefinition<TSchema, AggregateInputType<Schema.Schema.Type<TSchema>, TEdges, TPK>>;
|
|
124
|
+
/** A bound aggregate placeholder type — the operational form lives in effect-dynamodb. */
|
|
125
|
+
export type BoundAggregate<TSchema extends Schema.Top, _TKey = unknown, _TInput = unknown> = {
|
|
126
|
+
readonly schema: TSchema;
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=Aggregate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aggregate.d.ts","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregate (pure definition layer) — builds the AWS-free half of an Aggregate:
|
|
3
|
+
* the Schema.Class hierarchy binding, edge graph, partition/collection key
|
|
4
|
+
* configuration, and the derived `inputSchema` / `updateSchema` / `createSchema`.
|
|
5
|
+
*
|
|
6
|
+
* This module is AWS-SDK-free in BOTH its runtime import graph and its
|
|
7
|
+
* emitted `.d.ts` surface. The full `effect-dynamodb` package provides the
|
|
8
|
+
* operational `Aggregate.make` (with `get` / `create` / `update` / `delete` /
|
|
9
|
+
* `list`) that additionally carries the AWS runtime (DynamoClient, Marshaller,
|
|
10
|
+
* Batch/Transaction). Both reuse the pure {@link deriveAggregateSchemas}
|
|
11
|
+
* derivation so the schemas have a single source of truth.
|
|
12
|
+
*
|
|
13
|
+
* `Aggregate.make()` here returns a pure {@link AggregateDefinition} (top-level
|
|
14
|
+
* form) or a {@link SubAggregate} (sub-aggregate form). Consumers who only need
|
|
15
|
+
* the derived schemas can import it from `@effect-dynamodb/schema` without
|
|
16
|
+
* pulling the AWS SDK into their dependency graph or type surface.
|
|
17
|
+
*/
|
|
18
|
+
import { deriveAggregateSchemas } from "./internal/AggregateSchemas.js";
|
|
19
|
+
export { isManyEdge, isOneEdge, isRefEdge, many, one, ref, } from "./internal/AggregateEdges.js";
|
|
20
|
+
export { deriveAggregateSchemas, deriveElementInputSchema, deriveEntityFieldName, extractArrayElement, getSchemaFields, isFieldOptional, isSchemaMatchingEntity, unwrapModel, } from "./internal/AggregateSchemas.js";
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// TypeId
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
export const TypeId = Symbol.for("effect-dynamodb/Aggregate");
|
|
25
|
+
export function make(schema, config) {
|
|
26
|
+
if (!("table" in config) || config.table === undefined) {
|
|
27
|
+
return makeSubAggregate(schema, config);
|
|
28
|
+
}
|
|
29
|
+
return makeAggregateDefinition(schema, config);
|
|
30
|
+
}
|
|
31
|
+
const makeSubAggregate = (schema, config) => {
|
|
32
|
+
const sub = {
|
|
33
|
+
_tag: "SubAggregate",
|
|
34
|
+
schema,
|
|
35
|
+
root: config.root,
|
|
36
|
+
edges: config.edges,
|
|
37
|
+
with: (discConfig) => ({
|
|
38
|
+
_tag: "BoundSubAggregate",
|
|
39
|
+
aggregate: sub,
|
|
40
|
+
discriminator: discConfig.discriminator,
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
43
|
+
return sub;
|
|
44
|
+
};
|
|
45
|
+
const makeAggregateDefinition = (schema, config) => {
|
|
46
|
+
const derivedSchemas = deriveAggregateSchemas(schema, config.edges, config.pk.composite);
|
|
47
|
+
return {
|
|
48
|
+
[TypeId]: TypeId,
|
|
49
|
+
_tag: "Aggregate",
|
|
50
|
+
_tableTag: config.table.Tag,
|
|
51
|
+
schema,
|
|
52
|
+
pkField: config.pk.field,
|
|
53
|
+
collection: {
|
|
54
|
+
index: config.collection.index,
|
|
55
|
+
sk: { field: config.collection.sk.field },
|
|
56
|
+
},
|
|
57
|
+
listIndex: config.list
|
|
58
|
+
? {
|
|
59
|
+
index: config.list.index,
|
|
60
|
+
pk: { field: config.list.pk.field },
|
|
61
|
+
sk: { field: config.list.sk.field },
|
|
62
|
+
}
|
|
63
|
+
: undefined,
|
|
64
|
+
inputSchema: derivedSchemas.inputSchema,
|
|
65
|
+
createSchema: derivedSchemas.inputSchema,
|
|
66
|
+
updateSchema: derivedSchemas.updateSchema,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=Aggregate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aggregate.js","sourceRoot":"","sources":["../src/Aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAQvE,OAAO,EAEL,UAAU,EACV,SAAS,EACT,SAAS,EAGT,IAAI,EAEJ,GAAG,EAGH,GAAG,GACJ,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAEL,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,WAAW,GACZ,MAAM,gCAAgC,CAAA;AAWvC,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,CAAC,MAAM,MAAM,GAAkB,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;AAiI5E,MAAM,UAAU,IAAI,CAClB,MAAe,EACf,MAAqD;IAErD,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACvD,OAAO,gBAAgB,CAAC,MAAM,EAAE,MAA4B,CAAC,CAAA;IAC/D,CAAC;IACD,OAAO,uBAAuB,CAAC,MAAM,EAAE,MAAkC,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,gBAAgB,GAAG,CACvB,MAAe,EACf,MAA0B,EACH,EAAE;IACzB,MAAM,GAAG,GAA0B;QACjC,IAAI,EAAE,cAAc;QACpB,MAAM;QACN,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,CAAC,UAA+B,EAAE,EAAE,CAAC,CAAC;YAC1C,IAAI,EAAE,mBAAmB;YACzB,SAAS,EAAE,GAAG;YACd,aAAa,EAAE,UAAU,CAAC,aAAa;SACxC,CAAC;KACH,CAAA;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,MAAM,uBAAuB,GAAG,CAC9B,MAAe,EACf,MAAgC,EACF,EAAE;IAChC,MAAM,cAAc,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAA;IAExF,OAAO;QACL,CAAC,MAAM,CAAC,EAAE,MAAM;QAChB,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG;QAC3B,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK;QACxB,UAAU,EAAE;YACV,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK;YAC9B,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;SAC1C;QACD,SAAS,EAAE,MAAM,CAAC,IAAI;YACpB,CAAC,CAAC;gBACE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;gBACxB,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;gBACnC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;aACpC;YACH,CAAC,CAAC,SAAS;QACb,WAAW,EAAE,cAAc,CAAC,WAA+C;QAC3E,YAAY,EAAE,cAAc,CAAC,WAA+C;QAC5E,YAAY,EAAE,cAAc,CAAC,YAAyD;KACvD,CAAA;AACnC,CAAC,CAAA"}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamoModel — Schema annotations, date schemas, and model configuration for effect-dynamodb.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - `configure` — per-field DynamoDB overrides (field rename, storage encoding, immutable, identifier, ref)
|
|
6
|
+
* - `Hidden` annotation — marks fields as excluded from default decode (asModel/asRecord)
|
|
7
|
+
* - `DynamoEncoding` annotation — controls how date fields are stored in DynamoDB
|
|
8
|
+
* - Date schemas — wire ↔ domain ↔ storage transformations for DateTime.Utc, DateTime.Zoned, Date
|
|
9
|
+
* - `storedAs` modifier — overrides DynamoDB storage format via annotation
|
|
10
|
+
* - `SparseMap()` — opt a `Schema.Record` field into flattened storage (one
|
|
11
|
+
* top-level attribute per entry)
|
|
12
|
+
*
|
|
13
|
+
* See docs/design-dynamo-model.md for the three-layer model (wire → domain → storage).
|
|
14
|
+
*/
|
|
15
|
+
import { DateTime, Schema } from "effect";
|
|
16
|
+
/**
|
|
17
|
+
* Mark a schema field as the primary identifier for ref resolution.
|
|
18
|
+
*
|
|
19
|
+
* Entities that can be referenced via `DynamoModel.ref` must annotate exactly
|
|
20
|
+
* one field with `identifier`. The annotated field should be a string or
|
|
21
|
+
* branded string type.
|
|
22
|
+
*/
|
|
23
|
+
export declare const identifier: <S extends Schema.Top>(schema: S) => S;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a schema field has the Identifier annotation.
|
|
26
|
+
*/
|
|
27
|
+
export declare const isIdentifier: (schema: Schema.Top) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Find the identifier field in a schema with `.fields` (Schema.Class or Schema.Struct).
|
|
30
|
+
* Checks both schema-level `DynamoModel.identifier` annotations and ConfiguredModel
|
|
31
|
+
* `identifier: true` overrides.
|
|
32
|
+
*
|
|
33
|
+
* Returns the field name and schema, or undefined if no field has the identifier annotation.
|
|
34
|
+
*/
|
|
35
|
+
export declare const getIdentifierField: (model: Schema.Top) => {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly schema: Schema.Top;
|
|
38
|
+
} | undefined;
|
|
39
|
+
/** Annotation metadata stored on ref-annotated fields */
|
|
40
|
+
export interface RefAnnotation {
|
|
41
|
+
readonly _tag: "Ref";
|
|
42
|
+
/** Schema.Class identifier of the referenced type (e.g., "Team", "Player") */
|
|
43
|
+
readonly refSchemaId?: string | undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Mark a schema field as a denormalized reference to another entity.
|
|
47
|
+
*
|
|
48
|
+
* Ref fields:
|
|
49
|
+
* - In `Entity.Input`, become ID fields (e.g., `team: Team` → `teamId: string`)
|
|
50
|
+
* - In `Entity.Record`, remain the full entity domain type
|
|
51
|
+
* - In `Entity.Update`, become optional ID fields
|
|
52
|
+
* - In DynamoDB, store the entity's core domain data as an embedded map
|
|
53
|
+
*
|
|
54
|
+
* The referenced entity's model must have exactly one `DynamoModel.identifier`-annotated field.
|
|
55
|
+
*/
|
|
56
|
+
export declare const ref: <S extends Schema.Top>(schema: S) => S;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a schema field has the Ref annotation.
|
|
59
|
+
*/
|
|
60
|
+
export declare const isRef: (schema: Schema.Top) => boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a field is a ref, considering both schema-level annotations and
|
|
63
|
+
* ConfiguredModel overrides. Use this when you have access to the configured model.
|
|
64
|
+
*/
|
|
65
|
+
export declare const isRefField: (fieldName: string, model: Schema.Top) => boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get the full Ref annotation metadata from a schema field.
|
|
68
|
+
* Returns undefined if the field is not ref-annotated.
|
|
69
|
+
*/
|
|
70
|
+
export declare const getRefAnnotation: (schema: Schema.Top) => RefAnnotation | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Mark a schema field as hidden from default decode modes (asModel, asRecord).
|
|
73
|
+
*
|
|
74
|
+
* Hidden fields:
|
|
75
|
+
* - Stored in DynamoDB normally
|
|
76
|
+
* - Visible in asItem and asNative decode modes
|
|
77
|
+
* - Stripped from asModel and asRecord decode modes
|
|
78
|
+
*
|
|
79
|
+
* Use for internal/infrastructure fields that shouldn't leak into application code.
|
|
80
|
+
*/
|
|
81
|
+
export declare const Hidden: <S extends Schema.Top>(schema: S) => S;
|
|
82
|
+
/**
|
|
83
|
+
* Check if a schema field has the Hidden annotation.
|
|
84
|
+
*/
|
|
85
|
+
export declare const isHidden: (schema: Schema.Top) => boolean;
|
|
86
|
+
/** Unique symbol for the DynamoEncoding annotation */
|
|
87
|
+
export declare const DynamoEncodingKey: unique symbol;
|
|
88
|
+
/**
|
|
89
|
+
* Describes how a date field is stored in DynamoDB.
|
|
90
|
+
* - `storage` — the DynamoDB attribute format
|
|
91
|
+
* - `domain` — the domain type (for deserialization dispatch)
|
|
92
|
+
*/
|
|
93
|
+
export interface DynamoEncoding {
|
|
94
|
+
readonly storage: "string" | "epochMs" | "epochSeconds";
|
|
95
|
+
readonly domain: "DateTime.Utc" | "DateTime.Zoned" | "Date";
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Read the DynamoEncoding annotation from a schema, if present.
|
|
99
|
+
*/
|
|
100
|
+
export declare const getEncoding: (schema: Schema.Top) => DynamoEncoding | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Wire: ISO 8601 string ↔ Domain: DateTime.Utc
|
|
103
|
+
*
|
|
104
|
+
* Default storage: ISO string (`S`).
|
|
105
|
+
* This is a thin wrapper around `Schema.DateTimeUtcFromString` with the DynamoEncoding annotation.
|
|
106
|
+
*/
|
|
107
|
+
export declare const DateString: Schema.DateTimeUtcFromString;
|
|
108
|
+
/**
|
|
109
|
+
* Wire: epoch milliseconds (number) ↔ Domain: DateTime.Utc
|
|
110
|
+
*
|
|
111
|
+
* Default storage: epoch ms (`N`).
|
|
112
|
+
*/
|
|
113
|
+
export declare const DateEpochMs: Schema.decodeTo<Schema.DateTimeUtc, Schema.Number, never, never>;
|
|
114
|
+
/**
|
|
115
|
+
* Wire: epoch seconds (number) ↔ Domain: DateTime.Utc
|
|
116
|
+
*
|
|
117
|
+
* Default storage: epoch seconds (`N`).
|
|
118
|
+
* DynamoDB TTL requires this format.
|
|
119
|
+
*/
|
|
120
|
+
export declare const DateEpochSeconds: Schema.decodeTo<Schema.DateTimeUtc, Schema.Number, never, never>;
|
|
121
|
+
/**
|
|
122
|
+
* Wire: auto-detect epoch ms or seconds ↔ Domain: DateTime.Utc
|
|
123
|
+
*
|
|
124
|
+
* Uses a minimum threshold to disambiguate: if the value interpreted as ms
|
|
125
|
+
* produces a date before `minimum`, it tries seconds instead.
|
|
126
|
+
*
|
|
127
|
+
* @param options.minimum - Threshold date for disambiguation
|
|
128
|
+
* @param options.encode - Epoch schema for wire encoding (default: DateEpochMs)
|
|
129
|
+
*/
|
|
130
|
+
export declare const DateEpoch: (options: {
|
|
131
|
+
readonly minimum: string | DateTime.DateTime.Input;
|
|
132
|
+
readonly encode?: typeof DateEpochMs | typeof DateEpochSeconds;
|
|
133
|
+
}) => Schema.decodeTo<Schema.DateTimeUtc, Schema.Number, never, never>;
|
|
134
|
+
/**
|
|
135
|
+
* Wire: ISO 8601 string with offset/zone ↔ Domain: DateTime.Zoned
|
|
136
|
+
*
|
|
137
|
+
* Default storage: extended ISO with zone (`S`).
|
|
138
|
+
* Format: `2024-01-01T15:00:00+09:00[Asia/Tokyo]`
|
|
139
|
+
*
|
|
140
|
+
* Cannot use epoch storage — timezone information would be lost (enforced at type level via storedAs).
|
|
141
|
+
*/
|
|
142
|
+
export declare const DateTimeZoned: Schema.decodeTo<Schema.DateTimeZoned, Schema.String, never, never>;
|
|
143
|
+
/**
|
|
144
|
+
* Wire: ISO 8601 string ↔ Domain: native Date (mutable)
|
|
145
|
+
*
|
|
146
|
+
* Default storage: ISO string (`S`).
|
|
147
|
+
* For interop with non-Effect code that expects native JS Date objects.
|
|
148
|
+
*/
|
|
149
|
+
export declare const UnsafeDateString: Schema.decodeTo<Schema.DateValid, Schema.String, never, never>;
|
|
150
|
+
/**
|
|
151
|
+
* Wire: epoch milliseconds (number) ↔ Domain: native Date (mutable)
|
|
152
|
+
*
|
|
153
|
+
* Default storage: epoch ms (`N`).
|
|
154
|
+
*/
|
|
155
|
+
export declare const UnsafeDateEpochMs: Schema.decodeTo<Schema.DateValid, Schema.Number, never, never>;
|
|
156
|
+
/**
|
|
157
|
+
* Wire: epoch seconds (number) ↔ Domain: native Date (mutable)
|
|
158
|
+
*
|
|
159
|
+
* Default storage: epoch seconds (`N`).
|
|
160
|
+
*/
|
|
161
|
+
export declare const UnsafeDateEpochSeconds: Schema.decodeTo<Schema.DateValid, Schema.Number, never, never>;
|
|
162
|
+
/**
|
|
163
|
+
* Alias for `DateEpochSeconds`. DynamoDB TTL requires epoch seconds.
|
|
164
|
+
* A named alias makes intent clear at the call site.
|
|
165
|
+
*/
|
|
166
|
+
export declare const TTL: Schema.decodeTo<Schema.DateTimeUtc, Schema.Number, never, never>;
|
|
167
|
+
/**
|
|
168
|
+
* Override the DynamoDB storage format for a date field.
|
|
169
|
+
*
|
|
170
|
+
* `storedAs` reads the DynamoEncoding annotation from the target storage schema
|
|
171
|
+
* and applies its storage format to the field schema. The domain type must match
|
|
172
|
+
* (enforced at the type level via the `A` constraint).
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* // Wire: ISO string, DynamoDB: epoch seconds (for TTL)
|
|
177
|
+
* DynamoModel.DateString.pipe(DynamoModel.storedAs(DynamoModel.DateEpochSeconds))
|
|
178
|
+
*
|
|
179
|
+
* // Wire: epoch ms, DynamoDB: ISO string
|
|
180
|
+
* DynamoModel.DateEpochMs.pipe(DynamoModel.storedAs(DynamoModel.DateString))
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* Type-safe: incompatible domain types produce a compile error:
|
|
184
|
+
* ```typescript
|
|
185
|
+
* // Type error — DateTime.Zoned ≠ DateTime.Utc
|
|
186
|
+
* DynamoModel.DateTimeZoned.pipe(DynamoModel.storedAs(DynamoModel.DateEpochMs))
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export declare const storedAs: <A>(storageSchema: Schema.Schema<A>) => (<S extends Schema.Schema<A>>(fieldSchema: S) => S);
|
|
190
|
+
/** Unique symbol identifying a ConfiguredModel wrapper */
|
|
191
|
+
export declare const ConfiguredModelTag: unique symbol;
|
|
192
|
+
/**
|
|
193
|
+
* Sparse-map configuration carried on a `ConfiguredModel` attribute when the
|
|
194
|
+
* field is marked `storedAs: DynamoModel.SparseMap()`.
|
|
195
|
+
*
|
|
196
|
+
* - `prefix` — top-level attribute name prefix; defaults to the model field name.
|
|
197
|
+
* Each Record entry is stored as a separate top-level attribute named
|
|
198
|
+
* `<prefix>#<key>`. The default prefix can be overridden by passing
|
|
199
|
+
* `{ prefix }` to {@link SparseMap}.
|
|
200
|
+
*/
|
|
201
|
+
export interface SparseConfig {
|
|
202
|
+
readonly prefix: string;
|
|
203
|
+
}
|
|
204
|
+
/** Brand symbol identifying a {@link SparseMapConfig} produced by {@link SparseMap}. */
|
|
205
|
+
declare const SparseMapTag: unique symbol;
|
|
206
|
+
/**
|
|
207
|
+
* Typed config object returned by {@link SparseMap}. Pass as the `storedAs`
|
|
208
|
+
* value on a `Schema.Record` field in {@link configure} to opt into sparse
|
|
209
|
+
* map storage — each Record entry is flattened into a top-level DynamoDB
|
|
210
|
+
* attribute named `<prefix>#<key>`.
|
|
211
|
+
*/
|
|
212
|
+
export interface SparseMapConfig {
|
|
213
|
+
readonly [SparseMapTag]: true;
|
|
214
|
+
readonly prefix?: string | undefined;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Opt a `Schema.Record` field into sparse map storage.
|
|
218
|
+
*
|
|
219
|
+
* Each Record entry becomes an independently addressable top-level DynamoDB
|
|
220
|
+
* attribute (`<prefix>#<key>`) — concurrent writers to disjoint buckets
|
|
221
|
+
* never race, counters can `ADD` on a fresh item with no parent-map dance,
|
|
222
|
+
* and `attribute_exists`/`attribute_not_exists` work natively per entry.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```ts
|
|
226
|
+
* DynamoModel.configure(Page, {
|
|
227
|
+
* metrics: { storedAs: DynamoModel.SparseMap() },
|
|
228
|
+
* totals: { storedAs: DynamoModel.SparseMap({ prefix: "t" }) },
|
|
229
|
+
* })
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
* @param options.prefix - Override the top-level attribute name prefix.
|
|
233
|
+
* Defaults to the model field name. Distinct sparse fields on the same
|
|
234
|
+
* entity must have distinct prefixes (EDD-9023).
|
|
235
|
+
*
|
|
236
|
+
* See `DESIGN.md §7.5 Sparse Map Storage`.
|
|
237
|
+
*/
|
|
238
|
+
export declare const SparseMap: (options?: {
|
|
239
|
+
readonly prefix?: string | undefined;
|
|
240
|
+
}) => SparseMapConfig;
|
|
241
|
+
/** Type guard — returns true iff `value` is a {@link SparseMapConfig}. */
|
|
242
|
+
export declare const isSparseMapConfig: (value: unknown) => value is SparseMapConfig;
|
|
243
|
+
/**
|
|
244
|
+
* A model wrapped with DynamoDB-specific attribute overrides.
|
|
245
|
+
*
|
|
246
|
+
* Carries the original model plus per-field configuration:
|
|
247
|
+
* - `field` — rename domain field → DynamoDB attribute name
|
|
248
|
+
* - `storedAs` — override DynamoDB storage encoding (resolved to DynamoEncoding)
|
|
249
|
+
* OR a {@link SparseMapConfig} (via {@link SparseMap}) to
|
|
250
|
+
* flatten a `Schema.Record` field into per-entry top-level
|
|
251
|
+
* attributes (see {@link SparseConfig}).
|
|
252
|
+
* - `immutable` — mark field as read-only after creation (excluded from Entity.Update)
|
|
253
|
+
* - `identifier` — mark field as the identity field for ref resolution
|
|
254
|
+
* - `ref` — mark field as a denormalized reference to another entity
|
|
255
|
+
*/
|
|
256
|
+
export interface ConfiguredModel<M extends Schema.Top, A extends ConfigureAttributes<M> = ConfigureAttributes<M>> {
|
|
257
|
+
readonly [ConfiguredModelTag]: true;
|
|
258
|
+
readonly model: M;
|
|
259
|
+
readonly _attributes: A;
|
|
260
|
+
readonly attributes: globalThis.Record<string, {
|
|
261
|
+
readonly field?: string;
|
|
262
|
+
readonly encoding?: DynamoEncoding;
|
|
263
|
+
readonly immutable?: boolean;
|
|
264
|
+
readonly identifier?: boolean;
|
|
265
|
+
readonly ref?: boolean;
|
|
266
|
+
readonly sparse?: SparseConfig;
|
|
267
|
+
}>;
|
|
268
|
+
}
|
|
269
|
+
/** Extract the identifier field name from a ConfiguredModel's attributes type. */
|
|
270
|
+
export type ExtractIdentifier<Model> = Model extends ConfiguredModel<any, infer A> ? {
|
|
271
|
+
[K in keyof A & string]: A[K] extends {
|
|
272
|
+
readonly identifier: true;
|
|
273
|
+
} ? K : never;
|
|
274
|
+
}[keyof A & string] : undefined;
|
|
275
|
+
/**
|
|
276
|
+
* Check if a value is a ConfiguredModel.
|
|
277
|
+
*/
|
|
278
|
+
export declare const isConfiguredModel: (value: unknown) => value is ConfiguredModel<Schema.Top, any>;
|
|
279
|
+
/**
|
|
280
|
+
* Resolve sparse-map configuration for every field on a model that is marked
|
|
281
|
+
* `storedAs: DynamoModel.SparseMap()` via {@link configure}.
|
|
282
|
+
*
|
|
283
|
+
* Returns `Record<fieldName, SparseConfig>`. Empty when no sparse fields are
|
|
284
|
+
* configured.
|
|
285
|
+
*
|
|
286
|
+
* Walks `ConfiguredModel.attributes` only — schema-level annotations are not
|
|
287
|
+
* supported for sparse (it's a deployment concern, not a domain one).
|
|
288
|
+
*/
|
|
289
|
+
export declare const getSparseFields: (model: Schema.Top) => globalThis.Record<string, SparseConfig>;
|
|
290
|
+
/**
|
|
291
|
+
* Inspect a Schema field to determine whether it is shaped like a `Schema.Record`.
|
|
292
|
+
*
|
|
293
|
+
* Effect v4 `Schema.Record(K, V)` produces an AST `Objects` node with no
|
|
294
|
+
* `propertySignatures` and a single `indexSignatures` entry (string-keyed).
|
|
295
|
+
*
|
|
296
|
+
* Returns the value AST on match, otherwise `undefined`. Used by
|
|
297
|
+
* `Entity.make()` to validate sparse-map fields and detect nested sparse
|
|
298
|
+
* (a Record whose value is itself a Record).
|
|
299
|
+
*/
|
|
300
|
+
export declare const isRecordSchema: (schema: Schema.Top) => {
|
|
301
|
+
readonly valueAst: unknown;
|
|
302
|
+
} | undefined;
|
|
303
|
+
/** True iff `schema` is shaped like `Schema.Record(K, V)`. */
|
|
304
|
+
export declare const isRecord: (schema: Schema.Top) => boolean;
|
|
305
|
+
/** True iff `valueAst` (raw AST from a Record value position) is itself a Record AST. */
|
|
306
|
+
export declare const isRecordAst: (valueAst: unknown) => boolean;
|
|
307
|
+
/**
|
|
308
|
+
* Attribute override for a single field in `DynamoModel.configure`.
|
|
309
|
+
*
|
|
310
|
+
* - `field` — Rename the domain field to a different DynamoDB attribute name.
|
|
311
|
+
* - `storedAs` — Override DynamoDB storage format via a DynamoModel date schema,
|
|
312
|
+
* or {@link SparseMap}() to flatten a `Schema.Record` into
|
|
313
|
+
* per-entry top-level attributes (see {@link SparseConfig}).
|
|
314
|
+
* - `immutable` — Mark as read-only after creation (excluded from Entity.Update).
|
|
315
|
+
* - `identifier` — Mark as the identity field for ref resolution.
|
|
316
|
+
* - `ref` — Mark as a denormalized reference field.
|
|
317
|
+
*
|
|
318
|
+
* Note: the `prefix` option moved into the {@link SparseMap} config in 1.6 —
|
|
319
|
+
* pass `storedAs: DynamoModel.SparseMap({ prefix })` instead of declaring
|
|
320
|
+
* `prefix` as a sibling here. The sibling form had no meaning for non-sparse
|
|
321
|
+
* `storedAs` values and was a footgun.
|
|
322
|
+
*/
|
|
323
|
+
type AttributeConfig<A> = {
|
|
324
|
+
readonly field?: string;
|
|
325
|
+
readonly storedAs?: Schema.Schema<A> | SparseMapConfig;
|
|
326
|
+
readonly immutable?: boolean;
|
|
327
|
+
readonly identifier?: boolean;
|
|
328
|
+
readonly ref?: boolean;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Type-safe attribute overrides map: keys constrained to model fields,
|
|
332
|
+
* `storedAs` constrained to matching domain type.
|
|
333
|
+
*/
|
|
334
|
+
type ConfigureAttributes<M extends Schema.Top> = {
|
|
335
|
+
readonly [K in keyof Schema.Schema.Type<M>]?: AttributeConfig<Schema.Schema.Type<M>[K]>;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Compile-time validation: detects `field` rename targets that collide
|
|
339
|
+
* with existing model field names. Replaces the `field` type with an
|
|
340
|
+
* error tuple to produce a readable type error at the call site.
|
|
341
|
+
*/
|
|
342
|
+
type ValidateFieldRenames<Fields extends string, A> = {
|
|
343
|
+
[K in keyof A]: A[K] extends {
|
|
344
|
+
readonly field: infer F extends string;
|
|
345
|
+
} ? F extends Exclude<Fields, K & string> ? {
|
|
346
|
+
readonly field: [`EDD-9007: "${F}" collides with existing model field`];
|
|
347
|
+
} & Omit<A[K], "field"> : A[K] : A[K];
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* Create a configured model with per-field DynamoDB overrides.
|
|
351
|
+
*
|
|
352
|
+
* Separates DynamoDB infrastructure (storage format, field renaming) from
|
|
353
|
+
* the domain model, enabling pure models that work across storage backends.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```typescript
|
|
357
|
+
* class Order extends Schema.Class<Order>("Order")({
|
|
358
|
+
* orderId: Schema.String,
|
|
359
|
+
* placedAt: Schema.DateTimeUtcFromString,
|
|
360
|
+
* expiresAt: Schema.DateTimeUtcFromString,
|
|
361
|
+
* }) {}
|
|
362
|
+
*
|
|
363
|
+
* const OrderModel = DynamoModel.configure(Order, {
|
|
364
|
+
* expiresAt: { field: "ttl", storedAs: DynamoModel.DateEpochSeconds },
|
|
365
|
+
* })
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
export declare const configure: <M extends Schema.Top, const A extends ConfigureAttributes<M>>(model: M, attributes: A & ValidateFieldRenames<keyof Schema.Schema.Type<M> & string, A>) => ConfiguredModel<M, A>;
|
|
369
|
+
export {};
|
|
370
|
+
//# sourceMappingURL=DynamoModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DynamoModel.d.ts","sourceRoot":"","sources":["../src/DynamoModel.ts"],"names":[],"mappings":"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"}
|