effect 4.0.0-beta.83 → 4.0.0-beta.85

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 (235) hide show
  1. package/dist/Array.d.ts +64 -64
  2. package/dist/Array.js +26 -26
  3. package/dist/Cache.d.ts +1 -1
  4. package/dist/Cache.js +1 -1
  5. package/dist/Cause.d.ts +68 -68
  6. package/dist/Cause.js +47 -47
  7. package/dist/Channel.d.ts +5 -5
  8. package/dist/Channel.js +3 -3
  9. package/dist/Clock.d.ts +1 -1
  10. package/dist/Clock.js +1 -1
  11. package/dist/Combiner.d.ts +9 -9
  12. package/dist/Combiner.js +8 -8
  13. package/dist/Config.d.ts +15 -94
  14. package/dist/Config.d.ts.map +1 -1
  15. package/dist/Config.js +22 -70
  16. package/dist/Config.js.map +1 -1
  17. package/dist/ConfigProvider.d.ts +58 -74
  18. package/dist/ConfigProvider.d.ts.map +1 -1
  19. package/dist/ConfigProvider.js +66 -41
  20. package/dist/ConfigProvider.js.map +1 -1
  21. package/dist/Console.d.ts +1 -1
  22. package/dist/Console.js +1 -1
  23. package/dist/Context.d.ts.map +1 -1
  24. package/dist/Context.js +4 -3
  25. package/dist/Context.js.map +1 -1
  26. package/dist/Data.d.ts +15 -15
  27. package/dist/Data.js +3 -3
  28. package/dist/DateTime.d.ts +6 -6
  29. package/dist/DateTime.js +2 -2
  30. package/dist/Duration.d.ts +3 -3
  31. package/dist/Duration.js +3 -3
  32. package/dist/Effect.d.ts +84 -45
  33. package/dist/Effect.d.ts.map +1 -1
  34. package/dist/Effect.js +72 -33
  35. package/dist/Effect.js.map +1 -1
  36. package/dist/Equal.d.ts +7 -7
  37. package/dist/Equal.js +5 -5
  38. package/dist/Equivalence.d.ts +17 -17
  39. package/dist/Equivalence.js +13 -13
  40. package/dist/Exit.d.ts +3 -3
  41. package/dist/Exit.js +3 -3
  42. package/dist/Formatter.d.ts +5 -5
  43. package/dist/Formatter.js +4 -4
  44. package/dist/Function.d.ts +10 -10
  45. package/dist/Function.js +3 -3
  46. package/dist/HashMap.d.ts +3 -3
  47. package/dist/HashMap.js +1 -1
  48. package/dist/Iterable.d.ts +6 -6
  49. package/dist/Iterable.js +2 -2
  50. package/dist/JsonPatch.d.ts +2 -2
  51. package/dist/Layer.d.ts +1 -1
  52. package/dist/Layer.js +5 -4
  53. package/dist/Layer.js.map +1 -1
  54. package/dist/LayerMap.d.ts.map +1 -1
  55. package/dist/LayerMap.js +4 -3
  56. package/dist/LayerMap.js.map +1 -1
  57. package/dist/Logger.d.ts +1 -1
  58. package/dist/Logger.js +1 -1
  59. package/dist/Match.d.ts +8 -8
  60. package/dist/Match.js +8 -8
  61. package/dist/Metric.d.ts +3 -3
  62. package/dist/Metric.js +3 -3
  63. package/dist/Optic.d.ts +30 -30
  64. package/dist/Optic.js +12 -12
  65. package/dist/Option.d.ts +7 -7
  66. package/dist/Option.js +7 -7
  67. package/dist/Order.d.ts +23 -23
  68. package/dist/Order.js +20 -20
  69. package/dist/Pool.d.ts +1 -1
  70. package/dist/Pool.js +1 -1
  71. package/dist/Predicate.d.ts +88 -88
  72. package/dist/Predicate.js +47 -47
  73. package/dist/PubSub.d.ts +3 -3
  74. package/dist/PubSub.js +3 -3
  75. package/dist/Random.d.ts +31 -0
  76. package/dist/Random.d.ts.map +1 -1
  77. package/dist/Random.js +32 -0
  78. package/dist/Random.js.map +1 -1
  79. package/dist/Reducer.d.ts +1 -1
  80. package/dist/Reducer.js +1 -1
  81. package/dist/Result.d.ts +18 -18
  82. package/dist/Result.js +8 -8
  83. package/dist/Runtime.d.ts +1 -1
  84. package/dist/Runtime.js +1 -1
  85. package/dist/Schema.d.ts +313 -126
  86. package/dist/Schema.d.ts.map +1 -1
  87. package/dist/Schema.js +316 -127
  88. package/dist/Schema.js.map +1 -1
  89. package/dist/SchemaAST.d.ts +9 -8
  90. package/dist/SchemaAST.d.ts.map +1 -1
  91. package/dist/SchemaAST.js +203 -140
  92. package/dist/SchemaAST.js.map +1 -1
  93. package/dist/SchemaGetter.d.ts +48 -48
  94. package/dist/SchemaGetter.js +44 -44
  95. package/dist/SchemaIssue.d.ts +3 -3
  96. package/dist/SchemaIssue.js +3 -3
  97. package/dist/SchemaParser.d.ts +122 -22
  98. package/dist/SchemaParser.d.ts.map +1 -1
  99. package/dist/SchemaParser.js +186 -50
  100. package/dist/SchemaParser.js.map +1 -1
  101. package/dist/SchemaRepresentation.d.ts +1 -1
  102. package/dist/SchemaRepresentation.d.ts.map +1 -1
  103. package/dist/SchemaRepresentation.js +96 -2
  104. package/dist/SchemaRepresentation.js.map +1 -1
  105. package/dist/SchemaTransformation.d.ts +20 -20
  106. package/dist/SchemaTransformation.js +18 -18
  107. package/dist/Stream.d.ts +3 -3
  108. package/dist/Stream.js +2 -2
  109. package/dist/Stream.js.map +1 -1
  110. package/dist/String.d.ts +1 -1
  111. package/dist/String.js +1 -1
  112. package/dist/Struct.d.ts +1 -1
  113. package/dist/Struct.js +1 -1
  114. package/dist/Types.d.ts +13 -13
  115. package/dist/internal/effect.js +33 -20
  116. package/dist/internal/effect.js.map +1 -1
  117. package/dist/internal/schema/arbitrary.js +17 -1
  118. package/dist/internal/schema/arbitrary.js.map +1 -1
  119. package/dist/internal/schema/cause.d.ts +2 -0
  120. package/dist/internal/schema/cause.d.ts.map +1 -0
  121. package/dist/internal/schema/cause.js +24 -0
  122. package/dist/internal/schema/cause.js.map +1 -0
  123. package/dist/internal/schema/schema.d.ts +8 -4
  124. package/dist/internal/schema/schema.d.ts.map +1 -1
  125. package/dist/internal/schema/schema.js +21 -8
  126. package/dist/internal/schema/schema.js.map +1 -1
  127. package/dist/internal/stackTraceLimit.d.ts +2 -0
  128. package/dist/internal/stackTraceLimit.d.ts.map +1 -0
  129. package/dist/internal/stackTraceLimit.js +40 -0
  130. package/dist/internal/stackTraceLimit.js.map +1 -0
  131. package/dist/internal/tracer.d.ts.map +1 -1
  132. package/dist/internal/tracer.js +4 -3
  133. package/dist/internal/tracer.js.map +1 -1
  134. package/dist/testing/TestSchema.d.ts +3 -3
  135. package/dist/testing/TestSchema.js +1 -1
  136. package/dist/unstable/ai/AiError.d.ts +1 -1
  137. package/dist/unstable/ai/AiError.js +1 -1
  138. package/dist/unstable/ai/Chat.d.ts +1 -1
  139. package/dist/unstable/ai/Chat.js +1 -1
  140. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  141. package/dist/unstable/ai/Tool.js +4 -5
  142. package/dist/unstable/ai/Tool.js.map +1 -1
  143. package/dist/unstable/cli/Prompt.js +2 -2
  144. package/dist/unstable/cli/Prompt.js.map +1 -1
  145. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  146. package/dist/unstable/httpapi/HttpApiMiddleware.js +4 -3
  147. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  148. package/dist/unstable/httpapi/HttpApiScalar.d.ts +2 -2
  149. package/dist/unstable/persistence/PersistedQueue.js +1 -1
  150. package/dist/unstable/rpc/Rpc.d.ts +1 -1
  151. package/dist/unstable/rpc/Rpc.js +1 -1
  152. package/dist/unstable/rpc/RpcGroup.d.ts.map +1 -1
  153. package/dist/unstable/rpc/RpcGroup.js +3 -4
  154. package/dist/unstable/rpc/RpcGroup.js.map +1 -1
  155. package/dist/unstable/rpc/RpcMiddleware.d.ts.map +1 -1
  156. package/dist/unstable/rpc/RpcMiddleware.js +4 -3
  157. package/dist/unstable/rpc/RpcMiddleware.js.map +1 -1
  158. package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
  159. package/dist/unstable/sql/SqlResolver.js +15 -2
  160. package/dist/unstable/sql/SqlResolver.js.map +1 -1
  161. package/dist/unstable/workflow/Activity.d.ts +1 -0
  162. package/dist/unstable/workflow/Activity.d.ts.map +1 -1
  163. package/dist/unstable/workflow/Activity.js +1 -0
  164. package/dist/unstable/workflow/Activity.js.map +1 -1
  165. package/dist/unstable/workflow/WorkflowEngine.js +1 -1
  166. package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
  167. package/package.json +1 -1
  168. package/src/Array.ts +65 -65
  169. package/src/Cache.ts +1 -1
  170. package/src/Cause.ts +68 -68
  171. package/src/Channel.ts +5 -5
  172. package/src/Clock.ts +1 -1
  173. package/src/Combiner.ts +9 -9
  174. package/src/Config.ts +40 -108
  175. package/src/ConfigProvider.ts +139 -100
  176. package/src/Console.ts +1 -1
  177. package/src/Context.ts +4 -5
  178. package/src/Data.ts +15 -15
  179. package/src/DateTime.ts +6 -6
  180. package/src/Duration.ts +3 -3
  181. package/src/Effect.ts +89 -45
  182. package/src/Equal.ts +7 -7
  183. package/src/Equivalence.ts +17 -17
  184. package/src/Exit.ts +3 -3
  185. package/src/Formatter.ts +5 -5
  186. package/src/Function.ts +10 -10
  187. package/src/HashMap.ts +3 -3
  188. package/src/Iterable.ts +6 -6
  189. package/src/JsonPatch.ts +2 -2
  190. package/src/Layer.ts +5 -5
  191. package/src/LayerMap.ts +4 -3
  192. package/src/Logger.ts +1 -1
  193. package/src/Match.ts +8 -8
  194. package/src/Metric.ts +3 -3
  195. package/src/Optic.ts +30 -30
  196. package/src/Option.ts +7 -7
  197. package/src/Order.ts +23 -23
  198. package/src/Pool.ts +1 -1
  199. package/src/Predicate.ts +88 -88
  200. package/src/PubSub.ts +3 -3
  201. package/src/Random.ts +42 -0
  202. package/src/Reducer.ts +1 -1
  203. package/src/Result.ts +20 -20
  204. package/src/Runtime.ts +1 -1
  205. package/src/Schema.ts +389 -153
  206. package/src/SchemaAST.ts +237 -148
  207. package/src/SchemaGetter.ts +48 -48
  208. package/src/SchemaIssue.ts +3 -3
  209. package/src/SchemaParser.ts +197 -58
  210. package/src/SchemaRepresentation.ts +73 -3
  211. package/src/SchemaTransformation.ts +20 -20
  212. package/src/Stream.ts +4 -4
  213. package/src/String.ts +1 -1
  214. package/src/Struct.ts +1 -1
  215. package/src/Types.ts +13 -13
  216. package/src/internal/effect.ts +40 -21
  217. package/src/internal/schema/arbitrary.ts +23 -2
  218. package/src/internal/schema/cause.ts +26 -0
  219. package/src/internal/schema/schema.ts +36 -10
  220. package/src/internal/stackTraceLimit.ts +63 -0
  221. package/src/internal/tracer.ts +4 -3
  222. package/src/testing/TestSchema.ts +3 -3
  223. package/src/unstable/ai/AiError.ts +1 -1
  224. package/src/unstable/ai/Chat.ts +1 -1
  225. package/src/unstable/ai/Tool.ts +4 -3
  226. package/src/unstable/cli/Prompt.ts +1 -1
  227. package/src/unstable/httpapi/HttpApiMiddleware.ts +4 -3
  228. package/src/unstable/httpapi/HttpApiScalar.ts +2 -2
  229. package/src/unstable/persistence/PersistedQueue.ts +1 -1
  230. package/src/unstable/rpc/Rpc.ts +1 -1
  231. package/src/unstable/rpc/RpcGroup.ts +3 -4
  232. package/src/unstable/rpc/RpcMiddleware.ts +4 -3
  233. package/src/unstable/sql/SqlResolver.ts +15 -2
  234. package/src/unstable/workflow/Activity.ts +2 -0
  235. package/src/unstable/workflow/WorkflowEngine.ts +1 -1
