effect 4.0.0-beta.25 → 4.0.0-beta.27

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 (155) hide show
  1. package/dist/Cause.d.ts +1 -1
  2. package/dist/Config.js +4 -4
  3. package/dist/Config.js.map +1 -1
  4. package/dist/Data.d.ts +2 -2
  5. package/dist/Data.js +2 -2
  6. package/dist/Effect.d.ts +51 -35
  7. package/dist/Effect.d.ts.map +1 -1
  8. package/dist/Effect.js +16 -12
  9. package/dist/Effect.js.map +1 -1
  10. package/dist/ErrorReporter.d.ts +2 -4
  11. package/dist/ErrorReporter.d.ts.map +1 -1
  12. package/dist/ErrorReporter.js +1 -3
  13. package/dist/ErrorReporter.js.map +1 -1
  14. package/dist/Layer.d.ts +112 -117
  15. package/dist/Layer.d.ts.map +1 -1
  16. package/dist/Layer.js +43 -44
  17. package/dist/Layer.js.map +1 -1
  18. package/dist/LayerMap.d.ts +4 -4
  19. package/dist/LayerMap.js +3 -3
  20. package/dist/ManagedRuntime.d.ts +1 -1
  21. package/dist/ManagedRuntime.js +1 -1
  22. package/dist/Metric.d.ts +2 -4
  23. package/dist/Metric.d.ts.map +1 -1
  24. package/dist/Metric.js +2 -4
  25. package/dist/Metric.js.map +1 -1
  26. package/dist/Runtime.d.ts +66 -0
  27. package/dist/Runtime.d.ts.map +1 -1
  28. package/dist/Runtime.js +72 -5
  29. package/dist/Runtime.js.map +1 -1
  30. package/dist/Schedule.d.ts +36 -36
  31. package/dist/Schedule.js +14 -14
  32. package/dist/Schema.d.ts +15 -32
  33. package/dist/Schema.d.ts.map +1 -1
  34. package/dist/Schema.js +9 -17
  35. package/dist/Schema.js.map +1 -1
  36. package/dist/SchemaAST.js +91 -2
  37. package/dist/SchemaAST.js.map +1 -1
  38. package/dist/SchemaGetter.d.ts +3 -3
  39. package/dist/SchemaRepresentation.d.ts.map +1 -1
  40. package/dist/SchemaRepresentation.js +12 -8
  41. package/dist/SchemaRepresentation.js.map +1 -1
  42. package/dist/Stdio.d.ts +10 -2
  43. package/dist/Stdio.d.ts.map +1 -1
  44. package/dist/Stdio.js +18 -0
  45. package/dist/Stdio.js.map +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +1 -1
  48. package/dist/internal/schema/representation.js +7 -3
  49. package/dist/internal/schema/representation.js.map +1 -1
  50. package/dist/internal/schema/to-codec.js +7 -10
  51. package/dist/internal/schema/to-codec.js.map +1 -1
  52. package/dist/unstable/ai/AiError.d.ts +6 -3
  53. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  54. package/dist/unstable/ai/AiError.js +8 -4
  55. package/dist/unstable/ai/AiError.js.map +1 -1
  56. package/dist/unstable/ai/LanguageModel.js +7 -5
  57. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  58. package/dist/unstable/cli/CliError.d.ts +23 -56
  59. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  60. package/dist/unstable/cli/CliError.js +25 -57
  61. package/dist/unstable/cli/CliError.js.map +1 -1
  62. package/dist/unstable/cli/Command.d.ts +117 -62
  63. package/dist/unstable/cli/Command.d.ts.map +1 -1
  64. package/dist/unstable/cli/Command.js +95 -32
  65. package/dist/unstable/cli/Command.js.map +1 -1
  66. package/dist/unstable/cli/GlobalFlag.d.ts +1 -1
  67. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  68. package/dist/unstable/cli/Primitive.d.ts +1 -1
  69. package/dist/unstable/cli/Primitive.js +1 -1
  70. package/dist/unstable/cli/internal/command.d.ts +27 -10
  71. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  72. package/dist/unstable/cli/internal/command.js +40 -23
  73. package/dist/unstable/cli/internal/command.js.map +1 -1
  74. package/dist/unstable/cli/internal/config.js +42 -0
  75. package/dist/unstable/cli/internal/config.js.map +1 -1
  76. package/dist/unstable/cli/internal/help.d.ts +4 -4
  77. package/dist/unstable/cli/internal/help.d.ts.map +1 -1
  78. package/dist/unstable/cli/internal/help.js +25 -7
  79. package/dist/unstable/cli/internal/help.js.map +1 -1
  80. package/dist/unstable/cli/internal/parser.js +26 -6
  81. package/dist/unstable/cli/internal/parser.js.map +1 -1
  82. package/dist/unstable/http/Headers.d.ts +16 -0
  83. package/dist/unstable/http/Headers.d.ts.map +1 -1
  84. package/dist/unstable/http/Headers.js +11 -0
  85. package/dist/unstable/http/Headers.js.map +1 -1
  86. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  87. package/dist/unstable/httpapi/HttpApiBuilder.js +6 -7
  88. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  89. package/dist/unstable/httpapi/HttpApiClient.d.ts +6 -6
  90. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  91. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  92. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +10 -10
  93. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  94. package/dist/unstable/httpapi/HttpApiEndpoint.js +2 -2
  95. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  96. package/dist/unstable/httpapi/HttpApiError.d.ts +6 -15
  97. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  98. package/dist/unstable/httpapi/HttpApiError.js +16 -21
  99. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  100. package/dist/unstable/reactivity/Atom.d.ts +56 -0
  101. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  102. package/dist/unstable/reactivity/Atom.js +66 -0
  103. package/dist/unstable/reactivity/Atom.js.map +1 -1
  104. package/dist/unstable/reactivity/AtomHttpApi.d.ts +2 -2
  105. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  106. package/dist/unstable/rpc/RpcServer.d.ts +3 -0
  107. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  108. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  109. package/dist/unstable/schema/Model.d.ts +21 -0
  110. package/dist/unstable/schema/Model.d.ts.map +1 -1
  111. package/dist/unstable/schema/Model.js +15 -0
  112. package/dist/unstable/schema/Model.js.map +1 -1
  113. package/dist/unstable/sql/SqlSchema.d.ts +2 -2
  114. package/dist/unstable/sql/SqlSchema.d.ts.map +1 -1
  115. package/dist/unstable/sql/SqlSchema.js.map +1 -1
  116. package/package.json +1 -1
  117. package/src/Cause.ts +1 -1
  118. package/src/Config.ts +4 -4
  119. package/src/Data.ts +2 -2
  120. package/src/Effect.ts +60 -31
  121. package/src/ErrorReporter.ts +2 -4
  122. package/src/Layer.ts +112 -117
  123. package/src/LayerMap.ts +4 -4
  124. package/src/ManagedRuntime.ts +1 -1
  125. package/src/Metric.ts +2 -4
  126. package/src/Runtime.ts +95 -5
  127. package/src/Schedule.ts +36 -36
  128. package/src/Schema.ts +20 -52
  129. package/src/SchemaAST.ts +127 -2
  130. package/src/SchemaGetter.ts +3 -3
  131. package/src/SchemaRepresentation.ts +12 -8
  132. package/src/Stdio.ts +21 -2
  133. package/src/index.ts +1 -1
  134. package/src/internal/schema/representation.ts +8 -4
  135. package/src/internal/schema/to-codec.ts +7 -17
  136. package/src/unstable/ai/AiError.ts +8 -4
  137. package/src/unstable/ai/LanguageModel.ts +8 -5
  138. package/src/unstable/cli/CliError.ts +47 -59
  139. package/src/unstable/cli/Command.ts +348 -180
  140. package/src/unstable/cli/GlobalFlag.ts +1 -1
  141. package/src/unstable/cli/Primitive.ts +1 -1
  142. package/src/unstable/cli/internal/command.ts +62 -32
  143. package/src/unstable/cli/internal/config.ts +49 -0
  144. package/src/unstable/cli/internal/help.ts +41 -16
  145. package/src/unstable/cli/internal/parser.ts +36 -10
  146. package/src/unstable/http/Headers.ts +34 -0
  147. package/src/unstable/httpapi/HttpApiBuilder.ts +4 -7
  148. package/src/unstable/httpapi/HttpApiClient.ts +6 -6
  149. package/src/unstable/httpapi/HttpApiEndpoint.ts +4 -4
  150. package/src/unstable/httpapi/HttpApiError.ts +23 -21
  151. package/src/unstable/reactivity/Atom.ts +132 -0
  152. package/src/unstable/reactivity/AtomHttpApi.ts +2 -2
  153. package/src/unstable/rpc/RpcServer.ts +5 -0
  154. package/src/unstable/schema/Model.ts +31 -0
  155. package/src/unstable/sql/SqlSchema.ts +2 -2
