effect 4.0.0-beta.105 → 4.0.0-beta.107

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.
Files changed (181) hide show
  1. package/dist/Channel.d.ts +26 -0
  2. package/dist/Channel.d.ts.map +1 -1
  3. package/dist/Channel.js +47 -0
  4. package/dist/Channel.js.map +1 -1
  5. package/dist/Config.js +3 -3
  6. package/dist/Config.js.map +1 -1
  7. package/dist/ConfigProvider.d.ts +35 -3
  8. package/dist/ConfigProvider.d.ts.map +1 -1
  9. package/dist/ConfigProvider.js +41 -8
  10. package/dist/ConfigProvider.js.map +1 -1
  11. package/dist/Duration.d.ts.map +1 -1
  12. package/dist/Duration.js +13 -1
  13. package/dist/Duration.js.map +1 -1
  14. package/dist/Fiber.d.ts +1 -1
  15. package/dist/Fiber.d.ts.map +1 -1
  16. package/dist/Function.d.ts +26 -0
  17. package/dist/Function.d.ts.map +1 -1
  18. package/dist/Function.js +36 -0
  19. package/dist/Function.js.map +1 -1
  20. package/dist/JsonSchema.d.ts.map +1 -1
  21. package/dist/JsonSchema.js +34 -17
  22. package/dist/JsonSchema.js.map +1 -1
  23. package/dist/Schema.d.ts +32 -84
  24. package/dist/Schema.d.ts.map +1 -1
  25. package/dist/Schema.js +58 -54
  26. package/dist/Schema.js.map +1 -1
  27. package/dist/SchemaAST.d.ts +2 -17
  28. package/dist/SchemaAST.d.ts.map +1 -1
  29. package/dist/SchemaAST.js +39 -28
  30. package/dist/SchemaAST.js.map +1 -1
  31. package/dist/SchemaRepresentation.d.ts +44 -7
  32. package/dist/SchemaRepresentation.d.ts.map +1 -1
  33. package/dist/SchemaRepresentation.js +15 -4
  34. package/dist/SchemaRepresentation.js.map +1 -1
  35. package/dist/ScopedRef.d.ts.map +1 -1
  36. package/dist/ScopedRef.js +1 -1
  37. package/dist/ScopedRef.js.map +1 -1
  38. package/dist/Stream.d.ts +10 -0
  39. package/dist/Stream.d.ts.map +1 -1
  40. package/dist/Stream.js +12 -23
  41. package/dist/Stream.js.map +1 -1
  42. package/dist/TxQueue.js +1 -1
  43. package/dist/TxQueue.js.map +1 -1
  44. package/dist/internal/effect.js +2 -4
  45. package/dist/internal/effect.js.map +1 -1
  46. package/dist/internal/executionPlan.js +3 -2
  47. package/dist/internal/executionPlan.js.map +1 -1
  48. package/dist/internal/rcRef.js +18 -13
  49. package/dist/internal/rcRef.js.map +1 -1
  50. package/dist/internal/schema/fromJsonSchemaDocument.js +32 -16
  51. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  52. package/dist/internal/schema/toArbitrary.d.ts +1 -4
  53. package/dist/internal/schema/toArbitrary.d.ts.map +1 -1
  54. package/dist/internal/schema/toArbitrary.js +0 -74
  55. package/dist/internal/schema/toArbitrary.js.map +1 -1
  56. package/dist/internal/schema/toJsonSchemaDocument.js +18 -4
  57. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  58. package/dist/internal/schema/toRepresentation.js +45 -43
  59. package/dist/internal/schema/toRepresentation.js.map +1 -1
  60. package/dist/testing/TestSchema.js +2 -2
  61. package/dist/testing/TestSchema.js.map +1 -1
  62. package/dist/unstable/ai/McpSchema.d.ts +128 -128
  63. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  64. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  65. package/dist/unstable/ai/McpServer.js +23 -11
  66. package/dist/unstable/ai/McpServer.js.map +1 -1
  67. package/dist/unstable/ai/Prompt.d.ts +4 -3
  68. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  69. package/dist/unstable/ai/Prompt.js +38 -13
  70. package/dist/unstable/ai/Prompt.js.map +1 -1
  71. package/dist/unstable/cli/Argument.d.ts +6 -3
  72. package/dist/unstable/cli/Argument.d.ts.map +1 -1
  73. package/dist/unstable/cli/Argument.js +2 -1
  74. package/dist/unstable/cli/Argument.js.map +1 -1
  75. package/dist/unstable/cli/CliError.d.ts +20 -1
  76. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  77. package/dist/unstable/cli/CliError.js +26 -2
  78. package/dist/unstable/cli/CliError.js.map +1 -1
  79. package/dist/unstable/cli/Command.d.ts +23 -0
  80. package/dist/unstable/cli/Command.d.ts.map +1 -1
  81. package/dist/unstable/cli/Command.js +23 -4
  82. package/dist/unstable/cli/Command.js.map +1 -1
  83. package/dist/unstable/cluster/Entity.d.ts +2 -2
  84. package/dist/unstable/cluster/Entity.d.ts.map +1 -1
  85. package/dist/unstable/cluster/Entity.js.map +1 -1
  86. package/dist/unstable/cluster/EntityProxy.d.ts +3 -3
  87. package/dist/unstable/cluster/EntityProxy.d.ts.map +1 -1
  88. package/dist/unstable/cluster/EntityProxy.js +4 -3
  89. package/dist/unstable/cluster/EntityProxy.js.map +1 -1
  90. package/dist/unstable/cluster/Sharding.d.ts +2 -2
  91. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  92. package/dist/unstable/cluster/Sharding.js +14 -5
  93. package/dist/unstable/cluster/Sharding.js.map +1 -1
  94. package/dist/unstable/eventlog/EventLogEncryption.d.ts +6 -5
  95. package/dist/unstable/eventlog/EventLogEncryption.d.ts.map +1 -1
  96. package/dist/unstable/eventlog/EventLogEncryption.js +14 -12
  97. package/dist/unstable/eventlog/EventLogEncryption.js.map +1 -1
  98. package/dist/unstable/eventlog/EventLogMessage.d.ts +3 -3
  99. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  100. package/dist/unstable/eventlog/EventLogMessage.js +2 -3
  101. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  102. package/dist/unstable/eventlog/EventLogRemote.js +4 -4
  103. package/dist/unstable/eventlog/EventLogRemote.js.map +1 -1
  104. package/dist/unstable/eventlog/EventLogServerEncrypted.js +3 -2
  105. package/dist/unstable/eventlog/EventLogServerEncrypted.js.map +1 -1
  106. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  107. package/dist/unstable/http/HttpServerRequest.js +7 -1
  108. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  109. package/dist/unstable/http/Multipart.d.ts +2 -0
  110. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  111. package/dist/unstable/http/Multipart.js +4 -12
  112. package/dist/unstable/http/Multipart.js.map +1 -1
  113. package/dist/unstable/http/MultipartParser/internal/headers.d.ts.map +1 -1
  114. package/dist/unstable/http/MultipartParser/internal/headers.js +16 -2
  115. package/dist/unstable/http/MultipartParser/internal/headers.js.map +1 -1
  116. package/dist/unstable/http/MultipartParser/internal/multipart.d.ts.map +1 -1
  117. package/dist/unstable/http/MultipartParser/internal/multipart.js +23 -8
  118. package/dist/unstable/http/MultipartParser/internal/multipart.js.map +1 -1
  119. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  120. package/dist/unstable/httpapi/OpenApi.js +1 -1
  121. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  122. package/dist/unstable/process/ChildProcess.d.ts +8 -0
  123. package/dist/unstable/process/ChildProcess.d.ts.map +1 -1
  124. package/dist/unstable/process/ChildProcess.js.map +1 -1
  125. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  126. package/dist/unstable/rpc/RpcClient.js +5 -0
  127. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  128. package/dist/unstable/sql/Migrator.d.ts +9 -1
  129. package/dist/unstable/sql/Migrator.d.ts.map +1 -1
  130. package/dist/unstable/sql/Migrator.js +15 -2
  131. package/dist/unstable/sql/Migrator.js.map +1 -1
  132. package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
  133. package/dist/unstable/sql/SqlResolver.js +20 -16
  134. package/dist/unstable/sql/SqlResolver.js.map +1 -1
  135. package/dist/unstable/workers/Worker.d.ts.map +1 -1
  136. package/dist/unstable/workers/Worker.js +11 -12
  137. package/dist/unstable/workers/Worker.js.map +1 -1
  138. package/package.json +1 -1
  139. package/src/Channel.ts +58 -0
  140. package/src/Config.ts +3 -3
  141. package/src/ConfigProvider.ts +43 -8
  142. package/src/Duration.ts +12 -1
  143. package/src/Fiber.ts +1 -1
  144. package/src/Function.ts +37 -0
  145. package/src/JsonSchema.ts +43 -42
  146. package/src/Schema.ts +68 -146
  147. package/src/SchemaAST.ts +50 -30
  148. package/src/SchemaRepresentation.ts +44 -7
  149. package/src/ScopedRef.ts +3 -1
  150. package/src/Stream.ts +12 -30
  151. package/src/TxQueue.ts +1 -1
  152. package/src/internal/effect.ts +3 -6
  153. package/src/internal/executionPlan.ts +3 -2
  154. package/src/internal/rcRef.ts +24 -16
  155. package/src/internal/schema/fromJsonSchemaDocument.ts +36 -18
  156. package/src/internal/schema/toArbitrary.ts +0 -72
  157. package/src/internal/schema/toJsonSchemaDocument.ts +24 -4
  158. package/src/internal/schema/toRepresentation.ts +66 -48
  159. package/src/testing/TestSchema.ts +2 -2
  160. package/src/unstable/ai/McpServer.ts +23 -11
  161. package/src/unstable/ai/Prompt.ts +37 -15
  162. package/src/unstable/cli/Argument.ts +6 -3
  163. package/src/unstable/cli/CliError.ts +28 -2
  164. package/src/unstable/cli/Command.ts +44 -4
  165. package/src/unstable/cluster/Entity.ts +7 -2
  166. package/src/unstable/cluster/EntityProxy.ts +12 -5
  167. package/src/unstable/cluster/Sharding.ts +29 -17
  168. package/src/unstable/eventlog/EventLogEncryption.ts +15 -16
  169. package/src/unstable/eventlog/EventLogMessage.ts +2 -3
  170. package/src/unstable/eventlog/EventLogRemote.ts +4 -4
  171. package/src/unstable/eventlog/EventLogServerEncrypted.ts +2 -2
  172. package/src/unstable/http/HttpServerRequest.ts +8 -3
  173. package/src/unstable/http/Multipart.ts +4 -13
  174. package/src/unstable/http/MultipartParser/internal/headers.ts +16 -387
  175. package/src/unstable/http/MultipartParser/internal/multipart.ts +25 -8
  176. package/src/unstable/httpapi/OpenApi.ts +4 -1
  177. package/src/unstable/process/ChildProcess.ts +8 -0
  178. package/src/unstable/rpc/RpcClient.ts +5 -0
  179. package/src/unstable/sql/Migrator.ts +22 -9
  180. package/src/unstable/sql/SqlResolver.ts +28 -20
  181. package/src/unstable/workers/Worker.ts +13 -14
