effect 4.0.0-beta.25 → 4.0.0-beta.26

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 (110) hide show
  1. package/dist/Config.js +4 -4
  2. package/dist/Config.js.map +1 -1
  3. package/dist/Effect.d.ts +20 -13
  4. package/dist/Effect.d.ts.map +1 -1
  5. package/dist/Effect.js +2 -1
  6. package/dist/Effect.js.map +1 -1
  7. package/dist/Runtime.d.ts +66 -0
  8. package/dist/Runtime.d.ts.map +1 -1
  9. package/dist/Runtime.js +72 -5
  10. package/dist/Runtime.js.map +1 -1
  11. package/dist/Schema.d.ts +15 -32
  12. package/dist/Schema.d.ts.map +1 -1
  13. package/dist/Schema.js +9 -17
  14. package/dist/Schema.js.map +1 -1
  15. package/dist/SchemaAST.js +91 -2
  16. package/dist/SchemaAST.js.map +1 -1
  17. package/dist/SchemaGetter.d.ts +3 -3
  18. package/dist/SchemaRepresentation.d.ts.map +1 -1
  19. package/dist/SchemaRepresentation.js +12 -8
  20. package/dist/SchemaRepresentation.js.map +1 -1
  21. package/dist/Stdio.d.ts +10 -2
  22. package/dist/Stdio.d.ts.map +1 -1
  23. package/dist/Stdio.js +18 -0
  24. package/dist/Stdio.js.map +1 -1
  25. package/dist/internal/schema/representation.js +7 -3
  26. package/dist/internal/schema/representation.js.map +1 -1
  27. package/dist/internal/schema/to-codec.js +7 -10
  28. package/dist/internal/schema/to-codec.js.map +1 -1
  29. package/dist/unstable/ai/AiError.d.ts +6 -3
  30. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  31. package/dist/unstable/ai/AiError.js +8 -4
  32. package/dist/unstable/ai/AiError.js.map +1 -1
  33. package/dist/unstable/ai/LanguageModel.js +7 -5
  34. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  35. package/dist/unstable/cli/CliError.d.ts +19 -52
  36. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  37. package/dist/unstable/cli/CliError.js +21 -53
  38. package/dist/unstable/cli/CliError.js.map +1 -1
  39. package/dist/unstable/cli/Command.d.ts +117 -62
  40. package/dist/unstable/cli/Command.d.ts.map +1 -1
  41. package/dist/unstable/cli/Command.js +95 -32
  42. package/dist/unstable/cli/Command.js.map +1 -1
  43. package/dist/unstable/cli/GlobalFlag.d.ts +1 -1
  44. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  45. package/dist/unstable/cli/internal/command.d.ts +27 -10
  46. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  47. package/dist/unstable/cli/internal/command.js +40 -23
  48. package/dist/unstable/cli/internal/command.js.map +1 -1
  49. package/dist/unstable/cli/internal/config.js +42 -0
  50. package/dist/unstable/cli/internal/config.js.map +1 -1
  51. package/dist/unstable/cli/internal/help.d.ts +4 -4
  52. package/dist/unstable/cli/internal/help.d.ts.map +1 -1
  53. package/dist/unstable/cli/internal/help.js +25 -7
  54. package/dist/unstable/cli/internal/help.js.map +1 -1
  55. package/dist/unstable/cli/internal/parser.js +26 -6
  56. package/dist/unstable/cli/internal/parser.js.map +1 -1
  57. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  58. package/dist/unstable/httpapi/HttpApiBuilder.js +1 -7
  59. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  60. package/dist/unstable/httpapi/HttpApiClient.d.ts +6 -6
  61. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  62. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  63. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +10 -10
  64. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  65. package/dist/unstable/httpapi/HttpApiEndpoint.js +2 -2
  66. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  67. package/dist/unstable/httpapi/HttpApiError.d.ts +6 -15
  68. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  69. package/dist/unstable/httpapi/HttpApiError.js +16 -21
  70. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  71. package/dist/unstable/reactivity/Atom.d.ts +56 -0
  72. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  73. package/dist/unstable/reactivity/Atom.js +66 -0
  74. package/dist/unstable/reactivity/Atom.js.map +1 -1
  75. package/dist/unstable/reactivity/AtomHttpApi.d.ts +2 -2
  76. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  77. package/dist/unstable/rpc/RpcServer.d.ts +3 -0
  78. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  79. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  80. package/dist/unstable/sql/SqlSchema.d.ts +2 -2
  81. package/dist/unstable/sql/SqlSchema.d.ts.map +1 -1
  82. package/dist/unstable/sql/SqlSchema.js.map +1 -1
  83. package/package.json +1 -1
  84. package/src/Config.ts +4 -4
  85. package/src/Effect.ts +29 -9
  86. package/src/Runtime.ts +95 -5
  87. package/src/Schema.ts +20 -52
  88. package/src/SchemaAST.ts +127 -2
  89. package/src/SchemaGetter.ts +3 -3
  90. package/src/SchemaRepresentation.ts +12 -8
  91. package/src/Stdio.ts +21 -2
  92. package/src/internal/schema/representation.ts +8 -4
  93. package/src/internal/schema/to-codec.ts +7 -17
  94. package/src/unstable/ai/AiError.ts +8 -4
  95. package/src/unstable/ai/LanguageModel.ts +8 -5
  96. package/src/unstable/cli/CliError.ts +43 -55
  97. package/src/unstable/cli/Command.ts +348 -180
  98. package/src/unstable/cli/GlobalFlag.ts +1 -1
  99. package/src/unstable/cli/internal/command.ts +62 -32
  100. package/src/unstable/cli/internal/config.ts +49 -0
  101. package/src/unstable/cli/internal/help.ts +41 -16
  102. package/src/unstable/cli/internal/parser.ts +36 -10
  103. package/src/unstable/httpapi/HttpApiBuilder.ts +1 -7
  104. package/src/unstable/httpapi/HttpApiClient.ts +6 -6
  105. package/src/unstable/httpapi/HttpApiEndpoint.ts +4 -4
  106. package/src/unstable/httpapi/HttpApiError.ts +23 -21
  107. package/src/unstable/reactivity/Atom.ts +132 -0
  108. package/src/unstable/reactivity/AtomHttpApi.ts +2 -2
  109. package/src/unstable/rpc/RpcServer.ts +5 -0
  110. package/src/unstable/sql/SqlSchema.ts +2 -2
