effect-app 4.0.0-beta.267 → 4.0.0-beta.269
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 +30 -0
- package/dist/Model/filter/types/path/eager.d.ts +1 -29
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
- package/dist/Model/filter/types/path/eager.js +9 -10
- package/dist/Model/filter/types.d.ts +4 -4
- package/dist/RequestContext.d.ts +121 -4
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +7 -2
- package/dist/Schema/Class.d.ts +93 -1
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +25 -3
- package/dist/Schema/SpecialOpenApi.js +1 -1
- package/dist/Schema.d.ts +2 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +2 -2
- package/dist/client/errors.d.ts +1 -1
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +2 -2
- package/dist/client.d.ts +5 -5
- package/dist/rpc/Invalidation.js +3 -3
- package/dist/utils.d.ts +6 -6
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +15 -11
- package/package.json +3 -3
- package/src/Array.ts +2 -2
- package/src/Chunk.ts +3 -3
- package/src/Config/SecretURL.ts +1 -1
- package/src/Config/internal/configSecretURL.ts +1 -1
- package/src/Config.ts +1 -1
- package/src/Effect.ts +3 -3
- package/src/Emailer.ts +4 -4
- package/src/Inputify.type.ts +1 -1
- package/src/Layer.ts +2 -2
- package/src/Model/Repository/Registry.ts +3 -3
- package/src/Model/Repository/ext.ts +11 -11
- package/src/Model/Repository/internal/internal.ts +16 -16
- package/src/Model/Repository/legacy.ts +4 -4
- package/src/Model/Repository/makeRepo.ts +11 -11
- package/src/Model/Repository/service.ts +9 -9
- package/src/Model/Repository/validation.ts +2 -2
- package/src/Model/Repository.ts +6 -6
- package/src/Model/dsl.ts +4 -4
- package/src/Model/filter/filterApi.ts +1 -1
- package/src/Model/filter/types/errors.ts +3 -3
- package/src/Model/filter/types/fields.ts +2 -2
- package/src/Model/filter/types/path/common.ts +1 -1
- package/src/Model/filter/types/path/eager.ts +11 -9
- package/src/Model/filter/types/path/index.ts +2 -2
- package/src/Model/filter/types/validator.ts +3 -3
- package/src/Model/query/dsl.ts +6 -6
- package/src/Model/query/new-kid-interpreter.ts +9 -9
- package/src/Model/query.ts +2 -2
- package/src/Model.ts +4 -4
- package/src/NonEmptySet.ts +3 -3
- package/src/Option.ts +1 -1
- package/src/Pure.ts +2 -2
- package/src/QueueMaker.ts +3 -3
- package/src/RequestContext.ts +43 -10
- package/src/Schema/Class.ts +247 -5
- package/src/Schema/SchemaParser.ts +1 -1
- package/src/Schema/SpecialOpenApi.ts +2 -2
- package/src/Schema/email.ts +2 -2
- package/src/Schema/ext.ts +4 -4
- package/src/Schema/moreStrings.ts +4 -4
- package/src/Schema/numbers.ts +3 -3
- package/src/Schema/phoneNumber.ts +4 -4
- package/src/Schema/strings.ts +2 -2
- package/src/Schema.ts +23 -23
- package/src/Set.ts +1 -1
- package/src/Store.ts +11 -11
- package/src/_ext/Array.ts +1 -1
- package/src/client/InvalidationKeys.ts +3 -3
- package/src/client/apiClientFactory.ts +9 -9
- package/src/client/clientFor.ts +3 -3
- package/src/client/errors.ts +7 -2
- package/src/client/makeClient.ts +4 -4
- package/src/http/Request.ts +2 -2
- package/src/http.ts +1 -1
- package/src/ids.ts +2 -2
- package/src/index.ts +19 -19
- package/src/middleware.ts +1 -1
- package/src/rpc/Invalidation.ts +7 -7
- package/src/rpc/MiddlewareMaker.ts +6 -6
- package/src/rpc/RpcContextMap.ts +2 -2
- package/src/rpc/RpcMiddleware.ts +2 -2
- package/src/rpc.ts +4 -4
- package/src/runtime.ts +4 -4
- package/src/setupRequest.ts +6 -6
- package/src/toast.ts +4 -4
- package/src/transform.ts +1 -1
- package/src/utils/logger.ts +1 -1
- package/src/utils.ts +23 -19
- package/src/validation.ts +2 -2
- package/src/withToast.ts +7 -7
- package/tsconfig.json +1 -0
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
import { identity, pipe } from "effect/Function"
|
|
4
4
|
import * as Match from "effect/Match"
|
|
5
5
|
import * as SchemaAST from "effect/SchemaAST"
|
|
6
|
-
import * as Array from "../../Array.
|
|
7
|
-
import { toNonEmptyArray } from "../../Array.
|
|
8
|
-
import * as Option from "../../Option.
|
|
9
|
-
import * as S from "../../Schema.
|
|
10
|
-
import { dropUndefinedT } from "../../utils.
|
|
11
|
-
import type { FilterResult } from "../filter/filterApi.
|
|
12
|
-
import type { FieldValues } from "../filter/types.
|
|
13
|
-
import type { FieldPath } from "../filter/types/path/eager.
|
|
14
|
-
import { make, type Q, type QAll } from "../query/dsl.
|
|
6
|
+
import * as Array from "../../Array.ts"
|
|
7
|
+
import { toNonEmptyArray } from "../../Array.ts"
|
|
8
|
+
import * as Option from "../../Option.ts"
|
|
9
|
+
import * as S from "../../Schema.ts"
|
|
10
|
+
import { dropUndefinedT } from "../../utils.ts"
|
|
11
|
+
import type { FilterResult } from "../filter/filterApi.ts"
|
|
12
|
+
import type { FieldValues } from "../filter/types.ts"
|
|
13
|
+
import type { FieldPath } from "../filter/types/path/eager.ts"
|
|
14
|
+
import { make, type Q, type QAll } from "../query/dsl.ts"
|
|
15
15
|
|
|
16
16
|
export type AggregateIrExpression =
|
|
17
17
|
| { readonly _tag: "agg-count" }
|
package/src/Model/query.ts
CHANGED
package/src/Model.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from "./Model/dsl.
|
|
2
|
-
export * as Q from "./Model/query.
|
|
3
|
-
export { makeRepo } from "./Model/Repository.
|
|
4
|
-
export { type RegisteredRepository, RepositoryRegistry, RepositoryRegistryLive } from "./Model/Repository.
|
|
1
|
+
export * from "./Model/dsl.ts"
|
|
2
|
+
export * as Q from "./Model/query.ts"
|
|
3
|
+
export { makeRepo } from "./Model/Repository.ts"
|
|
4
|
+
export { type RegisteredRepository, RepositoryRegistry, RepositoryRegistryLive } from "./Model/Repository.ts"
|
package/src/NonEmptySet.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
|
2
2
|
import type * as Equivalence from "effect/Equivalence"
|
|
3
3
|
import * as Option from "effect/Option"
|
|
4
4
|
import type * as Order from "effect/Order"
|
|
5
|
-
import { flow, pipe } from "./Function.
|
|
6
|
-
import { filter_, filterMap, filterMap_, fromArray as fromArrayOriginal, insert as insertOriginal, insert_ as insert_Original, map, map_, reduce, reduce_, remove, remove_, type Set, toArray as toArrayOriginal } from "./Set.
|
|
5
|
+
import { flow, pipe } from "./Function.ts"
|
|
6
|
+
import { filter_, filterMap, filterMap_, fromArray as fromArrayOriginal, insert as insertOriginal, insert_ as insert_Original, map, map_, reduce, reduce_, remove, remove_, type Set, toArray as toArrayOriginal } from "./Set.ts"
|
|
7
7
|
|
|
8
8
|
export interface NonEmptyBrand {
|
|
9
9
|
readonly NonEmpty: unique symbol
|
|
@@ -89,4 +89,4 @@ export function fromSet<A>(set: Set<A>) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// TODO
|
|
92
|
-
export * from "./Set.
|
|
92
|
+
export * from "./Set.ts"
|
package/src/Option.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
5
|
// eslint-disable-next-line import/no-unassigned-import
|
|
6
|
-
import "./builtin.
|
|
6
|
+
import "./builtin.ts"
|
|
7
7
|
import { getOrUndefined as value, type Some } from "effect/Option"
|
|
8
8
|
import * as Option from "effect/Option"
|
|
9
9
|
|
package/src/Pure.ts
CHANGED
|
@@ -3,8 +3,8 @@ import * as Chunk from "effect/Chunk"
|
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
4
|
import * as Layer from "effect/Layer"
|
|
5
5
|
import * as Result from "effect/Result"
|
|
6
|
-
import * as Context from "./Context.
|
|
7
|
-
import { tuple } from "./Function.
|
|
6
|
+
import * as Context from "./Context.ts"
|
|
7
|
+
import { tuple } from "./Function.ts"
|
|
8
8
|
|
|
9
9
|
const S1 = Symbol()
|
|
10
10
|
const S2 = Symbol()
|
package/src/QueueMaker.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as Scope from "effect/Scope"
|
|
2
|
-
import type { NonEmptyReadonlyArray } from "./Array.
|
|
3
|
-
import type * as Effect from "./Effect.
|
|
4
|
-
import { RequestContext } from "./RequestContext.
|
|
2
|
+
import type { NonEmptyReadonlyArray } from "./Array.ts"
|
|
3
|
+
import type * as Effect from "./Effect.ts"
|
|
4
|
+
import { RequestContext } from "./RequestContext.ts"
|
|
5
5
|
|
|
6
6
|
export interface QueueBase<Evt, DrainEvt> {
|
|
7
7
|
drain: <DrainE, DrainR>(
|
package/src/RequestContext.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import * as Context from "./Context.
|
|
2
|
-
import { UserProfileId } from "./ids.
|
|
3
|
-
import * as S from "./Schema.
|
|
4
|
-
import { NonEmptyString255 } from "./Schema.
|
|
1
|
+
import * as Context from "./Context.ts"
|
|
2
|
+
import { UserProfileId } from "./ids.ts"
|
|
3
|
+
import * as S from "./Schema.ts"
|
|
4
|
+
import { NonEmptyString255 } from "./Schema.ts"
|
|
5
5
|
|
|
6
6
|
export const Locale = S.Literals(["en", "de"])
|
|
7
7
|
export type Locale = typeof Locale.Type
|
|
8
8
|
|
|
9
9
|
export class LocaleRef extends Context.Reference("Locale", { defaultValue: (): Locale => "en" }) {}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
RequestContext,
|
|
13
|
-
RequestContext.Encoded
|
|
14
|
-
>()(S.Struct({
|
|
11
|
+
class _RequestContext extends S.Opaque<_RequestContext>()(S.Struct({
|
|
15
12
|
span: S.Struct({
|
|
16
13
|
traceId: S.String,
|
|
17
14
|
spanId: S.String,
|
|
@@ -34,6 +31,17 @@ export class RequestContext extends S.Opaque<
|
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
33
|
|
|
34
|
+
// codegen:start {preset: modelFacade, className: _RequestContext, schema: S}
|
|
35
|
+
// eslint-disable-next-line typescript/no-unsafe-declaration-merging
|
|
36
|
+
export class RequestContext extends S.OpaqueFacadeClass<
|
|
37
|
+
RequestContext,
|
|
38
|
+
RequestContext.Encoded,
|
|
39
|
+
RequestContext.Make,
|
|
40
|
+
RequestContext.DecodingServices,
|
|
41
|
+
RequestContext.EncodingServices
|
|
42
|
+
>()(_RequestContext) {}
|
|
43
|
+
// codegen:end
|
|
44
|
+
|
|
37
45
|
export const spanAttributes = (ctx: Pick<RequestContext, "locale" | "namespace"> & Partial<RequestContext>) => ({
|
|
38
46
|
"code.function.name": ctx.name,
|
|
39
47
|
"app.locale": ctx.locale,
|
|
@@ -52,10 +60,35 @@ export const spanAttributes = (ctx: Pick<RequestContext, "locale" | "namespace">
|
|
|
52
60
|
: {})
|
|
53
61
|
})
|
|
54
62
|
|
|
55
|
-
// codegen:start {preset: model}
|
|
63
|
+
// codegen:start {preset: model, static: true, facade: true}
|
|
56
64
|
//
|
|
65
|
+
export interface RequestContext {
|
|
66
|
+
readonly span: { readonly traceId: string; readonly spanId: string; readonly sampled: boolean }
|
|
67
|
+
readonly name: S.NonEmptyString255
|
|
68
|
+
readonly locale: "en" | "de"
|
|
69
|
+
readonly namespace: S.NonEmptyString255
|
|
70
|
+
readonly sourceId?: undefined | S.NonEmptyString255
|
|
71
|
+
readonly userProfile?: undefined | { readonly sub: UserProfileId }
|
|
72
|
+
}
|
|
57
73
|
export namespace RequestContext {
|
|
58
|
-
export interface Encoded
|
|
74
|
+
export interface Encoded {
|
|
75
|
+
readonly span: { readonly traceId: string; readonly spanId: string; readonly sampled: boolean }
|
|
76
|
+
readonly name: string
|
|
77
|
+
readonly locale: "en" | "de"
|
|
78
|
+
readonly namespace: string
|
|
79
|
+
readonly sourceId?: undefined | string
|
|
80
|
+
readonly userProfile?: undefined | { readonly sub: string }
|
|
81
|
+
}
|
|
82
|
+
export interface Make {
|
|
83
|
+
readonly span: { readonly traceId: string; readonly spanId: string; readonly sampled: boolean }
|
|
84
|
+
readonly name: S.NonEmptyString255
|
|
85
|
+
readonly locale: "en" | "de"
|
|
86
|
+
readonly namespace: S.NonEmptyString255
|
|
87
|
+
readonly sourceId?: undefined | S.NonEmptyString255
|
|
88
|
+
readonly userProfile?: undefined | { readonly sub: UserProfileId }
|
|
89
|
+
}
|
|
90
|
+
export type DecodingServices = never
|
|
91
|
+
export type EncodingServices = never
|
|
59
92
|
}
|
|
60
93
|
//
|
|
61
94
|
// codegen:end
|
package/src/Schema/Class.ts
CHANGED
|
@@ -5,9 +5,9 @@ import * as Option from "effect/Option"
|
|
|
5
5
|
import * as S from "effect/Schema"
|
|
6
6
|
import * as SchemaAST from "effect/SchemaAST"
|
|
7
7
|
import * as SchemaIssue from "effect/SchemaIssue"
|
|
8
|
-
import { copyOrigin } from "../utils.
|
|
9
|
-
import { concurrencyUnbounded } from "./ext.
|
|
10
|
-
import * as SchemaParser from "./SchemaParser.
|
|
8
|
+
import { copyOrigin } from "../utils.ts"
|
|
9
|
+
import { concurrencyUnbounded } from "./ext.ts"
|
|
10
|
+
import * as SchemaParser from "./SchemaParser.ts"
|
|
11
11
|
|
|
12
12
|
type ClassAnnotations<Self> = S.Annotations.Declaration<Self, readonly [any]>
|
|
13
13
|
|
|
@@ -91,7 +91,7 @@ function makeRelaxedDeclaration(
|
|
|
91
91
|
* @example
|
|
92
92
|
* ```ts
|
|
93
93
|
* import * as Schema from "effect/Schema"
|
|
94
|
-
* import { Class } from "./Class.
|
|
94
|
+
* import { Class } from "./Class.ts"
|
|
95
95
|
*
|
|
96
96
|
* class A extends Class<A>("A")({ a: Schema.String }) {}
|
|
97
97
|
*
|
|
@@ -160,7 +160,7 @@ export const Class: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}
|
|
|
160
160
|
* @example
|
|
161
161
|
* ```ts
|
|
162
162
|
* import * as Schema from "effect/Schema"
|
|
163
|
-
* import { TaggedClass } from "./Class.
|
|
163
|
+
* import { TaggedClass } from "./Class.ts"
|
|
164
164
|
*
|
|
165
165
|
* class Circle extends TaggedClass<Circle>()("Circle", {
|
|
166
166
|
* radius: Schema.Number
|
|
@@ -309,3 +309,245 @@ export interface Opaque<Self, Encoded, SchemaS extends S.Top, Brand>
|
|
|
309
309
|
export const Opaque: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
|
|
310
310
|
schema: S
|
|
311
311
|
) => Opaque<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Like {@link Opaque}, but the class **instance type is exactly `Self`** (the supplied
|
|
315
|
+
* decoded `Type`) instead of the structurally-computed `struct["Type"] & Brand`.
|
|
316
|
+
*
|
|
317
|
+
* Stock `Opaque` types the instance as `struct["Type"] & Brand` and only overrides the
|
|
318
|
+
* schema's `Type`/`Encoded` *members* with `Self`/`Encoded`. So `make`/`copy`/consumers
|
|
319
|
+
* still resolve the struct's mapped `Type`. With a codegen-supplied pre-expanded literal
|
|
320
|
+
* `Type` interface, `OpaqueType` lets all of those resolve a single **named** interface
|
|
321
|
+
* (resolved once per checker) instead of re-deriving the mapped `Type` — cutting
|
|
322
|
+
* instantiation on `Type`-touching consumers.
|
|
323
|
+
*
|
|
324
|
+
* Use with `class X extends OpaqueType<X.Type, X.Encoded>()(struct) {}` where `X.Type`
|
|
325
|
+
* and `X.Encoded` are generated literal interfaces (see `@effect-app/eslint-codegen-model`,
|
|
326
|
+
* `static` + `type` mode).
|
|
327
|
+
*
|
|
328
|
+
* KNOWN GAP — **no branding**: the instance type is a plain structural `Self`, so opaque
|
|
329
|
+
* types of identical shape are mutually assignable. (Stock `Opaque` is also structural by
|
|
330
|
+
* default — `Brand` defaults to `{}` — so this only differs if you passed a non-default
|
|
331
|
+
* `Brand`.) Re-introducing a nominal brand on top of a supplied `Self` (e.g. branding the
|
|
332
|
+
* generated `Type` interface) is not yet implemented.
|
|
333
|
+
*
|
|
334
|
+
* NOTE: only `Type` (via `Self`) and `Encoded` are supplied statically here; `make`'s input
|
|
335
|
+
* (`~type.make.in`) and other derived members are still computed from the struct. See
|
|
336
|
+
* a future `OpaqueShape`-style helper if those also need to be supplied.
|
|
337
|
+
*/
|
|
338
|
+
export interface OpaqueType<Self, Encoded, SchemaS extends S.Top, Brand>
|
|
339
|
+
extends S.Opaque<Self, ExtendedSchema<SchemaS, Encoded>, Brand>
|
|
340
|
+
{
|
|
341
|
+
new(_: never): Self
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export const OpaqueType: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
|
|
345
|
+
schema: S
|
|
346
|
+
) => OpaqueType<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
|
|
347
|
+
|
|
348
|
+
// Override both the `Encoded` and make-input (`~type.make.in`) members in one go,
|
|
349
|
+
// like `ExtendedSchema` does for `Encoded` alone.
|
|
350
|
+
type ExtendedShape<SchemaS extends S.Top, Encoded, MakeIn> =
|
|
351
|
+
& Omit<SchemaS, "Encoded" | "~type.make.in">
|
|
352
|
+
& { readonly Encoded: Encoded; readonly "~type.make.in": MakeIn }
|
|
353
|
+
|
|
354
|
+
type OpaqueFacadeConstructorArgs<MakeIn> = {} extends MakeIn ? [props?: MakeIn, options?: S.MakeOptions]
|
|
355
|
+
: [props: MakeIn, options?: S.MakeOptions]
|
|
356
|
+
|
|
357
|
+
// Only the codec channels are required. `copy`/`fields`/`mapFields` are NOT
|
|
358
|
+
// required here: transformed schemas (`.pipe(S.encodeKeys/annotate/filter/...)`)
|
|
359
|
+
// don't expose them at the static level, and requiring them would reject those
|
|
360
|
+
// models from facading. When present they still flow through via
|
|
361
|
+
// `OpaqueFacadeStatics`; when absent the facade simply doesn't offer them.
|
|
362
|
+
type OpaqueFacadeInput<DecodingServices, EncodingServices> = S.Top & {
|
|
363
|
+
readonly DecodingServices: DecodingServices
|
|
364
|
+
readonly EncodingServices: EncodingServices
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Carry the schema's own statics, dropping the generic `S.Top` machinery and
|
|
368
|
+
// `prototype`. EXCEPT `to`: models compose each other via `X.to.fields` /
|
|
369
|
+
// `X.to.copy` at definition time, so it must survive on the facade.
|
|
370
|
+
type OpaqueFacadeStatics<SchemaS extends S.Top> = Omit<SchemaS, Exclude<keyof S.Top, "to"> | "prototype">
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Like {@link OpaqueType}, but ALSO supplies a static **make-input** shape, so
|
|
374
|
+
* `make`/`copy` resolve a named `MakeIn` interface instead of re-deriving the struct's
|
|
375
|
+
* mapped `~type.make.in`. Use with codegen-supplied `X.Type` / `X.Encoded` / `X.Make`:
|
|
376
|
+
*
|
|
377
|
+
* ```ts
|
|
378
|
+
* class X extends OpaqueShape<X.Type, X.Encoded, X.Make>()(struct) {}
|
|
379
|
+
* ```
|
|
380
|
+
*
|
|
381
|
+
* `decode`/`encode` already use the supplied `Type`/`Encoded` (they read the schema's
|
|
382
|
+
* `Type`/`Encoded` members, which are `Self`/`Encoded` here) — no separate override needed.
|
|
383
|
+
*
|
|
384
|
+
* NOTE — measured gain is modest (~5%): the struct passed to the wrapper is still
|
|
385
|
+
* constructed in full (definition cost dominates); the static shapes only cheapen
|
|
386
|
+
* consumer-side reads of `Type`/`Encoded`/`MakeIn`. Same `no-branding` gap as
|
|
387
|
+
* {@link OpaqueType}.
|
|
388
|
+
*/
|
|
389
|
+
export interface OpaqueShape<Self, Encoded, MakeIn, SchemaS extends S.Top, Brand>
|
|
390
|
+
extends S.Opaque<Self, ExtendedShape<SchemaS, Encoded, MakeIn>, Brand>
|
|
391
|
+
{
|
|
392
|
+
new(_: never): Self
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export const OpaqueShape: <Self, Encoded, MakeIn, Brand = {}>() => <S extends S.Top>(
|
|
396
|
+
schema: S
|
|
397
|
+
) => OpaqueShape<Self, Encoded, MakeIn, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Shallow public view for generated model facades.
|
|
401
|
+
*
|
|
402
|
+
* The runtime value can still be the full private schema class, but emitted
|
|
403
|
+
* declarations expose only named `Type` / `Encoded` / `Make` interfaces and a
|
|
404
|
+
* small static surface. This keeps downstream project references from pulling
|
|
405
|
+
* the private struct field map back through `typeof Model`.
|
|
406
|
+
*/
|
|
407
|
+
export interface OpaqueFacade<
|
|
408
|
+
Self,
|
|
409
|
+
Encoded,
|
|
410
|
+
MakeIn,
|
|
411
|
+
DecodingServices = never,
|
|
412
|
+
EncodingServices = DecodingServices,
|
|
413
|
+
Brand = {}
|
|
414
|
+
> extends
|
|
415
|
+
S.Bottom<
|
|
416
|
+
Self,
|
|
417
|
+
Encoded,
|
|
418
|
+
DecodingServices,
|
|
419
|
+
EncodingServices,
|
|
420
|
+
SchemaAST.AST,
|
|
421
|
+
S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
|
|
422
|
+
MakeIn,
|
|
423
|
+
Self,
|
|
424
|
+
readonly [],
|
|
425
|
+
MakeIn
|
|
426
|
+
>
|
|
427
|
+
{
|
|
428
|
+
new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Self & Brand
|
|
429
|
+
readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
|
|
430
|
+
// NOTE: `fields` / `mapFields` are intentionally NOT redeclared here. They are
|
|
431
|
+
// carried (precise) from the underlying schema via `OpaqueFacadeStatics`. A wide
|
|
432
|
+
// `mapFields(f: (fields: S.Struct.Fields) => To)` override would win overload
|
|
433
|
+
// resolution and erase field precision in `Q.project(X.mapFields(...))`.
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export function OpaqueFacade<
|
|
437
|
+
Self,
|
|
438
|
+
Encoded,
|
|
439
|
+
MakeIn,
|
|
440
|
+
DecodingServices = never,
|
|
441
|
+
EncodingServices = DecodingServices,
|
|
442
|
+
Brand = {}
|
|
443
|
+
>() {
|
|
444
|
+
return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
|
|
445
|
+
schema: SchemaS
|
|
446
|
+
): OpaqueFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand> & OpaqueFacadeStatics<SchemaS> =>
|
|
447
|
+
schema as SchemaS & OpaqueFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export interface OpaqueFacadeClass<
|
|
451
|
+
Self,
|
|
452
|
+
Encoded,
|
|
453
|
+
MakeIn,
|
|
454
|
+
DecodingServices = never,
|
|
455
|
+
EncodingServices = DecodingServices,
|
|
456
|
+
Brand = {}
|
|
457
|
+
> extends
|
|
458
|
+
S.Bottom<
|
|
459
|
+
Self,
|
|
460
|
+
Encoded,
|
|
461
|
+
DecodingServices,
|
|
462
|
+
EncodingServices,
|
|
463
|
+
SchemaAST.AST,
|
|
464
|
+
S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
|
|
465
|
+
MakeIn,
|
|
466
|
+
Self,
|
|
467
|
+
readonly [],
|
|
468
|
+
MakeIn
|
|
469
|
+
>
|
|
470
|
+
{
|
|
471
|
+
new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Brand
|
|
472
|
+
readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
|
|
473
|
+
// NOTE: `fields` / `mapFields` intentionally not redeclared — carried precise
|
|
474
|
+
// from the underlying schema via `OpaqueFacadeStatics` (see OpaqueFacade above).
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
export function OpaqueFacadeClass<
|
|
478
|
+
Self,
|
|
479
|
+
Encoded,
|
|
480
|
+
MakeIn,
|
|
481
|
+
DecodingServices = never,
|
|
482
|
+
EncodingServices = DecodingServices,
|
|
483
|
+
Brand = {}
|
|
484
|
+
>() {
|
|
485
|
+
return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
|
|
486
|
+
schema: SchemaS
|
|
487
|
+
):
|
|
488
|
+
& OpaqueFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
|
|
489
|
+
& OpaqueFacadeStatics<SchemaS> =>
|
|
490
|
+
{
|
|
491
|
+
// Make the result constructable (like `S.Opaque`), so the private `_X` may be a
|
|
492
|
+
// plain `S.Struct`/`S.TaggedStruct` (lighter type) — not only an `S.Opaque` class —
|
|
493
|
+
// while `export class X extends ...(_X)` still works.
|
|
494
|
+
class Facade {}
|
|
495
|
+
return Object.setPrototypeOf(Facade, schema)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Like {@link OpaqueFacadeClass}, but for error models (`TaggedErrorClass` /
|
|
501
|
+
* `ErrorClass`). The decoded instance type carries `Cause.YieldableError`, so
|
|
502
|
+
* `yield* new MyError(...)`, `Effect.fail(myError)`, and `instanceof` all keep
|
|
503
|
+
* working through the facade — the runtime `_X` is the real error class (the
|
|
504
|
+
* facade `X extends ...(_X)` inherits its prototype), and the type reflects it.
|
|
505
|
+
* Nothing is lost vs the underlying error class.
|
|
506
|
+
*/
|
|
507
|
+
export interface OpaqueErrorFacadeClass<
|
|
508
|
+
Self,
|
|
509
|
+
Encoded,
|
|
510
|
+
MakeIn,
|
|
511
|
+
DecodingServices = never,
|
|
512
|
+
EncodingServices = DecodingServices,
|
|
513
|
+
Brand = {}
|
|
514
|
+
> extends
|
|
515
|
+
S.Bottom<
|
|
516
|
+
Self,
|
|
517
|
+
Encoded,
|
|
518
|
+
DecodingServices,
|
|
519
|
+
EncodingServices,
|
|
520
|
+
SchemaAST.AST,
|
|
521
|
+
S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
|
|
522
|
+
MakeIn,
|
|
523
|
+
Self,
|
|
524
|
+
readonly [],
|
|
525
|
+
MakeIn
|
|
526
|
+
>
|
|
527
|
+
{
|
|
528
|
+
// YieldableError (not Self) on the constructed instance — like OpaqueFacadeClass's
|
|
529
|
+
// `new(): Brand`, the data type comes from the declaration-merged `interface X`,
|
|
530
|
+
// so `Self` must NOT appear here (would recurse). Merging `X & YieldableError`
|
|
531
|
+
// makes `yield* new X()` / `Effect.fail` / `instanceof` work without losing data.
|
|
532
|
+
new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Cause.YieldableError & Brand
|
|
533
|
+
readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export function OpaqueErrorFacadeClass<
|
|
537
|
+
Self,
|
|
538
|
+
Encoded,
|
|
539
|
+
MakeIn,
|
|
540
|
+
DecodingServices = never,
|
|
541
|
+
EncodingServices = DecodingServices,
|
|
542
|
+
Brand = {}
|
|
543
|
+
>() {
|
|
544
|
+
return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
|
|
545
|
+
schema: SchemaS
|
|
546
|
+
):
|
|
547
|
+
& OpaqueErrorFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
|
|
548
|
+
& OpaqueFacadeStatics<SchemaS> =>
|
|
549
|
+
{
|
|
550
|
+
class Facade {}
|
|
551
|
+
return Object.setPrototypeOf(Facade, schema)
|
|
552
|
+
}
|
|
553
|
+
}
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
*
|
|
13
13
|
* ```ts
|
|
14
14
|
* import { OpenApi } from "effect/unstable"
|
|
15
|
-
* import { deduplicateOpenApiSchemas } from "./SpecialOpenApi.
|
|
15
|
+
* import { deduplicateOpenApiSchemas } from "./SpecialOpenApi.ts"
|
|
16
16
|
*
|
|
17
17
|
* const api = HttpApi.make("myApi")
|
|
18
18
|
* .pipe(HttpApi.annotateContext(OpenApi.annotations({ transform: deduplicateOpenApiSchemas })))
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { postProcessJsonSchema } from "./SpecialJsonSchema.
|
|
22
|
+
import { postProcessJsonSchema } from "./SpecialJsonSchema.ts"
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Deduplicates `components.schemas` entries in an OpenAPI spec.
|
package/src/Schema/email.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { Refinement } from "effect-app/Function"
|
|
|
2
2
|
import { isValidEmail } from "effect-app/validation"
|
|
3
3
|
import * as S from "effect/Schema"
|
|
4
4
|
import type { Simplify } from "effect/Types"
|
|
5
|
-
import type { B } from "./schema.
|
|
6
|
-
import type { NonEmptyStringBrand } from "./strings.
|
|
5
|
+
import type { B } from "./schema.ts"
|
|
6
|
+
import type { NonEmptyStringBrand } from "./strings.ts"
|
|
7
7
|
|
|
8
8
|
export interface EmailBrand extends Simplify<NonEmptyStringBrand & B.Brand<"Email">> {}
|
|
9
9
|
|
package/src/Schema/ext.ts
CHANGED
|
@@ -40,10 +40,10 @@ import { isDateValid } from "effect/Schema"
|
|
|
40
40
|
import type * as SchemaAST from "effect/SchemaAST"
|
|
41
41
|
import * as SchemaIssue from "effect/SchemaIssue"
|
|
42
42
|
import * as SchemaTransformation from "effect/SchemaTransformation"
|
|
43
|
-
import { type NonEmptyReadonlyArray } from "../Array.
|
|
44
|
-
import * as Context from "../Context.
|
|
45
|
-
import { extendM, typedKeysOf } from "../utils.
|
|
46
|
-
import { type AST } from "./schema.
|
|
43
|
+
import { type NonEmptyReadonlyArray } from "../Array.ts"
|
|
44
|
+
import * as Context from "../Context.ts"
|
|
45
|
+
import { extendM, typedKeysOf } from "../utils.ts"
|
|
46
|
+
import { type AST } from "./schema.ts"
|
|
47
47
|
|
|
48
48
|
type ProvidedCodec<Self extends S.Top, R> = S.Codec<
|
|
49
49
|
Self["Type"],
|
|
@@ -18,10 +18,10 @@ import type * as SchemaAST from "effect/SchemaAST"
|
|
|
18
18
|
import type { Simplify } from "effect/Types"
|
|
19
19
|
import { customRandom, nanoid, urlAlphabet } from "nanoid"
|
|
20
20
|
import validator from "validator"
|
|
21
|
-
import { type BrandedSchema, fromBrand, nominal } from "./brand.
|
|
22
|
-
import { withDefaultMake } from "./ext.
|
|
23
|
-
import { type B as SchemaB } from "./schema.
|
|
24
|
-
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"
|
|
25
25
|
|
|
26
26
|
const nonEmptyString = S.NonEmptyString
|
|
27
27
|
|
package/src/Schema/numbers.ts
CHANGED
|
@@ -13,9 +13,9 @@ import * as Effect from "effect/Effect"
|
|
|
13
13
|
import * as S from "effect/Schema"
|
|
14
14
|
import type * as SchemaAST from "effect/SchemaAST"
|
|
15
15
|
import type { Simplify } from "effect/Types"
|
|
16
|
-
import { type BrandedSchema, fromBrand, nominal } from "./brand.
|
|
17
|
-
import { withDefaultMake } from "./ext.
|
|
18
|
-
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"
|
|
19
19
|
|
|
20
20
|
export interface PositiveIntBrand
|
|
21
21
|
extends Simplify<B.Brand<"PositiveInt"> & NonNegativeIntBrand & PositiveNumberBrand>
|
|
@@ -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
|
package/src/Schema/strings.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type * as B from "effect/Brand"
|
|
|
2
2
|
import * as S from "effect/Schema"
|
|
3
3
|
import type * as SchemaAST from "effect/SchemaAST"
|
|
4
4
|
import type { Simplify } from "effect/Types"
|
|
5
|
-
import { type BrandedSchema, fromBrand, nominal } from "./brand.
|
|
6
|
-
import { withDefaultMake } from "./ext.
|
|
5
|
+
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
6
|
+
import { withDefaultMake } from "./ext.ts"
|
|
7
7
|
|
|
8
8
|
export type NonEmptyStringBrand = B.Brand<"NonEmptyString">
|
|
9
9
|
export type NonEmptyString = string & NonEmptyStringBrand
|
package/src/Schema.ts
CHANGED
|
@@ -3,13 +3,13 @@ import * as SchemaAST from "effect/SchemaAST"
|
|
|
3
3
|
import { type Simplify } from "effect/Struct"
|
|
4
4
|
import type * as Tracer from "effect/Tracer"
|
|
5
5
|
import type { RequiredKeys } from "effect/Types"
|
|
6
|
-
import type { NonEmptyReadonlyArray } from "./Array.
|
|
7
|
-
import { fakerArb } from "./faker.
|
|
8
|
-
import { Email as EmailT, type Email as EmailType } from "./Schema/email.
|
|
9
|
-
import { concurrencyUnbounded, withDefaultMake, withDefaultParseOptions } from "./Schema/ext.
|
|
10
|
-
import { PhoneNumber as PhoneNumberT, type PhoneNumber as PhoneNumberType } from "./Schema/phoneNumber.
|
|
11
|
-
import { type AST } from "./Schema/schema.
|
|
12
|
-
import { copy, extendM, type StructuralCopyOrigin } from "./utils.
|
|
6
|
+
import type { NonEmptyReadonlyArray } from "./Array.ts"
|
|
7
|
+
import { fakerArb } from "./faker.ts"
|
|
8
|
+
import { Email as EmailT, type Email as EmailType } from "./Schema/email.ts"
|
|
9
|
+
import { concurrencyUnbounded, withDefaultMake, withDefaultParseOptions } from "./Schema/ext.ts"
|
|
10
|
+
import { PhoneNumber as PhoneNumberT, type PhoneNumber as PhoneNumberType } from "./Schema/phoneNumber.ts"
|
|
11
|
+
import { type AST } from "./Schema/schema.ts"
|
|
12
|
+
import { copy, extendM, type StructuralCopyOrigin } from "./utils.ts"
|
|
13
13
|
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
15
|
// Default helpers — re-exported from effect/Schema
|
|
@@ -109,23 +109,23 @@ export { withDecodingDefaultTypeKey } from "effect/Schema"
|
|
|
109
109
|
|
|
110
110
|
export * from "effect/Schema"
|
|
111
111
|
|
|
112
|
-
export * from "./Schema/Class.
|
|
113
|
-
export { Class, ErrorClass, Opaque, TaggedClass, TaggedErrorClass } from "./Schema/Class.
|
|
112
|
+
export * from "./Schema/Class.ts"
|
|
113
|
+
export { Class, ErrorClass, Opaque, OpaqueErrorFacadeClass, OpaqueFacade, OpaqueFacadeClass, OpaqueShape, OpaqueType, TaggedClass, TaggedErrorClass } from "./Schema/Class.ts"
|
|
114
114
|
|
|
115
|
-
export { fromBrand, nominal } from "./Schema/brand.
|
|
116
|
-
export { Array, Boolean, Date, DateFromString, DateValid, Finite, Literals, NullOr, Number, ReadonlyMap, ReadonlySet } from "./Schema/ext.
|
|
117
|
-
export { Int, NonNegativeInt } from "./Schema/numbers.
|
|
115
|
+
export { fromBrand, nominal } from "./Schema/brand.ts"
|
|
116
|
+
export { Array, Boolean, Date, DateFromString, DateValid, Finite, Literals, NullOr, Number, ReadonlyMap, ReadonlySet } from "./Schema/ext.ts"
|
|
117
|
+
export { Int, NonNegativeInt } from "./Schema/numbers.ts"
|
|
118
118
|
|
|
119
|
-
export * from "./Schema/email.
|
|
120
|
-
export * from "./Schema/ext.
|
|
121
|
-
export * from "./Schema/moreStrings.
|
|
122
|
-
export * from "./Schema/numbers.
|
|
123
|
-
export * from "./Schema/phoneNumber.
|
|
124
|
-
export * from "./Schema/schema.
|
|
125
|
-
export * from "./Schema/SpecialJsonSchema.
|
|
126
|
-
export * from "./Schema/SpecialOpenApi.
|
|
127
|
-
export * from "./Schema/strings.
|
|
128
|
-
export { NonEmptyString } from "./Schema/strings.
|
|
119
|
+
export * from "./Schema/email.ts"
|
|
120
|
+
export * from "./Schema/ext.ts"
|
|
121
|
+
export * from "./Schema/moreStrings.ts"
|
|
122
|
+
export * from "./Schema/numbers.ts"
|
|
123
|
+
export * from "./Schema/phoneNumber.ts"
|
|
124
|
+
export * from "./Schema/schema.ts"
|
|
125
|
+
export * from "./Schema/SpecialJsonSchema.ts"
|
|
126
|
+
export * from "./Schema/SpecialOpenApi.ts"
|
|
127
|
+
export * from "./Schema/strings.ts"
|
|
128
|
+
export { NonEmptyString } from "./Schema/strings.ts"
|
|
129
129
|
|
|
130
130
|
export * as SchemaIssue from "effect/SchemaIssue"
|
|
131
131
|
|
|
@@ -133,7 +133,7 @@ export const decodeEffectConcurrently: typeof S.decodeEffect = withDefaultParseO
|
|
|
133
133
|
export const decodeUnknownEffectConcurrently: typeof S.decodeUnknownEffect = withDefaultParseOptions(
|
|
134
134
|
S.decodeUnknownEffect
|
|
135
135
|
)
|
|
136
|
-
export * as SchemaParser from "./Schema/SchemaParser.
|
|
136
|
+
export * as SchemaParser from "./Schema/SchemaParser.ts"
|
|
137
137
|
|
|
138
138
|
export { Void as Void_ } from "effect/Schema"
|
|
139
139
|
|
package/src/Set.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as Option from "effect/Option"
|
|
|
6
6
|
import type * as Order from "effect/Order"
|
|
7
7
|
import { not } from "effect/Predicate"
|
|
8
8
|
import type * as Result from "effect/Result"
|
|
9
|
-
import { identity, pipe, type Predicate, type Refinement, tuple } from "./Function.
|
|
9
|
+
import { identity, pipe, type Predicate, type Refinement, tuple } from "./Function.ts"
|
|
10
10
|
|
|
11
11
|
export function find_<A, B extends A>(
|
|
12
12
|
as: ReadonlySet<A>,
|