package/src/Schema.ts CHANGED
@@ -63,7 +63,7 @@ import type * as SchemaRepresentation from "./SchemaRepresentation.ts"
63
63
  import * as SchemaTransformation from "./SchemaTransformation.ts"
64
64
  import type { Assign, Lambda, Mutable, Simplify } from "./Struct.ts"
65
65
  import * as Struct_ from "./Struct.ts"
66
- import * as FastCheck from "./testing/FastCheck.ts"
66
+ import type * as FastCheck from "./testing/FastCheck.ts"
67
67
  import type { RequiredKeys, UnionToIntersection } from "./Types.ts"
68
68
  import type { Unify } from "./Unify.ts"
69
69
 
@@ -2476,7 +2476,10 @@ interface optionalLambda extends Lambda {
2476
2476
  * @category combinators
2477
2477
  * @since 3.10.0
2478
2478
  */
2479
- export const optional = Struct_.lambda<optionalLambda>((self) => optionalKey(UndefinedOr(self)))
2479
+ export const optional = Struct_.lambda<optionalLambda>((self) => {
2480
+ const schema = UndefinedOr(self)
2481
+ return make(SchemaAST.optional(self.ast), { schema })
2482
+ })
2480
2483
 
2481
2484
  interface requiredLambda extends Lambda {
2482
2485
  <S extends Constraint>(self: optional<S>): S
@@ -5617,7 +5620,7 @@ export function decodeTo<To extends Constraint, From extends Constraint, RD = ne
5617
5620
  * ```
5618
5621
  *
5619
5622
  * @category transforming
5620
- * @since 3.10.0
5623
+ * @since 4.0.0
5621
5624
  */
5622
5625
  export function decode<S extends Constraint, RD = never, RE = never>(transformation: {
5623
5626
  readonly decode: SchemaGetter.Getter<S["Type"], S["Type"], RD>
@@ -5706,7 +5709,7 @@ export function encodeTo<To extends Constraint, From extends Constraint, RD = ne
5706
5709
  * ```
5707
5710
  *
5708
5711
  * @category transforming
5709
- * @since 3.10.0
5712
+ * @since 4.0.0
5710
5713
  */
5711
5714
  export function encode<S extends Constraint, RD = never, RE = never>(transformation: {
5712
5715
  readonly decode: SchemaGetter.Getter<S["Encoded"], S["Encoded"], RD>
@@ -14957,44 +14960,32 @@ export const TaggedError: {
14957
14960
  // -----------------------------------------------------------------------------
14958
14961
 
14959
14962
  /**
14960
- * A thunk that, given the `fast-check` module, returns an `Arbitrary<T>`.
14961
- * Use this type when you need to defer instantiation of the arbitrary, for
14962
- * example to support recursive schemas.
14963
+ * Represents a function that builds a fast-check `Arbitrary<T>` from the
14964
+ * `fast-check` module.
14965
+ *
14966
+ * **When to use**
14967
+ *
14968
+ * Use as the result type of schema arbitrary derivation.
14963
14969
  *
14964
14970
  * @category utility types
14965
14971
  * @since 4.0.0
14966
14972
  */
14967
- export type LazyArbitrary<T> = (fc: typeof FastCheck) => FastCheck.Arbitrary<T>
14973
+ export type Arbitrary<T> = (fc: typeof FastCheck) => FastCheck.Arbitrary<T>
14968
14974
 
14969
14975
  /**
14970
- * Derives a {@link LazyArbitrary} from a schema. The result is memoized so
14971
- * repeated calls with the same schema are cheap.
14972
- *
14973
- * **Details**
14976
+ * Returns an {@link Arbitrary} factory derived from a schema. The generated
14977
+ * values satisfy the schema and use its decoded `Type`.
14974
14978
  *
14975
- * Prefer {@link toArbitrary} when you need the arbitrary directly, or when you
14976
- * want derivation diagnostics via `{ report: true }`. Unsupported schema
14977
- * nodes, impossible constraints, invalid candidates, and recursive schemas
14978
- * without a finite terminal path fail immediately.
14979
+ * **When to use**
14979
14980
  *
14980
- * @category generators
14981
- * @since 4.0.0
14982
- */
14983
- export function toArbitraryLazy<S extends Constraint>(schema: S): LazyArbitrary<S["Type"]> {
14984
- const lawc = InternalArbitrary.memoized(schema.ast)
14985
- return (fc) => lawc(fc, {})
14986
- }
14987
-
14988
- /**
14989
- * Derives a `fast-check` `Arbitrary` from a schema for property-based
14990
- * testing. The derived arbitrary generates values that satisfy the schema.
14981
+ * Use when you need a fast-check generator for values accepted by a schema.
14991
14982
  *
14992
14983
  * **Details**
14993
14984
  *
14994
14985
  * Constraints refine base generators; candidates add weighted sources while
14995
- * filters still validate every value. `{ report: true }` returns warnings such
14996
- * as `OpaqueFilter`, while derivation errors remain fail-fast. Recursive
14997
- * schemas use terminal branches and fail when no finite terminal path exists.
14986
+ * filters still validate every value. Recursive schemas use terminal branches
14987
+ * and fail when no finite terminal path exists. The result is memoized so
14988
+ * repeated calls with the same schema are cheap.
14998
14989
  *
14999
14990
  * **Example** (Generating arbitrary values)
15000
14991
  *
@@ -15002,36 +14993,20 @@ export function toArbitraryLazy<S extends Constraint>(schema: S): LazyArbitrary<
15002
14993
  * import { Schema } from "effect"
15003
14994
  * import * as FastCheck from "fast-check"
15004
14995
  *
15005
- * const PersonArb = Schema.toArbitrary(
14996
+ * const makePersonArbitrary = Schema.toArbitrary(
15006
14997
  * Schema.Struct({ name: Schema.String, age: Schema.Number })
15007
14998
  * )
15008
14999
  *
15009
- * // Sample a random value
15010
- * FastCheck.sample(PersonArb, 1)
15000
+ * const PersonArbitrary = makePersonArbitrary(FastCheck)
15001
+ * FastCheck.sample(PersonArbitrary, 1)
15011
15002
  * ```
15012
15003
  *
15013
15004
  * @category generators
15014
15005
  * @since 4.0.0
15015
15006
  */
15016
- export function toArbitrary<S extends Constraint>(schema: S): FastCheck.Arbitrary<S["Type"]>
15017
- export function toArbitrary<S extends Constraint>(
15018
- schema: S,
15019
- options: { readonly report: true }
15020
- ): Annotations.ToArbitrary.WithReport<FastCheck.Arbitrary<S["Type"]>>
15021
- export function toArbitrary<S extends Constraint>(
15022
- schema: S,
15023
- options?: { readonly report?: boolean }
15024
- ): FastCheck.Arbitrary<S["Type"]> | Annotations.ToArbitrary.WithReport<FastCheck.Arbitrary<S["Type"]>> {
15025
- if (options?.report === true) {
15026
- const lawc = InternalArbitrary.memoized(schema.ast)
15027
- const report = InternalArbitrary.makeReport()
15028
- InternalArbitrary.collectReport(schema.ast, report)
15029
- return {
15030
- value: lawc(FastCheck, {}),
15031
- report: InternalArbitrary.toReport(report)
15032
- }
15033
- }
15034
- return toArbitraryLazy(schema)(FastCheck)
15007
+ export function toArbitrary<S extends Constraint>(schema: S): Arbitrary<S["Type"]> {
15008
+ const lawc = InternalArbitrary.memoized(schema.ast)
15009
+ return (fc) => lawc(fc, {})
15035
15010
  }
15036
15011
 
15037
15012
  // -----------------------------------------------------------------------------
@@ -15367,7 +15342,10 @@ export function toJsonSchemaDocument(
15367
15342
  schema: Constraint,
15368
15343
  options?: ToJsonSchemaOptions
15369
15344
  ): JsonSchema.Document<"draft-2020-12"> {
15370
- const document = InternalToRepresentation.toRepresentation(toCodecJsonAST(schema.ast))
15345
+ const document = InternalToRepresentation.toRepresentation(
15346
+ toCodecJsonAST(schema.ast),
15347
+ InternalToJsonSchemaDocument.toRepresentationOptions
15348
+ )
15371
15349
  return InternalToJsonSchemaDocument.toJsonSchemaDocument(document, options)
15372
15350
  }
15373
15351
 
@@ -15422,16 +15400,14 @@ export function toCodecJson<S extends Constraint>(schema: S): toCodecJson<S> {
15422
15400
  return make(toCodecJsonAST(schema.ast), { schema })
15423
15401
  }
15424
15402
 
15425
- const toCodecJsonASTBase = SchemaAST.applyToSelfOrLastLinkEncoding((ast) => {
15426
- const out = toCodecJsonBase(ast, toCodecJsonAST)
15403
+ /** @internal */
15404
+ export const toCodecJsonAST = SchemaAST.applyToSelfOrLastLinkEncodingIdempotent((ast) => {
15405
+ const out = toCodecJsonASTStep(ast, toCodecJsonAST)
15427
15406
  const context = ast.context
15428
15407
  if (out === ast || context === undefined) return out
15429
15408
  return SchemaAST.replaceContextLastLink(out, withoutConstructorDefault(context))
15430
15409
  })
15431
15410
 
15432
- /** @internal */
15433
- export const toCodecJsonAST = memoize(toCodecJsonASTBase)
15434
-
15435
15411
  function withoutConstructorDefault(context: SchemaAST.Context): SchemaAST.Context {
15436
15412
  return context.constructorDefault === undefined ?
15437
15413
  context :
@@ -15482,7 +15458,7 @@ const toCodecJsonReorder = makeReorder((ast: SchemaAST.AST) => {
15482
15458
  }
15483
15459
  })
15484
15460
 
15485
- function toCodecJsonBase(ast: SchemaAST.AST, recur: (ast: SchemaAST.AST) => SchemaAST.AST): SchemaAST.AST {
15461
+ function toCodecJsonASTStep(ast: SchemaAST.AST, recur: (ast: SchemaAST.AST) => SchemaAST.AST): SchemaAST.AST {
15486
15462
  switch (ast._tag) {
15487
15463
  case "Declaration": {
15488
15464
  const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec
@@ -15541,17 +15517,17 @@ function toCodecJsonBase(ast: SchemaAST.AST, recur: (ast: SchemaAST.AST) => Sche
15541
15517
  * @since 4.0.0
15542
15518
  */
15543
15519
  export function toCodecIso<S extends Constraint>(schema: S): Codec<S["Type"], S["Iso"]> {
15544
- return make(toCodecIsoTop(SchemaAST.toType(schema.ast)))
15520
+ return make(toCodecIsoAST(SchemaAST.toType(schema.ast)))
15545
15521
  }
15546
15522
 
15547
- const toCodecIsoTop = memoize((ast: SchemaAST.AST): SchemaAST.AST => {
15548
- const out = toCodecIsoBase(ast, toCodecIsoTop)
15523
+ const toCodecIsoAST = memoize((ast: SchemaAST.AST): SchemaAST.AST => {
15524
+ const out = toCodecIsoASTStep(ast, toCodecIsoAST)
15549
15525
  return out !== ast && ast.context !== undefined ?
15550
15526
  SchemaAST.replaceContextLastLink(out, withoutConstructorDefault(ast.context)) :
15551
15527
  out
15552
15528
  })
15553
15529
 
15554
- function toCodecIsoBase(ast: SchemaAST.AST, recur: (ast: SchemaAST.AST) => SchemaAST.AST): SchemaAST.AST {
15530
+ function toCodecIsoASTStep(ast: SchemaAST.AST, recur: (ast: SchemaAST.AST) => SchemaAST.AST): SchemaAST.AST {
15555
15531
  switch (ast._tag) {
15556
15532
  case "Declaration": {
15557
15533
  const getLink = ast.annotations?.toCodecIso ?? ast.annotations?.toCodec
@@ -15621,7 +15597,7 @@ export interface toCodecStringTree<S extends Constraint> extends
15621
15597
  * @since 4.0.0
15622
15598
  */
15623
15599
  export function toCodecStringTree<S extends Constraint>(schema: S): toCodecStringTree<S> {
15624
- return make(serializerStringTree(schema.ast), { schema })
15600
+ return make(toCodecStringTreeAST(schema.ast), { schema })
15625
15601
  }
15626
15602
 
15627
15603
  /**
@@ -15670,7 +15646,7 @@ export interface toCodecArrayFromSingle<S extends Constraint> extends
15670
15646
  * @since 4.0.0
15671
15647
  */
15672
15648
  export function toCodecArrayFromSingle<S extends Constraint>(schema: S): toCodecArrayFromSingle<S> {
15673
- return make(toCodecArrayFromSingleTop(schema.ast))
15649
+ return make(toCodecArrayFromSingleAST(schema.ast))
15674
15650
  }
15675
15651
 
15676
15652
  type XmlEncoderOptions = {
@@ -15807,7 +15783,7 @@ const toStringTreeReorder = makeReorder((ast: SchemaAST.AST) => {
15807
15783
  }
15808
15784
  })
15809
15785
 
15810
- function serializerTree(
15786
+ function toCodecStringTreeASTStep(
15811
15787
  ast: SchemaAST.AST,
15812
15788
  recur: (ast: SchemaAST.AST) => SchemaAST.AST,
15813
15789
  onMissingAnnotation: (ast: SchemaAST.AST) => SchemaAST.AST
@@ -15886,37 +15862,29 @@ const booleanToString = new SchemaAST.Link(
15886
15862
  )
15887
15863
  )
15888
15864
 
15889
- const SERIALIZER_ENSURE_ARRAY = "~effect/Schema/SERIALIZER_ENSURE_ARRAY"
15865
+ const arrayFromSingleTransformation = new SchemaTransformation.Transformation(
15866
+ SchemaGetter.transform((input: ReadonlyArray<unknown> | string) => typeof input === "string" ? [input] : input),
15867
+ SchemaGetter.passthrough()
15868
+ )
15890
15869
 
15891
- const isSerializerArrayFromSingle = (ast: SchemaAST.AST): boolean =>
15892
- SchemaAST.isUnion(ast) && ast.annotations?.[SERIALIZER_ENSURE_ARRAY] === true
15870
+ const isCodecArrayFromSingleLink = (link: SchemaAST.Link): boolean =>
15871
+ link.transformation === arrayFromSingleTransformation
15893
15872
 
15894
- const serializerStringTree = SchemaAST.applyToSelfOrLastLinkEncoding((ast) => {
15895
- if (isSerializerArrayFromSingle(ast)) {
15896
- return ast
15897
- }
15898
- const out = serializerTree(ast, serializerStringTree, (ast) => {
15873
+ const toCodecStringTreeAST = SchemaAST.applyToSelfOrLastLinkEncodingIdempotent((ast) => {
15874
+ const out = toCodecStringTreeASTStep(ast, toCodecStringTreeAST, (ast) => {
15899
15875
  throw new globalThis.Error("Missing structural codec for StringTree", { cause: ast })
15900
15876
  })
15901
15877
  if (out !== ast && ast.context !== undefined) {
15902
15878
  return SchemaAST.replaceContextLastLink(out, withoutConstructorDefault(ast.context))
15903
15879
  }
15904
15880
  return out
15905
- })
15881
+ }, { stopAt: isCodecArrayFromSingleLink })
15906
15882
 
15907
15883
  const toArrayFromSingleInputElement = (ast: SchemaAST.AST): SchemaAST.AST =>
15908
15884
  SchemaAST.isOptional(ast) ? SchemaAST.optionalKey(SchemaAST.unknown) : SchemaAST.unknown
15909
15885
 
15910
- const arrayFromSingleTransformation = new SchemaTransformation.Transformation(
15911
- SchemaGetter.transform((input: ReadonlyArray<unknown> | string) => typeof input === "string" ? [input] : input),
15912
- SchemaGetter.passthrough()
15913
- )
15914
-
15915
- const toCodecArrayFromSingleTop = SchemaAST.applyToSelfOrLastLinkEncoding((ast) => {
15916
- if (isSerializerArrayFromSingle(ast)) {
15917
- return ast
15918
- }
15919
- const out = onSerializerArrayFromSingle(ast)
15886
+ const toCodecArrayFromSingleAST = SchemaAST.applyToSelfOrLastLinkEncodingIdempotent((ast) => {
15887
+ const out = toCodecArrayFromSingleASTStep(ast)
15920
15888
  if (SchemaAST.isArrays(out)) {
15921
15889
  const ensure = SchemaAST.decodeTo(
15922
15890
  new SchemaAST.Union(
@@ -15928,8 +15896,7 @@ const toCodecArrayFromSingleTop = SchemaAST.applyToSelfOrLastLinkEncoding((ast)
15928
15896
  ),
15929
15897
  SchemaAST.string
15930
15898
  ],
15931
- "anyOf",
15932
- { [SERIALIZER_ENSURE_ARRAY]: true }
15899
+ "anyOf"
15933
15900
  ),
15934
15901
  out,
15935
15902
  arrayFromSingleTransformation
@@ -15937,12 +15904,12 @@ const toCodecArrayFromSingleTop = SchemaAST.applyToSelfOrLastLinkEncoding((ast)
15937
15904
  return SchemaAST.isOptional(ast) ? SchemaAST.optionalKey(ensure) : ensure
15938
15905
  }
15939
15906
  return out
15940
- })
15907
+ }, { stopAt: isCodecArrayFromSingleLink })
15941
15908
 
15942
- function onSerializerArrayFromSingle(ast: SchemaAST.AST): SchemaAST.AST {
15909
+ function toCodecArrayFromSingleASTStep(ast: SchemaAST.AST): SchemaAST.AST {
15943
15910
  return ast._tag === "Declaration" || ast._tag === "Arrays" || ast._tag === "Objects" || ast._tag === "Union" ||
15944
15911
  ast._tag === "Suspend"
15945
- ? ast.recur(toCodecArrayFromSingleTop)
15912
+ ? ast.recur(toCodecArrayFromSingleAST)
15946
15913
  : ast
15947
15914
  }
15948
15915
 
@@ -16768,6 +16735,15 @@ export declare namespace Annotations {
16768
16735
  readonly representation?:
16769
16736
  | SchemaRepresentation.CheckRepresentationAnnotation<SchemaAST.AST>
16770
16737
  | undefined
16738
+ /**
16739
+ * Compiles this filter to a JSON Schema fragment.
16740
+ *
16741
+ * **Gotchas**
16742
+ *
16743
+ * Treat the input schemas as immutable. The returned value must be a valid JSON Schema object graph and must not be
16744
+ * mutated after this function returns. Return a new object graph to produce different output during a later
16745
+ * compilation.
16746
+ */
16771
16747
  readonly toJsonSchema?: SchemaRepresentation.ToJsonSchema.Check | undefined
16772
16748
  readonly toCode?: SchemaRepresentation.Generation.Check | undefined
16773
16749
  /**
@@ -16818,8 +16794,7 @@ export declare namespace Annotations {
16818
16794
 
16819
16795
  /**
16820
16796
  * Types used by arbitrary-derivation annotations to configure `toArbitrary`
16821
- * hooks, filter hints, candidate sources, diagnostics, and merged generation
16822
- * constraints.
16797
+ * hooks, filter hints, candidate sources, and merged generation constraints.
16823
16798
  *
16824
16799
  * @since 4.0.0
16825
16800
  */
@@ -16832,8 +16807,7 @@ export declare namespace Annotations {
16832
16807
  * `constraint` refines the schema node's base generator. `candidate` adds a
16833
16808
  * weighted source before all filters run. If neither hint is provided, the
16834
16809
  * filter does not guide generation; generated values are still checked by
16835
- * the filter predicate. With `{ report: true }`, this is reported as
16836
- * `OpaqueFilter`.
16810
+ * the filter predicate.
16837
16811
  *
16838
16812
  * @category models
16839
16813
  * @since 4.0.0
@@ -17021,58 +16995,6 @@ export declare namespace Annotations {
17021
16995
  typeParameters: { readonly [K in keyof TypeParameters]: TypeParameter<TypeParameters[K]["Type"]> }
17022
16996
  ): (fc: typeof FastCheck, context: Context) => Output<T>
17023
16997
  }
17024
-
17025
- /**
17026
- * Wraps a derived value together with arbitrary-derivation diagnostics.
17027
- *
17028
- * @category models
17029
- * @since 4.0.0
17030
- */
17031
- export interface WithReport<A> {
17032
- readonly value: A
17033
- readonly report: Report
17034
- }
17035
-
17036
- /**
17037
- * Diagnostics collected while deriving an arbitrary.
17038
- *
17039
- * **Details**
17040
- *
17041
- * Reports contain warnings only. Unsupported schema nodes, impossible
17042
- * constraints, invalid candidate weights, and throwing candidate factories
17043
- * fail immediately.
17044
- *
17045
- * @category models
17046
- * @since 4.0.0
17047
- */
17048
- export interface Report {
17049
- readonly warnings: ReadonlyArray<Warning>
17050
- }
17051
-
17052
- /**
17053
- * Non-fatal arbitrary-derivation warning.
17054
- *
17055
- * @category models
17056
- * @since 4.0.0
17057
- */
17058
- export type Warning = OpaqueFilterWarning
17059
-
17060
- /**
17061
- * Warning emitted when a filter is handled only by the final `.filter`.
17062
- *
17063
- * **Details**
17064
- *
17065
- * The filter is still enforced. The warning means it did not contribute
17066
- * a constraint or candidate, so generation may rely on fast-check discards.
17067
- *
17068
- * @category models
17069
- * @since 4.0.0
17070
- */
17071
- export interface OpaqueFilterWarning {
17072
- readonly _tag: "OpaqueFilter"
17073
- readonly path: ReadonlyArray<PropertyKey>
17074
- readonly description?: string | undefined
17075
- }
17076
16998
  }
17077
16999
 
17078
17000
  /**
package/src/SchemaAST.ts CHANGED
@@ -16,7 +16,7 @@ import * as Cause from "./Cause.ts"
16
16
  import * as Effect from "./Effect.ts"
17
17
  import * as Exit from "./Exit.ts"
18
18
  import { format, formatPropertyKey } from "./Formatter.ts"
19
- import { identity, memoize } from "./Function.ts"
19
+ import { identity, memoize, memoizeIdempotent } from "./Function.ts"
20
20
  import { effectIsExit, iterateEager } from "./internal/effect.ts"
21
21
  import * as InternalRecord from "./internal/record.ts"
22
22
  import * as InternalAnnotations from "./internal/schema/annotations.ts"
@@ -2517,7 +2517,7 @@ export type Sentinel = {
2517
2517
  readonly literal: LiteralValue | symbol
2518
2518
  }
2519
2519
 
2520
- const toCandidate = memoize((ast: AST): AST => {
2520
+ const toCandidate = memoizeIdempotent((ast: AST): AST => {
2521
2521
  while (true) {
2522
2522
  if (isSuspend(ast)) return unknown
2523
2523
  const encoding = ast.encoding
@@ -2581,7 +2581,7 @@ function getCandidateTypes(ast: AST): ReadonlyArray<Type> {
2581
2581
  }
2582
2582
 
2583
2583
  /** @internal */
2584
- export function collectSentinels(ast: AST): Array<Sentinel> {
2584
+ export function collectSentinels(ast: AST): ReadonlyArray<Sentinel> {
2585
2585
  switch (ast._tag) {
2586
2586
  default:
2587
2587
  return []
@@ -3280,6 +3280,13 @@ function modifyOwnPropertyDescriptors<A extends AST>(
3280
3280
  return Object.create(Object.getPrototypeOf(ast), d)
3281
3281
  }
3282
3282
 
3283
+ const contextOwners = new WeakMap<AST, AST>()
3284
+
3285
+ /** @internal */
3286
+ export function getContextOwner(ast: AST): AST {
3287
+ return contextOwners.get(ast) ?? ast
3288
+ }
3289
+
3283
3290
  /** @internal */
3284
3291
  export function replaceEncoding<A extends AST>(ast: A, encoding: Encoding | undefined): A {
3285
3292
  if (ast.encoding === encoding) {
@@ -3295,9 +3302,15 @@ export function replaceContext<A extends AST>(ast: A, context: Context | undefin
3295
3302
  if (ast.context === context) {
3296
3303
  return ast
3297
3304
  }
3298
- return modifyOwnPropertyDescriptors(ast, (d) => {
3305
+ const owner = getContextOwner(ast)
3306
+ if (owner.context === context) {
3307
+ return owner as A
3308
+ }
3309
+ const out = modifyOwnPropertyDescriptors(ast, (d) => {
3299
3310
  d.context.value = context
3300
3311
  })
3312
+ contextOwners.set(out, owner)
3313
+ return out
3301
3314
  }
3302
3315
 
3303
3316
  /** @internal */
@@ -3365,6 +3378,21 @@ export function applyToSelfOrLastLinkEncoding(f: (ast: AST) => AST) {
3365
3378
  return memoize(out)
3366
3379
  }
3367
3380
 
3381
+ /** @internal */
3382
+ export function applyToSelfOrLastLinkEncodingIdempotent(
3383
+ f: (ast: AST) => AST,
3384
+ options?: { readonly stopAt?: (link: Link) => boolean }
3385
+ ) {
3386
+ function out(ast: AST): AST {
3387
+ if (ast.encoding) {
3388
+ const last = ast.encoding[ast.encoding.length - 1]
3389
+ return options?.stopAt?.(last) ? ast : replaceEncoding(ast, updateLastLink(ast.encoding, out))
3390
+ }
3391
+ return f(ast)
3392
+ }
3393
+ return memoizeIdempotent(out)
3394
+ }
3395
+
3368
3396
  /** @internal */
3369
3397
  export function middlewareDecoding(
3370
3398
  ast: AST,
@@ -3432,42 +3460,34 @@ export function annotateKey<A extends AST>(ast: A, annotations: Schema.Annotatio
3432
3460
  return replaceContext(ast, context)
3433
3461
  }
3434
3462
 
3435
- const optionalKeyLastLink = applyToLastLink(optionalKey)
3436
-
3437
- /**
3438
- * Marks an AST node's property key as optional by setting
3439
- * {@link Context.isOptional} to `true`.
3440
- *
3441
- * **Details**
3442
- *
3443
- * Also propagates the optional flag through the last link of the encoding
3444
- * chain if present.
3445
- *
3446
- * @see {@link isOptional}
3447
- * @see {@link Context}
3448
- * @category transforming
3449
- * @since 4.0.0
3450
- */
3451
- export function optionalKey<A extends AST>(ast: A): A {
3463
+ /** @internal */
3464
+ export const optionalKey: <A extends AST>(ast: A) => A = memoizeIdempotent(<A extends AST>(ast: A): A => {
3452
3465
  const context = ast.context ?
3453
3466
  ast.context.isOptional === false ?
3454
3467
  new Context(true, ast.context.isMutable, ast.context.constructorDefault, ast.context.annotations) :
3455
3468
  ast.context :
3456
3469
  new Context(true, false)
3457
3470
  return optionalKeyLastLink(replaceContext(ast, context))
3458
- }
3471
+ })
3459
3472
 
3460
- const mutableKeyLastLink = applyToLastLink(mutableKey)
3473
+ const optionalKeyLastLink = applyToLastLink(optionalKey)
3474
+
3475
+ /** @internal */
3476
+ export const optional = memoize(<A extends AST>(ast: A): Union<A | Undefined> =>
3477
+ optionalKey(new Union([ast, undefined_], "anyOf"))
3478
+ )
3461
3479
 
3462
3480
  /** @internal */
3463
- export function mutableKey<A extends AST>(ast: A): A {
3481
+ export const mutableKey = memoizeIdempotent(<A extends AST>(ast: A): A => {
3464
3482
  const context = ast.context ?
3465
3483
  ast.context.isMutable === false ?
3466
3484
  new Context(ast.context.isOptional, true, ast.context.constructorDefault, ast.context.annotations) :
3467
3485
  ast.context :
3468
3486
  new Context(false, true)
3469
3487
  return mutableKeyLastLink(replaceContext(ast, context))
3470
- }
3488
+ })
3489
+
3490
+ const mutableKeyLastLink = applyToLastLink(mutableKey)
3471
3491
 
3472
3492
  /** @internal */
3473
3493
  export function withConstructorDefault<A extends AST>(
@@ -3616,7 +3636,7 @@ function extractStructuralChecks(checks: Checks): Checks | undefined {
3616
3636
  * @category transforming
3617
3637
  * @since 4.0.0
3618
3638
  */
3619
- export const toType = memoize(<A extends AST>(ast: A): A => {
3639
+ export const toType = memoizeIdempotent(<A extends AST>(ast: A): A => {
3620
3640
  if (ast.encoding) {
3621
3641
  return toType(replaceEncoding(ast, undefined))
3622
3642
  }
@@ -3663,7 +3683,7 @@ export const toType = memoize(<A extends AST>(ast: A): A => {
3663
3683
  * @category transforming
3664
3684
  * @since 4.0.0
3665
3685
  */
3666
- export const toEncoded = memoize((ast: AST): AST => {
3686
+ export const toEncoded = memoizeIdempotent((ast: AST): AST => {
3667
3687
  return toType(flip(ast))
3668
3688
  })
3669
3689
 
@@ -3807,7 +3827,7 @@ export const enumsToLiterals = memoize((ast: Enum): Union<Literal> => {
3807
3827
  )
3808
3828
  })
3809
3829
 
3810
- const parameterFromPropertyKey = applyToSelfOrLastLinkEncoding((ast) => {
3830
+ const parameterFromPropertyKey = applyToSelfOrLastLinkEncodingIdempotent((ast) => {
3811
3831
  switch (ast._tag) {
3812
3832
  default:
3813
3833
  return ast
@@ -3819,7 +3839,7 @@ const parameterFromPropertyKey = applyToSelfOrLastLinkEncoding((ast) => {
3819
3839
  })
3820
3840
 
3821
3841
  /** @internal */
3822
- export const parameterFromString = applyToSelfOrLastLinkEncoding((ast) => {
3842
+ export const parameterFromString = applyToSelfOrLastLinkEncodingIdempotent((ast) => {
3823
3843
  switch (ast._tag) {
3824
3844
  default:
3825
3845
  return ast
@@ -3831,7 +3851,7 @@ export const parameterFromString = applyToSelfOrLastLinkEncoding((ast) => {
3831
3851
  }
3832
3852
  })
3833
3853
 
3834
- const partFromString = applyToSelfOrLastLinkEncoding((ast) => {
3854
+ const partFromString = applyToSelfOrLastLinkEncodingIdempotent((ast) => {
3835
3855
  switch (ast._tag) {
3836
3856
  default:
3837
3857
  return ast
@@ -55,7 +55,13 @@ export declare namespace ToJsonSchema {
55
55
  }
56
56
 
57
57
  /**
58
- * JSON Schema compiler for a check.
58
+ * Compiles a check to a JSON Schema fragment.
59
+ *
60
+ * **Gotchas**
61
+ *
62
+ * Treat the input schemas as immutable. The returned value must be a valid JSON Schema object graph and must not be
63
+ * mutated after this function returns. Return a new object graph to produce different output during a later
64
+ * compilation.
59
65
  *
60
66
  * @category models
61
67
  * @since 4.0.0
@@ -600,17 +606,37 @@ export const makeFilterGroupReviver: <P>(
600
606
  *
601
607
  * **When to use**
602
608
  *
603
- * Use when each JSON Schema node must be transformed before it is translated.
609
+ * Use when you need to configure pattern handling or transform each JSON Schema node before translation.
610
+ *
611
+ * **Details**
612
+ *
613
+ * `patterns` controls pattern constraints reached during best-effort translation, including `pattern`, the keys of
614
+ * `patternProperties`, and patterns nested in `propertyNames`:
615
+ *
616
+ * - `"error"` rejects the document and is the default.
617
+ * - `"ignore"` skips the constraint.
618
+ * - `"apply"` compiles and enforces the constraint with the runtime's native regular expression engine.
604
619
  *
605
620
  * **Gotchas**
606
621
  *
607
- * `onEnter` must return a JSON Schema object. Its result is used directly, and exceptions raised by the callback pass through unchanged.
622
+ * Use `patterns: "apply"` only for trusted documents because regular expression evaluation may block for an unbounded
623
+ * amount of time. `patterns: "ignore"` weakens validation by accepting values that the source document may reject.
624
+ * Ignoring `patternProperties` also skips its value constraints and `additionalProperties`, because matching keys cannot
625
+ * be determined without evaluating the patterns.
626
+ * `onEnter` must return a JSON Schema object. Its result is used directly, and exceptions raised by the callback pass
627
+ * through unchanged.
608
628
  *
609
629
  * @category models
610
630
  * @since 4.0.0
611
631
  */
612
632
  export interface FromJsonSchemaOptions {
613
633
  readonly onEnter?: ((schema: JsonSchema.JsonSchema) => JsonSchema.JsonSchema) | undefined
634
+ /**
635
+ * Controls how reached JSON Schema regular expression patterns are imported.
636
+ *
637
+ * @default "error"
638
+ */
639
+ readonly patterns?: "error" | "ignore" | "apply" | undefined
614
640
  }
615
641
 
616
642
  /**
@@ -728,7 +754,10 @@ export function toMultiDocument(document: Document): MultiDocument {
728
754
  *
729
755
  * **Gotchas**
730
756
  *
731
- * Opaque declarations are represented by an unconstrained JSON Schema. Check callback results are used directly, and exceptions raised by a callback pass through unchanged.
757
+ * Opaque declarations are represented by an unconstrained JSON Schema. Check callback results are used directly, and
758
+ * exceptions raised by a callback pass through unchanged. Callbacks must treat their input schemas as immutable. Each
759
+ * returned value must be a valid JSON Schema object graph and must not be mutated after the callback returns. Local
760
+ * definition references returned by callbacks are resolved together with compiler-generated references.
732
761
  *
733
762
  * @see {@link toJsonSchemaMultiDocument} for multiple roots sharing definitions
734
763
  *
@@ -751,7 +780,10 @@ export function toJsonSchemaDocument(
751
780
  *
752
781
  * **Gotchas**
753
782
  *
754
- * Every definition is compiled, including definitions that are not reachable from a root.
783
+ * Every definition is compiled, including definitions that are not reachable from a root. Check callbacks must treat
784
+ * their input schemas as immutable. Each returned value must be a valid JSON Schema object graph and must not be
785
+ * mutated after the callback returns. Local definition references returned by callbacks are resolved together with
786
+ * compiler-generated references.
755
787
  *
756
788
  * @see {@link toJsonSchemaDocument} for a single root
757
789
  *
@@ -1148,7 +1180,10 @@ export function fromRepresentations(
1148
1180
  *
1149
1181
  * **Gotchas**
1150
1182
  *
1151
- * Import is best-effort. Built-in declarations and checks are reconstructed with importer-owned revivers. Callback results are used directly, and exceptions raised by a callback pass through unchanged.
1183
+ * Import is best-effort. Built-in declarations and checks are reconstructed with importer-owned revivers. Pattern
1184
+ * constraints reached during translation cause an error by default. Use `patterns: "apply"` only for trusted documents,
1185
+ * or `patterns: "ignore"` to weaken validation explicitly. Callback results are used directly, and exceptions raised by a
1186
+ * callback pass through unchanged.
1152
1187
  *
1153
1188
  * @see {@link fromJsonSchemaMultiDocument} for multiple roots sharing definitions
1154
1189
  * @see {@link toRepresentation} for converting the result to a representation document
@@ -1172,7 +1207,9 @@ export function fromJsonSchemaDocument(
1172
1207
  *
1173
1208
  * **Gotchas**
1174
1209
  *
1175
- * Only definitions reachable from a root are translated. Callback results are used directly, and exceptions raised by a callback pass through unchanged.
1210
+ * Only definitions reachable from a root are translated. Pattern constraints reached during translation cause an error
1211
+ * by default. Use `patterns: "apply"` only for trusted documents, or `patterns: "ignore"` to weaken validation explicitly.
1212
+ * Callback results are used directly, and exceptions raised by a callback pass through unchanged.
1176
1213
  *
1177
1214
  * @see {@link fromJsonSchemaDocument} for a single root
1178
1215
  * @see {@link toRepresentations} for converting the returned schema ASTs to a representation document