effect-app 4.0.0-beta.33 → 4.0.0-beta.331
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 +1628 -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 +611 -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 +71 -0
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
- package/dist/Model/Repository/makeRepo.js +30 -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 +72 -0
- package/dist/Model/Repository/validation.d.ts.map +1 -0
- package/dist/Model/Repository/validation.js +39 -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 +12 -6
- package/dist/Schema/ext.d.ts +335 -61
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +388 -63
- package/dist/Schema/moreStrings.d.ts +82 -36
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/moreStrings.js +90 -53
- package/dist/Schema/numbers.d.ts +33 -21
- package/dist/Schema/numbers.d.ts.map +1 -1
- package/dist/Schema/numbers.js +65 -12
- package/dist/Schema/phoneNumber.d.ts.map +1 -1
- package/dist/Schema/phoneNumber.js +11 -7
- 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 +215 -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 +32 -14
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +38 -6
- 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 +988 -0
- package/src/Model/Repository/legacy.ts +29 -0
- package/src/Model/Repository/makeRepo.ts +168 -0
- package/src/Model/Repository/service.ts +676 -0
- package/src/Model/Repository/validation.ts +38 -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 +14 -7
- package/src/Schema/ext.ts +508 -102
- package/src/Schema/moreStrings.ts +217 -86
- package/src/Schema/numbers.ts +107 -28
- package/src/Schema/phoneNumber.ts +13 -9
- 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 +325 -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 +45 -7
- 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 +55 -10
- package/test/rpc.test.ts +38 -10
- package/test/rpcMiddlewareContext.test.ts +63 -0
- package/test/schema.test.ts +505 -26
- 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,36 @@
|
|
|
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 * as Getter from "effect/SchemaGetter"
|
|
18
|
+
import * as SchemaIssue from "effect/SchemaIssue"
|
|
5
19
|
import type { Simplify } from "effect/Types"
|
|
6
20
|
import { customRandom, nanoid, urlAlphabet } from "nanoid"
|
|
7
21
|
import validator from "validator"
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import type
|
|
22
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
23
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
24
|
+
import { withDefaultMake } from "./ext.ts"
|
|
25
|
+
import { type B as SchemaB } from "./schema.ts"
|
|
26
|
+
import type { NonEmptyString255Brand, NonEmptyStringBrand } from "./strings.ts"
|
|
12
27
|
|
|
13
28
|
const nonEmptyString = S.NonEmptyString
|
|
14
29
|
|
|
15
30
|
/**
|
|
16
31
|
* A string that is at least 1 character long and a maximum of 50.
|
|
17
32
|
*/
|
|
18
|
-
export interface NonEmptyString50Brand extends Simplify<
|
|
33
|
+
export interface NonEmptyString50Brand extends Simplify<SchemaB.Brand<"NonEmptyString50"> & NonEmptyString64Brand> {}
|
|
19
34
|
|
|
20
35
|
/**
|
|
21
36
|
* A string that is at least 1 character long and a maximum of 50.
|
|
@@ -25,11 +40,13 @@ export type NonEmptyString50 = string & NonEmptyString50Brand
|
|
|
25
40
|
/**
|
|
26
41
|
* A string that is at least 1 character long and a maximum of 50.
|
|
27
42
|
*/
|
|
28
|
-
export
|
|
43
|
+
export interface NonEmptyString50Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString50> {
|
|
44
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString50
|
|
45
|
+
}
|
|
46
|
+
export const NonEmptyString50: NonEmptyString50Schema = nonEmptyString.pipe(
|
|
29
47
|
S.check(S.isMaxLength(50)),
|
|
30
|
-
fromBrand(nominal<NonEmptyString50>(), {
|
|
48
|
+
fromBrand<NonEmptyString50>(nominal<NonEmptyString50>(), {
|
|
31
49
|
identifier: "NonEmptyString50",
|
|
32
|
-
title: "NonEmptyString50",
|
|
33
50
|
jsonSchema: {}
|
|
34
51
|
}),
|
|
35
52
|
withDefaultMake
|
|
@@ -38,7 +55,7 @@ export const NonEmptyString50 = nonEmptyString.pipe(
|
|
|
38
55
|
/**
|
|
39
56
|
* A string that is at least 1 character long and a maximum of 64.
|
|
40
57
|
*/
|
|
41
|
-
export interface NonEmptyString64Brand extends Simplify<
|
|
58
|
+
export interface NonEmptyString64Brand extends Simplify<SchemaB.Brand<"NonEmptyString64"> & NonEmptyString80Brand> {}
|
|
42
59
|
|
|
43
60
|
/**
|
|
44
61
|
* A string that is at least 1 character long and a maximum of 64.
|
|
@@ -48,11 +65,13 @@ export type NonEmptyString64 = string & NonEmptyString64Brand
|
|
|
48
65
|
/**
|
|
49
66
|
* A string that is at least 1 character long and a maximum of 64.
|
|
50
67
|
*/
|
|
51
|
-
export
|
|
68
|
+
export interface NonEmptyString64Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString64> {
|
|
69
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString64
|
|
70
|
+
}
|
|
71
|
+
export const NonEmptyString64: NonEmptyString64Schema = nonEmptyString.pipe(
|
|
52
72
|
S.check(S.isMaxLength(64)),
|
|
53
|
-
fromBrand(nominal<NonEmptyString64>(), {
|
|
73
|
+
fromBrand<NonEmptyString64>(nominal<NonEmptyString64>(), {
|
|
54
74
|
identifier: "NonEmptyString64",
|
|
55
|
-
title: "NonEmptyString64",
|
|
56
75
|
jsonSchema: {}
|
|
57
76
|
}),
|
|
58
77
|
withDefaultMake
|
|
@@ -61,7 +80,7 @@ export const NonEmptyString64 = nonEmptyString.pipe(
|
|
|
61
80
|
/**
|
|
62
81
|
* A string that is at least 1 character long and a maximum of 80.
|
|
63
82
|
*/
|
|
64
|
-
export interface NonEmptyString80Brand extends Simplify<
|
|
83
|
+
export interface NonEmptyString80Brand extends Simplify<SchemaB.Brand<"NonEmptyString80"> & NonEmptyString100Brand> {}
|
|
65
84
|
|
|
66
85
|
/**
|
|
67
86
|
* A string that is at least 1 character long and a maximum of 80.
|
|
@@ -72,11 +91,13 @@ export type NonEmptyString80 = string & NonEmptyString80Brand
|
|
|
72
91
|
* A string that is at least 1 character long and a maximum of 80.
|
|
73
92
|
*/
|
|
74
93
|
|
|
75
|
-
export
|
|
94
|
+
export interface NonEmptyString80Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString80> {
|
|
95
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString80
|
|
96
|
+
}
|
|
97
|
+
export const NonEmptyString80: NonEmptyString80Schema = nonEmptyString.pipe(
|
|
76
98
|
S.check(S.isMaxLength(80)),
|
|
77
|
-
fromBrand(nominal<NonEmptyString80>(), {
|
|
99
|
+
fromBrand<NonEmptyString80>(nominal<NonEmptyString80>(), {
|
|
78
100
|
identifier: "NonEmptyString80",
|
|
79
|
-
title: "NonEmptyString80",
|
|
80
101
|
jsonSchema: {}
|
|
81
102
|
}),
|
|
82
103
|
withDefaultMake
|
|
@@ -85,7 +106,7 @@ export const NonEmptyString80 = nonEmptyString.pipe(
|
|
|
85
106
|
/**
|
|
86
107
|
* A string that is at least 1 character long and a maximum of 100.
|
|
87
108
|
*/
|
|
88
|
-
export interface NonEmptyString100Brand extends Simplify<
|
|
109
|
+
export interface NonEmptyString100Brand extends Simplify<SchemaB.Brand<"NonEmptyString100"> & NonEmptyString255Brand> {}
|
|
89
110
|
|
|
90
111
|
/**
|
|
91
112
|
* A string that is at least 1 character long and a maximum of 100.
|
|
@@ -95,11 +116,13 @@ export type NonEmptyString100 = string & NonEmptyString100Brand
|
|
|
95
116
|
/**
|
|
96
117
|
* A string that is at least 1 character long and a maximum of 100.
|
|
97
118
|
*/
|
|
98
|
-
export
|
|
119
|
+
export interface NonEmptyString100Schema extends BrandedSchema<S.NonEmptyString, NonEmptyString100> {
|
|
120
|
+
(i: string, options?: SchemaAST.ParseOptions): NonEmptyString100
|
|
121
|
+
}
|
|
122
|
+
export const NonEmptyString100: NonEmptyString100Schema = nonEmptyString.pipe(
|
|
99
123
|
S.check(S.isMaxLength(100)),
|
|
100
|
-
fromBrand(nominal<NonEmptyString100>(), {
|
|
124
|
+
fromBrand<NonEmptyString100>(nominal<NonEmptyString100>(), {
|
|
101
125
|
identifier: "NonEmptyString100",
|
|
102
|
-
title: "NonEmptyString100",
|
|
103
126
|
jsonSchema: {}
|
|
104
127
|
}),
|
|
105
128
|
withDefaultMake
|
|
@@ -108,7 +131,7 @@ export const NonEmptyString100 = nonEmptyString.pipe(
|
|
|
108
131
|
/**
|
|
109
132
|
* A string that is at least 3 character long and a maximum of 255.
|
|
110
133
|
*/
|
|
111
|
-
export interface Min3String255Brand extends Simplify<
|
|
134
|
+
export interface Min3String255Brand extends Simplify<SchemaB.Brand<"Min3String255"> & NonEmptyString255Brand> {}
|
|
112
135
|
|
|
113
136
|
/**
|
|
114
137
|
* A string that is at least 3 character long and a maximum of 255.
|
|
@@ -118,58 +141,115 @@ export type Min3String255 = string & Min3String255Brand
|
|
|
118
141
|
/**
|
|
119
142
|
* A string that is at least 3 character long and a maximum of 255.
|
|
120
143
|
*/
|
|
121
|
-
export
|
|
144
|
+
export interface Min3String255Schema extends BrandedSchema<S.String, Min3String255> {
|
|
145
|
+
(i: string, options?: SchemaAST.ParseOptions): Min3String255
|
|
146
|
+
}
|
|
147
|
+
export const Min3String255: Min3String255Schema = pipe(
|
|
122
148
|
S.String,
|
|
123
149
|
S.check(S.isMinLength(3), S.isMaxLength(255)),
|
|
124
|
-
fromBrand(nominal<Min3String255>(), {
|
|
150
|
+
fromBrand<Min3String255>(nominal<Min3String255>(), {
|
|
151
|
+
identifier: "Min3String255",
|
|
152
|
+
jsonSchema: {}
|
|
153
|
+
}),
|
|
125
154
|
withDefaultMake
|
|
126
155
|
)
|
|
127
156
|
|
|
128
157
|
/**
|
|
129
158
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
130
159
|
*/
|
|
131
|
-
export interface StringIdBrand extends Simplify<
|
|
160
|
+
export interface StringIdBrand extends Simplify<SchemaB.Brand<"StringId"> & NonEmptyString50Brand> {}
|
|
132
161
|
|
|
133
162
|
/**
|
|
134
163
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
135
164
|
*/
|
|
136
165
|
export type StringId = string & StringIdBrand
|
|
137
166
|
|
|
138
|
-
const makeStringId = (): StringId => nanoid() as unknown as StringId
|
|
139
167
|
const minLength = 6
|
|
140
168
|
const maxLength = 50
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
const nanoidSize = 21
|
|
170
|
+
const nanoidByteLength = 10 * nanoidSize
|
|
171
|
+
|
|
172
|
+
const StringIdString = pipe(
|
|
173
|
+
S.String,
|
|
174
|
+
S.check(S.isMinLength(minLength), S.isMaxLength(maxLength)),
|
|
175
|
+
fromBrand<StringId>(nominal<StringId>(), {
|
|
176
|
+
identifier: "StringId",
|
|
177
|
+
jsonSchema: {}
|
|
178
|
+
})
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
const nanoidFromBytes = (bytes: Uint8Array) =>
|
|
182
|
+
customRandom(urlAlphabet, nanoidSize, (size) => bytes.subarray(0, size))() as StringId
|
|
183
|
+
|
|
184
|
+
// JSON stays a branded string (toCodec). Generation uses toCodecArbitrary — the native
|
|
185
|
+
// replacement for fast-check `toArbitrary` — same as the old StringIdArb:
|
|
186
|
+
// uint8Array(210).map(bytes => customRandom(urlAlphabet, 21, …)).
|
|
187
|
+
const StringIdSchemaBase = S.declareConstructor<StringId, string>()(
|
|
188
|
+
[],
|
|
189
|
+
() => (input, ast, options) =>
|
|
190
|
+
S.is(StringIdString)(input)
|
|
191
|
+
? Effect.succeed(input)
|
|
192
|
+
: Effect.fail(new SchemaIssue.InvalidType(ast, input, options)),
|
|
193
|
+
{
|
|
194
|
+
identifier: "StringId",
|
|
195
|
+
expected: "StringId",
|
|
196
|
+
toCodec: () =>
|
|
197
|
+
S.link<StringId>()(StringIdString, {
|
|
198
|
+
decode: Getter.passthrough(),
|
|
199
|
+
encode: Getter.passthrough()
|
|
200
|
+
}),
|
|
201
|
+
toCodecArbitrary: () =>
|
|
202
|
+
S.link<StringId>()(
|
|
203
|
+
S.Uint8Array.check(S.isMinLength(nanoidByteLength), S.isMaxLength(nanoidByteLength)),
|
|
204
|
+
{
|
|
205
|
+
decode: Getter.transform(nanoidFromBytes),
|
|
206
|
+
encode: Getter.forbiddenEncoding
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
const makeStringId = (s?: string): StringId =>
|
|
212
|
+
s !== undefined ? S.decodeSync(StringIdString)(s) : nanoid() as unknown as StringId
|
|
147
213
|
/**
|
|
148
214
|
* A string that is at least 6 characters long and a maximum of 50.
|
|
215
|
+
*
|
|
216
|
+
* `.withConstructorDefault` => fresh `nanoid()` (construction-only; not
|
|
217
|
+
* applied during decode — see file-level note).
|
|
149
218
|
*/
|
|
150
|
-
export
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
219
|
+
export interface StringIdSchema extends S.declareConstructor<StringId, string, readonly [], StringId> {
|
|
220
|
+
(i: string, options?: SchemaAST.ParseOptions): StringId
|
|
221
|
+
/** Generate fresh `nanoid()`-shaped `StringId`. */
|
|
222
|
+
make(): StringId
|
|
223
|
+
/** Construct a `StringId` from a known string (validated via decodeSync). */
|
|
224
|
+
make(input: string, options?: S.MakeOptions): StringId
|
|
225
|
+
readonly withConstructorDefault: S.withConstructorDefault<
|
|
226
|
+
S.declareConstructor<StringId, string, readonly [], StringId>
|
|
227
|
+
>
|
|
228
|
+
}
|
|
229
|
+
export const StringId: StringIdSchema = extendM(
|
|
230
|
+
StringIdSchemaBase,
|
|
161
231
|
(s) => ({
|
|
162
232
|
make: makeStringId,
|
|
163
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Construction-only default: fresh `nanoid()`-shaped `StringId`. Applied
|
|
235
|
+
* only when the field is omitted from `.make(...)` input. NOT applied
|
|
236
|
+
* during decode — cannot be used to JIT-migrate database fields. See
|
|
237
|
+
* file-level note.
|
|
238
|
+
*/
|
|
239
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(makeStringId)))
|
|
164
240
|
})
|
|
165
241
|
)
|
|
166
242
|
.pipe(withDefaultMake)
|
|
167
243
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Build a `StringId` schema whose values are required to start with a fixed
|
|
246
|
+
* `prefix` (joined with `separator`, default `-`).
|
|
247
|
+
*
|
|
248
|
+
* The returned schema exposes `.withConstructorDefault` that mints a fresh
|
|
249
|
+
* prefixed id. Construction-only — not applied during decode; see file-level
|
|
250
|
+
* note.
|
|
251
|
+
*/
|
|
252
|
+
export function prefixedStringId<Type extends StringId>() {
|
|
173
253
|
return <Prefix extends string, Separator extends string = "-">(
|
|
174
254
|
prefix: Prefix,
|
|
175
255
|
name: string,
|
|
@@ -177,27 +257,42 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
177
257
|
) => {
|
|
178
258
|
type FullPrefix = `${Prefix}${Separator}`
|
|
179
259
|
const pref = `${prefix}${separator ?? "-"}` as FullPrefix
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
S.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
260
|
+
const PrefixedString = StringIdString.pipe(
|
|
261
|
+
S.refine((x): x is Type => x.startsWith(pref), { identifier: name })
|
|
262
|
+
)
|
|
263
|
+
// Pre-rc.114: StringIdArb().map(x => pref + x.substring(0, 50 - pref.length))
|
|
264
|
+
const s = S.declareConstructor<Type, string>()(
|
|
265
|
+
[],
|
|
266
|
+
() => (input, ast, options) =>
|
|
267
|
+
S.is(PrefixedString)(input)
|
|
268
|
+
? Effect.succeed(input)
|
|
269
|
+
: Effect.fail(new SchemaIssue.InvalidType(ast, input, options)),
|
|
270
|
+
{
|
|
271
|
+
identifier: name,
|
|
272
|
+
expected: name,
|
|
273
|
+
toCodec: () =>
|
|
274
|
+
S.link<Type>()(PrefixedString, {
|
|
275
|
+
decode: Getter.passthrough(),
|
|
276
|
+
encode: Getter.passthrough()
|
|
277
|
+
}),
|
|
278
|
+
toCodecArbitrary: () =>
|
|
279
|
+
S.link<Type>()(
|
|
280
|
+
S.Uint8Array.check(S.isMinLength(nanoidByteLength), S.isMaxLength(nanoidByteLength)),
|
|
281
|
+
{
|
|
282
|
+
decode: Getter.transform((bytes) =>
|
|
283
|
+
(pref + nanoidFromBytes(bytes).substring(0, maxLength - pref.length)) as Type
|
|
284
|
+
),
|
|
285
|
+
encode: Getter.forbiddenEncoding
|
|
286
|
+
}
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
)
|
|
195
290
|
const schema = s.pipe(withDefaultMake)
|
|
196
|
-
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as
|
|
291
|
+
const make = () => (pref + StringId.make().substring(0, 50 - pref.length)) as Type
|
|
197
292
|
|
|
198
293
|
return extendM(
|
|
199
294
|
schema,
|
|
200
|
-
(ex): PrefixedStringUtils<
|
|
295
|
+
(ex): PrefixedStringUtils<Type, Prefix, Separator> => ({
|
|
201
296
|
make,
|
|
202
297
|
/**
|
|
203
298
|
* Automatically adds the prefix.
|
|
@@ -208,35 +303,60 @@ export function prefixedStringId<Brand extends StringId>() {
|
|
|
208
303
|
*/
|
|
209
304
|
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => ex(str),
|
|
210
305
|
prefix,
|
|
211
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Construction-only default: fresh prefixed id. Applied only when
|
|
308
|
+
* the field is omitted from `.make(...)` input. NOT applied during
|
|
309
|
+
* decode — cannot be used to JIT-migrate database fields. See
|
|
310
|
+
* file-level note.
|
|
311
|
+
*/
|
|
312
|
+
withConstructorDefault: schema.pipe(
|
|
313
|
+
S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>(
|
|
314
|
+
Effect.sync(make)
|
|
315
|
+
)
|
|
316
|
+
)
|
|
212
317
|
})
|
|
213
318
|
)
|
|
214
319
|
}
|
|
215
320
|
}
|
|
216
321
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Build a branded `StringId` schema for the given branded `Id` type.
|
|
324
|
+
*
|
|
325
|
+
* Exposes `.withConstructorDefault` that mints a fresh `nanoid()`-shaped id.
|
|
326
|
+
* Construction-only — not applied during decode; see file-level note.
|
|
327
|
+
*/
|
|
328
|
+
export const brandedStringId = <Id extends string & B.Brand<any>>(): BrandedStringIdSchema<Id> =>
|
|
220
329
|
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>>
|
|
330
|
+
Object.assign(Object.create(StringId), StringId) as BrandedStringIdSchema<Id>
|
|
225
331
|
)
|
|
226
332
|
|
|
227
333
|
export interface PrefixedStringUtils<
|
|
228
|
-
|
|
334
|
+
Type extends StringId,
|
|
229
335
|
Prefix extends string,
|
|
230
336
|
Separator extends string
|
|
231
337
|
> {
|
|
232
|
-
readonly make: () =>
|
|
233
|
-
readonly unsafeFrom: (str: string) =>
|
|
234
|
-
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) =>
|
|
338
|
+
readonly make: () => Type
|
|
339
|
+
readonly unsafeFrom: (str: string) => Type
|
|
340
|
+
prefixSafe: <REST extends string>(str: `${Prefix}${Separator}${REST}`) => Type
|
|
235
341
|
readonly prefix: Prefix
|
|
236
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Construction-only default: fresh prefixed id. Applied only when the
|
|
344
|
+
* field is omitted from `.make(...)` input. NOT applied during decode —
|
|
345
|
+
* cannot be used to JIT-migrate database fields. See file-level note.
|
|
346
|
+
*/
|
|
347
|
+
readonly withConstructorDefault: S.withConstructorDefault<S.Codec<Type, string> & S.WithoutConstructorDefault>
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface BrandedStringIdSchema<Id extends string & B.Brand<any>> extends BrandedSchema<S.String, Id> {
|
|
351
|
+
(i: string, options?: SchemaAST.ParseOptions): Id
|
|
352
|
+
/** Generate fresh `nanoid()`-shaped id (inherited from `StringId`). */
|
|
353
|
+
make(): Id
|
|
354
|
+
/** Construct an `Id` from a known string (validated via decodeSync). */
|
|
355
|
+
make(input: string, options?: S.MakeOptions): Id
|
|
356
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.String, Id>>
|
|
237
357
|
}
|
|
238
358
|
|
|
239
|
-
export interface UrlBrand extends Simplify<
|
|
359
|
+
export interface UrlBrand extends Simplify<SchemaB.Brand<"Url"> & NonEmptyStringBrand> {}
|
|
240
360
|
|
|
241
361
|
export type Url = string & UrlBrand
|
|
242
362
|
|
|
@@ -244,16 +364,27 @@ const isUrl: Refinement<string, Url> = (s: string): s is Url => {
|
|
|
244
364
|
return validator.default.isURL(s, { require_tld: false })
|
|
245
365
|
}
|
|
246
366
|
|
|
247
|
-
export
|
|
367
|
+
export interface UrlSchema extends S.refine<Url, S.String> {
|
|
368
|
+
(i: string, options?: SchemaAST.ParseOptions): Url
|
|
369
|
+
}
|
|
370
|
+
export const Url: UrlSchema = S
|
|
248
371
|
.String
|
|
249
372
|
.pipe(
|
|
250
|
-
S.
|
|
251
|
-
identifier: "Url",
|
|
373
|
+
S.annotate({
|
|
252
374
|
title: "Url",
|
|
253
|
-
|
|
375
|
+
format: "uri"
|
|
254
376
|
}),
|
|
255
|
-
S.
|
|
256
|
-
|
|
377
|
+
S.refine(isUrl, {
|
|
378
|
+
identifier: "Url",
|
|
379
|
+
jsonSchema: { format: "uri" },
|
|
380
|
+
// Native Arbitrary otherwise emits strings that `isURL({ require_tld: false })`
|
|
381
|
+
// accepts (`"R"`, `"prototype"`). Restore the old fast-check `fc.webUrl()` shape.
|
|
382
|
+
arbitraryConstraint: {
|
|
383
|
+
patterns: [{
|
|
384
|
+
source: "^https://[a-z]{3,12}\\.(?:com|net|org|de)(?:/[a-z0-9-]{0,16})?$",
|
|
385
|
+
flags: ""
|
|
386
|
+
}]
|
|
387
|
+
}
|
|
257
388
|
}),
|
|
258
389
|
withDefaultMake
|
|
259
390
|
)
|
package/src/Schema/numbers.ts
CHANGED
|
@@ -1,76 +1,155 @@
|
|
|
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"
|
|
13
|
+
import * as Order from "effect/Order"
|
|
2
14
|
import * as S from "effect/Schema"
|
|
3
15
|
import type { Simplify } from "effect/Types"
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
16
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
17
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
18
|
+
import { withDefaultMake } from "./ext.ts"
|
|
19
|
+
import { type B } from "./schema.ts"
|
|
7
20
|
|
|
8
21
|
export interface PositiveIntBrand
|
|
9
22
|
extends Simplify<B.Brand<"PositiveInt"> & NonNegativeIntBrand & PositiveNumberBrand>
|
|
10
23
|
{}
|
|
11
|
-
export
|
|
24
|
+
export type PositiveInt = number & PositiveIntBrand
|
|
25
|
+
/** Positive integer. `.withConstructorDefault` => `1` (construction-only). */
|
|
26
|
+
export interface PositiveIntSchema extends BrandedSchema<S.Int, PositiveInt> {
|
|
27
|
+
(i: number, options?: SchemaAST.ParseOptions): PositiveInt
|
|
28
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, PositiveInt>>
|
|
29
|
+
}
|
|
30
|
+
export const PositiveInt: PositiveIntSchema = extendM(
|
|
12
31
|
S.Int.pipe(
|
|
13
32
|
S.check(S.isGreaterThan(0)),
|
|
14
|
-
fromBrand(nominal<PositiveInt>(), { identifier: "PositiveInt",
|
|
33
|
+
fromBrand<PositiveInt>(nominal<PositiveInt>(), { identifier: "PositiveInt", jsonSchema: {} }),
|
|
15
34
|
withDefaultMake
|
|
16
35
|
),
|
|
17
|
-
(s) => ({
|
|
36
|
+
(s) => ({
|
|
37
|
+
/**
|
|
38
|
+
* Construction-only default `1`. Applied only when the field is omitted
|
|
39
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
40
|
+
* JIT-migrate database fields. See file-level note.
|
|
41
|
+
*/
|
|
42
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(1))))
|
|
43
|
+
})
|
|
18
44
|
)
|
|
19
|
-
export type PositiveInt = number & PositiveIntBrand
|
|
20
45
|
|
|
21
46
|
export interface NonNegativeIntBrand extends Simplify<B.Brand<"NonNegativeInt"> & IntBrand & NonNegativeNumberBrand> {}
|
|
22
|
-
export
|
|
47
|
+
export type NonNegativeInt = number & NonNegativeIntBrand
|
|
48
|
+
/** Non-negative integer. `.withConstructorDefault` => `0` (construction-only). */
|
|
49
|
+
export interface NonNegativeIntSchema extends BrandedSchema<S.Int, NonNegativeInt> {
|
|
50
|
+
(i: number, options?: SchemaAST.ParseOptions): NonNegativeInt
|
|
51
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, NonNegativeInt>>
|
|
52
|
+
}
|
|
53
|
+
export const NonNegativeInt: NonNegativeIntSchema = extendM(
|
|
23
54
|
S.Int.pipe(
|
|
24
55
|
S.check(S.isGreaterThanOrEqualTo(0)),
|
|
25
|
-
fromBrand(nominal<NonNegativeInt>(), {
|
|
56
|
+
fromBrand<NonNegativeInt>(nominal<NonNegativeInt>(), {
|
|
26
57
|
identifier: "NonNegativeInt",
|
|
27
|
-
title: "NonNegativeInt",
|
|
28
58
|
jsonSchema: {}
|
|
29
59
|
}),
|
|
30
60
|
withDefaultMake
|
|
31
61
|
),
|
|
32
|
-
(s) => ({
|
|
62
|
+
(s) => ({
|
|
63
|
+
/**
|
|
64
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
65
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
66
|
+
* JIT-migrate database fields. See file-level note.
|
|
67
|
+
*/
|
|
68
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
69
|
+
})
|
|
33
70
|
)
|
|
34
|
-
export type NonNegativeInt = number & NonNegativeIntBrand
|
|
35
71
|
|
|
36
72
|
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
73
|
export type Int = number & IntBrand
|
|
74
|
+
/** Integer. `.withConstructorDefault` => `0` (construction-only). */
|
|
75
|
+
export interface IntSchema extends BrandedSchema<S.Int, Int> {
|
|
76
|
+
(i: number, options?: SchemaAST.ParseOptions): Int
|
|
77
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Int, Int>>
|
|
78
|
+
}
|
|
79
|
+
export const Int: IntSchema = extendM(
|
|
80
|
+
S.Int.pipe(fromBrand<Int>(nominal<Int>(), { identifier: "Int", jsonSchema: {} }), withDefaultMake),
|
|
81
|
+
(s) => ({
|
|
82
|
+
/**
|
|
83
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
84
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
85
|
+
* JIT-migrate database fields. See file-level note.
|
|
86
|
+
*/
|
|
87
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
88
|
+
})
|
|
89
|
+
)
|
|
42
90
|
|
|
43
91
|
export interface PositiveNumberBrand extends Simplify<B.Brand<"PositiveNumber"> & NonNegativeNumberBrand> {}
|
|
44
|
-
export
|
|
92
|
+
export type PositiveNumber = number & PositiveNumberBrand
|
|
93
|
+
/** Positive finite number. `.withConstructorDefault` => `1` (construction-only). */
|
|
94
|
+
// Generation-only: native Arbitrary otherwise samples up to Number.MAX_VALUE, so derived totals
|
|
95
|
+
// (amount x weight, sums) overflow to Infinity. Validation and JSON Schema are unaffected.
|
|
96
|
+
const realisticMaximum = 1_000_000
|
|
97
|
+
|
|
98
|
+
export interface PositiveNumberSchema extends BrandedSchema<S.Finite, PositiveNumber> {
|
|
99
|
+
(i: number, options?: SchemaAST.ParseOptions): PositiveNumber
|
|
100
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Finite, PositiveNumber>>
|
|
101
|
+
}
|
|
102
|
+
export const PositiveNumber: PositiveNumberSchema = extendM(
|
|
45
103
|
S.Finite.pipe(
|
|
46
|
-
S.check(S.isGreaterThan(0
|
|
47
|
-
|
|
104
|
+
S.check(S.isGreaterThan(0, {
|
|
105
|
+
// the full constraint: annotations replace the check default, which carries `order` + `minimum`
|
|
106
|
+
arbitraryConstraint: { order: Order.Number, minimum: 0, exclusiveMinimum: true, maximum: realisticMaximum }
|
|
107
|
+
})),
|
|
108
|
+
fromBrand<PositiveNumber>(nominal<PositiveNumber>(), {
|
|
48
109
|
identifier: "PositiveNumber",
|
|
49
|
-
title: "PositiveNumber",
|
|
50
110
|
jsonSchema: {}
|
|
51
111
|
}),
|
|
52
112
|
withDefaultMake
|
|
53
113
|
),
|
|
54
|
-
(s) => ({
|
|
114
|
+
(s) => ({
|
|
115
|
+
/**
|
|
116
|
+
* Construction-only default `1`. Applied only when the field is omitted
|
|
117
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
118
|
+
* JIT-migrate database fields. See file-level note.
|
|
119
|
+
*/
|
|
120
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(1))))
|
|
121
|
+
})
|
|
55
122
|
)
|
|
56
|
-
export type PositiveNumber = number & PositiveNumberBrand
|
|
57
123
|
|
|
58
124
|
export interface NonNegativeNumberBrand extends Simplify<B.Brand<"NonNegativeNumber">> {}
|
|
59
|
-
export
|
|
125
|
+
export type NonNegativeNumber = number & NonNegativeNumberBrand
|
|
126
|
+
/** Non-negative finite number. `.withConstructorDefault` => `0` (construction-only). */
|
|
127
|
+
export interface NonNegativeNumberSchema extends BrandedSchema<S.Finite, NonNegativeNumber> {
|
|
128
|
+
(i: number, options?: SchemaAST.ParseOptions): NonNegativeNumber
|
|
129
|
+
readonly withConstructorDefault: S.withConstructorDefault<BrandedSchema<S.Finite, NonNegativeNumber>>
|
|
130
|
+
}
|
|
131
|
+
export const NonNegativeNumber: NonNegativeNumberSchema = extendM(
|
|
60
132
|
S
|
|
61
133
|
.Finite
|
|
62
134
|
.pipe(
|
|
63
|
-
S.check(S.isGreaterThanOrEqualTo(0
|
|
64
|
-
|
|
135
|
+
S.check(S.isGreaterThanOrEqualTo(0, {
|
|
136
|
+
arbitraryConstraint: { order: Order.Number, minimum: 0, maximum: realisticMaximum }
|
|
137
|
+
})),
|
|
138
|
+
fromBrand<NonNegativeNumber>(nominal<NonNegativeNumber>(), {
|
|
65
139
|
identifier: "NonNegativeNumber",
|
|
66
|
-
title: "NonNegativeNumber",
|
|
67
140
|
jsonSchema: {}
|
|
68
141
|
}),
|
|
69
142
|
withDefaultMake
|
|
70
143
|
),
|
|
71
|
-
(s) => ({
|
|
144
|
+
(s) => ({
|
|
145
|
+
/**
|
|
146
|
+
* Construction-only default `0`. Applied only when the field is omitted
|
|
147
|
+
* from `.make(...)` input. NOT applied during decode — cannot be used to
|
|
148
|
+
* JIT-migrate database fields. See file-level note.
|
|
149
|
+
*/
|
|
150
|
+
withConstructorDefault: s.pipe(S.withConstructorDefault(Effect.sync(() => s(0))))
|
|
151
|
+
})
|
|
72
152
|
)
|
|
73
|
-
export type NonNegativeNumber = number & NonNegativeNumberBrand
|
|
74
153
|
|
|
75
154
|
/** @deprecated Not an actual decimal */
|
|
76
155
|
export const NonNegativeDecimal = NonNegativeNumber
|