effect-app 4.0.0-beta.316 → 4.0.0-beta.317
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/CHANGELOG.md +16 -0
- package/dist/DataDependencies.d.ts +18 -162
- package/dist/DataDependencies.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +6 -5
- package/dist/Model/filter/filterApi.d.ts +2 -2
- package/dist/Model/filter/filterApi.d.ts.map +1 -1
- package/dist/Model/query/dsl.d.ts +21 -5
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Schema/ext.d.ts +28 -65
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +22 -37
- package/dist/Store.d.ts +8 -1
- package/dist/Store.d.ts.map +1 -1
- package/dist/Store.js +1 -1
- package/dist/rpc/Invalidation.d.ts +144 -1296
- package/dist/rpc/Invalidation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Model/Repository/internal/internal.ts +5 -4
- package/src/Model/filter/filterApi.ts +19 -1
- package/src/Model/query/dsl.ts +188 -7
- package/src/Schema/ext.ts +21 -40
- package/src/Store.ts +8 -1
- package/test/schema.test.ts +33 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Invalidation.d.ts","sourceRoot":"","sources":["../../src/rpc/Invalidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,wBAAwB,CAAA;AAC5E,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAEjC;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAmBjH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAAS,CAAA;AAC5C,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAEjF,6GAA6G;AAC7G,eAAO,MAAM,eAAe;;;CAAkC,CAAA;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,eAAe,CAAC,CAAA;AAEnE,oFAAoF;AACpF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAA2B,CAAA;AACxD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAErE,wFAAwF;AACxF,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"Invalidation.d.ts","sourceRoot":"","sources":["../../src/rpc/Invalidation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -581,7 +581,7 @@ export function makeRepoInternal<
|
|
|
581
581
|
.pipe(
|
|
582
582
|
Effect.andThen(
|
|
583
583
|
(items) =>
|
|
584
|
-
S.decodeEffectConcurrently(S.Array(a.schema ?? schema))(items).pipe(
|
|
584
|
+
S.decodeEffectConcurrently(S.Array(S.toCodecJson(a.schema ?? schema)))(items).pipe(
|
|
585
585
|
provideRctx,
|
|
586
586
|
timeSchema("decode", name, "aggregate", items.length)
|
|
587
587
|
)
|
|
@@ -593,7 +593,7 @@ export function makeRepoInternal<
|
|
|
593
593
|
.pipe(
|
|
594
594
|
Effect.andThen(
|
|
595
595
|
(items) =>
|
|
596
|
-
S.decodeEffectConcurrently(S.Array(a.schema ?? schema))(items).pipe(
|
|
596
|
+
S.decodeEffectConcurrently(S.Array(S.toCodecJson(a.schema ?? schema)))(items).pipe(
|
|
597
597
|
provideRctx,
|
|
598
598
|
timeSchema("decode", name, "project", items.length)
|
|
599
599
|
)
|
|
@@ -604,7 +604,7 @@ export function makeRepoInternal<
|
|
|
604
604
|
// TODO: mapFrom but need to support per field and dependencies
|
|
605
605
|
.pipe(
|
|
606
606
|
Effect.flatMap((items) =>
|
|
607
|
-
S.decodeEffectConcurrently(S.Array(a.schema))(items).pipe(
|
|
607
|
+
S.decodeEffectConcurrently(S.Array(S.toCodecJson(a.schema)))(items).pipe(
|
|
608
608
|
Effect.map(Array.getSomes),
|
|
609
609
|
provideRctx,
|
|
610
610
|
timeSchema("decode", name, "collect", items.length)
|
|
@@ -737,7 +737,7 @@ export function makeRepoInternal<
|
|
|
737
737
|
queryRaw<A, Out, QR>(schema: S.Codec<A, Out, QR>, q: Q.RawQuery<Encoded, Out>) {
|
|
738
738
|
return store.queryRaw(q).pipe(
|
|
739
739
|
Effect.flatMap((items) =>
|
|
740
|
-
S.decodeEffectConcurrently(S.Array(schema))(items).pipe(
|
|
740
|
+
S.decodeEffectConcurrently(S.Array(S.toCodecJson(schema)))(items as readonly S.Json[]).pipe(
|
|
741
741
|
timeSchema("decode", name, undefined, items.length)
|
|
742
742
|
)
|
|
743
743
|
),
|
|
@@ -887,6 +887,7 @@ export function makeStore<Encoded extends FieldValues>() {
|
|
|
887
887
|
: undefined,
|
|
888
888
|
{
|
|
889
889
|
...config,
|
|
890
|
+
schema,
|
|
890
891
|
partitionValue: config?.partitionValue
|
|
891
892
|
?? ((_) => "primary") /*(isIntegrationEvent(r) ? r.companyId : r.id*/
|
|
892
893
|
}
|
|
@@ -17,6 +17,24 @@ export type OtherOps =
|
|
|
17
17
|
| "notIncludes-any"
|
|
18
18
|
| "includes-all"
|
|
19
19
|
| "notIncludes-all"
|
|
20
|
+
| "hasKey"
|
|
21
|
+
| "notHasKey"
|
|
22
|
+
| "hasValue"
|
|
23
|
+
| "notHasValue"
|
|
24
|
+
| "hasKeyValue"
|
|
25
|
+
| "notHasKeyValue"
|
|
26
|
+
| "hasKey-any"
|
|
27
|
+
| "notHasKey-any"
|
|
28
|
+
| "hasKey-all"
|
|
29
|
+
| "notHasKey-all"
|
|
30
|
+
| "hasValue-any"
|
|
31
|
+
| "notHasValue-any"
|
|
32
|
+
| "hasValue-all"
|
|
33
|
+
| "notHasValue-all"
|
|
34
|
+
| "hasKeyValue-any"
|
|
35
|
+
| "notHasKeyValue-any"
|
|
36
|
+
| "hasKeyValue-all"
|
|
37
|
+
| "notHasKeyValue-all"
|
|
20
38
|
| "eq"
|
|
21
39
|
| "neq"
|
|
22
40
|
| "gt"
|
|
@@ -44,7 +62,7 @@ export type FilterR = {
|
|
|
44
62
|
op: Ops
|
|
45
63
|
|
|
46
64
|
path: string
|
|
47
|
-
value:
|
|
65
|
+
value: unknown
|
|
48
66
|
}
|
|
49
67
|
|
|
50
68
|
export type FilterResult =
|
package/src/Model/query/dsl.ts
CHANGED
|
@@ -1157,7 +1157,15 @@ export const aggregate: {
|
|
|
1157
1157
|
return new Project({ current, schema, mode: "aggregate", aggregateMap } as any)
|
|
1158
1158
|
}
|
|
1159
1159
|
|
|
1160
|
-
type GetArV<T> = T extends
|
|
1160
|
+
type GetArV<T> = T extends ReadonlySet<infer R> ? R
|
|
1161
|
+
: T extends readonly (infer R)[] ? R
|
|
1162
|
+
: never
|
|
1163
|
+
|
|
1164
|
+
type GetMapK<T> = T extends ReadonlyMap<infer K, infer _V> ? K : never
|
|
1165
|
+
type GetMapV<T> = T extends ReadonlyMap<infer _K, infer V> ? V : never
|
|
1166
|
+
type GetMapEntry<T> = T extends ReadonlyMap<infer K, infer V> ? readonly [K, V] : never
|
|
1167
|
+
|
|
1168
|
+
type InValues<T> = readonly T[] | ReadonlySet<T>
|
|
1161
1169
|
|
|
1162
1170
|
export type FilterContinuations<IsCurrentInitial extends boolean = false> = {
|
|
1163
1171
|
<
|
|
@@ -1207,13 +1215,12 @@ export type FilterContinuations<IsCurrentInitial extends boolean = false> = {
|
|
|
1207
1215
|
<
|
|
1208
1216
|
TFieldValues extends FieldValues,
|
|
1209
1217
|
TFieldName extends FieldPath<TFieldValues>,
|
|
1210
|
-
const V extends readonly FieldPathValue<TFieldValues, TFieldName>[],
|
|
1211
1218
|
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1212
1219
|
E extends boolean = false
|
|
1213
1220
|
>(
|
|
1214
1221
|
path: TFieldName,
|
|
1215
1222
|
op: "in" | "notIn",
|
|
1216
|
-
value:
|
|
1223
|
+
value: InValues<FieldPathValue<TFieldValues, TFieldName>>
|
|
1217
1224
|
): (
|
|
1218
1225
|
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1219
1226
|
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
@@ -1249,7 +1256,97 @@ export type FilterContinuations<IsCurrentInitial extends boolean = false> = {
|
|
|
1249
1256
|
| "notIncludes-any"
|
|
1250
1257
|
| "includes-all"
|
|
1251
1258
|
| "notIncludes-all",
|
|
1252
|
-
value:
|
|
1259
|
+
value: InValues<GetArV<V>>
|
|
1260
|
+
): (
|
|
1261
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1262
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1263
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1264
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1265
|
+
<
|
|
1266
|
+
TFieldValues extends FieldValues,
|
|
1267
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1268
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1269
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1270
|
+
E extends boolean = false
|
|
1271
|
+
>(
|
|
1272
|
+
path: TFieldName,
|
|
1273
|
+
op: "hasKey" | "notHasKey",
|
|
1274
|
+
value: GetMapK<V>
|
|
1275
|
+
): (
|
|
1276
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1277
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1278
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1279
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1280
|
+
<
|
|
1281
|
+
TFieldValues extends FieldValues,
|
|
1282
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1283
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1284
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1285
|
+
E extends boolean = false
|
|
1286
|
+
>(
|
|
1287
|
+
path: TFieldName,
|
|
1288
|
+
op: "hasValue" | "notHasValue",
|
|
1289
|
+
value: GetMapV<V>
|
|
1290
|
+
): (
|
|
1291
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1292
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1293
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1294
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1295
|
+
<
|
|
1296
|
+
TFieldValues extends FieldValues,
|
|
1297
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1298
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1299
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1300
|
+
E extends boolean = false
|
|
1301
|
+
>(
|
|
1302
|
+
path: TFieldName,
|
|
1303
|
+
op: "hasKeyValue" | "notHasKeyValue",
|
|
1304
|
+
value: GetMapEntry<V>
|
|
1305
|
+
): (
|
|
1306
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1307
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1308
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1309
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1310
|
+
<
|
|
1311
|
+
TFieldValues extends FieldValues,
|
|
1312
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1313
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1314
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1315
|
+
E extends boolean = false
|
|
1316
|
+
>(
|
|
1317
|
+
path: TFieldName,
|
|
1318
|
+
op: "hasKey-any" | "notHasKey-any" | "hasKey-all" | "notHasKey-all",
|
|
1319
|
+
value: InValues<GetMapK<V>>
|
|
1320
|
+
): (
|
|
1321
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1322
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1323
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1324
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1325
|
+
<
|
|
1326
|
+
TFieldValues extends FieldValues,
|
|
1327
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1328
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1329
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1330
|
+
E extends boolean = false
|
|
1331
|
+
>(
|
|
1332
|
+
path: TFieldName,
|
|
1333
|
+
op: "hasValue-any" | "notHasValue-any" | "hasValue-all" | "notHasValue-all",
|
|
1334
|
+
value: InValues<GetMapV<V>>
|
|
1335
|
+
): (
|
|
1336
|
+
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1337
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1338
|
+
) => IsCurrentInitial extends true ? QueryWhere<TFieldValues>
|
|
1339
|
+
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
1340
|
+
<
|
|
1341
|
+
TFieldValues extends FieldValues,
|
|
1342
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1343
|
+
V extends FieldPathValue<TFieldValues, TFieldName>,
|
|
1344
|
+
TFieldValuesRefined extends TFieldValues = TFieldValues,
|
|
1345
|
+
E extends boolean = false
|
|
1346
|
+
>(
|
|
1347
|
+
path: TFieldName,
|
|
1348
|
+
op: "hasKeyValue-any" | "notHasKeyValue-any" | "hasKeyValue-all" | "notHasKeyValue-all",
|
|
1349
|
+
value: InValues<GetMapEntry<V>>
|
|
1253
1350
|
): (
|
|
1254
1351
|
current: IsCurrentInitial extends true ? Query<TFieldValues>
|
|
1255
1352
|
: QueryWhere<TFieldValues, TFieldValuesRefined, E>
|
|
@@ -1318,12 +1415,12 @@ export type FilterContinuationsWithSubpath = {
|
|
|
1318
1415
|
TFieldName extends FieldPath<TFieldValues>,
|
|
1319
1416
|
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1320
1417
|
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1321
|
-
|
|
1418
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1322
1419
|
>(
|
|
1323
1420
|
subPath: TFieldName,
|
|
1324
1421
|
restPath: TFieldNameSub,
|
|
1325
1422
|
op: "in" | "notIn",
|
|
1326
|
-
value: V
|
|
1423
|
+
value: InValues<V>
|
|
1327
1424
|
): (
|
|
1328
1425
|
current: Query<TFieldValues>
|
|
1329
1426
|
) => QueryWhere<TFieldValues>
|
|
@@ -1357,7 +1454,91 @@ export type FilterContinuationsWithSubpath = {
|
|
|
1357
1454
|
| "notIncludes-any"
|
|
1358
1455
|
| "includes-all"
|
|
1359
1456
|
| "notIncludes-all",
|
|
1360
|
-
value:
|
|
1457
|
+
value: InValues<GetArV<V>>
|
|
1458
|
+
): (
|
|
1459
|
+
current: Query<TFieldValues>
|
|
1460
|
+
) => QueryWhere<TFieldValues>
|
|
1461
|
+
<
|
|
1462
|
+
TFieldValues extends FieldValues,
|
|
1463
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1464
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1465
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1466
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1467
|
+
>(
|
|
1468
|
+
subPath: TFieldName,
|
|
1469
|
+
restPath: TFieldNameSub,
|
|
1470
|
+
op: "hasKey" | "notHasKey",
|
|
1471
|
+
value: GetMapK<V>
|
|
1472
|
+
): (
|
|
1473
|
+
current: Query<TFieldValues>
|
|
1474
|
+
) => QueryWhere<TFieldValues>
|
|
1475
|
+
<
|
|
1476
|
+
TFieldValues extends FieldValues,
|
|
1477
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1478
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1479
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1480
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1481
|
+
>(
|
|
1482
|
+
subPath: TFieldName,
|
|
1483
|
+
restPath: TFieldNameSub,
|
|
1484
|
+
op: "hasValue" | "notHasValue",
|
|
1485
|
+
value: GetMapV<V>
|
|
1486
|
+
): (
|
|
1487
|
+
current: Query<TFieldValues>
|
|
1488
|
+
) => QueryWhere<TFieldValues>
|
|
1489
|
+
<
|
|
1490
|
+
TFieldValues extends FieldValues,
|
|
1491
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1492
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1493
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1494
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1495
|
+
>(
|
|
1496
|
+
subPath: TFieldName,
|
|
1497
|
+
restPath: TFieldNameSub,
|
|
1498
|
+
op: "hasKeyValue" | "notHasKeyValue",
|
|
1499
|
+
value: GetMapEntry<V>
|
|
1500
|
+
): (
|
|
1501
|
+
current: Query<TFieldValues>
|
|
1502
|
+
) => QueryWhere<TFieldValues>
|
|
1503
|
+
<
|
|
1504
|
+
TFieldValues extends FieldValues,
|
|
1505
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1506
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1507
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1508
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1509
|
+
>(
|
|
1510
|
+
subPath: TFieldName,
|
|
1511
|
+
restPath: TFieldNameSub,
|
|
1512
|
+
op: "hasKey-any" | "notHasKey-any" | "hasKey-all" | "notHasKey-all",
|
|
1513
|
+
value: InValues<GetMapK<V>>
|
|
1514
|
+
): (
|
|
1515
|
+
current: Query<TFieldValues>
|
|
1516
|
+
) => QueryWhere<TFieldValues>
|
|
1517
|
+
<
|
|
1518
|
+
TFieldValues extends FieldValues,
|
|
1519
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1520
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1521
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1522
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1523
|
+
>(
|
|
1524
|
+
subPath: TFieldName,
|
|
1525
|
+
restPath: TFieldNameSub,
|
|
1526
|
+
op: "hasValue-any" | "notHasValue-any" | "hasValue-all" | "notHasValue-all",
|
|
1527
|
+
value: InValues<GetMapV<V>>
|
|
1528
|
+
): (
|
|
1529
|
+
current: Query<TFieldValues>
|
|
1530
|
+
) => QueryWhere<TFieldValues>
|
|
1531
|
+
<
|
|
1532
|
+
TFieldValues extends FieldValues,
|
|
1533
|
+
TFieldName extends FieldPath<TFieldValues>,
|
|
1534
|
+
TFieldValuesSub extends TFieldValues[TFieldName][number],
|
|
1535
|
+
TFieldNameSub extends FieldPath<TFieldValuesSub>,
|
|
1536
|
+
V extends FieldPathValue<TFieldValuesSub, TFieldNameSub>
|
|
1537
|
+
>(
|
|
1538
|
+
subPath: TFieldName,
|
|
1539
|
+
restPath: TFieldNameSub,
|
|
1540
|
+
op: "hasKeyValue-any" | "notHasKeyValue-any" | "hasKeyValue-all" | "notHasKeyValue-all",
|
|
1541
|
+
value: InValues<GetMapEntry<V>>
|
|
1361
1542
|
): (
|
|
1362
1543
|
current: Query<TFieldValues>
|
|
1363
1544
|
) => QueryWhere<TFieldValues>
|
package/src/Schema/ext.ts
CHANGED
|
@@ -82,8 +82,6 @@ export const withDefaultParseOptions = <Decode extends DecodeLike>(
|
|
|
82
82
|
return (input: any, options?: SchemaAST.ParseOptions) => run(input, { ...defaultParseOptions, ...options })
|
|
83
83
|
}) as Decode
|
|
84
84
|
|
|
85
|
-
// TODO: v4 migration - Date is no longer by default encoded to string.
|
|
86
|
-
|
|
87
85
|
const DateString = S.String.annotate({
|
|
88
86
|
identifier: "DateOrInvalid",
|
|
89
87
|
description: "an ISO 8601 date string that will be decoded as a Date (may be invalid)",
|
|
@@ -107,18 +105,21 @@ export interface DateFromString extends S.decodeTo<S.Date, S.String> {}
|
|
|
107
105
|
* Encoding:
|
|
108
106
|
* - A `Date` is encoded as a `string`.
|
|
109
107
|
*
|
|
108
|
+
* Use this when the Encoded form must be JSON (`string`). Domain models should
|
|
109
|
+
* prefer {@link Date}, whose Encoded form is `Date`; JSON stores convert via
|
|
110
|
+
* `Schema.toCodecJson`.
|
|
111
|
+
*
|
|
110
112
|
* @since 4.0.0
|
|
111
113
|
*/
|
|
112
114
|
export const DateFromString: DateFromString = DateString.pipe(S.decodeTo(S.Date, SchemaTransformation.dateFromString))
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
export const Date = extendM(DateFromString, (s) => ({
|
|
116
|
+
const dateHelpers = (s: S.Date) => ({
|
|
116
117
|
/**
|
|
117
118
|
* Construction-only default `new Date()`. Applied only when the field is
|
|
118
119
|
* omitted from `.make(...)` input. NOT applied during decode — cannot be
|
|
119
120
|
* used to JIT-migrate database fields. See file-level note.
|
|
120
121
|
*/
|
|
121
|
-
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => new
|
|
122
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => new globalThis.Date()))),
|
|
122
123
|
/**
|
|
123
124
|
* Decode-time default `new Date()`. **Discouraged for persisted data:** a
|
|
124
125
|
* missing field may be data corruption, not an old-shape document; silently
|
|
@@ -126,38 +127,18 @@ export const Date = extendM(DateFromString, (s) => ({
|
|
|
126
127
|
* preferably versioned migration over a decode-time fallback. See
|
|
127
128
|
* file-level note.
|
|
128
129
|
*/
|
|
129
|
-
withDecodingDefaultType: s.pipe(S.withDecodingDefaultType(Effect.sync(() => new
|
|
130
|
-
}))
|
|
131
|
-
|
|
132
|
-
const DateValidString = S.String.annotate({
|
|
133
|
-
identifier: "Date",
|
|
134
|
-
description: "a valid ISO 8601 date string that will be decoded as a Date",
|
|
135
|
-
format: "date-time"
|
|
130
|
+
withDecodingDefaultType: s.pipe(S.withDecodingDefaultType(Effect.sync(() => new globalThis.Date())))
|
|
136
131
|
})
|
|
137
132
|
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
.pipe(
|
|
141
|
-
S.decodeTo(S.Date, SchemaTransformation.dateFromString)
|
|
142
|
-
)
|
|
133
|
+
/** Like the default Schema `Date` (Encoded is `Date`) with default helpers. */
|
|
134
|
+
export const Date = extendM(S.Date, dateHelpers)
|
|
143
135
|
|
|
144
|
-
/**
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
*/
|
|
151
|
-
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => new global.Date()))),
|
|
152
|
-
/**
|
|
153
|
-
* Decode-time default `new Date()`. **Discouraged for persisted data:** a
|
|
154
|
-
* missing field may be data corruption, not an old-shape document; silently
|
|
155
|
-
* substituting `new Date()` hides the problem. Prefer an explicit,
|
|
156
|
-
* preferably versioned migration over a decode-time fallback. See
|
|
157
|
-
* file-level note.
|
|
158
|
-
*/
|
|
159
|
-
withDecodingDefaultType: s.pipe(S.withDecodingDefaultType(Effect.sync(() => new global.Date())))
|
|
160
|
-
}))
|
|
136
|
+
/**
|
|
137
|
+
* Alias of {@link Date}. Core `Schema.Date` already rejects invalid Dates.
|
|
138
|
+
*
|
|
139
|
+
* @deprecated Use {@link Date}.
|
|
140
|
+
*/
|
|
141
|
+
export const DateValid = Date
|
|
161
142
|
|
|
162
143
|
/** Like the default Schema `Boolean` but with default helpers. */
|
|
163
144
|
export const Boolean = Object.assign(S.Boolean, {
|
|
@@ -337,10 +318,10 @@ export const ReadonlyMapFromArray = <KeySchema extends S.Top, ValueSchema extend
|
|
|
337
318
|
return schema
|
|
338
319
|
}
|
|
339
320
|
|
|
340
|
-
/** Like the default Schema `ReadonlySet`
|
|
321
|
+
/** Like the default Schema `ReadonlySet` (Encoded is `Set`) with default helpers. */
|
|
341
322
|
export const ReadonlySet = <ValueSchema extends S.Top>(value: ValueSchema) =>
|
|
342
323
|
pipe(
|
|
343
|
-
|
|
324
|
+
S.ReadonlySet(value),
|
|
344
325
|
(s) =>
|
|
345
326
|
Object.assign(s, {
|
|
346
327
|
/**
|
|
@@ -365,13 +346,13 @@ export const ReadonlySet = <ValueSchema extends S.Top>(value: ValueSchema) =>
|
|
|
365
346
|
})
|
|
366
347
|
)
|
|
367
348
|
|
|
368
|
-
/** Like the default Schema `ReadonlyMap`
|
|
349
|
+
/** Like the default Schema `ReadonlyMap` (Encoded is `Map`) with default helpers. */
|
|
369
350
|
export const ReadonlyMap = <KeySchema extends S.Top, ValueSchema extends S.Top>(pair: {
|
|
370
351
|
readonly key: KeySchema
|
|
371
352
|
readonly value: ValueSchema
|
|
372
353
|
}) =>
|
|
373
354
|
pipe(
|
|
374
|
-
|
|
355
|
+
S.ReadonlyMap(pair.key, pair.value),
|
|
375
356
|
(s) =>
|
|
376
357
|
Object.assign(s, {
|
|
377
358
|
/**
|
|
@@ -503,9 +484,9 @@ export type WithDefaults<Self extends S.Top> = (
|
|
|
503
484
|
// export type UnionToIntersection3<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I
|
|
504
485
|
// : never
|
|
505
486
|
|
|
506
|
-
/** Union of core `Schema.Date` (Date objects) and string-encoded `
|
|
487
|
+
/** Union of core `Schema.Date` (Date objects) and string-encoded `DateFromString`, with default helpers. */
|
|
507
488
|
export const inputDate = extendM(
|
|
508
|
-
S.Union([S.Date,
|
|
489
|
+
S.Union([S.Date, DateFromString]),
|
|
509
490
|
(s) => ({
|
|
510
491
|
/**
|
|
511
492
|
* Construction-only default `new Date()`. Applied only when the field is
|
package/src/Store.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { FieldPath } from "./Model/filter/types/path/index.ts"
|
|
|
11
11
|
import type { AggregateIrExpression, ComputedProjectionIrExpression, RawQuery } from "./Model/query.ts"
|
|
12
12
|
import type * as Option from "./Option.ts"
|
|
13
13
|
import * as RequestScopedDependencies from "./RequestScopedDependencies.ts"
|
|
14
|
-
import { NonEmptyString255 } from "./Schema.ts"
|
|
14
|
+
import { NonEmptyString255, type Top as SchemaTop } from "./Schema.ts"
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Adapter-neutral unique-key definition for stores that support unique indexes,
|
|
@@ -46,6 +46,13 @@ export interface StoreConfig<E> {
|
|
|
46
46
|
* Unique indexes, mainly for CosmosDB
|
|
47
47
|
*/
|
|
48
48
|
uniqueKeys?: UniqueKey[]
|
|
49
|
+
/**
|
|
50
|
+
* Domain schema whose Encoded shape is stored. JSON adapters use
|
|
51
|
+
* `Schema.toCodecJson(Schema.toEncoded(schema))` for documents, query
|
|
52
|
+
* values, and defaults. Date/Map/Set (and app types such as DateOnly)
|
|
53
|
+
* stay native on Encoded and lower only on this JSON boundary.
|
|
54
|
+
*/
|
|
55
|
+
schema?: SchemaTop
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
export type SupportedValues = string | boolean | number | null
|
package/test/schema.test.ts
CHANGED
|
@@ -265,14 +265,13 @@ test("TaggedUnion match dispatches on _tag", () => {
|
|
|
265
265
|
S.TaggedStruct("A", { a: S.String }),
|
|
266
266
|
S.TaggedStruct("B", { b: S.Finite })
|
|
267
267
|
])
|
|
268
|
-
type T = S.Schema.Type<typeof schema>
|
|
269
268
|
|
|
270
269
|
const matcher = schema.match({
|
|
271
270
|
A: (v) => `got A: ${v.a}`,
|
|
272
271
|
B: (v) => `got B: ${v.b}`
|
|
273
272
|
})
|
|
274
|
-
expect(matcher({ _tag: "A", a: "hello" }
|
|
275
|
-
expect(matcher({ _tag: "B", b: 42 }
|
|
273
|
+
expect(matcher({ _tag: "A", a: "hello" })).toBe("got A: hello")
|
|
274
|
+
expect(matcher({ _tag: "B", b: 42 })).toBe("got B: 42")
|
|
276
275
|
})
|
|
277
276
|
|
|
278
277
|
test("TaggedUnion with single member", () => {
|
|
@@ -319,8 +318,7 @@ test("TaggedUnion with encodeKeys renaming a non-tag key", () => {
|
|
|
319
318
|
expect(decoded2).toEqual({ _tag: "B", lastName: 42 })
|
|
320
319
|
|
|
321
320
|
// encode back to snake_case
|
|
322
|
-
|
|
323
|
-
const encoded = S.encodeSync(schema)({ _tag: "A", firstName: "Alice" } as T)
|
|
321
|
+
const encoded = S.encodeSync(schema)({ _tag: "A", firstName: "Alice" })
|
|
324
322
|
expect(encoded).toEqual({ _tag: "A", first_name: "Alice" })
|
|
325
323
|
|
|
326
324
|
// guards work on decoded values
|
|
@@ -387,7 +385,7 @@ describe("ReadonlySetFromArray", () => {
|
|
|
387
385
|
|
|
388
386
|
describe("ReadonlyMapFromArray", () => {
|
|
389
387
|
test("decodes an array of tuples to a Map", () => {
|
|
390
|
-
const schema = S.
|
|
388
|
+
const schema = S.ReadonlyMapFromArray({ key: S.String, value: S.Finite })
|
|
391
389
|
const decoded = S.decodeUnknownSync(schema)([["a", 1], ["b", 2]])
|
|
392
390
|
expect(decoded).toEqual(new Map([["a", 1], ["b", 2]]))
|
|
393
391
|
})
|
|
@@ -445,11 +443,18 @@ describe("ReadonlySet (with withConstructorDefault)", () => {
|
|
|
445
443
|
expect(made.items).toEqual(new Set())
|
|
446
444
|
})
|
|
447
445
|
|
|
448
|
-
test("decodes
|
|
446
|
+
test("decodes a Set with NumberFromString values", () => {
|
|
449
447
|
const schema = S.ReadonlySet(S.NumberFromString)
|
|
450
|
-
const decoded = S.decodeUnknownSync(schema)(["1", "2"])
|
|
448
|
+
const decoded = S.decodeUnknownSync(schema)(new Set(["1", "2"]))
|
|
451
449
|
expect(decoded).toEqual(new Set([1, 2]))
|
|
452
450
|
})
|
|
451
|
+
|
|
452
|
+
test("Encoded is a Set, not an array", () => {
|
|
453
|
+
const schema = S.ReadonlySet(S.String)
|
|
454
|
+
const encoded = S.encodeSync(schema)(new Set(["a"]))
|
|
455
|
+
expect(encoded).toEqual(new Set(["a"]))
|
|
456
|
+
expectTypeOf(encoded).toEqualTypeOf<ReadonlySet<string>>()
|
|
457
|
+
})
|
|
453
458
|
})
|
|
454
459
|
|
|
455
460
|
describe("ReadonlyMap (with withConstructorDefault)", () => {
|
|
@@ -460,11 +465,18 @@ describe("ReadonlyMap (with withConstructorDefault)", () => {
|
|
|
460
465
|
expect(made.items).toEqual(new Map())
|
|
461
466
|
})
|
|
462
467
|
|
|
463
|
-
test("decodes
|
|
468
|
+
test("decodes a Map with NumberFromString keys", () => {
|
|
464
469
|
const schema = S.ReadonlyMap({ key: S.NumberFromString, value: S.String })
|
|
465
|
-
const decoded = S.decodeUnknownSync(schema)([["1", "one"]])
|
|
470
|
+
const decoded = S.decodeUnknownSync(schema)(new Map([["1", "one"]]))
|
|
466
471
|
expect(decoded).toEqual(new Map([[1, "one"]]))
|
|
467
472
|
})
|
|
473
|
+
|
|
474
|
+
test("Encoded is a Map, not an array of tuples", () => {
|
|
475
|
+
const schema = S.ReadonlyMap({ key: S.String, value: S.Finite })
|
|
476
|
+
const encoded = S.encodeSync(schema)(new Map([["a", 1]]))
|
|
477
|
+
expect(encoded).toEqual(new Map([["a", 1]]))
|
|
478
|
+
expectTypeOf(encoded).toEqualTypeOf<ReadonlyMap<string, number>>()
|
|
479
|
+
})
|
|
468
480
|
})
|
|
469
481
|
|
|
470
482
|
describe("JSON Schema", () => {
|
|
@@ -506,8 +518,18 @@ describe("JSON Schema", () => {
|
|
|
506
518
|
})
|
|
507
519
|
})
|
|
508
520
|
|
|
509
|
-
test("Date
|
|
521
|
+
test("Date Encoded is Date; JSON codec encodes ISO strings", () => {
|
|
522
|
+
const d = new Date("2024-01-01T00:00:00.000Z")
|
|
523
|
+
expect(S.decodeUnknownSync(S.Date)(d)).toBe(d)
|
|
524
|
+
expect(S.encodeSync(S.Date)(d)).toBe(d)
|
|
525
|
+
expect(S.encodeSync(S.toCodecJson(S.Date))(d)).toBe("2024-01-01T00:00:00.000Z")
|
|
510
526
|
const doc = S.toJsonSchemaDocument(S.Date)
|
|
527
|
+
expect(doc.dialect).toBe("draft-2020-12")
|
|
528
|
+
expect(doc.schema).toEqual({ type: "string" })
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
test("DateFromString keeps string Encoded", () => {
|
|
532
|
+
const doc = S.toJsonSchemaDocument(S.DateFromString)
|
|
511
533
|
expect(doc).toStrictEqual({
|
|
512
534
|
dialect: "draft-2020-12",
|
|
513
535
|
schema: { "$ref": "#/$defs/DateOrInvalid" },
|
|
@@ -521,21 +543,6 @@ describe("JSON Schema", () => {
|
|
|
521
543
|
})
|
|
522
544
|
})
|
|
523
545
|
|
|
524
|
-
test("DateValid has identifier Date and ISO 8601 description", () => {
|
|
525
|
-
const doc = S.toJsonSchemaDocument(S.DateValid)
|
|
526
|
-
expect(doc).toStrictEqual({
|
|
527
|
-
dialect: "draft-2020-12",
|
|
528
|
-
schema: { "$ref": "#/$defs/Date" },
|
|
529
|
-
definitions: {
|
|
530
|
-
Date: {
|
|
531
|
-
type: "string",
|
|
532
|
-
description: "a valid ISO 8601 date string that will be decoded as a Date",
|
|
533
|
-
format: "date-time"
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
})
|
|
537
|
-
})
|
|
538
|
-
|
|
539
546
|
test("PhoneNumber has format phone", () => {
|
|
540
547
|
const doc = specialJsonSchemaDocument(S.PhoneNumber)
|
|
541
548
|
expect(doc).toStrictEqual({
|