effect 4.0.0-beta.104 → 4.0.0-beta.105

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 (191) hide show
  1. package/AGENTS.md +381 -0
  2. package/CLAUDE.md +381 -0
  3. package/ai-docs/README.md +44 -0
  4. package/ai-docs/package.json +36 -0
  5. package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
  6. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
  7. package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
  8. package/ai-docs/src/01_effect/01_basics/index.md +5 -0
  9. package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
  10. package/ai-docs/src/01_effect/02_schema/index.md +7 -0
  11. package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
  12. package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
  13. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
  14. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
  15. package/ai-docs/src/01_effect/03_services/index.md +5 -0
  16. package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
  17. package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
  18. package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
  19. package/ai-docs/src/01_effect/04_errors/index.md +1 -0
  20. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
  21. package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
  22. package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
  23. package/ai-docs/src/01_effect/05_resources/index.md +3 -0
  24. package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
  25. package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
  26. package/ai-docs/src/01_effect/06_running/index.md +1 -0
  27. package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
  28. package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
  29. package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
  30. package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
  31. package/ai-docs/src/03_stream/30_encoding.ts +165 -0
  32. package/ai-docs/src/03_stream/index.md +4 -0
  33. package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
  34. package/ai-docs/src/04_integration/index.md +5 -0
  35. package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
  36. package/ai-docs/src/05_batching/index.md +3 -0
  37. package/ai-docs/src/06_schedule/10_schedules.ts +110 -0
  38. package/ai-docs/src/06_schedule/index.md +3 -0
  39. package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
  40. package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
  41. package/ai-docs/src/07_datetime/index.md +5 -0
  42. package/ai-docs/src/08_observability/10_logging.ts +66 -0
  43. package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
  44. package/ai-docs/src/08_observability/index.md +7 -0
  45. package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
  46. package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
  47. package/ai-docs/src/09_testing/index.md +1 -0
  48. package/ai-docs/src/10_predicate/01_basics.ts +14 -0
  49. package/ai-docs/src/10_predicate/index.md +9 -0
  50. package/ai-docs/src/50_http-client/10_basics.ts +102 -0
  51. package/ai-docs/src/50_http-client/index.md +3 -0
  52. package/ai-docs/src/51_http-server/10_basics.ts +116 -0
  53. package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
  54. package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
  55. package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
  56. package/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
  57. package/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
  58. package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
  59. package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
  60. package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
  61. package/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
  62. package/ai-docs/src/51_http-server/index.md +3 -0
  63. package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
  64. package/ai-docs/src/60_child-process/index.md +3 -0
  65. package/ai-docs/src/70_cli/10_basics.ts +136 -0
  66. package/ai-docs/src/70_cli/index.md +5 -0
  67. package/ai-docs/src/71_ai/10_language-model.ts +156 -0
  68. package/ai-docs/src/71_ai/20_tools.ts +226 -0
  69. package/ai-docs/src/71_ai/30_chat.ts +158 -0
  70. package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
  71. package/ai-docs/src/71_ai/index.md +5 -0
  72. package/ai-docs/src/80_cluster/10_entities.ts +97 -0
  73. package/ai-docs/src/80_cluster/index.md +4 -0
  74. package/ai-docs/src/index.md +10 -0
  75. package/ai-docs/tsconfig.json +24 -0
  76. package/dist/Brand.d.ts +3 -3
  77. package/dist/Brand.d.ts.map +1 -1
  78. package/dist/Brand.js +4 -3
  79. package/dist/Brand.js.map +1 -1
  80. package/dist/Config.d.ts.map +1 -1
  81. package/dist/Config.js +2 -1
  82. package/dist/Config.js.map +1 -1
  83. package/dist/Context.d.ts +0 -1
  84. package/dist/Context.d.ts.map +1 -1
  85. package/dist/Context.js +1 -22
  86. package/dist/Context.js.map +1 -1
  87. package/dist/Cron.d.ts +31 -0
  88. package/dist/Cron.d.ts.map +1 -1
  89. package/dist/Cron.js +58 -2
  90. package/dist/Cron.js.map +1 -1
  91. package/dist/Optic.d.ts +35 -21
  92. package/dist/Optic.d.ts.map +1 -1
  93. package/dist/Optic.js +33 -34
  94. package/dist/Optic.js.map +1 -1
  95. package/dist/Schema.d.ts +73 -25
  96. package/dist/Schema.d.ts.map +1 -1
  97. package/dist/Schema.js +83 -50
  98. package/dist/Schema.js.map +1 -1
  99. package/dist/SchemaAST.d.ts +30 -0
  100. package/dist/SchemaAST.d.ts.map +1 -1
  101. package/dist/SchemaAST.js +40 -32
  102. package/dist/SchemaAST.js.map +1 -1
  103. package/dist/SchemaError.d.ts +8 -8
  104. package/dist/SchemaError.d.ts.map +1 -1
  105. package/dist/SchemaError.js +7 -6
  106. package/dist/SchemaError.js.map +1 -1
  107. package/dist/SchemaGetter.d.ts +8 -5
  108. package/dist/SchemaGetter.d.ts.map +1 -1
  109. package/dist/SchemaGetter.js +41 -37
  110. package/dist/SchemaGetter.js.map +1 -1
  111. package/dist/SchemaIssue.d.ts +195 -38
  112. package/dist/SchemaIssue.d.ts.map +1 -1
  113. package/dist/SchemaIssue.js +243 -68
  114. package/dist/SchemaIssue.js.map +1 -1
  115. package/dist/SchemaParser.d.ts +30 -0
  116. package/dist/SchemaParser.d.ts.map +1 -1
  117. package/dist/SchemaParser.js +39 -9
  118. package/dist/SchemaParser.js.map +1 -1
  119. package/dist/SchemaTransformation.d.ts +2 -2
  120. package/dist/SchemaTransformation.d.ts.map +1 -1
  121. package/dist/SchemaTransformation.js +26 -26
  122. package/dist/SchemaTransformation.js.map +1 -1
  123. package/dist/Stdio.d.ts +17 -4
  124. package/dist/Stdio.d.ts.map +1 -1
  125. package/dist/Stdio.js +6 -3
  126. package/dist/Stdio.js.map +1 -1
  127. package/dist/internal/schema/schema.js +1 -9
  128. package/dist/internal/schema/schema.js.map +1 -1
  129. package/dist/testing/TestSchema.d.ts +1 -1
  130. package/dist/testing/TestSchema.d.ts.map +1 -1
  131. package/dist/testing/TestSchema.js +8 -7
  132. package/dist/testing/TestSchema.js.map +1 -1
  133. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  134. package/dist/unstable/ai/Prompt.js +4 -4
  135. package/dist/unstable/ai/Prompt.js.map +1 -1
  136. package/dist/unstable/cluster/Reply.js +4 -4
  137. package/dist/unstable/cluster/Reply.js.map +1 -1
  138. package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
  139. package/dist/unstable/encoding/Msgpack.js +6 -6
  140. package/dist/unstable/encoding/Msgpack.js.map +1 -1
  141. package/dist/unstable/http/HttpClient.d.ts +59 -3
  142. package/dist/unstable/http/HttpClient.d.ts.map +1 -1
  143. package/dist/unstable/http/HttpClient.js +33 -19
  144. package/dist/unstable/http/HttpClient.js.map +1 -1
  145. package/dist/unstable/httpapi/HttpApiBuilder.js +10 -10
  146. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  147. package/dist/unstable/httpapi/HttpApiClient.js +9 -9
  148. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  149. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  150. package/dist/unstable/reactivity/AsyncResult.js +4 -4
  151. package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
  152. package/dist/unstable/reactivity/Atom.d.ts +26 -11
  153. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  154. package/dist/unstable/reactivity/Atom.js +9 -22
  155. package/dist/unstable/reactivity/Atom.js.map +1 -1
  156. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  157. package/dist/unstable/rpc/RpcClient.js +3 -1
  158. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  159. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  160. package/dist/unstable/rpc/RpcServer.js +3 -2
  161. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  162. package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
  163. package/dist/unstable/workflow/Workflow.js +2 -2
  164. package/dist/unstable/workflow/Workflow.js.map +1 -1
  165. package/package.json +5 -2
  166. package/src/Brand.ts +4 -4
  167. package/src/Config.ts +3 -1
  168. package/src/Context.ts +1 -23
  169. package/src/Cron.ts +65 -2
  170. package/src/Optic.ts +59 -58
  171. package/src/Schema.ts +145 -71
  172. package/src/SchemaAST.ts +85 -48
  173. package/src/SchemaError.ts +9 -9
  174. package/src/SchemaGetter.ts +89 -30
  175. package/src/SchemaIssue.ts +285 -80
  176. package/src/SchemaParser.ts +51 -17
  177. package/src/SchemaTransformation.ts +66 -18
  178. package/src/Stdio.ts +23 -4
  179. package/src/internal/schema/schema.ts +1 -17
  180. package/src/testing/TestSchema.ts +8 -8
  181. package/src/unstable/ai/Prompt.ts +14 -4
  182. package/src/unstable/cluster/Reply.ts +4 -4
  183. package/src/unstable/encoding/Msgpack.ts +12 -8
  184. package/src/unstable/http/HttpClient.ts +132 -23
  185. package/src/unstable/httpapi/HttpApiBuilder.ts +32 -13
  186. package/src/unstable/httpapi/HttpApiClient.ts +26 -8
  187. package/src/unstable/reactivity/AsyncResult.ts +11 -6
  188. package/src/unstable/reactivity/Atom.ts +44 -25
  189. package/src/unstable/rpc/RpcClient.ts +4 -1
  190. package/src/unstable/rpc/RpcServer.ts +4 -2
  191. package/src/unstable/workflow/Workflow.ts +2 -5