package/src/Schema.ts CHANGED
@@ -8667,11 +8667,11 @@ export function toJsonSchemaDocument(schema: Top, options?: ToJsonSchemaOptions)
8667
8667
  }
8668
8668
 
8669
8669
  // -----------------------------------------------------------------------------
8670
- // Serializer
8670
+ // Canonical Codecs
8671
8671
  // -----------------------------------------------------------------------------
8672
8672
 
8673
8673
  /**
8674
- * @category Serializer
8674
+ * @category Canonical Codecs
8675
8675
  * @since 4.0.0
8676
8676
  */
8677
8677
  export function toCodecJson<T, E, RD, RE>(schema: Codec<T, E, RD, RE>): Codec<T, unknown, RD, RE> {
@@ -8679,7 +8679,7 @@ export function toCodecJson<T, E, RD, RE>(schema: Codec<T, E, RD, RE>): Codec<T,
8679
8679
  }
8680
8680
 
8681
8681
  /**
8682
- * @category Serializer
8682
+ * @category Canonical Codecs
8683
8683
  * @since 4.0.0
8684
8684
  */
8685
8685
  export function toCodecIso<S extends Top>(schema: S): Codec<S["Type"], S["Iso"]> {
@@ -8687,13 +8687,13 @@ export function toCodecIso<S extends Top>(schema: S): Codec<S["Type"], S["Iso"]>
8687
8687
  }
8688
8688
 
8689
8689
  /**
8690
- * @category Serializer
8690
+ * @category Canonical Codecs
8691
8691
  * @since 4.0.0
8692
8692
  */
8693
8693
  export type StringTree = Tree<string | undefined>
8694
8694
 
8695
8695
  /**
8696
- * The StringTree serializer converts **every leaf value to a string**, while
8696
+ * The StringTree canonical codec converts **every leaf value to a string**, while
8697
8697
  * preserving the original structure.
8698
8698
  *
8699
8699
  * Declarations are converted to `undefined` (unless they have a
@@ -8707,7 +8707,7 @@ export type StringTree = Tree<string | undefined>
8707
8707
  *
8708
8708
  * Defaults to `false`.
8709
8709
  *
8710
- * @category Serializer
8710
+ * @category Canonical Codecs
8711
8711
  * @since 4.0.0
8712
8712
  */
8713
8713
  export function toCodecStringTree<T, E, RD, RE>(schema: Codec<T, E, RD, RE>): Codec<T, StringTree, RD, RE>
@@ -8740,7 +8740,7 @@ type XmlEncoderOptions = {
8740
8740
  }
8741
8741
 
8742
8742
  /**
8743
- * @category Serializer
8743
+ * @category Canonical Codecs
8744
8744
  * @since 4.0.0
8745
8745
  */