package/src/SchemaAST.ts CHANGED
@@ -21,10 +21,10 @@ import { memoize } from "./Function.ts"
21
21
  import { effectIsExit, iterateEager } from "./internal/effect.ts"
22
22
  import * as internalRecord from "./internal/record.ts"
23
23
  import * as InternalAnnotations from "./internal/schema/annotations.ts"
24
+ import * as InternalSchemaCause from "./internal/schema/cause.ts"
24
25
  import * as Option from "./Option.ts"
25
26
  import * as Pipeable from "./Pipeable.ts"
26
27
  import * as Predicate from "./Predicate.ts"
27
- import * as RegEx from "./RegExp.ts"
28
28
  import * as Result from "./Result.ts"
29
29
  import type * as Schema from "./Schema.ts"
30
30
  import * as SchemaGetter from "./SchemaGetter.ts"
@@ -678,7 +678,7 @@ export class Declaration extends Base {
678
678
  return Effect.mapEager(run(oinput.value, this, options), Option.some)
679
679
  }
680
680
  }
681
- private rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
681
+ private _rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
682
682
  const tps = mapOrSame(this.typeParameters, recur)
683
683
  return tps === this.typeParameters ?
684
684
  this :
@@ -686,11 +686,11 @@ export class Declaration extends Base {
686
686
  }