@@ -94,6 +94,9 @@ export function makeOption<S extends Schema.Constraint>(schema: S) {
94
94
  *
95
95
  * The returned function constructs a value from constructor input and throws an
96
96
  * `Error` with the `SchemaIssue.Issue` in its `cause` when construction fails.
97
+ * Schema validation failures use the generic message `"Schema validation failed"`.
98
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
99
+ * human-readable details are needed.
97
100
  *
98
101
  * **Gotchas**
99
102
  *
@@ -115,7 +118,7 @@ export function make<S extends Schema.Constraint>(schema: S) {
115
118
  exit.cause,
116
119
  "Constructor adapter can only throw schema issues"
117
120
  )
118
- throw new Error(issue.toString(), { cause: issue })
121
+ throw new Error("Schema validation failed", { cause: issue })
119
122
  }
120
123
  }
121
124
 
@@ -184,6 +187,9 @@ export function _issue<T>(ast: SchemaAST.AST) {
184
187
  * The assertion returns normally when validation succeeds. When the input does
185
188
  * not satisfy the schema with a schema-only failure, it throws an `Error` with
186
189
  * the `SchemaIssue.Issue` in its `cause`.
190
+ * Schema validation failures use the generic message `"Schema validation failed"`.
191
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
192
+ * human-readable details are needed.
187
193
  *
188
194
  * **Gotchas**
189
195
  *
@@ -202,7 +208,7 @@ export function asserts<S extends Schema.Constraint, I>(schema: S, input: I): as
202
208
  exit.cause,
203
209
  "Assertion adapter can only throw schema issues"
204
210
  )
