effect-app 4.0.0-beta.32 → 4.0.0-beta.321
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 +1570 -0
- package/dist/Array.d.ts +2 -1
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -4
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Config/SecretURL.d.ts +3 -1
- package/dist/Config/SecretURL.d.ts.map +1 -1
- package/dist/Config/SecretURL.js +3 -6
- package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
- package/dist/Config/internal/configSecretURL.js +2 -2
- package/dist/Config.d.ts +2 -0
- package/dist/Config.d.ts.map +1 -0
- package/dist/Config.js +8 -0
- package/dist/ConfigProvider.d.ts +2 -0
- package/dist/ConfigProvider.d.ts.map +1 -0
- package/dist/ConfigProvider.js +6 -0
- package/dist/{ServiceMap.d.ts → Context.d.ts} +18 -20
- package/dist/Context.d.ts.map +1 -0
- package/dist/Context.js +67 -0
- package/dist/DataDependencies.d.ts +136 -0
- package/dist/DataDependencies.d.ts.map +1 -0
- package/dist/DataDependencies.js +112 -0
- package/dist/Effect.d.ts +10 -9
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +6 -9
- package/dist/Emailer.d.ts +51 -0
- package/dist/Emailer.d.ts.map +1 -0
- package/dist/Emailer.js +7 -0
- package/dist/Function.d.ts.map +1 -1
- package/dist/Layer.d.ts +10 -6
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +3 -2
- package/dist/Model/Repository/Registry.d.ts +22 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +18 -0
- package/dist/Model/Repository/dependency.d.ts +6 -0
- package/dist/Model/Repository/dependency.d.ts.map +1 -0
- package/dist/Model/Repository/dependency.js +29 -0
- package/dist/Model/Repository/ext.d.ts +60 -0
- package/dist/Model/Repository/ext.d.ts.map +1 -0
- package/dist/Model/Repository/ext.js +124 -0
- package/dist/Model/Repository/internal/internal.d.ts +68 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
- package/dist/Model/Repository/internal/internal.js +579 -0
- package/dist/Model/Repository/legacy.d.ts +21 -0
- package/dist/Model/Repository/legacy.d.ts.map +1 -0
- package/dist/Model/Repository/legacy.js +2 -0
- package/dist/Model/Repository/makeRepo.d.ts +63 -0
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
- package/dist/Model/Repository/makeRepo.js +27 -0
- package/dist/Model/Repository/service.d.ts +121 -0
- package/dist/Model/Repository/service.d.ts.map +1 -0
- package/dist/Model/Repository/service.js +2 -0
- package/dist/Model/Repository/validation.d.ts +58 -0
- package/dist/Model/Repository/validation.d.ts.map +1 -0
- package/dist/Model/Repository/validation.js +32 -0
- package/dist/Model/Repository.d.ts +8 -0
- package/dist/Model/Repository.d.ts.map +1 -0
- package/dist/Model/Repository.js +8 -0
- package/dist/Model/dsl.d.ts +33 -0
- package/dist/Model/dsl.d.ts.map +1 -0
- package/dist/Model/dsl.js +43 -0
- package/dist/Model/filter/filterApi.d.ts +30 -0
- package/dist/Model/filter/filterApi.d.ts.map +1 -0
- package/dist/Model/filter/filterApi.js +2 -0
- package/dist/Model/filter/types/errors.d.ts +29 -0
- package/dist/Model/filter/types/errors.d.ts.map +1 -0
- package/dist/Model/filter/types/errors.js +2 -0
- package/dist/Model/filter/types/fields.d.ts +15 -0
- package/dist/Model/filter/types/fields.d.ts.map +1 -0
- package/dist/Model/filter/types/fields.js +2 -0
- package/dist/Model/filter/types/path/common.d.ts +316 -0
- package/dist/Model/filter/types/path/common.d.ts.map +1 -0
- package/dist/Model/filter/types/path/common.js +2 -0
- package/dist/Model/filter/types/path/eager.d.ts +94 -0
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
- package/dist/Model/filter/types/path/eager.js +36 -0
- package/dist/Model/filter/types/path/index.d.ts +4 -0
- package/dist/Model/filter/types/path/index.d.ts.map +1 -0
- package/dist/Model/filter/types/path/index.js +3 -0
- package/dist/Model/filter/types/utils.d.ts +79 -0
- package/dist/Model/filter/types/utils.d.ts.map +1 -0
- package/dist/Model/filter/types/utils.js +2 -0
- package/dist/Model/filter/types/validator.d.ts +30 -0
- package/dist/Model/filter/types/validator.d.ts.map +1 -0
- package/dist/Model/filter/types/validator.js +2 -0
- package/dist/Model/filter/types.d.ts +5 -0
- package/dist/Model/filter/types.d.ts.map +1 -0
- package/dist/Model/filter/types.js +7 -0
- package/dist/Model/query/dsl.d.ts +630 -0
- package/dist/Model/query/dsl.d.ts.map +1 -0
- package/dist/Model/query/dsl.js +376 -0
- package/dist/Model/query/new-kid-interpreter.d.ts +132 -0
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
- package/dist/Model/query/new-kid-interpreter.js +370 -0
- package/dist/Model/query.d.ts +15 -0
- package/dist/Model/query.d.ts.map +1 -0
- package/dist/Model/query.js +3 -0
- package/dist/Model.d.ts +6 -0
- package/dist/Model.d.ts.map +1 -0
- package/dist/Model.js +6 -0
- package/dist/NonEmptySet.d.ts +3 -1
- package/dist/NonEmptySet.d.ts.map +1 -1
- package/dist/NonEmptySet.js +2 -2
- package/dist/Option.d.ts +1 -0
- package/dist/Option.d.ts.map +1 -1
- package/dist/Option.js +3 -1
- package/dist/Pure.d.ts +7 -5
- package/dist/Pure.d.ts.map +1 -1
- package/dist/Pure.js +7 -4
- package/dist/QueueMaker.d.ts +11 -0
- package/dist/QueueMaker.d.ts.map +1 -0
- package/dist/QueueMaker.js +11 -0
- package/dist/RequestContext.d.ts +87 -0
- package/dist/RequestContext.d.ts.map +1 -0
- package/dist/RequestContext.js +45 -0
- package/dist/RequestScopedDependencies.d.ts +21 -0
- package/dist/RequestScopedDependencies.d.ts.map +1 -0
- package/dist/RequestScopedDependencies.js +16 -0
- package/dist/Schema/Class.d.ts +200 -20
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +268 -17
- package/dist/Schema/FastCheck.d.ts.map +1 -1
- package/dist/Schema/SchemaParser.d.ts +5 -0
- package/dist/Schema/SchemaParser.d.ts.map +1 -0
- package/dist/Schema/SchemaParser.js +6 -0
- package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
- package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
- package/dist/Schema/SpecialJsonSchema.js +117 -0
- package/dist/Schema/SpecialOpenApi.d.ts +32 -0
- package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
- package/dist/Schema/SpecialOpenApi.js +123 -0
- package/dist/Schema/brand.d.ts +5 -5
- package/dist/Schema/brand.d.ts.map +1 -1
- package/dist/Schema/brand.js +3 -1
- package/dist/Schema/email.d.ts.map +1 -1
- package/dist/Schema/email.js +7 -6
- package/dist/Schema/ext.d.ts +337 -56
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +381 -58
- package/dist/Schema/moreStrings.d.ts +82 -36
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +47 -51
- package/dist/Schema/numbers.d.ts +34 -21
- package/dist/Schema/numbers.d.ts.map +1 -1
- package/dist/Schema/numbers.js +55 -12
- package/dist/Schema/phoneNumber.d.ts.map +1 -1
- package/dist/Schema/phoneNumber.js +6 -6
- package/dist/Schema/schema.d.ts +1 -1
- package/dist/Schema/schema.d.ts.map +1 -1
- package/dist/Schema/schema.js +2 -2
- package/dist/Schema/strings.d.ts +18 -4
- package/dist/Schema/strings.d.ts.map +1 -1
- package/dist/Schema/strings.js +1 -5
- package/dist/Schema.d.ts +225 -7
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +193 -26
- package/dist/SchemaAST.d.ts +2 -0
- package/dist/SchemaAST.d.ts.map +1 -0
- package/dist/SchemaAST.js +2 -0
- package/dist/Set.d.ts +4 -1
- package/dist/Set.d.ts.map +1 -1
- package/dist/Set.js +3 -2
- package/dist/Store.d.ts +170 -0
- package/dist/Store.d.ts.map +1 -0
- package/dist/Store.js +113 -0
- package/dist/_ext/Array.d.ts +1 -1
- package/dist/_ext/Array.d.ts.map +1 -1
- package/dist/_ext/Array.js +4 -2
- package/dist/_ext/misc.d.ts +4 -1
- package/dist/_ext/misc.d.ts.map +1 -1
- package/dist/_ext/misc.js +4 -2
- package/dist/_ext/ord.ext.d.ts +2 -1
- package/dist/_ext/ord.ext.d.ts.map +1 -1
- package/dist/_ext/ord.ext.js +2 -2
- package/dist/builtin.d.ts +2 -14
- package/dist/builtin.d.ts.map +1 -1
- package/dist/builtin.js +1 -1
- package/dist/client/InvalidationKeys.d.ts +30 -0
- package/dist/client/InvalidationKeys.d.ts.map +1 -0
- package/dist/client/InvalidationKeys.js +37 -0
- package/dist/client/apiClientFactory.d.ts +19 -31
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +157 -39
- package/dist/client/clientFor.d.ts +54 -18
- package/dist/client/clientFor.d.ts.map +1 -1
- package/dist/client/clientFor.js +9 -1
- package/dist/client/errors.d.ts +82 -27
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +75 -19
- package/dist/client/makeClient.d.ts +490 -34
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +62 -30
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -1
- package/dist/faker.d.ts.map +1 -1
- package/dist/http/Request.d.ts +1 -1
- package/dist/http/Request.d.ts.map +1 -1
- package/dist/http/Request.js +2 -2
- package/dist/ids.d.ts +42 -14
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +30 -5
- package/dist/index.d.ts +6 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/middleware.d.ts +13 -7
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +14 -8
- package/dist/rpc/Invalidation.d.ts +1124 -0
- package/dist/rpc/Invalidation.d.ts.map +1 -0
- package/dist/rpc/Invalidation.js +178 -0
- package/dist/rpc/MiddlewareMaker.d.ts +11 -7
- package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
- package/dist/rpc/MiddlewareMaker.js +59 -38
- package/dist/rpc/RpcContextMap.d.ts +3 -3
- package/dist/rpc/RpcContextMap.d.ts.map +1 -1
- package/dist/rpc/RpcContextMap.js +4 -4
- package/dist/rpc/RpcMiddleware.d.ts +14 -10
- package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/rpc/RpcMiddleware.js +1 -1
- package/dist/rpc.d.ts +1 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -2
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +40 -0
- package/dist/setupRequest.d.ts +20 -0
- package/dist/setupRequest.d.ts.map +1 -0
- package/dist/setupRequest.js +72 -0
- package/dist/toast.d.ts +51 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +34 -0
- package/dist/transform.d.ts +1 -1
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +4 -5
- package/dist/utils/effectify.d.ts +1 -1
- package/dist/utils/effectify.d.ts.map +1 -1
- package/dist/utils/effectify.js +2 -2
- package/dist/utils/extend.d.ts.map +1 -1
- package/dist/utils/gen.d.ts +4 -4
- package/dist/utils/gen.d.ts.map +1 -1
- package/dist/utils/logLevel.d.ts +2 -2
- package/dist/utils/logLevel.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +4 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +4 -4
- package/dist/utils.d.ts +34 -39
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +33 -37
- package/dist/validation/validators.d.ts.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/withToast.d.ts +30 -0
- package/dist/withToast.d.ts.map +1 -0
- package/dist/withToast.js +64 -0
- package/package.json +27 -251
- package/src/Array.ts +5 -5
- package/src/Chunk.ts +3 -3
- package/src/Config/SecretURL.ts +6 -3
- package/src/Config/internal/configSecretURL.ts +2 -2
- package/src/Config.ts +7 -0
- package/src/ConfigProvider.ts +5 -0
- package/src/{ServiceMap.ts → Context.ts} +56 -63
- package/src/DataDependencies.ts +171 -0
- package/src/Effect.ts +15 -17
- package/src/Emailer.ts +51 -0
- package/src/Inputify.type.ts +1 -1
- package/src/Layer.ts +11 -7
- package/src/Model/Repository/Registry.ts +35 -0
- package/src/Model/Repository/dependency.ts +32 -0
- package/src/Model/Repository/ext.ts +374 -0
- package/src/Model/Repository/internal/internal.ts +950 -0
- package/src/Model/Repository/legacy.ts +29 -0
- package/src/Model/Repository/makeRepo.ts +156 -0
- package/src/Model/Repository/service.ts +676 -0
- package/src/Model/Repository/validation.ts +31 -0
- package/src/Model/Repository.ts +7 -0
- package/src/Model/dsl.ts +129 -0
- package/src/Model/filter/filterApi.ts +78 -0
- package/src/Model/filter/types/errors.ts +47 -0
- package/src/Model/filter/types/fields.ts +50 -0
- package/src/Model/filter/types/path/common.ts +404 -0
- package/src/Model/filter/types/path/eager.ts +329 -0
- package/src/Model/filter/types/path/index.ts +4 -0
- package/src/Model/filter/types/utils.ts +128 -0
- package/src/Model/filter/types/validator.ts +46 -0
- package/src/Model/filter/types.ts +6 -0
- package/src/Model/query/dsl.ts +3092 -0
- package/src/Model/query/new-kid-interpreter.ts +532 -0
- package/src/Model/query.ts +13 -0
- package/src/Model.ts +5 -0
- package/src/NonEmptySet.ts +6 -4
- package/src/Option.ts +2 -0
- package/src/Pure.ts +10 -7
- package/src/QueueMaker.ts +11 -0
- package/src/RequestContext.ts +48 -0
- package/src/RequestScopedDependencies.ts +45 -0
- package/src/Schema/Class.ts +648 -60
- package/src/Schema/SchemaParser.ts +12 -0
- package/src/Schema/SpecialJsonSchema.ts +137 -0
- package/src/Schema/SpecialOpenApi.ts +130 -0
- package/src/Schema/brand.ts +24 -9
- package/src/Schema/email.ts +9 -7
- package/src/Schema/ext.ts +502 -98
- package/src/Schema/moreStrings.ts +145 -83
- package/src/Schema/numbers.ts +97 -28
- package/src/Schema/phoneNumber.ts +8 -8
- package/src/Schema/schema.ts +1 -1
- package/src/Schema/strings.ts +23 -14
- package/src/Schema.ts +403 -46
- package/src/SchemaAST.ts +1 -0
- package/src/Set.ts +6 -2
- package/src/Store.ts +280 -0
- package/src/_ext/Array.ts +4 -2
- package/src/_ext/misc.ts +4 -1
- package/src/_ext/ord.ext.ts +2 -1
- package/src/builtin-json.d.ts +24 -0
- package/src/builtin.ts +16 -21
- package/src/client/InvalidationKeys.ts +55 -0
- package/src/client/apiClientFactory.ts +301 -141
- package/src/client/clientFor.ts +107 -34
- package/src/client/errors.ts +100 -29
- package/src/client/makeClient.ts +594 -80
- package/src/client.ts +6 -4
- package/src/http/Request.ts +3 -3
- package/src/http.ts +1 -1
- package/src/ids.ts +33 -6
- package/src/index.ts +20 -23
- package/src/middleware.ts +13 -9
- package/src/rpc/Invalidation.ts +278 -0
- package/src/rpc/MiddlewareMaker.ts +88 -80
- package/src/rpc/README.md +2 -2
- package/src/rpc/RpcContextMap.ts +7 -6
- package/src/rpc/RpcMiddleware.ts +19 -13
- package/src/rpc.ts +4 -4
- package/src/runtime.ts +57 -0
- package/src/setupRequest.ts +138 -0
- package/src/toast.ts +54 -0
- package/src/transform.ts +4 -4
- package/src/utils/effectify.ts +1 -1
- package/src/utils/gen.ts +8 -8
- package/src/utils/logLevel.ts +1 -1
- package/src/utils/logger.ts +4 -3
- package/src/utils.ts +85 -158
- package/src/validation.ts +2 -2
- package/src/withToast.ts +133 -0
- package/test/dist/rpc.test.d.ts.map +1 -1
- package/test/dist/rpcMiddlewareContext.test.d.ts.map +1 -0
- package/test/dist/secretURL.test.d.ts.map +1 -0
- package/test/dist/special.test.d.ts.map +1 -0
- package/test/moreStrings.test.ts +7 -9
- package/test/rpc.test.ts +42 -14
- package/test/rpcMiddlewareContext.test.ts +63 -0
- package/test/schema.test.ts +514 -35
- package/test/secretURL.test.ts +160 -0
- package/test/special.test.ts +1261 -0
- package/test/utils.test.ts +7 -7
- package/tsconfig.base.json +6 -5
- package/tsconfig.json +9 -2
- package/tsconfig.src.json +29 -29
- package/tsconfig.test.json +2 -2
- package/dist/Operations.d.ts +0 -123
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -29
- package/dist/ServiceMap.d.ts.map +0 -1
- package/dist/ServiceMap.js +0 -91
- package/eslint.config.mjs +0 -26
- package/src/Operations.ts +0 -55
- package/tsconfig.json.bak +0 -12
|
@@ -1,21 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Branded string ID schemas with `.withConstructorDefault` extensions.
|
|
3
|
+
*
|
|
4
|
+
* Each `.withConstructorDefault` here is **only** applied when the field is
|
|
5
|
+
* omitted during construction (`.make(...)`). It is **not** applied during
|
|
6
|
+
* decode and therefore cannot be used to JIT-migrate database fields.
|
|
7
|
+
*
|
|
8
|
+
* For persisted data, prefer an explicit, preferably versioned migration
|
|
9
|
+
* over decode-time fallbacks. See `./ext.ts` for the full policy note.
|
|
10
|
+
*/
|
|
2
11
|
import type { Refinement } from "effect-app/Function"
|
|
3
12
|
import { extendM } from "effect-app/utils"
|
|
13
|
+
import type * as B from "effect/Brand"
|
|
14
|
+
import * as Effect from "effect/Effect"
|
|
15
|
+
import { pipe } from "effect/Function"
|
|
4
16
|
import * as S from "effect/Schema"
|
|
5
17
|
import type { Simplify } from "effect/Types"
|
|
6
|
-
import {
|
|
18
|
+
import { nanoid } from "nanoid"
|
|
7
19
|
import validator from "validator"
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import type
|
|
20
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
21
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
22
|
+
import { withDefaultMake } from "./ext.ts"
|
|
23
|
+
import { type B as SchemaB } from "./schema.ts"
|
|
24
|
+
import type { NonEmptyString255Brand, NonEmptyStringBrand } from "./strings.ts"
|
|
12
25
|
|
|
13
26
|
const nonEmptyString = S.NonEmptyString
|
|
14
27
|
|
|
15
28
|
/**
|
|
16
29
|
* A string that is at least 1 character long and a maximum of 50.
|
|
17
30
|
*/
|
|
18
|
-
export interface NonEmptyString50Brand extends Simplify<
|
|
31
|
+
export interface NonEmptyString50Brand extends Simplify<SchemaB.Brand<"NonEmptyString50"> & NonEmptyString64Brand> {}
|
|
19
32
|
|
|
20
33
|
/**
|
|
21
34
|
* A string that is at least 1 character long and a maximum of 50.
|
|
@@ -25,11 +38,13 @@ export type NonEmptyString50 = string & NonEmptyString50Brand
|
|
|
25
38
|
/**
|
|
26
39
|
* A string that is at least 1 character long and a maximum of 50.
|
|
27
40
|
*/
|
|
28
|
-
export
|
|
41
|
+
export interface NonEmptyString50Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString50> {
|
|
42
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString50
|
|
43
|
+
}
|
|
44
|
+
export const NonEmptyString50: NonEmptyString50Schema = nonEmptyString.pipe(
|
|
29
45
|
S.check(S.isMaxLength(50)),
|
|
30
|
-
fromBrand(nominal<NonEmptyString50>(), {
|
|
46
|
+
fromBrand<NonEmptyString50>(nominal<NonEmptyString50>(), {
|
|
31
47
|
identifier: "NonEmptyString50",
|
|
32
|
-
title: "NonEmptyString50",
|
|
33
48
|
jsonSchema: {}
|
|
34
49
|
}),
|
|
35
50
|
withDefaultMake
|
|
@@ -38,7 +53,7 @@ export const NonEmptyString50 = nonEmptyString.pipe(
|
|
|
38
53
|
/**
|
|
39
54
|
* A string that is at least 1 character long and a maximum of 64.
|
|
40
55
|
*/
|
|
41
|
-
export interface NonEmptyString64Brand extends Simplify<
|
|
56
|
+
export interface NonEmptyString64Brand extends Simplify<SchemaB.Brand<"NonEmptyString64"> & NonEmptyString80Brand> {}
|
|
42
57
|
|
|
43
58
|
/**
|
|
44
59
|
* A string that is at least 1 character long and a maximum of 64.
|
|
@@ -48,11 +63,13 @@ export type NonEmptyString64 = string & NonEmptyString64Brand
|
|
|
48
63
|
/**
|
|
49
64
|
* A string that is at least 1 character long and a maximum of 64.
|
|
50
65
|
*/
|
|
51
|
-
export
|
|
66
|
+
export interface NonEmptyString64Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString64> {
|
|
67
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString64
|
|
68
|
+
}
|
|
69
|
+
export const NonEmptyString64: NonEmptyString64Schema = nonEmptyString.pipe(
|
|
52
70
|
S.check(S.isMaxLength(64)),
|
|
53
|
-
fromBrand(nominal<NonEmptyString64>(), {
|
|
71
|
+
fromBrand<NonEmptyString64>(nominal<NonEmptyString64>(), {
|
|
54
72
|
identifier: "NonEmptyString64",
|
|
55
|
-
title: "NonEmptyString64",
|
|
56
73
|
jsonSchema: {}
|
|
57
74
|
}),
|
|
58
75
|
withDefaultMake
|
|
@@ -61,7 +78,7 @@ export const NonEmptyString64 = nonEmptyString.pipe(
|
|
|
61
78
|
/**
|
|
62
79
|
* A string that is at least 1 character long and a maximum of 80.
|
|
63
80
|
*/
|
|
64
|
-
export interface NonEmptyString80Brand extends Simplify<
|
|
81
|
+
export interface NonEmptyString80Brand extends Simplify<SchemaB.Brand<"NonEmptyString80"> & NonEmptyString100Brand> {}
|
|
65
82
|
|
|
66
83
|
/**
|
|
67
84
|
* A string that is at least 1 character long and a maximum of 80.
|
|
@@ -72,11 +89,13 @@ export type NonEmptyString80 = string & NonEmptyString80Brand
|
|
|
72
89
|
* A string that is at least 1 character long and a maximum of 80.
|
|
73
90
|
*/
|
|
74
91
|
|
|
75
|
-
export
|
|
92
|
+
export interface NonEmptyString80Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString80> {
|
|
93
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString80
|
|
94
|
+
}
|
|
95
|
+
export const NonEmptyString80: NonEmptyString80Schema = nonEmptyString.pipe(
|
|
76
96
|
S.check(S.isMaxLength(80)),
|
|
77
|
-
fromBrand(nominal<NonEmptyString80>(), {
|
|
97
|
+
fromBrand<NonEmptyString80>(nominal<NonEmptyString80>(), {
|
|
78
98
|
identifier: "NonEmptyString80",
|
|
79
|
-
title: "NonEmptyString80",
|
|
80
99
|
jsonSchema: {}
|
|
81
100
|
}),
|
|
82
101
|
withDefaultMake
|
|
@@ -85,7 +104,7 @@ export const NonEmptyString80 = nonEmptyString.pipe(
|
|
|
85
104
|
/**
|
|
86
105
|
* A string that is at least 1 character long and a maximum of 100.
|
|
87
106
|
*/
|
|
88
|
-
export interface NonEmptyString100Brand extends Simplify<
|
|
107
|
+
export interface NonEmptyString100Brand extends Simplify<SchemaB.Brand<"NonEmptyString100"> & NonEmptyString255Brand> {}
|
|
89
108
|
|
|
90
109
|
/**
|
|
91
110
|
* A string that is at least 1 character long and a maximum of 100.
|
|
@@ -95,11 +114,13 @@ export type NonEmptyString100 = string & NonEmptyString100Brand
|
|
|
95
114
|
/**
|
|
96
115
|
* A string that is at least 1 character long and a maximum of 100.
|
|
97
116
|
*/
|
|
98
|
-
export
|
|
117
|
+
export interface NonEmptyString100Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString100> {
|
|
118
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString100
|
|
119
|
+
}
|
|
120
|
+
export const NonEmptyString100: NonEmptyString100Schema = nonEmptyString.pipe(
|
|
99
121
|
S.check(S.isMaxLength(100)),
|
|
100
|
-
fromBrand(nominal<NonEmptyString100>(), {
|
|
122
|
+
fromBrand<NonEmptyString100>(nominal<NonEmptyString100>(), {
|
|
101
123
|
identifier: "NonEmptyString100",
|
|
102
|
-
title: "NonEmptyString100",
|
|
103
124
|
jsonSchema: {}
|
|
104
125
|
}),
|
|
105
126
|
withDefaultMake
|
|
@@ -108,7 +129,7 @@ export const NonEmptyString100 = nonEmptyString.pipe(
|
|
|
108
129
|
/**
|
|
109
130
|
* A string that is at least 3 character long and a maximum of 255.
|
|
110
131
|
*/
|
|
111
|
-
export interface Min3String255Brand extends Simplify<
|
|
132
|
+
export interface Min3String255Brand extends Simplify<SchemaB.Brand<"Min3String255"> & NonEmptyString255Brand> {}
|
|
112
133
|
|
|
113
134
|
/**
|
|
114
135
|
* A string that is at least 3 character long and a maximum of 255.
|
|
@@ -118,58 +139,79 @@ export type Min3String255 = string & Min3String255Brand
|
|
|
118
139
|
/**
|
|
119
140
|
* A string that is at least 3 character long and a maximum of 255.
|
|
120
141
|
*/
|
|
121
|
-
export
|
|
142
|
+
export interface Min3String255Schema extends BrandedSchema<S.String, Min3String255> {
|
|
143
|
+
(i: string, options?: SchemaAST.ParseOptions): Min3String255
|
|
144
|
+
}
|
|
145
|
+
export const Min3String255: Min3String255Schema = pipe(
|
|
122
146
|
S.String,
|
|
123
147
|
S.check(S.isMinLength(3), S.isMaxLength(255)),
|
|
124
|
-
fromBrand(nominal<Min3String255>(), {
|
|
148
|
+
fromBrand<Min3String255>(nominal<Min3String255>(), {
|
|
149
|
+
identifier: "Min3String255",
|
|
150
|
+
jsonSchema: {}
|
|
151
|
+
}),
|
|
125
152
|
withDefaultMake
|
|
126
153
|
)
|
|
127
154
|
|
|
128
155
|
/**
|
|
129
156
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
130
157
|
*/
|
|
131
|
-
export interface StringIdBrand extends Simplify<
|
|
158
|
+
export interface StringIdBrand extends Simplify<SchemaB.Brand<"StringId"> & NonEmptyString50Brand> {}
|
|
132
159
|
|
|
133
160
|
/**
|
|
134
161
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
135
162
|
*/
|
|
136
163
|
export type StringId = string & StringIdBrand
|
|
137
164
|
|
|
138
|
-
const makeStringId = (): StringId => nanoid() as unknown as StringId
|
|
139
165
|
const minLength = 6
|
|
140
166
|
const maxLength = 50
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
167
|
+
const StringIdSchemaBase = pipe(
|
|
168
|
+
S.String,
|
|
169
|
+
S.check(S.isMinLength(minLength), S.isMaxLength(maxLength)),
|
|
170
|
+
fromBrand<StringId>(nominal<StringId>(), {
|
|
171
|
+
identifier: "StringId",
|
|
172
|
+
jsonSchema: {}
|
|
173
|
+
})
|
|
174
|
+
)
|
|
175
|
+
const makeStringId = (s?: string): StringId =>
|
|
176
|
+
s !== undefined ? S.decodeSync(StringIdSchemaBase)(s) : nanoid() as unknown as StringId
|
|
147
177
|
/**
|
|
148
178
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
179
|
+
*
|
|
180
|
+
* `.withConstructorDefault` => fresh `nanoid()` (construction-only; not
|
|
181
|
+
* applied during decode — see file-level note).
|
|
149
182
|
*/
|
|
150
|
-
export
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
),
|
|
183
|
+
export interface StringIdSchema extends BrandedSchema<S.String, StringId> {
|
|
184
|
+
(i: string, options?: SchemaAST.ParseOptions): StringId
|
|
185
|
+
/** Generate fresh `nanoid()`-shaped `StringId`. */
|
|
186
|
+
make(): StringId
|
|
187
|
+
/** Construct a `StringId` from a known string (validated via decodeSync). */
|
|
188
|
+
make(input: string, options?: S.MakeOptions): StringId
|
|
189
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.String, StringId>>
|
|
190
|
+
}
|
|
191
|
+
export const StringId: StringIdSchema = extendM(
|
|
192
|
+
StringIdSchemaBase,
|
|
161
193
|
(s) => ({
|
|
162
194
|
make: makeStringId,
|
|
163
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Construction-only default: fresh `nanoid()`-shaped `StringId`. Applied
|
|
197
|
+
* only when the field is omitted from `.make(...)` input. NOT applied
|
|
198
|
+
* during decode — cannot be used to JIT-migrate database fields. See
|
|
199
|
+
* file-level note.
|
|
200
|
+
*/
|
|
201
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(makeStringId)))
|
|
164
202
|
})
|
|
165
203
|
)
|
|
166
204
|
.pipe(withDefaultMake)
|
|
167
205
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Build a `StringId` schema whose values are required to start with a fixed
|
|
208
|
+
* `prefix` (joined with `separator`, default `-`).
|
|
209
|
+
*
|
|
210
|
+
* The returned schema exposes `.withConstructorDefault` that mints a fresh
|
|
211
|
+
* prefixed id. Construction-only — not applied during decode; see file-level
|
|
212
|
+
* note.
|
|
213
|
+
*/
|
|
214
|
+
export function prefixedStringId<Type extends StringId>() {
|
|
173
215
|
return <Prefix extends string, Separator extends string = "-">(
|
|
174
216
|
prefix: Prefix,
|
|
175
217
|
name: string,
|
|
@@ -177,27 +219,19 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
177
219
|
) => {
|
|
178
220
|
type FullPrefix = `${Prefix}${Separator}`
|
|
179
221
|
const pref = `${prefix}${separator ?? "-"}` as FullPrefix
|
|
180
|
-
const arb = (): S.LazyArbitrary<string & Brand> => (fc) =>
|
|
181
|
-
StringIdArb()(fc).map(
|
|
182
|
-
(x) => (pref + x.substring(0, 50 - pref.length)) as Brand
|
|
183
|
-
)
|
|
184
222
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
185
|
-
const s
|
|
223
|
+
const s = StringIdSchemaBase
|
|
186
224
|
.pipe(
|
|
187
|
-
S.refine((x: string): x is
|
|
188
|
-
identifier: name
|
|
189
|
-
title: name
|
|
190
|
-
}),
|
|
191
|
-
S.annotate({
|
|
192
|
-
toArbitrary: () => (fc) => arb()(fc)
|
|
225
|
+
S.refine((x: string): x is Type => x.startsWith(pref), {
|
|
226
|
+
identifier: name
|
|
193
227
|
})
|
|
194
|
-
)
|
|
228
|
+
)
|
|
195
229
|
const schema = s.pipe(withDefaultMake)
|
|
196
|
-
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as
|
|
230
|
+
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as Type
|
|
197
231
|
|
|
198
232
|
return extendM(
|
|
199
233
|
schema,
|
|
200
|
-
(ex): PrefixedStringUtils<
|
|
234
|
+
(ex): PrefixedStringUtils<Type, Prefix, Separator> => ({
|
|
201
235
|
make,
|
|
202
236
|
/**
|
|
203
237
|
* Automatically adds the prefix.
|
|
@@ -208,35 +242,60 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
208
242
|
*/
|
|
209
243
|
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => ex(str),
|
|
210
244
|
prefix,
|
|
211
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Construction-only default: fresh prefixed id. Applied only when
|
|
247
|
+
* the field is omitted from `.make(...)` input. NOT applied during
|
|
248
|
+
* decode — cannot be used to JIT-migrate database fields. See
|
|
249
|
+
* file-level note.
|
|
250
|
+
*/
|
|
251
|
+
withConstructorDefault: schema.pipe(
|
|
252
|
+
S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>(
|
|
253
|
+
Effect.sync(make)
|
|
254
|
+
)
|
|
255
|
+
)
|
|
212
256
|
})
|
|
213
257
|
)
|
|
214
258
|
}
|
|
215
259
|
}
|
|
216
260
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Build a branded `StringId` schema for the given branded `Id` type.
|
|
263
|
+
*
|
|
264
|
+
* Exposes `.withConstructorDefault` that mints a fresh `nanoid()`-shaped id.
|
|
265
|
+
* Construction-only — not applied during decode; see file-level note.
|
|
266
|
+
*/
|
|
267
|
+
export const brandedStringId = <Id extends string & B.Brand<any>>(): BrandedStringIdSchema<Id> =>
|
|
220
268
|
withDefaultMake(
|
|
221
|
-
Object.assign(Object.create(StringId), StringId) as
|
|
222
|
-
make: () => string & Brand
|
|
223
|
-
withDefault: S.withConstructorDefault<S.Codec<string & Brand, string> & S.WithoutConstructorDefault>
|
|
224
|
-
} & WithDefaults<S.Codec<string & Brand, string>>
|
|
269
|
+
Object.assign(Object.create(StringId), StringId) as BrandedStringIdSchema<Id>
|
|
225
270
|
)
|
|
226
271
|
|
|
227
272
|
export interface PrefixedStringUtils<
|
|
228
|
-
|
|
273
|
+
Type extends StringId,
|
|
229
274
|
Prefix extends string,
|
|
230
275
|
Separator extends string
|
|
231
276
|
> {
|
|
232
|
-
readonly make: () =>
|
|
233
|
-
readonly unsafeFrom: (str: string) =>
|
|
234
|
-
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) =>
|
|
277
|
+
readonly make: () => Type
|
|
278
|
+
readonly unsafeFrom: (str: string) => Type
|
|
279
|
+
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => Type
|
|
235
280
|
readonly prefix: Prefix
|
|
236
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Construction-only default: fresh prefixed id. Applied only when the
|
|
283
|
+
* field is omitted from `.make(...)` input. NOT applied during decode —
|
|
284
|
+
* cannot be used to JIT-migrate database fields. See file-level note.
|
|
285
|
+
*/
|
|
286
|
+
readonly withConstructorDefault: S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export interface BrandedStringIdSchema<Id extends string & B.Brand<any>> extends BrandedSchema<S.String, Id> {
|
|
290
|
+
(i: string, options?: SchemaAST.ParseOptions): Id
|
|
291
|
+
/** Generate fresh `nanoid()`-shaped id (inherited from `StringId`). */
|
|
292
|
+
make(): Id
|
|
293
|
+
/** Construct an `Id` from a known string (validated via decodeSync). */
|
|
294
|
+
make(input: string, options?: S.MakeOptions): Id
|
|
295
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.String, Id>>
|
|
237
296
|
}
|
|
238
297
|
|
|
239
|
-
export interface UrlBrand extends Simplify<
|
|
298
|
+
export interface UrlBrand extends Simplify<SchemaB.Brand<"Url"> & NonEmptyStringBrand> {}
|
|
240
299
|
|
|
241
300
|
export type Url = string & UrlBrand
|
|
242
301
|
|
|
@@ -244,16 +303,19 @@ const isUrl: Refinement<string, Url> = (s: string): s is Url => {
|
|
|
244
303
|
return validator.default.isURL(s, { require_tld: false })
|
|
245
304
|
}
|
|
246
305
|
|
|
247
|
-
export
|
|
306
|
+
export interface UrlSchema extends S.refine<Url, S.String> {
|
|
307
|
+
(i: string, options?: SchemaAST.ParseOptions): Url
|
|
308
|
+
}
|
|
309
|
+
export const Url: UrlSchema = S
|
|
248
310
|
.String
|
|
249
311
|
.pipe(
|
|
312
|
+
S.annotate({
|
|
313
|
+
title: "Url",
|
|
314
|
+
format: "uri"
|
|
315
|
+
}),
|
|
250
316
|
S.refine(isUrl, {
|
|
251
317
|
identifier: "Url",
|
|
252
|
-
title: "Url",
|
|
253
318
|
jsonSchema: { format: "uri" }
|
|
254
319
|
}),
|
|
255
|
-
S.annotate({
|
|
256
|
-
toArbitrary: () => (fc) => fc.webUrl().map((_) => _ as Url)
|
|
257
|
-
}),
|
|
258
320
|
withDefaultMake
|
|
259
321
|
)
|
package/src/Schema/numbers.ts
CHANGED
|
@@ -1,76 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Numeric brand schemas with `.withConstructorDefault` extensions.
|
|
3
|
+
*
|
|
4
|
+
* Each `.withConstructorDefault` here is **only** applied when the field is
|
|
5
|
+
* omitted during construction (`.make(...)`). It is **not** applied during
|
|
6
|
+
* decode and therefore cannot be used to JIT-migrate database fields.
|
|
7
|
+
*
|
|
8
|
+
* For persisted data, prefer an explicit, preferably versioned migration
|
|
9
|
+
* over decode-time fallbacks. See `./ext.ts` for the full policy note.
|
|
10
|
+
*/
|
|
1
11
|
import { extendM } from "effect-app/utils"
|
|
12
|
+
import * as Effect from "effect/Effect"
|
|
2
13
|
import * as S from "effect/Schema"
|
|
3
14
|
import type { Simplify } from "effect/Types"
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
15
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
16
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
17
|
+
import { withDefaultMake } from "./ext.ts"
|
|
18
|
+
import { type B } from "./schema.ts"
|
|
7
19
|
|
|
8
20
|
export interface PositiveIntBrand
|
|
9
21
|
extends Simplify<B.Brand<"PositiveInt"> & NonNegativeIntBrand & PositiveNumberBrand>
|
|
10
22
|
{}
|
|
11
|
-
export
|
|
23
|
+
export type PositiveInt = number & PositiveIntBrand
|
|
24
|
+
/** Positive integer. `.withConstructorDefault` => `1` (construction-only). */
|
|
25
|
+
export interface PositiveIntSchema extends BrandedSchema<S.Int, PositiveInt> {
|
|
26
|
+
(i: number, options?: SchemaAST.ParseOptions): PositiveInt
|
|
27
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, PositiveInt>>
|
|
28
|
+
}
|
|
29
|
+
export const PositiveInt: PositiveIntSchema = extendM(
|
|
12
30
|
S.Int.pipe(
|
|
13
31
|
S.check(S.isGreaterThan(0)),
|
|
14
|
-
fromBrand(nominal<PositiveInt>(), { identifier: "PositiveInt",
|
|
32
|
+
fromBrand<PositiveInt>(nominal<PositiveInt>(), { identifier: "PositiveInt", jsonSchema: {} }),
|
|
15
33
|
withDefaultMake
|
|
16
34
|
),
|
|
17
|
-
(s) => ({
|
|
35
|
+
(s) => ({
|
|
36
|
+
/**
|
|
37
|
+
* Construction-only default `1`. Applied only when the field is omitted
|
|
38
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
39
|
+
* JIT-migrate database fields. See file-level note.
|
|
40
|
+
*/
|
|
41
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(1))))
|
|
42
|
+
})
|
|
18
43
|
)
|
|
19
|
-
export type PositiveInt = number & PositiveIntBrand
|
|
20
44
|
|
|
21
45
|
export interface NonNegativeIntBrand extends Simplify<B.Brand<"NonNegativeInt"> & IntBrand & NonNegativeNumberBrand> {}
|
|
22
|
-
export
|
|
46
|
+
export type NonNegativeInt = number & NonNegativeIntBrand
|
|
47
|
+
/** Non-negative integer. `.withConstructorDefault` => `0` (construction-only). */
|
|
48
|
+
export interface NonNegativeIntSchema extends BrandedSchema<S.Int, NonNegativeInt> {
|
|
49
|
+
(i: number, options?: SchemaAST.ParseOptions): NonNegativeInt
|
|
50
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, NonNegativeInt>>
|
|
51
|
+
}
|
|
52
|
+
export const NonNegativeInt: NonNegativeIntSchema = extendM(
|
|
23
53
|
S.Int.pipe(
|
|
24
54
|
S.check(S.isGreaterThanOrEqualTo(0)),
|
|
25
|
-
fromBrand(nominal<NonNegativeInt>(), {
|
|
55
|
+
fromBrand<NonNegativeInt>(nominal<NonNegativeInt>(), {
|
|
26
56
|
identifier: "NonNegativeInt",
|
|
27
|
-
title: "NonNegativeInt",
|
|
28
57
|
jsonSchema: {}
|
|
29
58
|
}),
|
|
30
59
|
withDefaultMake
|
|
31
60
|
),
|
|
32
|
-
(s) => ({
|
|
61
|
+
(s) => ({
|
|
62
|
+
/**
|
|
63
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
64
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
65
|
+
* JIT-migrate database fields. See file-level note.
|
|
66
|
+
*/
|
|
67
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
68
|
+
})
|
|
33
69
|
)
|
|
34
|
-
export type NonNegativeInt = number & NonNegativeIntBrand
|
|
35
70
|
|
|
36
71
|
export interface IntBrand extends Simplify<B.Brand<"Int">> {}
|
|
37
|
-
export const Int = extendM(
|
|
38
|
-
S.Int.pipe(fromBrand(nominal<Int>(), { identifier: "Int", title: "Int", jsonSchema: {} }), withDefaultMake),
|
|
39
|
-
(s) => ({ withDefault: s.pipe(withDefaultConstructor(() => s(0))) })
|
|
40
|
-
)
|
|
41
72
|
export type Int = number & IntBrand
|
|
73
|
+
/** Integer. `.withConstructorDefault` => `0` (construction-only). */
|
|
74
|
+
export interface IntSchema extends BrandedSchema<S.Int, Int> {
|
|
75
|
+
(i: number, options?: SchemaAST.ParseOptions): Int
|
|
76
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, Int>>
|
|
77
|
+
}
|
|
78
|
+
export const Int: IntSchema = extendM(
|
|
79
|
+
S.Int.pipe(fromBrand<Int>(nominal<Int>(), { identifier: "Int", jsonSchema: {} }), withDefaultMake),
|
|
80
|
+
(s) => ({
|
|
81
|
+
/**
|
|
82
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
83
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
84
|
+
* JIT-migrate database fields. See file-level note.
|
|
85
|
+
*/
|
|
86
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
87
|
+
})
|
|
88
|
+
)
|
|
42
89
|
|
|
43
90
|
export interface PositiveNumberBrand extends Simplify<B.Brand<"PositiveNumber"> & NonNegativeNumberBrand> {}
|
|
44
|
-
export
|
|
45
|
-
|
|
91
|
+
export type PositiveNumber = number & PositiveNumberBrand
|
|
92
|
+
/** Positive finite number. `.withConstructorDefault` => `1` (construction-only). */
|
|
93
|
+
export interface PositiveNumberSchema extends BrandedSchema<S.Finite, PositiveNumber> {
|
|
94
|
+
(i: number, options?: SchemaAST.ParseOptions): PositiveNumber
|
|
95
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Finite, PositiveNumber>>
|
|
96
|
+
}
|
|
97
|
+
export const PositiveNumber: PositiveNumberSchema = extendM(
|
|
98
|
+
S.Finite.pipe(
|
|
46
99
|
S.check(S.isGreaterThan(0)),
|
|
47
|
-
fromBrand(nominal<PositiveNumber>(), {
|
|
100
|
+
fromBrand<PositiveNumber>(nominal<PositiveNumber>(), {
|
|
48
101
|
identifier: "PositiveNumber",
|
|
49
|
-
title: "PositiveNumber",
|
|
50
102
|
jsonSchema: {}
|
|
51
103
|
}),
|
|
52
104
|
withDefaultMake
|
|
53
105
|
),
|
|
54
|
-
(s) => ({
|
|
106
|
+
(s) => ({
|
|
107
|
+
/**
|
|
108
|
+
* Construction-only default `1`. Applied only when the field is omitted
|
|
109
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
110
|
+
* JIT-migrate database fields. See file-level note.
|
|
111
|
+
*/
|
|
112
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(1))))
|
|
113
|
+
})
|
|
55
114
|
)
|
|
56
|
-
export type PositiveNumber = number & PositiveNumberBrand
|
|
57
115
|
|
|
58
116
|
export interface NonNegativeNumberBrand extends Simplify<B.Brand<"NonNegativeNumber">> {}
|
|
59
|
-
export
|
|
117
|
+
export type NonNegativeNumber = number & NonNegativeNumberBrand
|
|
118
|
+
/** Non-negative finite number. `.withConstructorDefault` => `0` (construction-only). */
|
|
119
|
+
export interface NonNegativeNumberSchema extends BrandedSchema<S.Finite, NonNegativeNumber> {
|
|
120
|
+
(i: number, options?: SchemaAST.ParseOptions): NonNegativeNumber
|
|
121
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Finite, NonNegativeNumber>>
|
|
122
|
+
}
|
|
123
|
+
export const NonNegativeNumber: NonNegativeNumberSchema = extendM(
|
|
60
124
|
S
|
|
61
|
-
.
|
|
125
|
+
.Finite
|
|
62
126
|
.pipe(
|
|
63
127
|
S.check(S.isGreaterThanOrEqualTo(0)),
|
|
64
|
-
fromBrand(nominal<NonNegativeNumber>(), {
|
|
128
|
+
fromBrand<NonNegativeNumber>(nominal<NonNegativeNumber>(), {
|
|
65
129
|
identifier: "NonNegativeNumber",
|
|
66
|
-
title: "NonNegativeNumber",
|
|
67
130
|
jsonSchema: {}
|
|
68
131
|
}),
|
|
69
132
|
withDefaultMake
|
|
70
133
|
),
|
|
71
|
-
(s) => ({
|
|
134
|
+
(s) => ({
|
|
135
|
+
/**
|
|
136
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
137
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
138
|
+
* JIT-migrate database fields. See file-level note.
|
|
139
|
+
*/
|
|
140
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
141
|
+
})
|
|
72
142
|
)
|
|
73
|
-
export type NonNegativeNumber = number & NonNegativeNumberBrand
|
|
74
143
|
|
|
75
144
|
/** @deprecated Not an actual decimal */
|
|
76
145
|
export const NonNegativeDecimal = NonNegativeNumber
|
|
@@ -2,10 +2,9 @@ import type { Refinement } from "effect-app/Function"
|
|
|
2
2
|
import { isValidPhone } from "effect-app/validation"
|
|
3
3
|
import * as S from "effect/Schema"
|
|
4
4
|
import type { Simplify } from "effect/Types"
|
|
5
|
-
import { withDefaultMake } from "./ext.
|
|
6
|
-
import {
|
|
7
|
-
import type {
|
|
8
|
-
import type { NonEmptyStringBrand } from "./strings.js"
|
|
5
|
+
import { withDefaultMake } from "./ext.ts"
|
|
6
|
+
import type { B } from "./schema.ts"
|
|
7
|
+
import type { NonEmptyStringBrand } from "./strings.ts"
|
|
9
8
|
|
|
10
9
|
export interface PhoneNumberBrand extends Simplify<B.Brand<"PhoneNumber"> & NonEmptyStringBrand> {}
|
|
11
10
|
export type PhoneNumber = string & PhoneNumberBrand
|
|
@@ -13,14 +12,15 @@ export type PhoneNumber = string & PhoneNumberBrand
|
|
|
13
12
|
export const PhoneNumber = S
|
|
14
13
|
.String
|
|
15
14
|
.pipe(
|
|
15
|
+
S.annotate({
|
|
16
|
+
title: "PhoneNumber",
|
|
17
|
+
description: "a phone number with at least 7 digits",
|
|
18
|
+
format: "phone"
|
|
19
|
+
}),
|
|
16
20
|
S.refine(isValidPhone as Refinement<string, PhoneNumber>, {
|
|
17
21
|
identifier: "PhoneNumber",
|
|
18
|
-
title: "PhoneNumber",
|
|
19
22
|
description: "a phone number with at least 7 digits",
|
|
20
23
|
jsonSchema: { format: "phone" }
|
|
21
24
|
}),
|
|
22
|
-
S.annotate({
|
|
23
|
-
toArbitrary: () => (fc) => Numbers(7, 10)(fc).map((_) => _ as PhoneNumber)
|
|
24
|
-
}),
|
|
25
25
|
withDefaultMake
|
|
26
26
|
)
|