effect-app 4.0.0-beta.27 → 4.0.0-beta.272
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 +1275 -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/Effect.d.ts +10 -9
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +5 -8
- 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/ext.d.ts +60 -0
- package/dist/Model/Repository/ext.d.ts.map +1 -0
- package/dist/Model/Repository/ext.js +122 -0
- package/dist/Model/Repository/internal/internal.d.ts +63 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
- package/dist/Model/Repository/internal/internal.js +430 -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 +54 -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 +7 -0
- package/dist/Model/Repository.d.ts.map +1 -0
- package/dist/Model/Repository.js +7 -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 +493 -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 +136 -0
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
- package/dist/Model/query/new-kid-interpreter.js +336 -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 +5 -0
- package/dist/Model.d.ts.map +1 -0
- package/dist/Model.js +5 -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 +17 -14
- package/dist/QueueMaker.d.ts +13 -0
- package/dist/QueueMaker.d.ts.map +1 -0
- package/dist/QueueMaker.js +4 -0
- package/dist/RequestContext.d.ts +154 -0
- package/dist/RequestContext.d.ts.map +1 -0
- package/dist/RequestContext.js +54 -0
- package/dist/Schema/Class.d.ts +160 -19
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +260 -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 +118 -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 +4 -2
- 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 -4
- package/dist/Schema/ext.d.ts +338 -55
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +358 -53
- package/dist/Schema/moreStrings.d.ts +82 -36
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +49 -42
- 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 -3
- 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 +213 -7
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +190 -11
- 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 +121 -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/client/InvalidationKeys.d.ts +29 -0
- package/dist/client/InvalidationKeys.d.ts.map +1 -0
- package/dist/client/InvalidationKeys.js +33 -0
- package/dist/client/apiClientFactory.d.ts +19 -31
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +104 -34
- package/dist/client/clientFor.d.ts +52 -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 +494 -32
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +66 -24
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -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 +420 -0
- package/dist/rpc/Invalidation.d.ts.map +1 -0
- package/dist/rpc/Invalidation.js +168 -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 +19 -0
- package/dist/setupRequest.d.ts.map +1 -0
- package/dist/setupRequest.js +69 -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 +22 -247
- 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/Effect.ts +14 -16
- 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/ext.ts +375 -0
- package/src/Model/Repository/internal/internal.ts +741 -0
- package/src/Model/Repository/legacy.ts +29 -0
- package/src/Model/Repository/makeRepo.ts +145 -0
- package/src/Model/Repository/service.ts +676 -0
- package/src/Model/Repository/validation.ts +31 -0
- package/src/Model/Repository.ts +6 -0
- package/src/Model/dsl.ts +129 -0
- package/src/Model/filter/filterApi.ts +60 -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 +2694 -0
- package/src/Model/query/new-kid-interpreter.ts +484 -0
- package/src/Model/query.ts +13 -0
- package/src/Model.ts +4 -0
- package/src/NonEmptySet.ts +6 -4
- package/src/Option.ts +2 -0
- package/src/Pure.ts +22 -20
- package/src/QueueMaker.ts +19 -0
- package/src/RequestContext.ts +95 -0
- package/src/Schema/Class.ts +593 -59
- package/src/Schema/SchemaParser.ts +12 -0
- package/src/Schema/SpecialJsonSchema.ts +139 -0
- package/src/Schema/SpecialOpenApi.ts +130 -0
- package/src/Schema/brand.ts +22 -2
- package/src/Schema/email.ts +9 -4
- package/src/Schema/ext.ts +446 -91
- package/src/Schema/moreStrings.ts +147 -68
- package/src/Schema/numbers.ts +97 -28
- package/src/Schema/phoneNumber.ts +9 -5
- package/src/Schema/strings.ts +23 -14
- package/src/Schema.ts +389 -25
- package/src/Set.ts +6 -2
- package/src/Store.ts +277 -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/client/InvalidationKeys.ts +50 -0
- package/src/client/apiClientFactory.ts +234 -135
- package/src/client/clientFor.ts +105 -34
- package/src/client/errors.ts +100 -29
- package/src/client/makeClient.ts +594 -73
- package/src/client.ts +5 -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 +261 -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 +56 -0
- package/src/setupRequest.ts +134 -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/secretURL.test.d.ts.map +1 -0
- package/test/dist/special.test.d.ts.map +1 -0
- package/test/moreStrings.test.ts +1 -1
- package/test/rpc.test.ts +46 -6
- package/test/schema.test.ts +459 -30
- package/test/secretURL.test.ts +160 -0
- package/test/special.test.ts +1258 -0
- package/test/utils.test.ts +7 -7
- package/tsconfig.base.json +6 -5
- package/tsconfig.json +3 -1
- package/tsconfig.json.bak +2 -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
|
@@ -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"
|
|
17
|
+
import type * as SchemaAST from "effect/SchemaAST"
|
|
5
18
|
import type { Simplify } from "effect/Types"
|
|
6
19
|
import { customRandom, nanoid, urlAlphabet } from "nanoid"
|
|
7
20
|
import validator from "validator"
|
|
8
|
-
import { fromBrand, nominal } from "./brand.
|
|
9
|
-
import {
|
|
10
|
-
import { type B } from "./schema.
|
|
11
|
-
import type { NonEmptyString255Brand, NonEmptyStringBrand } from "./strings.
|
|
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,86 @@ 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
167
|
const size = 21
|
|
142
168
|
const length = 10 * size
|
|
169
|
+
const StringIdSchemaBase = pipe(
|
|
170
|
+
S.String,
|
|
171
|
+
S.check(S.isMinLength(minLength), S.isMaxLength(maxLength)),
|
|
172
|
+
fromBrand<StringId>(nominal<StringId>(), {
|
|
173
|
+
identifier: "StringId",
|
|
174
|
+
toArbitrary: () => (fc) => StringIdArb()(fc),
|
|
175
|
+
jsonSchema: {}
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
const makeStringId = (s?: string): StringId =>
|
|
179
|
+
s !== undefined ? S.decodeSync(StringIdSchemaBase)(s) : nanoid() as unknown as StringId
|
|
143
180
|
const StringIdArb = (): S.LazyArbitrary<StringId> => (fc) =>
|
|
144
181
|
fc
|
|
145
182
|
.uint8Array({ minLength: length, maxLength: length })
|
|
146
183
|
.map((_) => customRandom(urlAlphabet, size, (size) => _.subarray(0, size))() as StringId)
|
|
147
184
|
/**
|
|
148
185
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
186
|
+
*
|
|
187
|
+
* `.withConstructorDefault` => fresh `nanoid()` (construction-only; not
|
|
188
|
+
* applied during decode — see file-level note).
|
|
149
189
|
*/
|
|
150
|
-
export
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
),
|
|
190
|
+
export interface StringIdSchema extends BrandedSchema<S.String, StringId> {
|
|
191
|
+
(i: string, options?: SchemaAST.ParseOptions): StringId
|
|
192
|
+
/** Generate fresh `nanoid()`-shaped `StringId`. */
|
|
193
|
+
make(): StringId
|
|
194
|
+
/** Construct a `StringId` from a known string (validated via decodeSync). */
|
|
195
|
+
make(input: string, options?: S.MakeOptions): StringId
|
|
196
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.String, StringId>>
|
|
197
|
+
}
|
|
198
|
+
export const StringId: StringIdSchema = extendM(
|
|
199
|
+
StringIdSchemaBase,
|
|
161
200
|
(s) => ({
|
|
162
201
|
make: makeStringId,
|
|
163
|
-
|
|
202
|
+
/**
|
|
203
|
+
* Construction-only default: fresh `nanoid()`-shaped `StringId`. Applied
|
|
204
|
+
* only when the field is omitted from `.make(...)` input. NOT applied
|
|
205
|
+
* during decode — cannot be used to JIT-migrate database fields. See
|
|
206
|
+
* file-level note.
|
|
207
|
+
*/
|
|
208
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(makeStringId)))
|
|
164
209
|
})
|
|
165
210
|
)
|
|
166
211
|
.pipe(withDefaultMake)
|
|
167
212
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
213
|
+
/**
|
|
214
|
+
* Build a `StringId` schema whose values are required to start with a fixed
|
|
215
|
+
* `prefix` (joined with `separator`, default `-`).
|
|
216
|
+
*
|
|
217
|
+
* The returned schema exposes `.withConstructorDefault` that mints a fresh
|
|
218
|
+
* prefixed id. Construction-only — not applied during decode; see file-level
|
|
219
|
+
* note.
|
|
220
|
+
*/
|
|
221
|
+
export function prefixedStringId<Type extends StringId>() {
|
|
173
222
|
return <Prefix extends string, Separator extends string = "-">(
|
|
174
223
|
prefix: Prefix,
|
|
175
224
|
name: string,
|
|
@@ -177,27 +226,26 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
177
226
|
) => {
|
|
178
227
|
type FullPrefix = `${Prefix}${Separator}`
|
|
179
228
|
const pref = `${prefix}${separator ?? "-"}` as FullPrefix
|
|
180
|
-
const arb = (): S.LazyArbitrary<
|
|
229
|
+
const arb = (): S.LazyArbitrary<Type> => (fc) =>
|
|
181
230
|
StringIdArb()(fc).map(
|
|
182
|
-
(x) => (pref + x.substring(0, 50 - pref.length)) as
|
|
231
|
+
(x) => (pref + x.substring(0, 50 - pref.length)) as Type
|
|
183
232
|
)
|
|
184
233
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
185
|
-
const s
|
|
234
|
+
const s = StringIdSchemaBase
|
|
186
235
|
.pipe(
|
|
187
|
-
S.refine((x: string): x is
|
|
188
|
-
identifier: name
|
|
189
|
-
title: name
|
|
236
|
+
S.refine((x: string): x is Type => x.startsWith(pref), {
|
|
237
|
+
identifier: name
|
|
190
238
|
}),
|
|
191
239
|
S.annotate({
|
|
192
240
|
toArbitrary: () => (fc) => arb()(fc)
|
|
193
241
|
})
|
|
194
|
-
)
|
|
242
|
+
)
|
|
195
243
|
const schema = s.pipe(withDefaultMake)
|
|
196
|
-
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as
|
|
244
|
+
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as Type
|
|
197
245
|
|
|
198
246
|
return extendM(
|
|
199
247
|
schema,
|
|
200
|
-
(ex): PrefixedStringUtils<
|
|
248
|
+
(ex): PrefixedStringUtils<Type, Prefix, Separator> => ({
|
|
201
249
|
make,
|
|
202
250
|
/**
|
|
203
251
|
* Automatically adds the prefix.
|
|
@@ -208,35 +256,60 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
208
256
|
*/
|
|
209
257
|
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => ex(str),
|
|
210
258
|
prefix,
|
|
211
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Construction-only default: fresh prefixed id. Applied only when
|
|
261
|
+
* the field is omitted from `.make(...)` input. NOT applied during
|
|
262
|
+
* decode — cannot be used to JIT-migrate database fields. See
|
|
263
|
+
* file-level note.
|
|
264
|
+
*/
|
|
265
|
+
withConstructorDefault: schema.pipe(
|
|
266
|
+
S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>(
|
|
267
|
+
Effect.sync(make)
|
|
268
|
+
)
|
|
269
|
+
)
|
|
212
270
|
})
|
|
213
271
|
)
|
|
214
272
|
}
|
|
215
273
|
}
|
|
216
274
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Build a branded `StringId` schema for the given branded `Id` type.
|
|
277
|
+
*
|
|
278
|
+
* Exposes `.withConstructorDefault` that mints a fresh `nanoid()`-shaped id.
|
|
279
|
+
* Construction-only — not applied during decode; see file-level note.
|
|
280
|
+
*/
|
|
281
|
+
export const brandedStringId = <Id extends string & B.Brand<any>>(): BrandedStringIdSchema<Id> =>
|
|
220
282
|
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>>
|
|
283
|
+
Object.assign(Object.create(StringId), StringId) as BrandedStringIdSchema<Id>
|
|
225
284
|
)
|
|
226
285
|
|
|
227
286
|
export interface PrefixedStringUtils<
|
|
228
|
-
|
|
287
|
+
Type extends StringId,
|
|
229
288
|
Prefix extends string,
|
|
230
289
|
Separator extends string
|
|
231
290
|
> {
|
|
232
|
-
readonly make: () =>
|
|
233
|
-
readonly unsafeFrom: (str: string) =>
|
|
234
|
-
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) =>
|
|
291
|
+
readonly make: () => Type
|
|
292
|
+
readonly unsafeFrom: (str: string) => Type
|
|
293
|
+
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => Type
|
|
235
294
|
readonly prefix: Prefix
|
|
236
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Construction-only default: fresh prefixed id. Applied only when the
|
|
297
|
+
* field is omitted from `.make(...)` input. NOT applied during decode —
|
|
298
|
+
* cannot be used to JIT-migrate database fields. See file-level note.
|
|
299
|
+
*/
|
|
300
|
+
readonly withConstructorDefault: S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>
|
|
237
301
|
}
|
|
238
302
|
|
|
239
|
-
export interface
|
|
303
|
+
export interface BrandedStringIdSchema<Id extends string & B.Brand<any>> extends BrandedSchema<S.String, Id> {
|
|
304
|
+
(i: string, options?: SchemaAST.ParseOptions): Id
|
|
305
|
+
/** Generate fresh `nanoid()`-shaped id (inherited from `StringId`). */
|
|
306
|
+
make(): Id
|
|
307
|
+
/** Construct an `Id` from a known string (validated via decodeSync). */
|
|
308
|
+
make(input: string, options?: S.MakeOptions): Id
|
|
309
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.String, Id>>
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export interface UrlBrand extends Simplify<SchemaB.Brand<"Url"> & NonEmptyStringBrand> {}
|
|
240
313
|
|
|
241
314
|
export type Url = string & UrlBrand
|
|
242
315
|
|
|
@@ -244,12 +317,18 @@ const isUrl: Refinement<string, Url> = (s: string): s is Url => {
|
|
|
244
317
|
return validator.default.isURL(s, { require_tld: false })
|
|
245
318
|
}
|
|
246
319
|
|
|
247
|
-
export
|
|
320
|
+
export interface UrlSchema extends S.refine<Url, S.String> {
|
|
321
|
+
(i: string, options?: SchemaAST.ParseOptions): Url
|
|
322
|
+
}
|
|
323
|
+
export const Url: UrlSchema = S
|
|
248
324
|
.String
|
|
249
325
|
.pipe(
|
|
326
|
+
S.annotate({
|
|
327
|
+
title: "Url",
|
|
328
|
+
format: "uri"
|
|
329
|
+
}),
|
|
250
330
|
S.refine(isUrl, {
|
|
251
331
|
identifier: "Url",
|
|
252
|
-
title: "Url",
|
|
253
332
|
jsonSchema: { format: "uri" }
|
|
254
333
|
}),
|
|
255
334
|
S.annotate({
|
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"
|
|
14
|
+
import type * as SchemaAST from "effect/SchemaAST"
|
|
3
15
|
import type { Simplify } from "effect/Types"
|
|
4
|
-
import { fromBrand, nominal } from "./brand.
|
|
5
|
-
import {
|
|
6
|
-
import { type B } from "./schema.
|
|
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,10 @@ 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 { Numbers } from "./FastCheck.
|
|
7
|
-
import type { B } from "./schema.
|
|
8
|
-
import type { NonEmptyStringBrand } from "./strings.
|
|
5
|
+
import { withDefaultMake } from "./ext.ts"
|
|
6
|
+
import { Numbers } from "./FastCheck.ts"
|
|
7
|
+
import type { B } from "./schema.ts"
|
|
8
|
+
import type { NonEmptyStringBrand } from "./strings.ts"
|
|
9
9
|
|
|
10
10
|
export interface PhoneNumberBrand extends Simplify<B.Brand<"PhoneNumber"> & NonEmptyStringBrand> {}
|
|
11
11
|
export type PhoneNumber = string & PhoneNumberBrand
|
|
@@ -13,9 +13,13 @@ export type PhoneNumber = string & PhoneNumberBrand
|
|
|
13
13
|
export const PhoneNumber = S
|
|
14
14
|
.String
|
|
15
15
|
.pipe(
|
|
16
|
+
S.annotate({
|
|
17
|
+
title: "PhoneNumber",
|
|
18
|
+
description: "a phone number with at least 7 digits",
|
|
19
|
+
format: "phone"
|
|
20
|
+
}),
|
|
16
21
|
S.refine(isValidPhone as Refinement<string, PhoneNumber>, {
|
|
17
22
|
identifier: "PhoneNumber",
|
|
18
|
-
title: "PhoneNumber",
|
|
19
23
|
description: "a phone number with at least 7 digits",
|
|
20
24
|
jsonSchema: { format: "phone" }
|
|
21
25
|
}),
|
package/src/Schema/strings.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import type * as B from "effect/Brand"
|
|
2
2
|
import * as S from "effect/Schema"
|
|
3
|
+
import type * as SchemaAST from "effect/SchemaAST"
|
|
3
4
|
import type { Simplify } from "effect/Types"
|
|
4
|
-
import { fromBrand, nominal } from "./brand.
|
|
5
|
-
import { withDefaultMake } from "./ext.
|
|
5
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
6
|
+
import { withDefaultMake } from "./ext.ts"
|
|
6
7
|
|
|
7
8
|
export type NonEmptyStringBrand = B.Brand<"NonEmptyString">
|
|
8
9
|
export type NonEmptyString = string & NonEmptyStringBrand
|
|
9
|
-
export
|
|
10
|
+
export interface NonEmptyStringSchema extends BrandedSchema<S.NonEmptyString, NonEmptyString> {
|
|
11
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString
|
|
12
|
+
}
|
|
13
|
+
export const NonEmptyString: NonEmptyStringSchema = S
|
|
10
14
|
.NonEmptyString
|
|
11
15
|
.pipe(
|
|
12
|
-
fromBrand(nominal<NonEmptyString>(), {
|
|
16
|
+
fromBrand<NonEmptyString>(nominal<NonEmptyString>(), {
|
|
13
17
|
identifier: "NonEmptyString",
|
|
14
|
-
title: "NonEmptyString",
|
|
15
18
|
jsonSchema: {}
|
|
16
19
|
}),
|
|
17
20
|
withDefaultMake
|
|
@@ -19,13 +22,15 @@ export const NonEmptyString = S
|
|
|
19
22
|
|
|
20
23
|
export interface NonEmptyString64kBrand extends Simplify<B.Brand<"NonEmptyString64k"> & NonEmptyStringBrand> {}
|
|
21
24
|
export type NonEmptyString64k = string & NonEmptyString64kBrand
|
|
22
|
-
export
|
|
25
|
+
export interface NonEmptyString64kSchema extends BrandedSchema<S.NonEmptyString, NonEmptyString64k> {
|
|
26
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString64k
|
|
27
|
+
}
|
|
28
|
+
export const NonEmptyString64k: NonEmptyString64kSchema = S
|
|
23
29
|
.NonEmptyString
|
|
24
30
|
.pipe(
|
|
25
31
|
S.check(S.isMaxLength(64 * 1024)),
|
|
26
|
-
fromBrand(nominal<NonEmptyString64k>(), {
|
|
32
|
+
fromBrand<NonEmptyString64k>(nominal<NonEmptyString64k>(), {
|
|
27
33
|
identifier: "NonEmptyString64k",
|
|
28
|
-
title: "NonEmptyString64k",
|
|
29
34
|
jsonSchema: {}
|
|
30
35
|
}),
|
|
31
36
|
withDefaultMake
|
|
@@ -33,13 +38,15 @@ export const NonEmptyString64k = S
|
|
|
33
38
|
|
|
34
39
|
export interface NonEmptyString2kBrand extends Simplify<B.Brand<"NonEmptyString2k"> & NonEmptyString64kBrand> {}
|
|
35
40
|
export type NonEmptyString2k = string & NonEmptyString2kBrand
|
|
36
|
-
export
|
|
41
|
+
export interface NonEmptyString2kSchema extends BrandedSchema<S.NonEmptyString, NonEmptyString2k> {
|
|
42
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString2k
|
|
43
|
+
}
|
|
44
|
+
export const NonEmptyString2k: NonEmptyString2kSchema = S
|
|
37
45
|
.NonEmptyString
|
|
38
46
|
.pipe(
|
|
39
47
|
S.check(S.isMaxLength(2 * 1024)),
|
|
40
|
-
fromBrand(nominal<NonEmptyString2k>(), {
|
|
48
|
+
fromBrand<NonEmptyString2k>(nominal<NonEmptyString2k>(), {
|
|
41
49
|
identifier: "NonEmptyString2k",
|
|
42
|
-
title: "NonEmptyString2k",
|
|
43
50
|
jsonSchema: {}
|
|
44
51
|
}),
|
|
45
52
|
withDefaultMake
|
|
@@ -47,13 +54,15 @@ export const NonEmptyString2k = S
|
|
|
47
54
|
|
|
48
55
|
export interface NonEmptyString255Brand extends Simplify<B.Brand<"NonEmptyString255"> & NonEmptyString2kBrand> {}
|
|
49
56
|
export type NonEmptyString255 = string & NonEmptyString255Brand
|
|
50
|
-
export
|
|
57
|
+
export interface NonEmptyString255Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString255> {
|
|
58
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString255
|
|
59
|
+
}
|
|
60
|
+
export const NonEmptyString255: NonEmptyString255Schema = S
|
|
51
61
|
.NonEmptyString
|
|
52
62
|
.pipe(
|
|
53
63
|
S.check(S.isMaxLength(255)),
|
|
54
|
-
fromBrand(nominal<NonEmptyString255>(), {
|
|
64
|
+
fromBrand<NonEmptyString255>(nominal<NonEmptyString255>(), {
|
|
55
65
|
identifier: "NonEmptyString255",
|
|
56
|
-
title: "NonEmptyString255",
|
|
57
66
|
jsonSchema: {}
|
|
58
67
|
}),
|
|
59
68
|
withDefaultMake
|