8746
8746
  export function toEncoderXml<T, E, RD, RE>(
@@ -8860,8 +8860,6 @@ function serializerTree(
8860
8860
  onMissingAnnotation: (ast: AST.AST) => AST.AST
8861
8861
  ): AST.AST {
8862
8862
  switch (ast._tag) {
8863
- case "Unknown":
8864
- case "ObjectKeyword":
8865
8863
  case "Declaration": {
8866
8864
  const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec
8867
8865
  if (Predicate.isFunction(getLink)) {
@@ -8878,6 +8876,9 @@ function serializerTree(
8878
8876
  return AST.replaceEncoding(ast, [nullToString])
8879
8877
  case "Boolean":
8880
8878
  return AST.replaceEncoding(ast, [booleanToString])
8879
+ case "Unknown":
8880
+ case "ObjectKeyword":
8881
+ return AST.replaceEncoding(ast, [AST.unknownToStringTree])
8881
8882
  case "Enum":
8882
8883
  case "Number":
8883
8884
  case "Literal":
@@ -9104,13 +9105,13 @@ export function toDifferJsonPatch<T, E>(schema: Codec<T, E>): Differ<T, JsonPatc
9104
9105
  * @category Tree
9105
9106
  * @since 4.0.0
9106
9107
  */
9107
- export type Tree<Node> = Node | TreeObject<Node> | ReadonlyArray<Tree<Node>>
9108
+ export type Tree<Node> = Node | TreeRecord<Node> | ReadonlyArray<Tree<Node>>
9108
9109
 
9109
9110
  /**
9110
9111
  * @category Tree
9111
9112
  * @since 4.0.0
9112
9113
  */
9113
- export interface TreeObject<A> {
9114
+ export interface TreeRecord<A> {
9114
9115
  readonly [x: string]: Tree<A>
9115
9116
  }
9116
9117
 
@@ -9133,51 +9134,12 @@ export function Tree<S extends Top>(node: S) {
9133
9134
  return Tree
9134
9135
  }
9135
9136
 
9136
- /**
9137
- * @category Tree
9138
- * @since 4.0.0
9139
- */
9140
- export type MutableTree<A> = A | MutableTreeRecord<A> | Array<MutableTree<A>>
9141
-
9142
- /**
9143
- * @category Tree
9144
- * @since 4.0.0
9145
- */
9146
- export interface MutableTreeRecord<A> {
9147
- [x: string]: MutableTree<A>
9148
- }
9149
-
9150
- /**
9151
- * @category Tree
9152
- * @since 4.0.0
9153
- */
9154
- export function MutableTree<S extends Top>(node: S) {
9155
- const MutableTree$ref = suspend((): Codec<
9156
- MutableTree<S["Type"]>,
9157
- MutableTree<S["Encoded"]>,
9158
- S["DecodingServices"],
9159
- S["EncodingServices"]
9160
- > => MutableTree)
9161
- const MutableTree = Union([
9162
- node,
9163
- mutable(Array(MutableTree$ref)),
9164
- Record(String, mutableKey(MutableTree$ref))
9165
- ])
9166
- return MutableTree
9167
- }
9168
-
9169
9137
  /**
9170
9138
  * @category JSON
9171
9139
  * @since 4.0.0
9172
9140
  */
9173
9141
  export type Json = null | number | boolean | string | JsonArray | JsonObject
9174
9142
 
9175
- /**
9176
- * @category JSON
9177
- * @since 4.0.0
9178
- */
9179
- export const Json: Codec<Json> = Tree(Union([Null, Number, Boolean, String]))
9180
-
9181
9143
  /**
9182
9144
  * @category JSON
9183
9145
  * @since 4.0.0
@@ -9196,13 +9158,13 @@ export interface JsonObject {
9196
9158
  * @category JSON
9197
9159
  * @since 4.0.0
9198
9160
  */
9199
- export type MutableJson = null | number | boolean | string | MutableJsonArray | MutableJsonObject
9161
+ export const Json: Codec<Json> = make(AST.Json)
9200
9162
 
9201
9163
  /**
9202
9164
  * @category JSON
9203
9165
  * @since 4.0.0
9204
9166
  */
9205
- export const MutableJson: Codec<MutableJson> = MutableTree(Union([Null, Number, Boolean, String]))
9167
+ export type MutableJson = null | number | boolean | string | MutableJsonArray | MutableJsonObject
9206
9168
 
9207
9169
  /**
9208
9170
  * @category JSON
@@ -9218,6 +9180,12 @@ export interface MutableJsonObject {
9218
9180
  [x: string]: MutableJson
9219
9181
  }
9220
9182
 
9183
+ /**
9184
+ * @category JSON
9185
+ * @since 4.0.0
9186
+ */
9187
+ export const MutableJson: Codec<MutableJson> = make(AST.MutableJson)
9188
+
9221
9189
  // -----------------------------------------------------------------------------
9222
9190
  // Annotations
9223
9191
  // -----------------------------------------------------------------------------
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
+ )
@@ -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