687
687
  /** @internal */
688
688
  recur(recur: (ast: AST) => AST) {
689
- return this.rebuild(recur, this.checks, this.encodingChecks)
689
+ return this._rebuild(recur, this.checks, this.encodingChecks)
690
690
  }
691
691
  /** @internal */
692
692
  flip(recur: (ast: AST) => AST) {
693
- return this.rebuild(recur, this.encodingChecks, this.checks)
693
+ return this._rebuild(recur, this.encodingChecks, this.checks)
694
694
  }
695
695
  /** @internal */
696
696
  getExpected(): string {
@@ -1065,11 +1065,12 @@ function isTemplateLiteralPart(ast: AST): ast is TemplateLiteralPart {
1065
1065
  case "String":
1066
1066
  case "Number":
1067
1067
  case "BigInt":
1068
+ return true
1068
1069
  case "Literal":
1069
1070
  case "TemplateLiteral":
1070
- return true
1071
+ return ast.checks === undefined
1071
1072
  case "Union":
1072
- return ast.types.every(isTemplateLiteralPart)
1073
+ return ast.checks === undefined && ast.types.every(isTemplateLiteralPart)
1073
1074
  default:
1074
1075
  return false
1075
1076
  }
@@ -1081,8 +1082,7 @@ function isTemplateLiteralPart(ast: AST): ast is TemplateLiteralPart {
1081
1082
  *
1082
1083
  * **Details**
1083
1084
  *
1084
- * `parts` is an array of AST nodes; each part contributes to the
1085
- * template literal pattern. A regex is derived from the parts to validate
1085
+ * `parts` is an array of AST nodes; each part contributes to matching
1086
1086
  * strings at runtime.
1087
1087
  *
1088
1088
  * @see {@link isTemplateLiteral}
@@ -1129,19 +1129,22 @@ export class TemplateLiteral extends Base {
1129
1129
  return "string"
1130
1130
  }
1131
1131
  /** @internal */
1132
+ matchPart(s: string, options: ParseOptions): string | undefined {
1133
+ return segmentTemplateLiteralParts(this.encodedParts, s, options) === undefined ? undefined : s
1134
+ }
1135
+ /** @internal */
1132
1136
  asTemplateLiteralParser(): Arrays {
1133
- const tuple = new Arrays(false, this.parts.map(templateLiteralPartFromString), [])
1134
- const regExp = getTemplateLiteralRegExp(this)
1137
+ const tuple = new Arrays(false, this.parts.map(partFromString), [])
1135
1138
  return decodeTo(
1136
1139
  string,
1137
1140
  tuple,
1138
1141
  new SchemaTransformation.Transformation(
1139
- SchemaGetter.transformOrFail((s: string) => {
1140
- const match = regExp.exec(s)
1141
- if (match) return Effect.succeed(match.slice(1, this.parts.length + 1))
1142
+ SchemaGetter.transformOrFail((s: string, options) => {
1143
+ const segments = segmentTemplateLiteralParts(this.encodedParts, s, options)
1144
+ if (segments !== undefined) return Effect.succeed(segments)
1142
1145
  return Effect.fail(
1143
1146
  new SchemaIssue.InvalidValue(Option.some(s), {
1144
- message: `Expected a value matching ${regExp.source}, got ${format(s)}`
1147
+ message: `Expected a string matching template literal parts, got ${format(s)}`
1145
1148
  })
1146
1149
  )
1147
1150
  }),
@@ -1247,6 +1250,10 @@ export class Literal extends Base {
1247
1250
  return fromConst(this, this.literal)
1248
1251
  }
1249
1252
  /** @internal */
1253
+ matchPart(s: string, _options: ParseOptions): LiteralValue | undefined {
1254
+ return s === globalThis.String(this.literal) ? this.literal : undefined
1255
+ }
1256
+ /** @internal */
1250
1257
  toCodecJson(): AST {
1251
1258
  return typeof this.literal === "bigint" ? literalToString(this) : this
1252
1259
  }
@@ -1289,6 +1296,10 @@ export class String extends Base {
1289
1296
  return fromRefinement(this, Predicate.isString)
1290
1297
  }
1291
1298
  /** @internal */
1299
+ matchPart(s: string, options: ParseOptions): string | undefined {
1300
+ return applyTemplateLiteralPartChecks(this, s, options)
1301
+ }
1302
+ /** @internal */
1292
1303
  getExpected(): string {
1293
1304
  return "string"
1294
1305
  }
@@ -1335,6 +1346,19 @@ export class Number extends Base {
1335
1346
  return fromRefinement(this, Predicate.isNumber)
1336
1347
  }
1337
1348
  /** @internal */
1349
+ matchKey(s: string, options: ParseOptions): number | undefined {
1350
+ return this._match(isStringNumberRegExp, s, options)
1351
+ }
1352
+ /** @internal */
1353
+ matchPart(s: string, options: ParseOptions): number | undefined {
1354
+ return this._match(isStringFiniteRegExp, s, options)
1355
+ }
1356
+ private _match(regexp: RegExp, s: string, options: ParseOptions): number | undefined {
1357
+ return regexp.test(s)
1358
+ ? applyTemplateLiteralPartChecks(this, globalThis.Number(s), options)
1359
+ : undefined
1360
+ }
1361
+ /** @internal */
1338
1362
  toCodecJson(): AST {
1339
1363
  if (this.checks && (hasCheck(this.checks, "isFinite") || hasCheck(this.checks, "isInt"))) {
1340
1364
  return this
@@ -1444,6 +1468,10 @@ export class Symbol extends Base {
1444
1468
  return fromRefinement(this, Predicate.isSymbol)
1445
1469
  }
1446
1470
  /** @internal */
1471
+ matchKey(s: symbol, options: ParseOptions): symbol | undefined {
1472
+ return applyTemplateLiteralPartChecks(this, s, options)
1473
+ }
1474
+ /** @internal */
1447
1475
  toCodecStringTree(): AST {
1448
1476
  return replaceEncoding(this, [symbolToString])
1449
1477
  }
@@ -1493,6 +1521,12 @@ export class BigInt extends Base {
1493
1521
  return fromRefinement(this, Predicate.isBigInt)
1494
1522
  }
1495
1523
  /** @internal */
1524
+ matchPart(s: string, options: ParseOptions): bigint | undefined {
1525
+ return isStringBigIntRegExp.test(s)
1526
+ ? applyTemplateLiteralPartChecks(this, globalThis.BigInt(s), options)
1527
+ : undefined
1528
+ }
1529
+ /** @internal */
1496
1530
  toCodecStringTree(): AST {
1497
1531
  return replaceEncoding(this, [bigIntToString])
1498
1532
  }
@@ -1667,7 +1701,7 @@ export class Arrays extends Base {
1667
1701
  return Option.some(state.output)
1668
1702
  })
1669
1703
  }
1670
- private rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
1704
+ private _rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
1671
1705
  const elements = mapOrSame(this.elements, recur)
1672
1706
  const rest = mapOrSame(this.rest, recur)
1673
1707
  return elements === this.elements && rest === this.rest ?
@@ -1685,11 +1719,11 @@ export class Arrays extends Base {
1685
1719
  }
1686
1720
  /** @internal */
1687
1721
  recur(recur: (ast: AST) => AST) {
1688
- return this.rebuild(recur, this.checks, this.encodingChecks)
1722
+ return this._rebuild(recur, this.checks, this.encodingChecks)
1689
1723
  }
1690
1724
  /** @internal */
1691
1725
  flip(recur: (ast: AST) => AST) {
1692
- return this.rebuild(recur, this.encodingChecks, this.checks)
1726
+ return this._rebuild(recur, this.encodingChecks, this.checks)
1693
1727
  }
1694
1728
  /** @internal */
1695
1729
  getExpected(): string {
@@ -1755,16 +1789,24 @@ const wrapPropertyKeyIssue = (
1755
1789
  key: PropertyKey,
1756
1790
  exit: Exit.Failure<any, SchemaIssue.Issue>
1757
1791
  ) => {
1758
- const issueResult = Cause.findError(exit.cause)
1759
- if (Result.isFailure(issueResult)) {
1792
+ if (exit.cause.reasons.length === 0) {
1760
1793
  return exit
1761
1794
  }
1762
- const issue = new SchemaIssue.Pointer([key], issueResult.success)
1795
+ const issue = InternalSchemaCause.getSchemaIssue(exit.cause)
1796
+ if (issue === undefined) {
1797
+ return Exit.failCause(
1798
+ Cause.map(
1799
+ exit.cause,
1800
+ (issue) => new SchemaIssue.Composite(ast, s.oinput, [new SchemaIssue.Pointer([key], issue)])
1801
+ )
1802
+ )
1803
+ }
1804
+ const pointer = new SchemaIssue.Pointer([key], issue)
1763
1805
  if (s.options.errors === "all") {
1764
- if (s.issues) s.issues.push(issue)
1765
- else s.issues = [issue]
1806
+ if (s.issues) s.issues.push(pointer)
1807
+ else s.issues = [pointer]
1766
1808
  } else {
1767
- return Exit.fail(new SchemaIssue.Composite(ast, s.oinput, [issue]))
1809
+ return Exit.fail(new SchemaIssue.Composite(ast, s.oinput, [pointer]))
1768
1810
  }
1769
1811
  }
1770
1812
 
@@ -1774,33 +1816,36 @@ const wrapPropertyKeyIssue = (
1774
1816
  */
1775
1817
  export const FINITE_PATTERN = "[+-]?\\d*\\.?\\d+(?:[Ee][+-]?\\d+)?"
1776
1818
 
1777
- const isNumberStringRegExp = new globalThis.RegExp(`(?:${FINITE_PATTERN}|Infinity|-Infinity|NaN)`)
1778
-
1779
1819
  /**
1780
1820
  * Returns the object keys that match the index signature parameter schema.
1781
1821
  * @internal
1782
1822
  */
1783
1823
  export function getIndexSignatureKeys(
1784
1824
  input: { readonly [x: PropertyKey]: unknown },
1785
- parameter: AST
1825
+ parameter: IndexSignatureParameter,
1826
+ options: ParseOptions = defaultParseOptions
1786
1827
  ): ReadonlyArray<PropertyKey> {
1787
- const encoded = toEncoded(parameter)
1788
- switch (encoded._tag) {
1789
- case "String":
1790
- return Object.keys(input)
1791
- case "TemplateLiteral": {
1792
- const regExp = getTemplateLiteralRegExp(encoded)
1793
- return Object.keys(input).filter((k) => regExp.test(k))
1828
+ let stringKeys: ReadonlyArray<string> | undefined
1829
+ let symbolKeys: ReadonlyArray<symbol> | undefined
1830
+
1831
+ function go(parameter: AST): ReadonlyArray<PropertyKey> {
1832
+ switch (parameter._tag) {
1833
+ case "String":
1834
+ case "TemplateLiteral":
1835
+ return (stringKeys ??= Object.keys(input)).filter((k) => parameter.matchPart(k, options) !== undefined)
1836
+ case "Number":
1837
+ return (stringKeys ??= Object.keys(input)).filter((k) => parameter.matchKey(k, options) !== undefined)
1838
+ case "Symbol":
1839
+ return (symbolKeys ??= Object.getOwnPropertySymbols(input)).filter((k) =>
1840
+ parameter.matchKey(k, options) !== undefined
1841
+ )
1842
+ case "Union":
1843
+ return [...new Set(parameter.types.flatMap(go))]
1844
+ default:
1845
+ return []
1794
1846
  }
1795
- case "Symbol":
1796
- return Object.getOwnPropertySymbols(input)
1797
- case "Number":
1798
- return Object.keys(input).filter((k) => isNumberStringRegExp.test(k))
1799
- case "Union":
1800
- return [...new Set(encoded.types.flatMap((t) => getIndexSignatureKeys(input, t)))]
1801
- default:
1802
- return []
1803
1847
  }
1848
+ return go(parameterFromPropertyKey(toEncoded(parameter)))
1804
1849
  }
1805
1850
 
1806
1851
  /**
@@ -1860,6 +1905,31 @@ export class KeyValueCombiner {
1860
1905
  }
1861
1906
  }
1862
1907
 
1908
+ type IndexSignatureParameter =
1909
+ | String
1910
+ | Number
1911
+ | Symbol
1912
+ | TemplateLiteral
1913
+ | Union<IndexSignatureParameter>
1914
+
1915
+ function isIndexSignatureParameterSide(ast: AST): ast is IndexSignatureParameter {
1916
+ switch (ast._tag) {
1917
+ case "String":
1918
+ case "Number":
1919
+ case "Symbol":
1920
+ case "TemplateLiteral":
1921
+ return true
1922
+ case "Union":
1923
+ return ast.types.every(isIndexSignatureParameterSide)
1924
+ default:
1925
+ return false
1926
+ }
1927
+ }
1928
+
1929
+ function isIndexSignatureParameter(ast: AST): ast is IndexSignatureParameter {
1930
+ return isIndexSignatureParameterSide(ast) && isIndexSignatureParameterSide(toEncoded(ast))
1931
+ }
1932
+
1863
1933
  /**
1864
1934
  * Represents an index signature entry within an {@link Objects} node.
1865
1935
  *
@@ -1886,7 +1956,7 @@ export class KeyValueCombiner {
1886
1956
  * @since 3.10.0
1887
1957
  */
1888
1958
  export class IndexSignature {
1889
- readonly parameter: AST
1959
+ readonly parameter: IndexSignatureParameter
1890
1960
  readonly type: AST
1891
1961
  readonly merge: KeyValueCombiner | undefined
1892
1962
 
@@ -1895,6 +1965,9 @@ export class IndexSignature {
1895
1965
  type: AST,
1896
1966
  merge: KeyValueCombiner | undefined
1897
1967
  ) {
1968
+ if (!isIndexSignatureParameter(parameter)) {
1969
+ throw new Error(`Invalid index signature parameter ${parameter._tag}`)
1970
+ }
1898
1971
  this.parameter = parameter
1899
1972
  this.type = type
1900
1973
  this.merge = merge
@@ -2017,7 +2090,7 @@ export class Objects extends Base {
2017
2090
  s,
2018
2091
  [key, is]
2019
2092
  ) {
2020
- const parserKey = recur(indexSignatureParameterFromString(is.parameter))
2093
+ const parserKey = recur(parameterFromPropertyKey(is.parameter))
2021
2094
  const effKey = parserKey(Option.some(key), s.options)
2022
2095
  const exitKey = (effectIsExit(effKey) ? effKey : yield* Effect.exit(effKey)) as Exit.Exit<
2023
2096
  Option.Option<PropertyKey>,
@@ -2124,7 +2197,7 @@ export class Objects extends Base {
2124
2197
  const keyPairs = Arr.empty<[PropertyKey, IndexSignature]>()
2125
2198
  for (let i = 0; i < indexCount; i++) {
2126
2199
  const is = ast.indexSignatures[i]
2127
- const keys = getIndexSignatureKeys(input, is.parameter)
2200
+ const keys = getIndexSignatureKeys(input, is.parameter, options)
2128
2201
  for (let j = 0; j < keys.length; j++) {
2129
2202
  const key = keys[j]
2130
2203
  keyPairs.push([key, is])
@@ -2151,8 +2224,9 @@ export class Objects extends Base {
2151
2224
  return Option.some(out)
2152
2225
  })
2153
2226
  }
2154
- private rebuild(
2227
+ private _rebuild(
2155
2228
  recur: (ast: AST) => AST,
2229
+ recurParameter: (ast: AST) => AST,
2156
2230
  flipMerge: boolean,
2157
2231
  checks: Checks | undefined,
2158
2232
  encodingChecks: Checks | undefined
@@ -2163,7 +2237,7 @@ export class Objects extends Base {
2163
2237
  })
2164
2238
 
2165
2239
  const indexes = mapOrSame(this.indexSignatures, (is) => {
2166
- const p = recur(is.parameter)
2240
+ const p = recurParameter(is.parameter)
2167
2241
  const t = recur(is.type)
2168
2242
  const merge = flipMerge ? is.merge?.flip() : is.merge
2169
2243
  return p === is.parameter && t === is.type && merge === is.merge
@@ -2185,11 +2259,11 @@ export class Objects extends Base {
2185
2259
  }
2186
2260
  /** @internal */
2187
2261
  flip(recur: (ast: AST) => AST): AST {
2188
- return this.rebuild(recur, true, this.encodingChecks, this.checks)
2262
+ return this._rebuild(recur, recur, true, this.encodingChecks, this.checks)
2189
2263
  }
2190
2264
  /** @internal */
2191
- recur(recur: (ast: AST) => AST): AST {
2192
- return this.rebuild(recur, false, this.checks, this.encodingChecks)
2265
+ recur(recur: (ast: AST) => AST, recurParameter: (ast: AST) => AST = recur): AST {
2266
+ return this._rebuild(recur, recurParameter, false, this.checks, this.encodingChecks)
2193
2267
  }
2194
2268
  /** @internal */
2195
2269
  getExpected(): string {
@@ -2248,14 +2322,10 @@ const parseProperties = iterateEager<{
2248
2322
  }
2249
2323
  })
2250
2324
 
2251
- function mergeChecks(checks: Checks | undefined, b: AST): Checks | undefined {
2252
- if (!checks) {
2253
- return b.checks
2254
- }
2255
- if (!b.checks) {
2256
- return checks
2257
- }
2258
- return [...checks, ...b.checks]
2325
+ function combineChecks(a: Checks | undefined, b: Checks | undefined): Checks | undefined {
2326
+ if (!a) return b
2327
+ if (!b) return a
2328
+ return [...a, ...b]
2259
2329
  }
2260
2330
 
2261
2331
  /** @internal */
@@ -2304,10 +2374,10 @@ export function structWithRest(ast: Objects, records: ReadonlyArray<Objects>): O
2304
2374
  let propertySignatures = ast.propertySignatures
2305
2375
  let indexSignatures = ast.indexSignatures
2306
2376
  let checks = ast.checks
2307
- for (const r of records) {
2308
- propertySignatures = propertySignatures.concat(r.propertySignatures)
2309
- indexSignatures = indexSignatures.concat(r.indexSignatures)
2310
- checks = mergeChecks(checks, r)
2377
+ for (const record of records) {
2378
+ propertySignatures = propertySignatures.concat(record.propertySignatures)
2379
+ indexSignatures = indexSignatures.concat(record.indexSignatures)
2380
+ checks = combineChecks(checks, record.checks)
2311
2381
  }
2312
2382
  return new Objects(propertySignatures, indexSignatures, undefined, checks)
2313
2383
  }
@@ -2589,7 +2659,7 @@ export class Union<A extends AST = AST> extends Base {
2589
2659
  })
2590
2660
  }
2591
2661
  }
2592
- private rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
2662
+ private _rebuild(recur: (ast: AST) => AST, checks: Checks | undefined, encodingChecks: Checks | undefined) {
2593
2663
  const types = mapOrSame(this.types, recur)
2594
2664
  return types === this.types ?
2595
2665
  this :
@@ -2597,11 +2667,19 @@ export class Union<A extends AST = AST> extends Base {
2597
2667
  }
2598
2668
  /** @internal */
2599
2669
  recur(recur: (ast: AST) => AST) {
2600
- return this.rebuild(recur, this.checks, this.encodingChecks)
2670
+ return this._rebuild(recur, this.checks, this.encodingChecks)
2601
2671
  }
2602
2672
  /** @internal */
2603
2673
  flip(recur: (ast: AST) => AST) {
2604
- return this.rebuild(recur, this.encodingChecks, this.checks)
2674
+ return this._rebuild(recur, this.encodingChecks, this.checks)
2675
+ }
2676
+ /** @internal */
2677
+ matchPart(s: string, options: ParseOptions): LiteralValue | undefined {
2678
+ for (const type of this.types) {
2679
+ const out = (type as TemplateLiteralPart).matchPart(s, options)
2680
+ if (out !== undefined) return out
2681
+ }
2682
+ return undefined
2605
2683
  }
2606
2684
  /** @internal */
2607
2685
  getExpected(getExpected: (ast: AST) => string): string {
@@ -2658,12 +2736,12 @@ const parseUnion = iterateEager<{
2658
2736
  },
2659
2737
  step(s, candidate, exit) {
2660
2738
  if (exit._tag === "Failure") {
2661
- const issueResult = Cause.findError(exit.cause)
2662
- if (Result.isFailure(issueResult)) {
2739
+ const issue = InternalSchemaCause.getSchemaIssue(exit.cause)
2740
+ if (issue === undefined) {
2663
2741
  return exit
2664
2742
  }
2665
- if (s.issues) s.issues.push(issueResult.success)
2666
- else s.issues = [issueResult.success]
2743
+ if (s.issues) s.issues.push(issue)
2744
+ else s.issues = [issue]
2667
2745
  } else {
2668
2746
  if (s.out && s.ast.mode === "oneOf") {
2669
2747
  s.successes.push(candidate)
@@ -2723,7 +2801,7 @@ export function memoizeThunk<A>(f: () => A): () => A {
2723
2801
  * define recursive or mutually recursive schemas without infinite loops at
2724
2802
  * construction time.
2725
2803
  *
2726
- * **Example** (Recursive schema AST)
2804
+ * **Example** (Defining recursive schema ASTs)
2727
2805
  *
2728
2806
  * ```ts
2729
2807
  * import { Schema, SchemaAST } from "effect"
@@ -3043,8 +3121,8 @@ export function replaceChecks<A extends AST>(ast: A, checks: Checks | undefined)
3043
3121
  }
3044
3122
 
3045
3123
  /** @internal */
3046
- export function appendChecks<A extends AST>(ast: A, checks: Checks): A {
3047
- return replaceChecks(ast, ast.checks ? [...ast.checks, ...checks] : checks)
3124
+ export function appendChecks<A extends AST>(ast: A, checks: Checks | undefined): A {
3125
+ return replaceChecks(ast, combineChecks(ast.checks, checks))
3048
3126
  }
3049
3127
 
3050
3128
  function updateLastLink(encoding: Encoding, f: (ast: AST) => AST): Encoding {
@@ -3213,39 +3291,31 @@ function parseParameter(ast: AST): {
3213
3291
  literals: ReadonlyArray<PropertyKey>
3214
3292
  parameters: ReadonlyArray<AST>
3215
3293
  } {
3216
- switch (ast._tag) {
3217
- case "Literal":
3218
- return {
3219
- literals: Predicate.isPropertyKey(ast.literal) ? [ast.literal] : [],
3220
- parameters: []
3221
- }
3222
- case "UniqueSymbol":
3223
- return {
3224
- literals: [ast.symbol],
3225
- parameters: []
3226
- }
3227
- case "String":
3228
- case "Number":
3229
- case "Symbol":
3230
- case "TemplateLiteral":
3231
- return {
3232
- literals: [],
3233
- parameters: [ast]
3234
- }
3235
- case "Union": {
3236
- const out: {
3237
- literals: ReadonlyArray<PropertyKey>
3238
- parameters: ReadonlyArray<AST>
3239
- } = { literals: [], parameters: [] }
3240
- for (let i = 0; i < ast.types.length; i++) {
3241
- const parsed = parseParameter(ast.types[i])
3242
- out.literals = out.literals.concat(parsed.literals)
3243
- out.parameters = out.parameters.concat(parsed.parameters)
3244
- }
3245
- return out
3294
+ const literals: Array<PropertyKey> = []
3295
+ const parameters: Array<AST> = []
3296
+ function go(ast: AST) {
3297
+ switch (ast._tag) {
3298
+ case "Literal":
3299
+ if (Predicate.isPropertyKey(ast.literal)) {
3300
+ literals.push(ast.literal)
3301
+ }
3302
+ return
3303
+ case "UniqueSymbol":
3304
+ literals.push(ast.symbol)
3305
+ return
3306
+ case "Never":
3307
+ return
3308
+ case "Union":
3309
+ for (let i = 0; i < ast.types.length; i++) {
3310
+ go(ast.types[i])
3311
+ }
3312
+ return
3313
+ default:
3314
+ parameters.push(ast)
3246
3315
  }
3247
3316
  }
3248
- return { literals: [], parameters: [] }
3317
+ go(ast)
3318
+ return { literals, parameters }
3249
3319
  }
3250
3320
 
3251
3321
  /** @internal */
@@ -3407,45 +3477,6 @@ export function containsUndefined(ast: AST): boolean {
3407
3477
  }
3408
3478
  }
3409
3479
 
3410
- function getTemplateLiteralSource(ast: TemplateLiteral, top: boolean): string {
3411
- return ast.encodedParts.map((part) =>
3412
- handleTemplateLiteralASTPartParens(part, getTemplateLiteralASTPartPattern(part), top)
3413
- ).join("")
3414
- }
3415
-
3416
- /** @internal */
3417
- export const getTemplateLiteralRegExp = memoize((ast: TemplateLiteral): RegExp => {
3418
- return new globalThis.RegExp(`^${getTemplateLiteralSource(ast, true)}$`)
3419
- })
3420
-
3421
- function getTemplateLiteralASTPartPattern(part: TemplateLiteralPart): string {
3422
- switch (part._tag) {
3423
- case "Literal":
3424
- return RegEx.escape(globalThis.String(part.literal))
3425
- case "String":
3426
- return STRING_PATTERN
3427
- case "Number":
3428
- return FINITE_PATTERN
3429
- case "BigInt":
3430
- return BIGINT_PATTERN
3431
- case "TemplateLiteral":
3432
- return getTemplateLiteralSource(part, false)
3433
- case "Union":
3434
- return part.types.map(getTemplateLiteralASTPartPattern).join("|")
3435
- }
3436
- }
3437
-
3438
- function handleTemplateLiteralASTPartParens(part: TemplateLiteralPart, s: string, top: boolean): string {
3439
- if (isUnion(part)) {
3440
- if (!top) {
3441
- return `(?:${s})`
3442
- }
3443
- } else if (!top) {
3444
- return s
3445
- }
3446
- return `(${s})`
3447
- }
3448
-
3449
3480
  function fromConst<const T>(
3450
3481
  ast: AST,
3451
3482
  value: T
@@ -3475,6 +3506,52 @@ function fromRefinement<T>(
3475
3506
  }
3476
3507
  }
3477
3508
 
3509
+ function applyTemplateLiteralPartChecks<A>(ast: AST, value: A, options: ParseOptions): A | undefined {
3510
+ if (options?.disableChecks || ast.checks === undefined) return value
3511
+ const issues: Array<SchemaIssue.Issue> = []
3512
+ collectIssues(ast.checks, value, issues, ast, options)
3513
+ return issues.length === 0 ? value : undefined
3514
+ }
3515
+
3516
+ function segmentTemplateLiteralParts(
3517
+ parts: ReadonlyArray<TemplateLiteralPart>,
3518
+ input: string,
3519
+ options: ParseOptions
3520
+ ): Array<string> | undefined {
3521
+ const out = new Array<string>(parts.length)
3522
+ const failures = new Set<string>()
3523
+ function go(i: number, pos: number): boolean {
3524
+ if (i === parts.length) return pos === input.length
3525
+ const key = `${i}/${pos}`
3526
+ if (failures.has(key)) return false
3527
+ const part = parts[i]
3528
+ if (i === parts.length - 1) {
3529
+ const s = input.slice(pos)
3530
+ if (part.matchPart(s, options) !== undefined) {
3531
+ out[i] = s
3532
+ return true
3533
+ }
3534
+ } else if (part._tag === "Literal") {
3535
+ const s = globalThis.String(part.literal)
3536
+ if (input.startsWith(s, pos) && go(i + 1, pos + s.length)) {
3537
+ out[i] = s
3538
+ return true
3539
+ }
3540
+ } else {
3541
+ for (let end = input.length; end >= pos; end--) {
3542
+ const s = input.slice(pos, end)
3543
+ if (part.matchPart(s, options) !== undefined && go(i + 1, end)) {
3544
+ out[i] = s
3545
+ return true
3546
+ }
3547
+ }
3548
+ }
3549
+ failures.add(key)
3550
+ return false
3551
+ }
3552
+ return go(0, 0) ? out : undefined
3553
+ }
3554
+
3478
3555
  /** @internal */
3479
3556
  export const enumsToLiterals = memoize((ast: Enum): Union<Literal> => {
3480
3557
  return new Union(
@@ -3491,30 +3568,40 @@ export function toCodec(f: (ast: AST) => AST) {
3491
3568
  return memoize(out)
3492
3569
  }
3493
3570
 
3494
- const indexSignatureParameterFromString = toCodec((ast) => {
3571
+ const parameterFromPropertyKey = toCodec((ast) => {
3495
3572
  switch (ast._tag) {
3496
3573
  default:
3497
3574
  return ast
3498
3575
  case "Number":
3499
3576
  return ast.toCodecStringTree()
3500
3577
  case "Union":
3501
- return ast.recur(indexSignatureParameterFromString)
3578
+ return ast.recur(parameterFromPropertyKey)
3502
3579
  }
3503
3580
  })
3504
3581
 
3505
- const templateLiteralPartFromString = toCodec((ast) => {
3582
+ /** @internal */
3583
+ export const parameterFromString = toCodec((ast) => {
3506
3584
  switch (ast._tag) {
3507
3585
  default:
3508
3586
  return ast
3509
- case "String":
3510
- case "TemplateLiteral":
3587
+ case "Symbol":
3588
+ case "UniqueSymbol":
3589
+ return ast.toCodecStringTree()
3590
+ case "Union":
3591
+ return ast.recur(parameterFromString)
3592
+ }
3593
+ })
3594
+
3595
+ const partFromString = toCodec((ast) => {
3596
+ switch (ast._tag) {
3597
+ default:
3511
3598
  return ast
3512
- case "BigInt":
3513
3599
  case "Number":
3514
3600
  case "Literal":
3601
+ case "BigInt":
3515
3602
  return ast.toCodecStringTree()
3516
3603
  case "Union":
3517
- return ast.recur(templateLiteralPartFromString)
3604
+ return ast.recur(partFromString)
3518
3605
  }
3519
3606
  })
3520
3607
 
@@ -3526,6 +3613,8 @@ export const STRING_PATTERN = "[\\s\\S]*?"
3526
3613
 
3527
3614
  const isStringFiniteRegExp = new globalThis.RegExp(`^${FINITE_PATTERN}$`)
3528
3615
 
3616
+ const isStringNumberRegExp = new globalThis.RegExp(`(?:${FINITE_PATTERN}|Infinity|-Infinity|NaN)`)
3617
+
3529
3618
  /** @internal */
3530
3619
  export function isStringFinite(annotations?: Schema.Annotations.Filter) {
3531
3620
  return isPattern(