205
- throw new Error(issue.toString(), { cause: issue })
211
+ throw new Error("Schema validation failed", { cause: issue })
206
212
  }
207
213
  }
208
214
 
@@ -282,6 +288,9 @@ export const decodeEffect: <S extends Schema.Constraint>(
282
288
  *
283
289
  * The returned function resolves with the decoded `Type` on success and rejects
284
290
  * with an `Error` whose cause is a `SchemaIssue.Issue` on decoding failure.
291
+ * Schema validation failures use the generic message `"Schema validation failed"`.
292
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
293
+ * human-readable details are needed.
285
294
  *
286
295
  * **Gotchas**
287
296
  *
@@ -314,6 +323,9 @@ export function decodeUnknownPromise<S extends Schema.ConstraintDecoder<unknown>
314
323
  *
315
324
  * The returned function resolves with the decoded `Type` on success and rejects
316
325
  * with an `Error` whose cause is a `SchemaIssue.Issue` on decoding failure.
326
+ * Schema validation failures use the generic message `"Schema validation failed"`.
327
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
328
+ * human-readable details are needed.
317
329
  *
318
330
  * **Gotchas**
319
331
  *
@@ -492,6 +504,9 @@ export const decodeResult: <S extends Schema.ConstraintDecoder<unknown>>(
492
504
  *
493
505
  * The returned function returns the decoded `Type` on success and throws an
494
506
  * `Error` with the `SchemaIssue.Issue` in its `cause` on decoding failure.
507
+ * Schema validation failures use the generic message `"Schema validation failed"`.
508
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
509
+ * human-readable details are needed.
495
510
  *
496
511
  * **Gotchas**
497
512
  *
@@ -526,6 +541,9 @@ export function decodeUnknownSync<S extends Schema.ConstraintDecoder<unknown>>(
526
541
  *
527
542
  * The returned function returns the decoded `Type` on success and throws an
528
543
  * `Error` with the `SchemaIssue.Issue` in its `cause` on decoding failure.
544
+ * Schema validation failures use the generic message `"Schema validation failed"`.
545
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
546
+ * human-readable details are needed.
529
547
  *
530
548
  * **Gotchas**
531
549
  *
@@ -620,6 +638,9 @@ export const encodeEffect: <S extends Schema.Constraint>(
620
638
  *
621
639
  * The returned function resolves with the schema's `Encoded` value on success and
622
640
  * rejects with an `Error` whose cause is a `SchemaIssue.Issue` on encoding failure.
641
+ * Schema validation failures use the generic message `"Schema validation failed"`.
642
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
643
+ * human-readable details are needed.
623
644
  *
624
645
  * **Gotchas**
625
646
  *
@@ -651,6 +672,9 @@ export const encodeUnknownPromise = <S extends Schema.ConstraintEncoder<unknown>
651
672
  *
652
673
  * The returned function resolves with the schema's `Encoded` value on success and
653
674
  * rejects with an `Error` whose cause is a `SchemaIssue.Issue` on encoding failure.
675
+ * Schema validation failures use the generic message `"Schema validation failed"`.
676
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
677
+ * human-readable details are needed.
654
678
  *
655
679
  * **Gotchas**
656
680
  *
@@ -826,6 +850,9 @@ export const encodeResult: <S extends Schema.ConstraintEncoder<unknown>>(
826
850
  *
827
851
  * The returned function returns the schema's `Encoded` value on success and throws
828
852
  * an `Error` with the `SchemaIssue.Issue` in its `cause` on encoding failure.
853
+ * Schema validation failures use the generic message `"Schema validation failed"`.
854
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
855
+ * human-readable details are needed.
829
856
  *
830
857
  * **Gotchas**
831
858
  *
@@ -859,6 +886,9 @@ export function encodeUnknownSync<S extends Schema.ConstraintEncoder<unknown>>(
859
886
  *
860
887
  * The returned function returns the schema's `Encoded` value on success and throws
861
888
  * an `Error` with the `SchemaIssue.Issue` in its `cause` on encoding failure.
889
+ * Schema validation failures use the generic message `"Schema validation failed"`.
890
+ * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when
891
+ * human-readable details are needed.
862
892
  *
863
893
  * **Gotchas**
864
894
  *
@@ -927,7 +957,7 @@ function asPromise<T, E>(
927
957
  exit.cause,
928
958
  "Promise adapter can only reject schema issues"
929
959
  )
930
- throw new Error(issue.toString(), { cause: issue })
960
+ throw new Error("Schema validation failed", { cause: issue })
931
961
  })
932
962
  }
933
963
 
@@ -977,7 +1007,7 @@ function asSync<T, E>(
977
1007
  return exit.value
978
1008
  }
979
1009
  const issue = InternalSchemaCause.getSchemaIssueOrThrow(exit.cause, "Sync adapter can only throw schema issues")
980
- throw new Error(issue.toString(), { cause: issue })
1010
+ throw new Error("Schema validation failed", { cause: issue })
981
1011
  }
982
1012
  }
983
1013
 
@@ -1086,9 +1116,7 @@ function makeParser(
1086
1116
  if (input !== InternalParser.missing && output !== InternalParser.missing) {
1087
1117
  const issues = SchemaAST.collectIssues(encodingChecks, input, undefined, ast, options)
1088
1118
  if (issues) {
1089
- result = Effect.fail(
1090
- new SchemaIssue.Composite(ast, issues)
1091
- )
1119
+ result = Effect.fail(new SchemaIssue.Composite(ast, issues, input, options))
1092
1120
  }
1093
1121
  }
1094
1122
  }
@@ -1097,9 +1125,7 @@ function makeParser(
1097
1125
  if (input !== InternalParser.missing && value !== InternalParser.missing) {
1098
1126
  const issues = SchemaAST.collectIssues(encodingChecks, input, undefined, ast, options)
1099
1127
  if (issues) {
1100
- return Effect.fail(
1101
- new SchemaIssue.Composite(ast, issues)
1102
- )
1128
+ return Effect.fail(new SchemaIssue.Composite(ast, issues, input, options))
1103
1129
  }
1104
1130
  }
1105
1131
  return Effect.succeed(value)
@@ -1116,9 +1142,7 @@ function makeParser(
1116
1142
  if (value === InternalParser.missing) return result
1117
1143
  const issues = SchemaAST.collectIssues(checks, value, undefined, ast, options)
1118
1144
  if (issues) {
1119
- result = Effect.fail(
1120
- new SchemaIssue.Composite(ast, issues)
1121
- )
1145
+ result = Effect.fail(new SchemaIssue.Composite(ast, issues, value, options))
1122
1146
  }
1123
1147
  }
1124
1148
  } else {
@@ -1126,9 +1150,7 @@ function makeParser(
1126
1150
  if (value !== InternalParser.missing) {
1127
1151
  const issues = SchemaAST.collectIssues(checks, value, undefined, ast, options)
1128
1152
  if (issues) {
1129
- return Effect.fail(
1130
- new SchemaIssue.Composite(ast, issues)
1131
- )
1153
+ return Effect.fail(new SchemaIssue.Composite(ast, issues, value, options))
1132
1154
  }
1133
1155
  }
1134
1156
  return Effect.succeed(value)
@@ -1175,7 +1197,19 @@ function makeParser(
1175
1197
  }
1176
1198
  result = Effect.catchCause(
1177
1199
  result,
1178
- (cause) => Effect.failCauseSync(() => Cause.map(cause, (issue) => new SchemaIssue.Encoding(ast, issue)))
1200
+ (cause) =>
1201
+ Effect.failCauseSync(() =>
1202
+ Cause.map(
1203
+ cause,
1204
+ (issue) =>
1205
+ new SchemaIssue.Encoding(
1206
+ ast,
1207
+ issue,
1208
+ input,
1209
+ options
1210
+ )
1211
+ )
1212
+ )
1179
1213
  )
1180
1214
  return Effect.flatMapEager(result, (value) => {
1181
1215
  const local = parseLocal(value, options)
@@ -263,10 +263,10 @@ export const make = <T, E, RD = never, RE = never>(options: {
263
263
  * Schema.decodeTo(
264
264
  * Schema.Date,
265
265
  * SchemaTransformation.transformOrFail({
266
- * decode: (s) => {
266
+ * decode: (s, options) => {
267
267
  * const d = new Date(s)
268
268
  * return isNaN(d.getTime())
269
- * ? Effect.fail(new SchemaIssue.InvalidValue({ message: "Invalid date" }))
269
+ * ? Effect.fail(new SchemaIssue.InvalidValue({ message: "Invalid date" }, s, options))
270
270
  * : Effect.succeed(d)
271
271
  * },
272
272
  * encode: (d) => Effect.succeed(d.toISOString())
@@ -974,9 +974,16 @@ export const durationFromString: Transformation<Duration.Duration, string> = tra
974
974
  Duration.Duration,
975
975
  string
976
976
  >({
977
- decode: (s) =>
977
+ decode: (s, options) =>
978
978
  Option.match(Duration.fromInput(s as Duration.Input), {
979
- onNone: () => Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid Duration string" })),
979
+ onNone: () =>
980
+ Effect.fail(
981
+ new SchemaIssue.InvalidValue(
982
+ { expected: "a valid Duration string" },
983
+ s,
984
+ options
985
+ )
986
+ ),
980
987
  onSome: Effect.succeed
981
988
  }),
982
989
  encode: (duration) => Effect.succeed(globalThis.String(duration))
@@ -1015,11 +1022,15 @@ export const durationFromString: Transformation<Duration.Duration, string> = tra
1015
1022
  */
1016
1023
  export const durationFromNanos: Transformation<Duration.Duration, bigint> = transformOrFail({
1017
1024
  decode: (i) => Effect.succeed(Duration.nanos(i)),
1018
- encode: (a) =>
1025
+ encode: (a, options) =>
1019
1026
  Option.match(Duration.toNanos(a), {
1020
1027
  onNone: () =>
1021
1028
  Effect.fail(
1022
- new SchemaIssue.InvalidValue({ message: "Expected a Duration representable as a bigint" })
1029
+ new SchemaIssue.InvalidValue(
1030
+ { expected: "a Duration representable as a bigint" },
1031
+ a,
1032
+ options
1033
+ )
1023
1034
  ),
1024
1035
  onSome: (nanos) => Effect.succeed(nanos)
1025
1036
  })
@@ -1395,10 +1406,16 @@ export function optionFromOptional<T>(): Transformation<Option.Option<T>, T | un
1395
1406
  * @since 4.0.0
1396
1407
  */
1397
1408
  export const urlFromString: Transformation<URL, string> = transformOrFail<URL, string>({
1398
- decode: (s) =>
1409
+ decode: (s, options) =>
1399
1410
  URL.canParse(s)
1400
1411
  ? Effect.succeed(new URL(s))
1401
- : Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid URL string" })),
1412
+ : Effect.fail(
1413
+ new SchemaIssue.InvalidValue(
1414
+ { expected: "a valid URL string" },
1415
+ s,
1416
+ options
1417
+ )
1418
+ ),
1402
1419
  encode: (url) => Effect.succeed(url.href)
1403
1420
  })
1404
1421
 
@@ -1424,10 +1441,16 @@ export const bigDecimalFromString: Transformation<BigDecimal.BigDecimal, string>
1424
1441
  BigDecimal.BigDecimal,
1425
1442
  string
1426
1443
  >({
1427
- decode: (s) => {
1444
+ decode: (s, options) => {
1428
1445
  const result = BigDecimal.fromString(s)
1429
1446
  return Option.isNone(result)
1430
- ? Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid BigDecimal string" }))
1447
+ ? Effect.fail(
1448
+ new SchemaIssue.InvalidValue(
1449
+ { expected: "a valid BigDecimal string" },
1450
+ s,
1451
+ options
1452
+ )
1453
+ )
1431
1454
  : Effect.succeed(result.value)
1432
1455
  },
1433
1456
  encode: (bd) => Effect.succeed(BigDecimal.format(bd))
@@ -1784,9 +1807,16 @@ export const timeZoneNamedFromString: Transformation<DateTime.TimeZone.Named, st
1784
1807
  DateTime.TimeZone.Named,
1785
1808
  string
1786
1809
  >({
1787
- decode: (s) => {
1810
+ decode: (s, options) => {
1788
1811
  return Option.match(DateTime.zoneMakeNamed(s), {
1789
- onNone: () => Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid IANA time zone" })),
1812
+ onNone: () =>
1813
+ Effect.fail(
1814
+ new SchemaIssue.InvalidValue(
1815
+ { expected: "a valid IANA time zone" },
1816
+ s,
1817
+ options
1818
+ )
1819
+ ),
1790
1820
  onSome: Effect.succeed
1791
1821
  })
1792
1822
  },
@@ -1818,9 +1848,16 @@ export const timeZoneFromString: Transformation<DateTime.TimeZone, string> = tra
1818
1848
  DateTime.TimeZone,
1819
1849
  string
1820
1850
  >({
1821
- decode: (s) => {
1851
+ decode: (s, options) => {
1822
1852
  return Option.match(DateTime.zoneFromString(s), {
1823
- onNone: () => Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid time zone" })),
1853
+ onNone: () =>
1854
+ Effect.fail(
1855
+ new SchemaIssue.InvalidValue(
1856
+ { expected: "a valid time zone" },
1857
+ s,
1858
+ options
1859
+ )
1860
+ ),
1824
1861
  onSome: Effect.succeed
1825
1862
  })
1826
1863
  },
@@ -1852,9 +1889,16 @@ export const dateTimeUtcFromString: Transformation<DateTime.Utc, string> = trans
1852
1889
  DateTime.Utc,
1853
1890
  string
1854
1891
  >({
1855
- decode: (s) => {
1892
+ decode: (s, options) => {
1856
1893
  return Option.match(DateTime.make(s), {
1857
- onNone: () => Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a valid UTC DateTime string" })),
1894
+ onNone: () =>
1895
+ Effect.fail(
1896
+ new SchemaIssue.InvalidValue(
1897
+ { expected: "a valid UTC DateTime string" },
1898
+ s,
1899
+ options
1900
+ )
1901
+ ),
1858
1902
  onSome: (result) => Effect.succeed(DateTime.toUtc(result))
1859
1903
  })
1860
1904
  },
@@ -1885,11 +1929,15 @@ export const dateTimeZonedFromString: Transformation<DateTime.Zoned, string> = t
1885
1929
  DateTime.Zoned,
1886
1930
  string
1887
1931
  >({
1888
- decode: (s) => {
1932
+ decode: (s, options) => {
1889
1933
  return Option.match(DateTime.makeZonedFromString(s), {
1890
1934
  onNone: () =>
1891
1935
  Effect.fail(
1892
- new SchemaIssue.InvalidValue({ message: "Expected a valid Zoned DateTime string" })
1936
+ new SchemaIssue.InvalidValue(
1937
+ { expected: "a valid Zoned DateTime string" },
1938
+ s,
1939
+ options
1940
+ )
1893
1941
  ),
1894
1942
  onSome: Effect.succeed
1895
1943
  })
package/src/Stdio.ts CHANGED
@@ -63,6 +63,18 @@ export const TypeId: TypeId = "~effect/Stdio"
63
63
  export interface Stdio {
64
64
  readonly [TypeId]: TypeId
65
65
  readonly args: Effect.Effect<ReadonlyArray<string>>
66
+ /**
67
+ * Whether standard input is attached to a terminal.
68
+ *
69
+ * @since 4.0.0
70
+ */
71
+ readonly stdinIsTerminal: Effect.Effect<boolean>
72
+ /**
73
+ * Whether standard output is attached to a terminal.
74
+ *
75
+ * @since 4.0.0
76
+ */
77
+ readonly stdoutIsTerminal: Effect.Effect<boolean>
66
78
  stdout(options?: {
67
79
  readonly endOnDone?: boolean | undefined
68
80
  }): Sink.Sink<void, string | Uint8Array, never, PlatformError>
@@ -98,16 +110,23 @@ export const Stdio: Context.Service<Stdio, Stdio> = Context.Service<Stdio>(TypeI
98
110
  *
99
111
  * **Details**
100
112
  *
101
- * The returned service reuses the supplied fields unchanged and only adds the
102
- * `Stdio` type identifier; it does not create a `Layer` or provide defaults.
113
+ * The returned service reuses the supplied fields unchanged and adds the
114
+ * `Stdio` type identifier. Omitted terminal-detection fields default to
115
+ * effects that succeed with `false`.
103
116
  *
104
117
  * @see {@link layerTest} for a test layer with default fields that can be overridden
105
118
  *
106
119
  * @category constructors
107
120
  * @since 4.0.0
108
121
  */
109
- export const make = (options: Omit<Stdio, TypeId>): Stdio => ({
122
+ export const make = (
123
+ options:
124
+ & Omit<Stdio, TypeId | "stdinIsTerminal" | "stdoutIsTerminal">
125
+ & Partial<Pick<Stdio, "stdinIsTerminal" | "stdoutIsTerminal">>
126
+ ): Stdio => ({
110
127
  [TypeId]: TypeId,
128
+ stdinIsTerminal: Effect.succeed(false),
129
+ stdoutIsTerminal: Effect.succeed(false),
111
130
  ...options
112
131
  })
113
132
 
@@ -123,7 +142,7 @@ export const make = (options: Omit<Stdio, TypeId>): Stdio => ({
123
142
  *
124
143
  * Any provided fields override defaults. By default, arguments are empty,
125
144
  * standard output and error are draining sinks, and standard input is an empty
126
- * stream.
145
+ * stream, and terminal-detection effects succeed with `false`.
127
146
  *
128
147
  * @see {@link make} for constructing a `Stdio` service directly without a `Layer` or defaults
129
148
  *
@@ -1,10 +1,6 @@
1
- import * as Cause from "../../Cause.ts"
2
- import * as Effect from "../../Effect.ts"
3
1
  import * as Pipeable from "../../Pipeable.ts"
4
2
  import type * as Schema from "../../Schema.ts"
5
3
  import * as SchemaAST from "../../SchemaAST.ts"
6
- import { SchemaError } from "../../SchemaError.ts"
7
- import type { Issue } from "../../SchemaIssue.ts"
8
4
  import * as SchemaParser from "../../SchemaParser.ts"
9
5
  import type * as SchemaRepresentation from "../../SchemaRepresentation.ts"
10
6
 
@@ -75,20 +71,8 @@ export function make<S extends Schema.Constraint>(ast: S["ast"], options?: objec
75
71
  )
76
72
  self.ast = ast
77
73
  self.rebuild = (ast: SchemaAST.AST) => make(ast, options)
78
- const makeEffect = SchemaParser.makeEffect(self)
79
- self.makeEffect = (input: S["~type.make.in"], options?: Schema.MakeOptions) =>
80
- fromIssueEffect(makeEffect(input, options))
74
+ self.makeEffect = SchemaParser.makeEffect(self)
81
75
  self.make = SchemaParser.make(self)
82
76
  self.makeOption = SchemaParser.makeOption(self)
83
77
  return self
84
78
  }
85
-
86
- /** @internal */
87
- export function fromIssueEffect<A, R>(
88
- self: Effect.Effect<A, Issue, R>
89
- ): Effect.Effect<A, SchemaError, R> {
90
- return Effect.catchCause(
91
- self,
92
- (cause) => Effect.failCauseSync(() => Cause.map(cause, (issue) => new SchemaError(issue)))
93
- )
94
- }
@@ -17,7 +17,7 @@ import * as Record from "../Record.ts"
17
17
  import * as Result from "../Result.ts"
18
18
  import * as Schema from "../Schema.ts"
19
19
  import * as SchemaAST from "../SchemaAST.ts"
20
- import type * as SchemaIssue from "../SchemaIssue.ts"
20
+ import * as SchemaIssue from "../SchemaIssue.ts"
21
21
  import * as SchemaParser from "../SchemaParser.ts"
22
22
  import * as FastCheck from "../testing/FastCheck.ts"
23
23
 
@@ -123,7 +123,7 @@ export class Asserts<S extends Schema.Constraint> {
123
123
  async function succeed(input: S["~type.make.in"], expected?: S["Type"]) {
124
124
  const r = await Effect.runPromise(
125
125
  makeEffect(input, options).pipe(
126
- Effect.mapErrorEager((issue) => issue.toString()),
126
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
127
127
  Effect.result
128
128
  )
129
129
  )
@@ -135,7 +135,7 @@ export class Asserts<S extends Schema.Constraint> {
135
135
  async fail(input: unknown, message: string) {
136
136
  const r = await Effect.runPromise(
137
137
  makeEffect(input, options).pipe(
138
- Effect.mapErrorEager((issue) => issue.toString()),
138
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
139
139
  Effect.result
140
140
  )
141
141
  )
@@ -178,7 +178,7 @@ export class Asserts<S extends Schema.Constraint> {
178
178
  const r = await Effect.runPromise(
179
179
  encodeEffect(t).pipe(
180
180
  Effect.flatMapEager((e) => decodeUnknownEffect(e)),
181
- Effect.mapErrorEager((issue) => issue.toString()),
181
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
182
182
  Effect.result
183
183
  )
184
184
  )
@@ -367,7 +367,7 @@ export class Decoding<S extends Schema.Constraint> {
367
367
  ) {
368
368
  const r = await Effect.runPromise(
369
369
  this.decodeUnknownEffect(input, this.options?.parseOptions).pipe(
370
- Effect.mapErrorEager((issue) => issue.toString()),
370
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
371
371
  Effect.result
372
372
  )
373
373
  )
@@ -401,7 +401,7 @@ export class Decoding<S extends Schema.Constraint> {
401
401
  ) {
402
402
  const r = await Effect.runPromise(
403
403
  this.decodeUnknownEffect(input, this.options?.parseOptions).pipe(
404
- Effect.mapErrorEager((issue) => issue.toString()),
404
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
405
405
  Effect.result
406
406
  )
407
407
  )
@@ -507,7 +507,7 @@ export class Encoding<S extends Schema.Constraint> {
507
507
  ) {
508
508
  const r = await Effect.runPromise(
509
509
  this.encodeUnknownEffect(input, this.options?.parseOptions).pipe(
510
- Effect.mapErrorEager((issue) => issue.toString()),
510
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
511
511
  Effect.result
512
512
  )
513
513
  )
@@ -541,7 +541,7 @@ export class Encoding<S extends Schema.Constraint> {
541
541
  ) {
542
542
  const r = await Effect.runPromise(
543
543
  this.encodeUnknownEffect(input, this.options?.parseOptions).pipe(
544
- Effect.mapErrorEager((issue) => issue.toString()),
544
+ Effect.mapErrorEager(SchemaIssue.defaultFormatter),
545
545
  Effect.result
546
546
  )
547
547
  )
@@ -1840,20 +1840,30 @@ export const Prompt: Schema.Codec<Prompt, PromptEncoded> = Schema.Struct({
1840
1840
  Schema.decodeTo(
1841
1841
  $Prompt,
1842
1842
  SchemaTransformation.transformOrFail({
1843
- decode: (input) =>
1843
+ decode: (input, options) =>
1844
1844
  Effect.mapBothEager(
1845
1845
  SchemaParser.decodeEffect(Schema.Array(Message))(input.content),
1846
1846
  {
1847
1847
  onSuccess: makePrompt,
1848
- onFailure: () => new SchemaIssue.InvalidValue({ message: "Invalid Prompt messages" })
1848
+ onFailure: () =>
1849
+ new SchemaIssue.InvalidValue(
1850
+ { message: "Invalid Prompt messages" },
1851
+ input.content,
1852
+ options
1853
+ )
1849
1854
  }
1850
1855
  ),
1851
- encode: (prompt) =>
1856
+ encode: (prompt, options) =>
1852
1857
  Effect.mapBothEager(
1853
1858
  SchemaParser.encodeEffect(Schema.Array(Message))(prompt.content),
1854
1859
  {
1855
1860
  onSuccess: (messages) => ({ content: messages }),
1856
- onFailure: () => new SchemaIssue.InvalidValue({ message: "Invalid Prompt messages" })
1861
+ onFailure: () =>
1862
+ new SchemaIssue.InvalidValue(
1863
+ { message: "Invalid Prompt messages" },
1864
+ prompt.content,
1865
+ options
1866
+ )
1857
1867
  }
1858
1868
  )
1859
1869
  })
@@ -242,10 +242,10 @@ export class Chunk<R extends Rpc.Any> extends Data.TaggedClass("Chunk")<{
242
242
  [success],
243
243
  ([success]) => (input, ast, options) => {
244
244
  if (!isReply(input) || input._tag !== "Chunk") {
245
- return Effect.fail(new SchemaIssue.InvalidType(ast))
245
+ return Effect.fail(new SchemaIssue.InvalidType(ast, input, options))
246
246
  }
247
247
  return Effect.mapBothEager(SchemaParser.decodeEffect(Schema.NonEmptyArray(success))(input.values, options), {
248
- onFailure: (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["values"], issue)]),
248
+ onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "values", issue, input, options),
249
249
  onSuccess: (values) => new Chunk({ ...input, values } as any)
250
250
  })
251
251
  },
@@ -351,10 +351,10 @@ export class WithExit<R extends Rpc.Any> extends Data.TaggedClass("WithExit")<{
351
351
  [exitSchema],
352
352
  ([exit]) => (input, ast, options) => {
353
353
  if (!isReply(input) || input._tag !== "WithExit") {
354
- return Effect.fail(new SchemaIssue.InvalidType(ast))
354
+ return Effect.fail(new SchemaIssue.InvalidType(ast, input, options))
355
355
  }
356
356
  return Effect.mapBothEager(SchemaParser.decodeEffect(exit)(input.exit, options), {
357
- onFailure: (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["exit"], issue)]),
357
+ onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "exit", issue, input, options),
358
358
  onSuccess: (exit) => new WithExit({ ...input, exit: exit as any })
359
359
  })
360
360
  },
@@ -387,25 +387,29 @@ export const transformation: SchemaTransformation.Transformation<
387
387
  unknown,
388
388
  Uint8Array<ArrayBuffer>
389
389
  > = SchemaTransformation.transformOrFail({
390
- decode(e, _options) {
390
+ decode(e, options) {
391
391
  try {
392
392
  return Effect.succeed(Msgpackr.decode(e))
393
393
  } catch {
394
394
  return Effect.fail(
395
- new SchemaIssue.InvalidValue({
396
- message: "Expected valid MessagePack bytes"
397
- })
395
+ new SchemaIssue.InvalidValue(
396
+ { expected: "valid MessagePack bytes" },
397
+ e,
398
+ options
399
+ )
398
400
  )
399
401
  }
400
402
  },
401
- encode(t, _options) {
403
+ encode(t, options) {
402
404
  try {
403
405
  return Effect.succeed(Msgpackr.encode(t) as Uint8Array<ArrayBuffer>)
404
406
  } catch {
405
407
  return Effect.fail(
406
- new SchemaIssue.InvalidValue({
407
- message: "Expected a MessagePack-serializable value"
408
- })
408
+ new SchemaIssue.InvalidValue(
409
+ { expected: "a MessagePack-serializable value" },
410
+ t,
411
+ options
412
+ )
409
413
  )
410
414
  }
411
415
  }