package/src/SchemaAST.ts CHANGED
@@ -651,7 +651,7 @@ export class Undefined extends Base {
651
651
  return fromConst(this, undefined)
652
652
  }
653
653
  /** @internal */
654
- encodeToNull(): AST {
654
+ toCodecJson(): AST {
655
655
  return replaceEncoding(this, [undefinedToNull])
656
656
  }
657
657
  /** @internal */
@@ -697,7 +697,7 @@ export class Void extends Base {
697
697
  return fromConst(this, undefined)
698
698
  }
699
699
  /** @internal */
700
- encodeToNull(): AST {
700
+ toCodecJson(): AST {
701
701
  return replaceEncoding(this, [undefinedToNull])
702
702
  }
703
703
  /** @internal */
@@ -3369,3 +3369,128 @@ export const resolveTitle: (ast: AST) => string | undefined = InternalAnnotation
3369
3369
  * @since 4.0.0
3370
3370
  */
3371
3371
  export const resolveDescription: (ast: AST) => string | undefined = InternalAnnotations.resolveDescription
3372
+
3373
+ /**
3374
+ * Returns true if the value is a JSON value.
3375
+ *
3376
+ * When a cyclic reference is detected, returns false.
3377
+ *
3378
+ * @internal
3379
+ */
3380
+ export function isJson(u: unknown): u is Schema.Json {
3381
+ const seen = new Set<unknown>()
3382
+ return recur(u)
3383
+
3384
+ function recur(u: unknown): boolean {
3385
+ if (u === null || typeof u === "string" || typeof u === "boolean") {
3386
+ return true
3387
+ }
3388
+ if (typeof u === "number") {
3389
+ return globalThis.Number.isFinite(u)
3390
+ }
3391
+ if (typeof u !== "object" || u === undefined) {
3392
+ return false
3393
+ }
3394
+ if (seen.has(u)) {
3395
+ return false
3396
+ }
3397
+ seen.add(u)
3398
+ if (Array.isArray(u)) {
3399
+ return u.every(recur)
3400
+ }
3401
+ return Object.keys(u).every((key) => recur((u as Record<string, unknown>)[key]))
3402
+ }
3403
+ }
3404
+
3405
+ /** @internal */
3406
+ export const Json = new Declaration(
3407
+ [],
3408
+ () => (input, ast) =>
3409
+ isJson(input) ?
3410
+ Effect.succeed(input) :
3411
+ Effect.fail(new Issue.InvalidType(ast, Option.some(input))),
3412
+ {
3413
+ typeConstructor: {
3414
+ _tag: "effect/Json"
3415
+ },
3416
+ generation: {
3417
+ runtime: `Schema.Json`,
3418
+ Type: `Schema.Json`
3419
+ },
3420
+ expected: "JSON value",
3421
+ toCodecJson: () => new Link(unknown, Transformation.passthrough())
3422
+ }
3423
+ )
3424
+
3425
+ /** @internal */
3426
+ export const MutableJson = annotate(Json, {
3427
+ typeConstructor: {
3428
+ _tag: "effect/MutableJson"
3429
+ },
3430
+ generation: {
3431
+ runtime: `Schema.MutableJson`,
3432
+ Type: `Schema.MutableJson`
3433
+ }
3434
+ })
3435
+
3436
+ /** @internal */
3437
+ export const unknownToNull = new Link(
3438
+ null_,
3439
+ new Transformation.Transformation(
3440
+ Getter.passthrough(),
3441
+ Getter.transform(() => null)
3442
+ )
3443
+ )
3444
+
3445
+ /** @internal */
3446
+ export const unknownToJson = new Link(
3447
+ Json,
3448
+ Transformation.passthrough()
3449
+ )
3450
+
3451
+ /**
3452
+ * Returns true if the value is a StringTree value.
3453
+ *
3454
+ * When a cyclic reference is detected, returns false.
3455
+ *
3456
+ * @internal
3457
+ */
3458
+ export function isStringTree(u: unknown): u is Schema.StringTree {
3459
+ const seen = new Set<unknown>()
3460
+ return recur(u)
3461
+
3462
+ function recur(u: unknown): boolean {
3463
+ if (u === undefined || typeof u === "string") {
3464
+ return true
3465
+ }
3466
+ if (typeof u !== "object" || u === null) {
3467
+ return false
3468
+ }
3469
+ if (seen.has(u)) {
3470
+ return false
3471
+ }
3472
+ seen.add(u)
3473
+ if (Array.isArray(u)) {
3474
+ return u.every(recur)
3475
+ }
3476
+ return Object.keys(u).every((key) => recur((u as Record<string, unknown>)[key]))
3477
+ }
3478
+ }
3479
+
3480
+ const StringTree = new Declaration(
3481
+ [],
3482
+ () => (input, ast) =>
3483
+ isStringTree(input) ?
3484
+ Effect.succeed(input) :
3485
+ Effect.fail(new Issue.InvalidType(ast, Option.some(input))),
3486
+ {
3487
+ expected: "StringTree",
3488
+ toCodecStringTree: () => new Link(unknown, Transformation.passthrough())
3489
+ }
3490
+ )
3491
+
3492
+ /** @internal */
3493
+ export const unknownToStringTree = new Link(
3494
+ StringTree,
3495
+ Transformation.passthrough()
3496
+ )
@@ -1517,7 +1517,7 @@ export function dateTimeUtcFromInput<E extends DateTime.DateTime.Input>(): Gette
1517
1517
  * @category FormData
1518
1518
  * @since 4.0.0
1519
1519
  */
1520
- export function decodeFormData(): Getter<Schema.TreeObject<string | Blob>, FormData> {
1520
+ export function decodeFormData(): Getter<Schema.TreeRecord<string | Blob>, FormData> {
1521
1521
  return transform((input) => makeTreeRecord(Array.from(input.entries())))
1522
1522
  }
1523
1523
 
@@ -1594,7 +1594,7 @@ export function encodeFormData(): Getter<FormData, unknown> {
1594
1594
  * @category URLSearchParams
1595
1595
  * @since 4.0.0
1596
1596
  */
1597
- export function decodeURLSearchParams(): Getter<Schema.TreeObject<string>, URLSearchParams> {
1597
+ export function decodeURLSearchParams(): Getter<Schema.TreeRecord<string>, URLSearchParams> {
1598
1598
  return transform((input) => makeTreeRecord(Array.from(input.entries())))
1599
1599
  }
1600
1600
 
@@ -1699,7 +1699,7 @@ function bracketPathToTokens(bracketPath: string): Array<string | number> {
1699
1699
  */
1700
1700
  export function makeTreeRecord<A>(
1701
1701
  bracketPathEntries: ReadonlyArray<readonly [bracketPath: string, value: A]>
1702
- ): Schema.TreeObject<A> {
1702
+ ): Schema.TreeRecord<A> {
1703
1703
  const out: any = {}
1704
1704
  bracketPathEntries.forEach(([key, value]) => {
1705
1705
  const tokens = bracketPathToTokens(key)
@@ -1741,6 +1741,12 @@ export const toSchemaDefaultReviver: Reviver<Schema.Top> = (s, recur) => {
1741
1741
  case "URLSearchParams":
1742
1742
  return Schema.URLSearchParams
1743
1743
  // effect types
1744
+ case "effect/Option":
1745
+ return Schema.Option(typeParameters[0])
1746
+ case "effect/Result":
1747
+ return Schema.Result(typeParameters[0], typeParameters[1])
1748
+ case "effect/Redacted":
1749
+ return Schema.Redacted(typeParameters[0])
1744
1750
  case "effect/DateTime.TimeZone":
1745
1751
  return Schema.TimeZone
1746
1752
  case "effect/DateTime.TimeZone.Named":
@@ -1753,6 +1759,8 @@ export const toSchemaDefaultReviver: Reviver<Schema.Top> = (s, recur) => {
1753
1759
  return Schema.DateTimeZoned
1754
1760
  case "effect/BigDecimal":
1755
1761
  return Schema.BigDecimal
1762
+ case "effect/Chunk":
1763
+ return Schema.Chunk(typeParameters[0])
1756
1764
  case "effect/Cause":
1757
1765
  return Schema.Cause(typeParameters[0], typeParameters[1])
1758
1766
  case "effect/Cause/Failure":
@@ -1761,18 +1769,14 @@ export const toSchemaDefaultReviver: Reviver<Schema.Top> = (s, recur) => {
1761
1769
  return Schema.Duration
1762
1770
  case "effect/Exit":
1763
1771
  return Schema.Exit(typeParameters[0], typeParameters[1], typeParameters[2])
1772
+ case "effect/Json":
1773
+ return Schema.Json
1774
+ case "effect/MutableJson":
1775
+ return Schema.MutableJson
1764
1776
  case "effect/HashMap":
1765
1777
  return Schema.HashMap(typeParameters[0], typeParameters[1])
1766
- case "effect/Option":
1767
- return Schema.Option(typeParameters[0])
1768
- case "effect/Redacted":
1769
- return Schema.Redacted(typeParameters[0])
1770
- case "effect/Result":
1771
- return Schema.Result(typeParameters[0], typeParameters[1])
1772
1778
  case "effect/HashSet":
1773
1779
  return Schema.HashSet(typeParameters[0])
1774
- case "effect/Chunk":
1775
- return Schema.Chunk(typeParameters[0])
1776
1780
  }
1777
1781
  }
1778
1782
  }
package/src/Stdio.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * @since 4.0.0
3
3
  */
4
+ import * as Effect from "./Effect.ts"
5
+ import * as Layer from "./Layer.ts"
4
6
  import type { PlatformError } from "./PlatformError.ts"
5
7
  import * as ServiceMap from "./ServiceMap.ts"
6
- import type * as Sink from "./Sink.ts"
7
- import type * as Stream from "./Stream.ts"
8
+ import * as Sink from "./Sink.ts"
9
+ import * as Stream from "./Stream.ts"
8
10
 
9
11
  /**
10
12
  * @since 4.0.0
@@ -24,6 +26,7 @@ export const TypeId: TypeId = "~effect/Stdio"
24
26
  */
25
27
  export interface Stdio {
26
28
  readonly [TypeId]: TypeId
29
+ readonly args: Effect.Effect<ReadonlyArray<string>>
27
30
  readonly stdout: Sink.Sink<void, string | Uint8Array, never, PlatformError>
28
31
  readonly stderr: Sink.Sink<void, string | Uint8Array, never, PlatformError>
29
32
  readonly stdin: Stream.Stream<Uint8Array, PlatformError>
@@ -42,3 +45,19 @@ export const make = (options: Omit<Stdio, TypeId>): Stdio => ({
42
45
  [TypeId]: TypeId,
43
46
  ...options
44
47
  })
48
+
49
+ /**
50
+ * @since 4.0.0
51
+ * @category Layers
52
+ */
53
+ export const layerTest = (impl: Partial<Stdio>): Layer.Layer<Stdio> =>
54
+ Layer.succeed(
55
+ Stdio,
56
+ make({
57
+ args: Effect.succeed([]),
58
+ stdout: Sink.drain,
59
+ stderr: Sink.drain,
60
+ stdin: Stream.empty,
61
+ ...impl
62
+ })
63
+ )
package/src/index.ts CHANGED
@@ -1160,7 +1160,7 @@ export * as Equivalence from "./Equivalence.ts"
1160
1160
  *
1161
1161
  * // Opt in to error reporting with Effect.withErrorReporting
1162
1162
  * const program = Effect.gen(function*() {
1163
- * yield* new RateLimitError({ retryAfter: 60 })
1163
+ * return yield* new RateLimitError({ retryAfter: 60 })
1164
1164
  * }).pipe(
1165
1165
  * Effect.withErrorReporting,
1166
1166
  * Effect.provide(ErrorReporter.layer([consoleReporter]))
@@ -341,11 +341,11 @@ export function toJsonSchemaMultiDocument(
341
341
  function on(schema: SchemaRepresentation.Representation): JsonSchema.JsonSchema {
342
342
  switch (schema._tag) {
343
343
  case "Any":
344
- return {}
345
344
  case "Unknown":
345
+ case "ObjectKeyword":
346
+ return {}
346
347
  case "Void":
347
348
  case "Undefined":
348
- case "ObjectKeyword":
349
349
  return { type: "null" }
350
350
  case "BigInt":
351
351
  return {
@@ -494,10 +494,14 @@ export function toJsonSchemaMultiDocument(
494
494
  }
495
495
 
496
496
  out.additionalProperties = additionalProperties
497
- const patternProperties: Record<string, JsonSchema.JsonSchema> = {}
497
+ const patternProperties: Record<string, JsonSchema.JsonSchema | false> = {}
498
498
  // Handle index signatures
499
499
  for (const is of schema.indexSignatures) {
500
- const type = recur(is.type)
500
+ let type: JsonSchema.JsonSchema | false = recur(is.type)
501
+ // Collapse unannotated Never ({ not: {} }) to false, but keep annotated schemas as objects.
502
+ if (Object.keys(type).length === 1 && "not" in type) {
503
+ type = false
504
+ }
501
505
  const patterns = getParameterPatterns(is.parameter)
502
506
  if (patterns.length > 0) {
503
507
  for (const pattern of patterns) {
@@ -1,8 +1,6 @@
1
1
  import { memoize } from "../../Function.ts"
2
2
  import * as Predicate from "../../Predicate.ts"
3
3
  import * as AST from "../../SchemaAST.ts"
4
- import * as Getter from "../../SchemaGetter.ts"
5
- import * as Transformation from "../../SchemaTransformation.ts"
6
4
  import * as InternalSchema from "./schema.ts"
7
5
 
8
6
  /** @internal */
@@ -16,8 +14,6 @@ export const toCodecJson = AST.toCodec((ast) => {
16
14
 
17
15
  function toCodecJsonBase(ast: AST.AST): AST.AST {
18
16
  switch (ast._tag) {
19
- case "Unknown":
20
- case "ObjectKeyword":
21
17
  case "Declaration": {
22
18
  const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec
23
19
  if (Predicate.isFunction(getLink)) {
@@ -28,18 +24,20 @@ function toCodecJsonBase(ast: AST.AST): AST.AST {
28
24
  const to = toCodecJson(link.to)
29
25
  return AST.replaceEncoding(ast, to === link.to ? [link] : [new AST.Link(to, link.transformation)])
30
26
  }
31
- return AST.replaceEncoding(ast, [unknownToNull])
27
+ return AST.replaceEncoding(ast, [AST.unknownToNull])
32
28
  }
29
+ case "Unknown":
30
+ case "ObjectKeyword":
31
+ return AST.replaceEncoding(ast, [AST.unknownToJson])
33
32
  case "Undefined":
34
33
  case "Void":
35
- return ast.encodeToNull()
34
+ case "Literal":
35
+ case "Number":
36
+ return ast.toCodecJson()
36
37
  case "UniqueSymbol":
37
38
  case "Symbol":
38
39
  case "BigInt":
39
40
  return ast.toCodecStringTree()
40
- case "Literal":
41
- case "Number":
42
- return ast.toCodecJson()
43
41
  case "Objects": {
44
42
  if (ast.propertySignatures.some((ps) => typeof ps.name !== "string")) {
45
43
  throw new globalThis.Error("Objects property names must be strings", { cause: ast })
@@ -110,14 +108,6 @@ export function makeReorder(getPriority: (ast: AST.AST) => number) {
110
108
  }
111
109
  }
112
110
 
113
- const unknownToNull = new AST.Link(
114
- AST.null,
115
- new Transformation.Transformation(
116
- Getter.passthrough(),
117
- Getter.transform(() => null)
118
- )
119
- )
120
-
121
111
  /** @internal */
122
112
  export const toCodecIso = memoize((ast: AST.AST): AST.AST => {
123
113
  const out = toCodecIsoBase(ast)
@@ -756,7 +756,8 @@ export class InvalidOutputError extends Schema.ErrorClass<InvalidOutputError>(
756
756
  * import { AiError } from "effect/unstable/ai"
757
757
  *
758
758
  * const error = new AiError.StructuredOutputError({
759
- * description: "Expected a valid JSON object"
759
+ * description: "Expected a valid JSON object",
760
+ * responseText: "{\"foo\":}"
760
761
  * })
761
762
  *
762
763
  * console.log(error.isRetryable) // true
@@ -772,6 +773,7 @@ export class StructuredOutputError extends Schema.ErrorClass<StructuredOutputErr
772
773
  )({
773
774
  _tag: Schema.tag("StructuredOutputError"),
774
775
  description: Schema.String,
776
+ responseText: Schema.String,
775
777
  metadata: providerMetadataWithDefaults<StructuredOutputErrorMetadata>(),
776
778
  usage: Schema.optional(UsageInfo)
777
779
  }) {
@@ -798,16 +800,18 @@ export class StructuredOutputError extends Schema.ErrorClass<StructuredOutputErr
798
800
  * import { AiError } from "effect/unstable/ai"
799
801
  *
800
802
  * declare const schemaError: Schema.SchemaError
803
+ * declare const rawText: string
801
804
  *
802
- * const parseError = AiError.StructuredOutputError.fromSchemaError(schemaError)
805
+ * const parseError = AiError.StructuredOutputError.fromSchemaError(schemaError, rawText)
803
806
  * ```
804
807
  *
805
808
  * @since 1.0.0
806
809
  * @category constructors
807
810
  */
808
- static fromSchemaError(error: Schema.SchemaError): StructuredOutputError {
811
+ static fromSchemaError(error: Schema.SchemaError, responseText: string): StructuredOutputError {
809
812
  return new StructuredOutputError({
810
- description: error.message
813
+ description: error.message,
814
+ responseText
811
815
  })
812
816
  }
813
817
 
@@ -1864,29 +1864,32 @@ export const getObjectName = <StructuredOutputSchema extends Schema.Top>(
1864
1864
  const resolveStructuredOutput = Effect.fnUntraced(function*<
1865
1865
  StructuredOutputSchema extends Schema.Top
1866
1866
  >(response: ReadonlyArray<Response.AllParts<any>>, schema: StructuredOutputSchema) {
1867
- const text: Array<string> = []
1867
+ const texts: Array<string> = []
1868
1868
  for (const part of response) {
1869
1869
  if (part.type === "text") {
1870
- text.push(part.text)
1870
+ texts.push(part.text)
1871
1871
  }
1872
1872
  }
1873
1873
 
1874
+ const text = texts.join("")
1875
+
1874
1876
  if (text.length === 0) {
1875
1877
  return yield* AiError.make({
1876
1878
  module: "LanguageModel",
1877
1879
  method: "generateObject",
1878
1880
  reason: new AiError.StructuredOutputError({
1879
- description: "No text content in response"
1881
+ description: "No text content in response",
1882
+ responseText: text
1880
1883
  })
1881
1884
  })
1882
1885
  }
1883
1886
 
1884
1887
  const decode = Schema.decodeEffect(Schema.fromJsonString(schema))
1885
- return yield* Effect.mapError(decode(text.join("")), (error) =>
1888
+ return yield* Effect.mapError(decode(text), (error) =>
1886
1889
  AiError.make({
1887
1890
  module: "LanguageModel",
1888
1891
  method: "generateObject",
1889
- reason: AiError.StructuredOutputError.fromSchemaError(error)
1892
+ reason: AiError.StructuredOutputError.fromSchemaError(error, text)
1890
1893
  }))
1891
1894
  })
1892
1895
 
@@ -2,6 +2,7 @@
2
2
  * @since 4.0.0
3
3
  */
4
4
  import * as Predicate from "../../Predicate.ts"
5
+ import * as Runtime from "../../Runtime.ts"
5
6
  import * as Schema from "../../Schema.ts"
6
7
 
7
8
  /**
@@ -107,7 +108,7 @@ export type CliError =
107
108
  * // In CLI parsing context
108
109
  * const parseCommand = Effect.gen(function*() {
109
110
  * // If parsing encounters unknown flag
110
- * return yield* Effect.fail(unrecognizedError)
111
+ * return yield* unrecognizedError
111
112
  * })
112
113
  * ```
113
114
  *
@@ -200,7 +201,7 @@ export class DuplicateOption extends Schema.ErrorClass(`${TypeId}/DuplicateOptio
200
201
  * Effect.gen(function*() {
201
202
  * const apiKey = options["api-key"]
202
203
  * if (!apiKey) {
203
- * return yield* Effect.fail(missingOptionError)
204
+ * return yield* missingOptionError
204
205
  * }
205
206
  * return apiKey
206
207
  * })
@@ -245,7 +246,7 @@ export class MissingOption extends Schema.ErrorClass(`${TypeId}/MissingOption`)(
245
246
  * const parseArguments = (args: Array<string>) =>
246
247
  * Effect.gen(function*() {
247
248
  * if (args.length === 0) {
248
- * return yield* Effect.fail(missingArgError)
249
+ * return yield* missingArgError
249
250
  * }
250
251
  * return args[0]
251
252
  * })
@@ -353,7 +354,7 @@ export class InvalidValue extends Schema.ErrorClass(`${TypeId}/InvalidValue`)({
353
354
  * Effect.gen(function*() {
354
355
  * const validCommands = ["deploy", "destroy", "status"]
355
356
  * if (!validCommands.includes(subcommand)) {
356
- * return yield* Effect.fail(unknownSubcommandError)
357
+ * return yield* unknownSubcommandError
357
358
  * }
358
359
  * return subcommand
359
360
  * })
@@ -386,61 +387,6 @@ export class UnknownSubcommand extends Schema.ErrorClass(`${TypeId}/UnknownSubco
386
387
  }
387
388
  }
388
389
 
389
- /**
390
- * Control flow indicator when help is requested via --help flag.
391
- * This is not an error but uses the error channel for control flow.
392
- *
393
- * @example
394
- * ```ts
395
- * import { Effect } from "effect"
396
- * import { CliError } from "effect/unstable/cli"
397
- *
398
- * const showHelpIndicator = new CliError.ShowHelp({
399
- * commandPath: ["myapp", "deploy", "production"]
400
- * })
401
- *
402
- * console.log(showHelpIndicator.message)
403
- * // "Help requested"
404
- *
405
- * // In help flag handling
406
- * const handleHelpFlag = (hasHelpFlag: boolean) =>
407
- * Effect.gen(function*() {
408
- * if (hasHelpFlag) {
409
- * return yield* Effect.fail(showHelpIndicator)
410
- * }
411
- * return "continuing with command"
412
- * })
413
- *
414
- * // In error handling
415
- * const handleCliErrors = (error: CliError.CliError): void => {
416
- * if (error._tag === "ShowHelp") {
417
- * // Display help for the command path
418
- * console.log(`Displaying help for: ${error.commandPath.join(" ")}`)
419
- * }
420
- * // Handle other errors...
421
- * }
422
- * ```
423
- *
424
- * @since 4.0.0
425
- * @category models
426
- */
427
- export class ShowHelp extends Schema.ErrorClass(`${TypeId}/ShowHelp`)({
428
- _tag: Schema.tag("ShowHelp"),
429
- commandPath: Schema.Array(Schema.String)
430
- }) {
431
- /**
432
- * @since 4.0.0
433
- */
434
- readonly [TypeId] = TypeId
435
-
436
- /**
437
- * @since 4.0.0
438
- */
439
- override get message() {
440
- return "Help requested"
441
- }
442
- }
443
-
444
390
  /**
445
391
  * Wrapper for user (handler) errors to unify under CLI error channel when desired.
446
392
  *
@@ -485,3 +431,45 @@ export class UserError extends Schema.ErrorClass(`${TypeId}/UserError`)({
485
431
  */
486
432
  readonly [TypeId] = TypeId
487
433
  }
434
+
435
+ const NonShowHelpErrors: Schema.Union<
436
+ readonly [
437
+ typeof UnrecognizedOption,
438
+ typeof DuplicateOption,
439
+ typeof MissingOption,
440
+ typeof MissingArgument,
441
+ typeof InvalidValue,
442
+ typeof UnknownSubcommand,
443
+ typeof UserError
444
+ ]
445
+ > = Schema.Union([
446
+ UnrecognizedOption,
447
+ DuplicateOption,
448
+ MissingOption,
449
+ MissingArgument,
450
+ InvalidValue,
451
+ UnknownSubcommand,
452
+ UserError
453
+ ])
454
+
455
+ /**
456
+ * Control flow indicator when help is requested via --help flag.
457
+ * This is not an error but uses the error channel for control flow.
458
+ *
459
+ * @since 4.0.0
460
+ * @category models
461
+ */
462
+ export class ShowHelp extends Schema.ErrorClass(`${TypeId}/ShowHelp`)({
463
+ _tag: Schema.tag("ShowHelp"),
464
+ commandPath: Schema.Array(Schema.String),
465
+ errors: Schema.Array(NonShowHelpErrors)
466
+ }) {
467
+ readonly [TypeId] = TypeId
468
+
469
+ override readonly [Runtime.errorExitCode] = this.errors.length ? 1 : 0
470
+ override readonly [Runtime.errorReported] = false
471
+
472
+ override get message() {
473
+ return "Help requested"
474
+ }
475
+ }