@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2

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 (452) hide show
  1. package/SourceLocation/package.json +6 -0
  2. package/dist/cjs/Effect.js +2 -28
  3. package/dist/cjs/Effect.js.map +1 -1
  4. package/dist/cjs/FiberRef.js +12 -1
  5. package/dist/cjs/FiberRef.js.map +1 -1
  6. package/dist/cjs/Layer.js +2 -24
  7. package/dist/cjs/Layer.js.map +1 -1
  8. package/dist/cjs/RuntimeFlags.js +1 -29
  9. package/dist/cjs/RuntimeFlags.js.map +1 -1
  10. package/dist/cjs/SourceLocation.js +60 -0
  11. package/dist/cjs/SourceLocation.js.map +1 -0
  12. package/dist/cjs/Tracer.js +1 -15
  13. package/dist/cjs/Tracer.js.map +1 -1
  14. package/dist/cjs/Utils.js +1 -1
  15. package/dist/cjs/Utils.js.map +1 -1
  16. package/dist/cjs/index.js +3 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/clock.js +1 -1
  19. package/dist/cjs/internal/clock.js.map +1 -1
  20. package/dist/cjs/internal/core.js +17 -50
  21. package/dist/cjs/internal/core.js.map +1 -1
  22. package/dist/cjs/internal/effect/circular.js +18 -30
  23. package/dist/cjs/internal/effect/circular.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +16 -65
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +1 -5
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +1 -3
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/logger.js +25 -2
  31. package/dist/cjs/internal/logger.js.map +1 -1
  32. package/dist/cjs/internal/runtimeFlags.js +2 -11
  33. package/dist/cjs/internal/runtimeFlags.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +1 -114
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/dts/Config.d.ts +2 -2
  37. package/dist/dts/Config.d.ts.map +1 -1
  38. package/dist/dts/Effect.d.ts +8 -29
  39. package/dist/dts/Effect.d.ts.map +1 -1
  40. package/dist/dts/FiberRef.d.ts +12 -0
  41. package/dist/dts/FiberRef.d.ts.map +1 -1
  42. package/dist/dts/Layer.d.ts +0 -22
  43. package/dist/dts/Layer.d.ts.map +1 -1
  44. package/dist/dts/RuntimeFlags.d.ts +0 -28
  45. package/dist/dts/RuntimeFlags.d.ts.map +1 -1
  46. package/dist/dts/SourceLocation.d.ts +88 -0
  47. package/dist/dts/SourceLocation.d.ts.map +1 -0
  48. package/dist/dts/Tracer.d.ts +0 -15
  49. package/dist/dts/Tracer.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +6 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/layer.d.ts.map +1 -1
  54. package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
  55. package/dist/esm/Effect.js +0 -26
  56. package/dist/esm/Effect.js.map +1 -1
  57. package/dist/esm/FiberRef.js +11 -0
  58. package/dist/esm/FiberRef.js.map +1 -1
  59. package/dist/esm/Layer.js +0 -22
  60. package/dist/esm/Layer.js.map +1 -1
  61. package/dist/esm/RuntimeFlags.js +0 -28
  62. package/dist/esm/RuntimeFlags.js.map +1 -1
  63. package/dist/esm/SourceLocation.js +51 -0
  64. package/dist/esm/SourceLocation.js.map +1 -0
  65. package/dist/esm/Tracer.js +0 -14
  66. package/dist/esm/Tracer.js.map +1 -1
  67. package/dist/esm/Utils.js +1 -1
  68. package/dist/esm/Utils.js.map +1 -1
  69. package/dist/esm/index.js +6 -0
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/internal/clock.js +1 -1
  72. package/dist/esm/internal/clock.js.map +1 -1
  73. package/dist/esm/internal/core.js +12 -45
  74. package/dist/esm/internal/core.js.map +1 -1
  75. package/dist/esm/internal/effect/circular.js +18 -30
  76. package/dist/esm/internal/effect/circular.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +13 -60
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/layer/circular.js +0 -4
  80. package/dist/esm/internal/layer/circular.js.map +1 -1
  81. package/dist/esm/internal/layer.js +0 -2
  82. package/dist/esm/internal/layer.js.map +1 -1
  83. package/dist/esm/internal/logger.js +25 -2
  84. package/dist/esm/internal/logger.js.map +1 -1
  85. package/dist/esm/internal/runtimeFlags.js +1 -9
  86. package/dist/esm/internal/runtimeFlags.js.map +1 -1
  87. package/dist/esm/internal/tracer.js +0 -111
  88. package/dist/esm/internal/tracer.js.map +1 -1
  89. package/package.json +12 -1
  90. package/src/Arbitrary.ts +1101 -0
  91. package/src/Array.ts +3589 -0
  92. package/src/BigDecimal.ts +1349 -0
  93. package/src/BigInt.ts +643 -0
  94. package/src/Boolean.ts +287 -0
  95. package/src/Brand.ts +360 -0
  96. package/src/Cache.ts +281 -0
  97. package/src/Cause.ts +1555 -0
  98. package/src/Channel.ts +2355 -0
  99. package/src/ChildExecutorDecision.ts +146 -0
  100. package/src/Chunk.ts +1495 -0
  101. package/src/Clock.ts +111 -0
  102. package/src/Config.ts +542 -0
  103. package/src/ConfigError.ts +270 -0
  104. package/src/ConfigProvider.ts +333 -0
  105. package/src/ConfigProviderPathPatch.ts +100 -0
  106. package/src/Console.ts +226 -0
  107. package/src/Context.ts +585 -0
  108. package/src/Cron.ts +706 -0
  109. package/src/Data.ts +596 -0
  110. package/src/DateTime.ts +1686 -0
  111. package/src/DefaultServices.ts +34 -0
  112. package/src/Deferred.ts +301 -0
  113. package/src/Differ.ts +450 -0
  114. package/src/Duration.ts +1000 -0
  115. package/src/Effect.ts +14817 -0
  116. package/src/Effectable.ts +107 -0
  117. package/src/Either.ts +1040 -0
  118. package/src/Encoding.ts +195 -0
  119. package/src/Equal.ts +98 -0
  120. package/src/Equivalence.ts +235 -0
  121. package/src/ExecutionPlan.ts +308 -0
  122. package/src/ExecutionStrategy.ts +119 -0
  123. package/src/Exit.ts +467 -0
  124. package/src/FastCheck.ts +9 -0
  125. package/src/Fiber.ts +744 -0
  126. package/src/FiberHandle.ts +540 -0
  127. package/src/FiberId.ts +195 -0
  128. package/src/FiberMap.ts +656 -0
  129. package/src/FiberRef.ts +444 -0
  130. package/src/FiberRefs.ts +204 -0
  131. package/src/FiberRefsPatch.ts +105 -0
  132. package/src/FiberSet.ts +491 -0
  133. package/src/FiberStatus.ts +108 -0
  134. package/src/Function.ts +1222 -0
  135. package/src/GlobalValue.ts +53 -0
  136. package/src/Graph.ts +3732 -0
  137. package/src/GroupBy.ts +103 -0
  138. package/src/HKT.ts +45 -0
  139. package/src/Hash.ts +195 -0
  140. package/src/HashMap.ts +519 -0
  141. package/src/HashRing.ts +317 -0
  142. package/src/HashSet.ts +2346 -0
  143. package/src/Inspectable.ts +287 -0
  144. package/src/Iterable.ts +1119 -0
  145. package/src/JSONSchema.ts +1044 -0
  146. package/src/KeyedPool.ts +167 -0
  147. package/src/Layer.ts +1228 -0
  148. package/src/LayerMap.ts +436 -0
  149. package/src/List.ts +977 -0
  150. package/src/LogLevel.ts +285 -0
  151. package/src/LogSpan.ts +25 -0
  152. package/src/Logger.ts +702 -0
  153. package/src/Mailbox.ts +268 -0
  154. package/src/ManagedRuntime.ts +180 -0
  155. package/src/Match.ts +1477 -0
  156. package/src/MergeDecision.ts +95 -0
  157. package/src/MergeState.ts +172 -0
  158. package/src/MergeStrategy.ts +107 -0
  159. package/src/Metric.ts +780 -0
  160. package/src/MetricBoundaries.ts +69 -0
  161. package/src/MetricHook.ts +151 -0
  162. package/src/MetricKey.ts +224 -0
  163. package/src/MetricKeyType.ts +262 -0
  164. package/src/MetricLabel.ts +47 -0
  165. package/src/MetricPair.ts +71 -0
  166. package/src/MetricPolling.ts +148 -0
  167. package/src/MetricRegistry.ts +48 -0
  168. package/src/MetricState.ts +257 -0
  169. package/src/Micro.ts +4405 -0
  170. package/src/ModuleVersion.ts +18 -0
  171. package/src/MutableHashMap.ts +411 -0
  172. package/src/MutableHashSet.ts +706 -0
  173. package/src/MutableList.ts +297 -0
  174. package/src/MutableQueue.ts +227 -0
  175. package/src/MutableRef.ts +202 -0
  176. package/src/NonEmptyIterable.ts +32 -0
  177. package/src/Number.ts +1071 -0
  178. package/src/Option.ts +2170 -0
  179. package/src/Order.ts +373 -0
  180. package/src/Ordering.ts +111 -0
  181. package/src/ParseResult.ts +2031 -0
  182. package/src/PartitionedSemaphore.ts +200 -0
  183. package/src/Pipeable.ts +566 -0
  184. package/src/Pool.ts +204 -0
  185. package/src/Predicate.ts +1405 -0
  186. package/src/Pretty.ts +205 -0
  187. package/src/PrimaryKey.ts +23 -0
  188. package/src/PubSub.ts +182 -0
  189. package/src/Queue.ts +644 -0
  190. package/src/Random.ts +204 -0
  191. package/src/RateLimiter.ts +138 -0
  192. package/src/RcMap.ts +141 -0
  193. package/src/RcRef.ts +122 -0
  194. package/src/Readable.ts +93 -0
  195. package/src/Record.ts +1274 -0
  196. package/src/RedBlackTree.ts +421 -0
  197. package/src/Redacted.ts +144 -0
  198. package/src/Ref.ts +180 -0
  199. package/src/RegExp.ts +38 -0
  200. package/src/Reloadable.ts +127 -0
  201. package/src/Request.ts +347 -0
  202. package/src/RequestBlock.ts +118 -0
  203. package/src/RequestResolver.ts +366 -0
  204. package/src/Resource.ts +119 -0
  205. package/src/Runtime.ts +383 -0
  206. package/src/RuntimeFlags.ts +336 -0
  207. package/src/RuntimeFlagsPatch.ts +183 -0
  208. package/src/STM.ts +2045 -0
  209. package/src/Schedule.ts +2219 -0
  210. package/src/ScheduleDecision.ts +62 -0
  211. package/src/ScheduleInterval.ts +151 -0
  212. package/src/ScheduleIntervals.ts +122 -0
  213. package/src/Scheduler.ts +353 -0
  214. package/src/Schema.ts +10914 -0
  215. package/src/SchemaAST.ts +3043 -0
  216. package/src/Scope.ts +204 -0
  217. package/src/ScopedCache.ts +151 -0
  218. package/src/ScopedRef.ts +117 -0
  219. package/src/Secret.ts +88 -0
  220. package/src/SingleProducerAsyncInput.ts +67 -0
  221. package/src/Sink.ts +1461 -0
  222. package/src/SortedMap.ts +287 -0
  223. package/src/SortedSet.ts +390 -0
  224. package/src/SourceLocation.ts +108 -0
  225. package/src/Stream.ts +6468 -0
  226. package/src/StreamEmit.ts +136 -0
  227. package/src/StreamHaltStrategy.ts +123 -0
  228. package/src/Streamable.ts +45 -0
  229. package/src/String.ts +778 -0
  230. package/src/Struct.ts +243 -0
  231. package/src/Subscribable.ts +100 -0
  232. package/src/SubscriptionRef.ts +298 -0
  233. package/src/Supervisor.ts +240 -0
  234. package/src/Symbol.ts +29 -0
  235. package/src/SynchronizedRef.ts +270 -0
  236. package/src/TArray.ts +495 -0
  237. package/src/TDeferred.ts +100 -0
  238. package/src/TMap.ts +515 -0
  239. package/src/TPriorityQueue.ts +223 -0
  240. package/src/TPubSub.ts +200 -0
  241. package/src/TQueue.ts +432 -0
  242. package/src/TRandom.ts +129 -0
  243. package/src/TReentrantLock.ts +224 -0
  244. package/src/TRef.ts +178 -0
  245. package/src/TSemaphore.ts +129 -0
  246. package/src/TSet.ts +365 -0
  247. package/src/TSubscriptionRef.ts +192 -0
  248. package/src/Take.ts +258 -0
  249. package/src/TestAnnotation.ts +158 -0
  250. package/src/TestAnnotationMap.ts +119 -0
  251. package/src/TestAnnotations.ts +117 -0
  252. package/src/TestClock.ts +556 -0
  253. package/src/TestConfig.ts +47 -0
  254. package/src/TestContext.ts +36 -0
  255. package/src/TestLive.ts +53 -0
  256. package/src/TestServices.ts +390 -0
  257. package/src/TestSized.ts +55 -0
  258. package/src/Tracer.ts +182 -0
  259. package/src/Trie.ts +840 -0
  260. package/src/Tuple.ts +305 -0
  261. package/src/Types.ts +353 -0
  262. package/src/Unify.ts +113 -0
  263. package/src/UpstreamPullRequest.ts +117 -0
  264. package/src/UpstreamPullStrategy.ts +121 -0
  265. package/src/Utils.ts +809 -0
  266. package/src/index.ts +1568 -0
  267. package/src/internal/array.ts +8 -0
  268. package/src/internal/blockedRequests.ts +520 -0
  269. package/src/internal/cache.ts +733 -0
  270. package/src/internal/cause.ts +1050 -0
  271. package/src/internal/channel/channelExecutor.ts +1200 -0
  272. package/src/internal/channel/channelState.ts +134 -0
  273. package/src/internal/channel/childExecutorDecision.ts +96 -0
  274. package/src/internal/channel/continuation.ts +200 -0
  275. package/src/internal/channel/mergeDecision.ts +113 -0
  276. package/src/internal/channel/mergeState.ts +120 -0
  277. package/src/internal/channel/mergeStrategy.ts +72 -0
  278. package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
  279. package/src/internal/channel/subexecutor.ts +229 -0
  280. package/src/internal/channel/upstreamPullRequest.ts +84 -0
  281. package/src/internal/channel/upstreamPullStrategy.ts +87 -0
  282. package/src/internal/channel.ts +2603 -0
  283. package/src/internal/clock.ts +95 -0
  284. package/src/internal/completedRequestMap.ts +9 -0
  285. package/src/internal/concurrency.ts +54 -0
  286. package/src/internal/config.ts +716 -0
  287. package/src/internal/configError.ts +304 -0
  288. package/src/internal/configProvider/pathPatch.ts +97 -0
  289. package/src/internal/configProvider.ts +799 -0
  290. package/src/internal/console.ts +153 -0
  291. package/src/internal/context.ts +337 -0
  292. package/src/internal/core-effect.ts +2293 -0
  293. package/src/internal/core-stream.ts +998 -0
  294. package/src/internal/core.ts +3189 -0
  295. package/src/internal/data.ts +36 -0
  296. package/src/internal/dataSource.ts +327 -0
  297. package/src/internal/dateTime.ts +1277 -0
  298. package/src/internal/defaultServices/console.ts +100 -0
  299. package/src/internal/defaultServices.ts +163 -0
  300. package/src/internal/deferred.ts +46 -0
  301. package/src/internal/differ/chunkPatch.ts +211 -0
  302. package/src/internal/differ/contextPatch.ts +232 -0
  303. package/src/internal/differ/hashMapPatch.ts +220 -0
  304. package/src/internal/differ/hashSetPatch.ts +176 -0
  305. package/src/internal/differ/orPatch.ts +311 -0
  306. package/src/internal/differ/readonlyArrayPatch.ts +210 -0
  307. package/src/internal/differ.ts +200 -0
  308. package/src/internal/doNotation.ts +80 -0
  309. package/src/internal/effect/circular.ts +895 -0
  310. package/src/internal/effectable.ts +131 -0
  311. package/src/internal/either.ts +110 -0
  312. package/src/internal/encoding/base64.ts +286 -0
  313. package/src/internal/encoding/base64Url.ts +29 -0
  314. package/src/internal/encoding/common.ts +51 -0
  315. package/src/internal/encoding/hex.ts +315 -0
  316. package/src/internal/errors.ts +7 -0
  317. package/src/internal/executionPlan.ts +114 -0
  318. package/src/internal/executionStrategy.ts +74 -0
  319. package/src/internal/fiber.ts +388 -0
  320. package/src/internal/fiberId.ts +267 -0
  321. package/src/internal/fiberMessage.ts +82 -0
  322. package/src/internal/fiberRefs/patch.ts +144 -0
  323. package/src/internal/fiberRefs.ts +297 -0
  324. package/src/internal/fiberRuntime.ts +3842 -0
  325. package/src/internal/fiberScope.ts +71 -0
  326. package/src/internal/fiberStatus.ts +119 -0
  327. package/src/internal/groupBy.ts +530 -0
  328. package/src/internal/hashMap/array.ts +49 -0
  329. package/src/internal/hashMap/bitwise.ts +32 -0
  330. package/src/internal/hashMap/config.ts +14 -0
  331. package/src/internal/hashMap/keySet.ts +8 -0
  332. package/src/internal/hashMap/node.ts +391 -0
  333. package/src/internal/hashMap.ts +586 -0
  334. package/src/internal/hashSet.ts +323 -0
  335. package/src/internal/keyedPool.ts +244 -0
  336. package/src/internal/layer/circular.ts +214 -0
  337. package/src/internal/layer.ts +1483 -0
  338. package/src/internal/logSpan.ts +20 -0
  339. package/src/internal/logger-circular.ts +24 -0
  340. package/src/internal/logger.ts +522 -0
  341. package/src/internal/mailbox.ts +561 -0
  342. package/src/internal/managedRuntime/circular.ts +6 -0
  343. package/src/internal/managedRuntime.ts +134 -0
  344. package/src/internal/matcher.ts +652 -0
  345. package/src/internal/metric/boundaries.ts +75 -0
  346. package/src/internal/metric/hook.ts +483 -0
  347. package/src/internal/metric/key.ts +167 -0
  348. package/src/internal/metric/keyType.ts +238 -0
  349. package/src/internal/metric/label.ts +41 -0
  350. package/src/internal/metric/pair.ts +48 -0
  351. package/src/internal/metric/polling.ts +149 -0
  352. package/src/internal/metric/registry.ts +187 -0
  353. package/src/internal/metric/state.ts +290 -0
  354. package/src/internal/metric.ts +577 -0
  355. package/src/internal/opCodes/cause.ts +35 -0
  356. package/src/internal/opCodes/channel.ts +83 -0
  357. package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
  358. package/src/internal/opCodes/channelMergeDecision.ts +11 -0
  359. package/src/internal/opCodes/channelMergeState.ts +17 -0
  360. package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
  361. package/src/internal/opCodes/channelState.ts +23 -0
  362. package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
  363. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
  364. package/src/internal/opCodes/config.ts +65 -0
  365. package/src/internal/opCodes/configError.ts +35 -0
  366. package/src/internal/opCodes/continuation.ts +11 -0
  367. package/src/internal/opCodes/deferred.ts +11 -0
  368. package/src/internal/opCodes/effect.ts +89 -0
  369. package/src/internal/opCodes/layer.ts +59 -0
  370. package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
  371. package/src/internal/option.ts +80 -0
  372. package/src/internal/pool.ts +432 -0
  373. package/src/internal/pubsub.ts +1762 -0
  374. package/src/internal/query.ts +204 -0
  375. package/src/internal/queue.ts +766 -0
  376. package/src/internal/random.ts +161 -0
  377. package/src/internal/rateLimiter.ts +93 -0
  378. package/src/internal/rcMap.ts +285 -0
  379. package/src/internal/rcRef.ts +192 -0
  380. package/src/internal/redBlackTree/iterator.ts +200 -0
  381. package/src/internal/redBlackTree/node.ts +68 -0
  382. package/src/internal/redBlackTree.ts +1245 -0
  383. package/src/internal/redacted.ts +73 -0
  384. package/src/internal/ref.ts +171 -0
  385. package/src/internal/reloadable.ts +140 -0
  386. package/src/internal/request.ts +177 -0
  387. package/src/internal/resource.ts +76 -0
  388. package/src/internal/ringBuffer.ts +68 -0
  389. package/src/internal/runtime.ts +558 -0
  390. package/src/internal/runtimeFlags.ts +178 -0
  391. package/src/internal/runtimeFlagsPatch.ts +103 -0
  392. package/src/internal/schedule/decision.ts +47 -0
  393. package/src/internal/schedule/interval.ts +101 -0
  394. package/src/internal/schedule/intervals.ts +180 -0
  395. package/src/internal/schedule.ts +2199 -0
  396. package/src/internal/schema/errors.ts +191 -0
  397. package/src/internal/schema/schemaId.ts +106 -0
  398. package/src/internal/schema/util.ts +50 -0
  399. package/src/internal/scopedCache.ts +644 -0
  400. package/src/internal/scopedRef.ts +118 -0
  401. package/src/internal/secret.ts +89 -0
  402. package/src/internal/singleShotGen.ts +35 -0
  403. package/src/internal/sink.ts +2120 -0
  404. package/src/internal/stack.ts +10 -0
  405. package/src/internal/stm/core.ts +817 -0
  406. package/src/internal/stm/entry.ts +59 -0
  407. package/src/internal/stm/journal.ts +123 -0
  408. package/src/internal/stm/opCodes/stm.ts +71 -0
  409. package/src/internal/stm/opCodes/stmState.ts +17 -0
  410. package/src/internal/stm/opCodes/strategy.ts +17 -0
  411. package/src/internal/stm/opCodes/tExit.ts +29 -0
  412. package/src/internal/stm/opCodes/tryCommit.ts +11 -0
  413. package/src/internal/stm/stm.ts +1453 -0
  414. package/src/internal/stm/stmState.ts +136 -0
  415. package/src/internal/stm/tArray.ts +550 -0
  416. package/src/internal/stm/tDeferred.ts +81 -0
  417. package/src/internal/stm/tExit.ts +190 -0
  418. package/src/internal/stm/tMap.ts +824 -0
  419. package/src/internal/stm/tPriorityQueue.ts +267 -0
  420. package/src/internal/stm/tPubSub.ts +551 -0
  421. package/src/internal/stm/tQueue.ts +393 -0
  422. package/src/internal/stm/tRandom.ts +140 -0
  423. package/src/internal/stm/tReentrantLock.ts +352 -0
  424. package/src/internal/stm/tRef.ts +195 -0
  425. package/src/internal/stm/tSemaphore.ts +113 -0
  426. package/src/internal/stm/tSet.ts +259 -0
  427. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  428. package/src/internal/stm/tryCommit.ts +34 -0
  429. package/src/internal/stm/txnId.ts +14 -0
  430. package/src/internal/stm/versioned.ts +4 -0
  431. package/src/internal/stream/debounceState.ts +57 -0
  432. package/src/internal/stream/emit.ts +123 -0
  433. package/src/internal/stream/haltStrategy.ts +94 -0
  434. package/src/internal/stream/handoff.ts +187 -0
  435. package/src/internal/stream/handoffSignal.ts +59 -0
  436. package/src/internal/stream/pull.ts +34 -0
  437. package/src/internal/stream/sinkEndReason.ts +30 -0
  438. package/src/internal/stream/zipAllState.ts +88 -0
  439. package/src/internal/stream/zipChunksState.ts +56 -0
  440. package/src/internal/stream.ts +8801 -0
  441. package/src/internal/string-utils.ts +107 -0
  442. package/src/internal/subscriptionRef.ts +138 -0
  443. package/src/internal/supervisor/patch.ts +190 -0
  444. package/src/internal/supervisor.ts +303 -0
  445. package/src/internal/synchronizedRef.ts +114 -0
  446. package/src/internal/take.ts +199 -0
  447. package/src/internal/testing/sleep.ts +27 -0
  448. package/src/internal/testing/suspendedWarningData.ts +85 -0
  449. package/src/internal/testing/warningData.ts +94 -0
  450. package/src/internal/tracer.ts +150 -0
  451. package/src/internal/trie.ts +722 -0
  452. package/src/internal/version.ts +7 -0
@@ -0,0 +1,3043 @@
1
+ /**
2
+ * @since 3.10.0
3
+ */
4
+
5
+ import * as Arr from "./Array.js"
6
+ import type { Effect } from "./Effect.js"
7
+ import type { Equivalence } from "./Equivalence.js"
8
+ import { dual, identity } from "./Function.js"
9
+ import { globalValue } from "./GlobalValue.js"
10
+ import * as Inspectable from "./Inspectable.js"
11
+ import * as errors_ from "./internal/schema/errors.js"
12
+ import * as util_ from "./internal/schema/util.js"
13
+ import * as Number from "./Number.js"
14
+ import * as Option from "./Option.js"
15
+ import * as Order from "./Order.js"
16
+ import type { ParseIssue } from "./ParseResult.js"
17
+ import * as Predicate from "./Predicate.js"
18
+ import * as regexp from "./RegExp.js"
19
+ import type { Concurrency } from "./Types.js"
20
+
21
+ /**
22
+ * @category model
23
+ * @since 3.10.0
24
+ */
25
+ export type AST =
26
+ | Declaration
27
+ | Literal
28
+ | UniqueSymbol
29
+ | UndefinedKeyword
30
+ | VoidKeyword
31
+ | NeverKeyword
32
+ | UnknownKeyword
33
+ | AnyKeyword
34
+ | StringKeyword
35
+ | NumberKeyword
36
+ | BooleanKeyword
37
+ | BigIntKeyword
38
+ | SymbolKeyword
39
+ | ObjectKeyword
40
+ | Enums
41
+ | TemplateLiteral
42
+ // possible transformations
43
+ | Refinement
44
+ | TupleType
45
+ | TypeLiteral
46
+ | Union
47
+ | Suspend
48
+ // transformations
49
+ | Transformation
50
+
51
+ // -------------------------------------------------------------------------------------
52
+ // annotations
53
+ // -------------------------------------------------------------------------------------
54
+
55
+ /**
56
+ * @category annotations
57
+ * @since 3.19.0
58
+ * @experimental
59
+ */
60
+ export type TypeConstructorAnnotation = {
61
+ readonly _tag: string
62
+ [key: PropertyKey]: unknown
63
+ }
64
+
65
+ /**
66
+ * @category annotations
67
+ * @since 3.19.0
68
+ * @experimental
69
+ */
70
+ export const TypeConstructorAnnotationId: unique symbol = Symbol.for("effect/annotation/TypeConstructor")
71
+
72
+ /**
73
+ * @category annotations
74
+ * @since 3.10.0
75
+ */
76
+ export type BrandAnnotation = Arr.NonEmptyReadonlyArray<string | symbol>
77
+
78
+ /**
79
+ * @category annotations
80
+ * @since 3.10.0
81
+ */
82
+ export const BrandAnnotationId: unique symbol = Symbol.for("effect/annotation/Brand")
83
+
84
+ /**
85
+ * @category annotations
86
+ * @since 3.10.0
87
+ */
88
+ export type SchemaIdAnnotation = string | symbol
89
+
90
+ /**
91
+ * @category annotations
92
+ * @since 3.10.0
93
+ */
94
+ export const SchemaIdAnnotationId: unique symbol = Symbol.for("effect/annotation/SchemaId")
95
+
96
+ /**
97
+ * @category annotations
98
+ * @since 3.10.0
99
+ */
100
+ export type MessageAnnotation = (issue: ParseIssue) => string | Effect<string> | {
101
+ readonly message: string | Effect<string>
102
+ readonly override: boolean
103
+ }
104
+
105
+ /**
106
+ * @category annotations
107
+ * @since 3.10.0
108
+ */
109
+ export const MessageAnnotationId: unique symbol = Symbol.for("effect/annotation/Message")
110
+
111
+ /**
112
+ * @category annotations
113
+ * @since 3.10.0
114
+ */
115
+ export type MissingMessageAnnotation = () => string | Effect<string>
116
+
117
+ /**
118
+ * @category annotations
119
+ * @since 3.10.0
120
+ */
121
+ export const MissingMessageAnnotationId: unique symbol = Symbol.for("effect/annotation/MissingMessage")
122
+
123
+ /**
124
+ * @category annotations
125
+ * @since 3.10.0
126
+ */
127
+ export type IdentifierAnnotation = string
128
+
129
+ /**
130
+ * @category annotations
131
+ * @since 3.10.0
132
+ */
133
+ export const IdentifierAnnotationId: unique symbol = Symbol.for("effect/annotation/Identifier")
134
+
135
+ /**
136
+ * @category annotations
137
+ * @since 3.10.0
138
+ */
139
+ export type TitleAnnotation = string
140
+
141
+ /**
142
+ * @category annotations
143
+ * @since 3.10.0
144
+ */
145
+ export const TitleAnnotationId: unique symbol = Symbol.for("effect/annotation/Title")
146
+
147
+ /** @internal */
148
+ export const AutoTitleAnnotationId: unique symbol = Symbol.for("effect/annotation/AutoTitle")
149
+
150
+ /**
151
+ * @category annotations
152
+ * @since 3.10.0
153
+ */
154
+ export type DescriptionAnnotation = string
155
+
156
+ /**
157
+ * @category annotations
158
+ * @since 3.10.0
159
+ */
160
+ export const DescriptionAnnotationId: unique symbol = Symbol.for("effect/annotation/Description")
161
+
162
+ /**
163
+ * @category annotations
164
+ * @since 3.10.0
165
+ */
166
+ export type ExamplesAnnotation<A> = Arr.NonEmptyReadonlyArray<A>
167
+
168
+ /**
169
+ * @category annotations
170
+ * @since 3.10.0
171
+ */
172
+ export const ExamplesAnnotationId: unique symbol = Symbol.for("effect/annotation/Examples")
173
+
174
+ /**
175
+ * @category annotations
176
+ * @since 3.10.0
177
+ */
178
+ export type DefaultAnnotation<A> = A
179
+
180
+ /**
181
+ * @category annotations
182
+ * @since 3.10.0
183
+ */
184
+ export const DefaultAnnotationId: unique symbol = Symbol.for("effect/annotation/Default")
185
+
186
+ /**
187
+ * @category annotations
188
+ * @since 3.10.0
189
+ */
190
+ export type JSONSchemaAnnotation = object
191
+
192
+ /**
193
+ * @category annotations
194
+ * @since 3.10.0
195
+ */
196
+ export const JSONSchemaAnnotationId: unique symbol = Symbol.for("effect/annotation/JSONSchema")
197
+
198
+ /**
199
+ * @category annotations
200
+ * @since 3.10.0
201
+ */
202
+ export const ArbitraryAnnotationId: unique symbol = Symbol.for("effect/annotation/Arbitrary")
203
+
204
+ /**
205
+ * @category annotations
206
+ * @since 3.10.0
207
+ */
208
+ export const PrettyAnnotationId: unique symbol = Symbol.for("effect/annotation/Pretty")
209
+
210
+ /**
211
+ * @category annotations
212
+ * @since 3.10.0
213
+ */
214
+ export type EquivalenceAnnotation<A, TypeParameters extends ReadonlyArray<any> = readonly []> = (
215
+ ...equivalences: { readonly [K in keyof TypeParameters]: Equivalence<TypeParameters[K]> }
216
+ ) => Equivalence<A>
217
+
218
+ /**
219
+ * @category annotations
220
+ * @since 3.10.0
221
+ */
222
+ export const EquivalenceAnnotationId: unique symbol = Symbol.for("effect/annotation/Equivalence")
223
+
224
+ /**
225
+ * @category annotations
226
+ * @since 3.10.0
227
+ */
228
+ export type DocumentationAnnotation = string
229
+
230
+ /**
231
+ * @category annotations
232
+ * @since 3.10.0
233
+ */
234
+ export const DocumentationAnnotationId: unique symbol = Symbol.for("effect/annotation/Documentation")
235
+
236
+ /**
237
+ * @category annotations
238
+ * @since 3.10.0
239
+ */
240
+ export type ConcurrencyAnnotation = Concurrency | undefined
241
+
242
+ /**
243
+ * @category annotations
244
+ * @since 3.10.0
245
+ */
246
+ export const ConcurrencyAnnotationId: unique symbol = Symbol.for("effect/annotation/Concurrency")
247
+
248
+ /**
249
+ * @category annotations
250
+ * @since 3.10.0
251
+ */
252
+ export type BatchingAnnotation = boolean | "inherit" | undefined
253
+
254
+ /**
255
+ * @category annotations
256
+ * @since 3.10.0
257
+ */
258
+ export const BatchingAnnotationId: unique symbol = Symbol.for("effect/annotation/Batching")
259
+
260
+ /**
261
+ * @category annotations
262
+ * @since 3.10.0
263
+ */
264
+ export type ParseIssueTitleAnnotation = (issue: ParseIssue) => string | undefined
265
+
266
+ /**
267
+ * @category annotations
268
+ * @since 3.10.0
269
+ */
270
+ export const ParseIssueTitleAnnotationId: unique symbol = Symbol.for("effect/annotation/ParseIssueTitle")
271
+
272
+ /**
273
+ * @category annotations
274
+ * @since 3.10.0
275
+ */
276
+ export const ParseOptionsAnnotationId: unique symbol = Symbol.for("effect/annotation/ParseOptions")
277
+
278
+ /**
279
+ * @category annotations
280
+ * @since 3.10.0
281
+ */
282
+ export type DecodingFallbackAnnotation<A> = (issue: ParseIssue) => Effect<A, ParseIssue>
283
+
284
+ /**
285
+ * @category annotations
286
+ * @since 3.10.0
287
+ */
288
+ export const DecodingFallbackAnnotationId: unique symbol = Symbol.for("effect/annotation/DecodingFallback")
289
+
290
+ /**
291
+ * @category annotations
292
+ * @since 3.10.0
293
+ */
294
+ export const SurrogateAnnotationId: unique symbol = Symbol.for("effect/annotation/Surrogate")
295
+
296
+ /**
297
+ * @category annotations
298
+ * @since 3.10.0
299
+ */
300
+ export type SurrogateAnnotation = AST
301
+
302
+ /** @internal */
303
+ export const StableFilterAnnotationId: unique symbol = Symbol.for("effect/annotation/StableFilter")
304
+
305
+ /**
306
+ * A stable filter consistently applies fixed validation rules, such as
307
+ * 'minItems', 'maxItems', and 'itemsCount', to ensure array length complies
308
+ * with set criteria regardless of the input data's content.
309
+ *
310
+ * @internal
311
+ */
312
+ export type StableFilterAnnotation = boolean
313
+
314
+ /**
315
+ * @category annotations
316
+ * @since 3.10.0
317
+ */
318
+ export interface Annotations {
319
+ readonly [_: string]: unknown
320
+ readonly [_: symbol]: unknown
321
+ }
322
+
323
+ /**
324
+ * @category annotations
325
+ * @since 3.10.0
326
+ */
327
+ export interface Annotated {
328
+ readonly annotations: Annotations
329
+ }
330
+
331
+ /**
332
+ * @category annotations
333
+ * @since 3.10.0
334
+ */
335
+ export const getAnnotation: {
336
+ <A>(key: symbol): (annotated: Annotated) => Option.Option<A>
337
+ <A>(annotated: Annotated, key: symbol): Option.Option<A>
338
+ } = dual(
339
+ 2,
340
+ <A>(annotated: Annotated, key: symbol): Option.Option<A> =>
341
+ Object.prototype.hasOwnProperty.call(annotated.annotations, key) ?
342
+ Option.some(annotated.annotations[key] as any) :
343
+ Option.none()
344
+ )
345
+
346
+ /**
347
+ * @category annotations
348
+ * @since 3.19.0
349
+ * @experimental
350
+ */
351
+ export const getTypeConstructorAnnotation = getAnnotation<TypeConstructorAnnotation>(TypeConstructorAnnotationId)
352
+
353
+ /**
354
+ * @category annotations
355
+ * @since 3.10.0
356
+ */
357
+ export const getBrandAnnotation = getAnnotation<BrandAnnotation>(BrandAnnotationId)
358
+
359
+ /**
360
+ * @category annotations
361
+ * @since 3.14.2
362
+ */
363
+ export const getSchemaIdAnnotation = getAnnotation<SchemaIdAnnotation>(SchemaIdAnnotationId)
364
+
365
+ /**
366
+ * @category annotations
367
+ * @since 3.10.0
368
+ */
369
+ export const getMessageAnnotation = getAnnotation<MessageAnnotation>(MessageAnnotationId)
370
+
371
+ /**
372
+ * @category annotations
373
+ * @since 3.10.0
374
+ */
375
+ export const getMissingMessageAnnotation = getAnnotation<MissingMessageAnnotation>(MissingMessageAnnotationId)
376
+
377
+ /**
378
+ * @category annotations
379
+ * @since 3.10.0
380
+ */
381
+ export const getTitleAnnotation = getAnnotation<TitleAnnotation>(TitleAnnotationId)
382
+
383
+ /** @internal */
384
+ export const getAutoTitleAnnotation = getAnnotation<TitleAnnotation>(AutoTitleAnnotationId)
385
+
386
+ /**
387
+ * @category annotations
388
+ * @since 3.10.0
389
+ */
390
+ export const getIdentifierAnnotation = getAnnotation<IdentifierAnnotation>(IdentifierAnnotationId)
391
+
392
+ /**
393
+ * @category annotations
394
+ * @since 3.10.0
395
+ */
396
+ export const getDescriptionAnnotation = getAnnotation<DescriptionAnnotation>(DescriptionAnnotationId)
397
+
398
+ /**
399
+ * @category annotations
400
+ * @since 3.10.0
401
+ */
402
+ export const getExamplesAnnotation = getAnnotation<ExamplesAnnotation<unknown>>(ExamplesAnnotationId)
403
+
404
+ /**
405
+ * @category annotations
406
+ * @since 3.10.0
407
+ */
408
+ export const getDefaultAnnotation = getAnnotation<DefaultAnnotation<unknown>>(DefaultAnnotationId)
409
+
410
+ /**
411
+ * @category annotations
412
+ * @since 3.10.0
413
+ */
414
+ export const getJSONSchemaAnnotation = getAnnotation<JSONSchemaAnnotation>(JSONSchemaAnnotationId)
415
+
416
+ /**
417
+ * @category annotations
418
+ * @since 3.10.0
419
+ */
420
+ export const getDocumentationAnnotation = getAnnotation<DocumentationAnnotation>(DocumentationAnnotationId)
421
+
422
+ /**
423
+ * @category annotations
424
+ * @since 3.10.0
425
+ */
426
+ export const getConcurrencyAnnotation = getAnnotation<ConcurrencyAnnotation>(ConcurrencyAnnotationId)
427
+
428
+ /**
429
+ * @category annotations
430
+ * @since 3.10.0
431
+ */
432
+ export const getBatchingAnnotation = getAnnotation<BatchingAnnotation>(BatchingAnnotationId)
433
+
434
+ /**
435
+ * @category annotations
436
+ * @since 3.10.0
437
+ */
438
+ export const getParseIssueTitleAnnotation = getAnnotation<ParseIssueTitleAnnotation>(ParseIssueTitleAnnotationId)
439
+
440
+ /**
441
+ * @category annotations
442
+ * @since 3.10.0
443
+ */
444
+ export const getParseOptionsAnnotation = getAnnotation<ParseOptions>(ParseOptionsAnnotationId)
445
+
446
+ /**
447
+ * @category annotations
448
+ * @since 3.10.0
449
+ */
450
+ export const getDecodingFallbackAnnotation = getAnnotation<DecodingFallbackAnnotation<unknown>>(
451
+ DecodingFallbackAnnotationId
452
+ )
453
+
454
+ /**
455
+ * @category annotations
456
+ * @since 3.10.0
457
+ */
458
+ export const getSurrogateAnnotation = getAnnotation<SurrogateAnnotation>(SurrogateAnnotationId)
459
+
460
+ const getStableFilterAnnotation = getAnnotation<StableFilterAnnotation>(StableFilterAnnotationId)
461
+
462
+ /** @internal */
463
+ export const hasStableFilter = (annotated: Annotated) =>
464
+ Option.exists(getStableFilterAnnotation(annotated), (b) => b === true)
465
+
466
+ /**
467
+ * @category annotations
468
+ * @since 3.10.0
469
+ */
470
+ export const JSONIdentifierAnnotationId: unique symbol = Symbol.for("effect/annotation/JSONIdentifier")
471
+
472
+ /**
473
+ * @category annotations
474
+ * @since 3.10.0
475
+ */
476
+ export const getJSONIdentifierAnnotation = getAnnotation<IdentifierAnnotation>(JSONIdentifierAnnotationId)
477
+
478
+ /**
479
+ * @category annotations
480
+ * @since 3.10.0
481
+ */
482
+ export const getJSONIdentifier = (annotated: Annotated) =>
483
+ Option.orElse(getJSONIdentifierAnnotation(annotated), () => getIdentifierAnnotation(annotated))
484
+
485
+ // -------------------------------------------------------------------------------------
486
+ // schema ids
487
+ // -------------------------------------------------------------------------------------
488
+
489
+ /**
490
+ * @category schema id
491
+ * @since 3.10.0
492
+ */
493
+ export const ParseJsonSchemaId: unique symbol = Symbol.for("effect/schema/ParseJson")
494
+
495
+ /**
496
+ * @category model
497
+ * @since 3.10.0
498
+ */
499
+ export class Declaration implements Annotated {
500
+ /**
501
+ * @since 3.10.0
502
+ */
503
+ readonly _tag = "Declaration"
504
+ constructor(
505
+ readonly typeParameters: ReadonlyArray<AST>,
506
+ readonly decodeUnknown: (
507
+ ...typeParameters: ReadonlyArray<AST>
508
+ ) => (input: unknown, options: ParseOptions, self: Declaration) => Effect<any, ParseIssue, any>,
509
+ readonly encodeUnknown: (
510
+ ...typeParameters: ReadonlyArray<AST>
511
+ ) => (input: unknown, options: ParseOptions, self: Declaration) => Effect<any, ParseIssue, any>,
512
+ readonly annotations: Annotations = {}
513
+ ) {}
514
+ /**
515
+ * @since 3.10.0
516
+ */
517
+ toString() {
518
+ return Option.getOrElse(getExpected(this), () => "<declaration schema>")
519
+ }
520
+ /**
521
+ * @since 3.10.0
522
+ */
523
+ toJSON(): object {
524
+ return {
525
+ _tag: this._tag,
526
+ typeParameters: this.typeParameters.map((ast) => ast.toJSON()),
527
+ annotations: toJSONAnnotations(this.annotations)
528
+ }
529
+ }
530
+ }
531
+
532
+ const createASTGuard = <T extends AST["_tag"]>(tag: T) => (ast: AST): ast is Extract<AST, { _tag: T }> =>
533
+ ast._tag === tag
534
+
535
+ /**
536
+ * @category guards
537
+ * @since 3.10.0
538
+ */
539
+ export const isDeclaration: (ast: AST) => ast is Declaration = createASTGuard("Declaration")
540
+
541
+ /**
542
+ * @category model
543
+ * @since 3.10.0
544
+ */
545
+ export type LiteralValue = string | number | boolean | null | bigint
546
+
547
+ /**
548
+ * @category model
549
+ * @since 3.10.0
550
+ */
551
+ export class Literal implements Annotated {
552
+ /**
553
+ * @since 3.10.0
554
+ */
555
+ readonly _tag = "Literal"
556
+ constructor(readonly literal: LiteralValue, readonly annotations: Annotations = {}) {}
557
+ /**
558
+ * @since 3.10.0
559
+ */
560
+ toString() {
561
+ return Option.getOrElse(getExpected(this), () => Inspectable.formatUnknown(this.literal))
562
+ }
563
+ /**
564
+ * @since 3.10.0
565
+ */
566
+ toJSON(): object {
567
+ return {
568
+ _tag: this._tag,
569
+ literal: Predicate.isBigInt(this.literal) ? String(this.literal) : this.literal,
570
+ annotations: toJSONAnnotations(this.annotations)
571
+ }
572
+ }
573
+ }
574
+
575
+ /**
576
+ * @category guards
577
+ * @since 3.10.0
578
+ */
579
+ export const isLiteral: (ast: AST) => ast is Literal = createASTGuard("Literal")
580
+
581
+ const $null = new Literal(null)
582
+
583
+ export {
584
+ /**
585
+ * @category constructors
586
+ * @since 3.10.0
587
+ */
588
+ $null as null
589
+ }
590
+
591
+ /**
592
+ * @category model
593
+ * @since 3.10.0
594
+ */
595
+ export class UniqueSymbol implements Annotated {
596
+ /**
597
+ * @since 3.10.0
598
+ */
599
+ readonly _tag = "UniqueSymbol"
600
+ constructor(readonly symbol: symbol, readonly annotations: Annotations = {}) {}
601
+ /**
602
+ * @since 3.10.0
603
+ */
604
+ toString() {
605
+ return Option.getOrElse(getExpected(this), () => Inspectable.formatUnknown(this.symbol))
606
+ }
607
+ /**
608
+ * @since 3.10.0
609
+ */
610
+ toJSON(): object {
611
+ return {
612
+ _tag: this._tag,
613
+ symbol: String(this.symbol),
614
+ annotations: toJSONAnnotations(this.annotations)
615
+ }
616
+ }
617
+ }
618
+
619
+ /**
620
+ * @category guards
621
+ * @since 3.10.0
622
+ */
623
+ export const isUniqueSymbol: (ast: AST) => ast is UniqueSymbol = createASTGuard("UniqueSymbol")
624
+
625
+ /**
626
+ * @category model
627
+ * @since 3.10.0
628
+ */
629
+ export class UndefinedKeyword implements Annotated {
630
+ /**
631
+ * @since 3.10.0
632
+ */
633
+ readonly _tag = "UndefinedKeyword"
634
+ constructor(readonly annotations: Annotations = {}) {}
635
+ /**
636
+ * @since 3.10.0
637
+ */
638
+ toString() {
639
+ return formatKeyword(this)
640
+ }
641
+ /**
642
+ * @since 3.10.0
643
+ */
644
+ toJSON(): object {
645
+ return {
646
+ _tag: this._tag,
647
+ annotations: toJSONAnnotations(this.annotations)
648
+ }
649
+ }
650
+ }
651
+
652
+ /**
653
+ * @category constructors
654
+ * @since 3.10.0
655
+ */
656
+ export const undefinedKeyword: UndefinedKeyword = new UndefinedKeyword({
657
+ [TitleAnnotationId]: "undefined"
658
+ })
659
+
660
+ /**
661
+ * @category guards
662
+ * @since 3.10.0
663
+ */
664
+ export const isUndefinedKeyword: (ast: AST) => ast is UndefinedKeyword = createASTGuard("UndefinedKeyword")
665
+
666
+ /**
667
+ * @category model
668
+ * @since 3.10.0
669
+ */
670
+ export class VoidKeyword implements Annotated {
671
+ /**
672
+ * @since 3.10.0
673
+ */
674
+ readonly _tag = "VoidKeyword"
675
+ constructor(readonly annotations: Annotations = {}) {}
676
+ /**
677
+ * @since 3.10.0
678
+ */
679
+ toString() {
680
+ return formatKeyword(this)
681
+ }
682
+ /**
683
+ * @since 3.10.0
684
+ */
685
+ toJSON(): object {
686
+ return {
687
+ _tag: this._tag,
688
+ annotations: toJSONAnnotations(this.annotations)
689
+ }
690
+ }
691
+ }
692
+
693
+ /**
694
+ * @category constructors
695
+ * @since 3.10.0
696
+ */
697
+ export const voidKeyword: VoidKeyword = new VoidKeyword({
698
+ [TitleAnnotationId]: "void"
699
+ })
700
+
701
+ /**
702
+ * @category guards
703
+ * @since 3.10.0
704
+ */
705
+ export const isVoidKeyword: (ast: AST) => ast is VoidKeyword = createASTGuard("VoidKeyword")
706
+
707
+ /**
708
+ * @category model
709
+ * @since 3.10.0
710
+ */
711
+ export class NeverKeyword implements Annotated {
712
+ /**
713
+ * @since 3.10.0
714
+ */
715
+ readonly _tag = "NeverKeyword"
716
+ constructor(readonly annotations: Annotations = {}) {}
717
+ /**
718
+ * @since 3.10.0
719
+ */
720
+ toString() {
721
+ return formatKeyword(this)
722
+ }
723
+ /**
724
+ * @since 3.10.0
725
+ */
726
+ toJSON(): object {
727
+ return {
728
+ _tag: this._tag,
729
+ annotations: toJSONAnnotations(this.annotations)
730
+ }
731
+ }
732
+ }
733
+
734
+ /**
735
+ * @category constructors
736
+ * @since 3.10.0
737
+ */
738
+ export const neverKeyword: NeverKeyword = new NeverKeyword({
739
+ [TitleAnnotationId]: "never"
740
+ })
741
+
742
+ /**
743
+ * @category guards
744
+ * @since 3.10.0
745
+ */
746
+ export const isNeverKeyword: (ast: AST) => ast is NeverKeyword = createASTGuard("NeverKeyword")
747
+
748
+ /**
749
+ * @category model
750
+ * @since 3.10.0
751
+ */
752
+ export class UnknownKeyword implements Annotated {
753
+ /**
754
+ * @since 3.10.0
755
+ */
756
+ readonly _tag = "UnknownKeyword"
757
+ constructor(readonly annotations: Annotations = {}) {}
758
+ /**
759
+ * @since 3.10.0
760
+ */
761
+ toString() {
762
+ return formatKeyword(this)
763
+ }
764
+ /**
765
+ * @since 3.10.0
766
+ */
767
+ toJSON(): object {
768
+ return {
769
+ _tag: this._tag,
770
+ annotations: toJSONAnnotations(this.annotations)
771
+ }
772
+ }
773
+ }
774
+
775
+ /**
776
+ * @category constructors
777
+ * @since 3.10.0
778
+ */
779
+ export const unknownKeyword: UnknownKeyword = new UnknownKeyword({
780
+ [TitleAnnotationId]: "unknown"
781
+ })
782
+
783
+ /**
784
+ * @category guards
785
+ * @since 3.10.0
786
+ */
787
+ export const isUnknownKeyword: (ast: AST) => ast is UnknownKeyword = createASTGuard("UnknownKeyword")
788
+
789
+ /**
790
+ * @category model
791
+ * @since 3.10.0
792
+ */
793
+ export class AnyKeyword implements Annotated {
794
+ /**
795
+ * @since 3.10.0
796
+ */
797
+ readonly _tag = "AnyKeyword"
798
+ constructor(readonly annotations: Annotations = {}) {}
799
+ /**
800
+ * @since 3.10.0
801
+ */
802
+ toString() {
803
+ return formatKeyword(this)
804
+ }
805
+ /**
806
+ * @since 3.10.0
807
+ */
808
+ toJSON(): object {
809
+ return {
810
+ _tag: this._tag,
811
+ annotations: toJSONAnnotations(this.annotations)
812
+ }
813
+ }
814
+ }
815
+
816
+ /**
817
+ * @category constructors
818
+ * @since 3.10.0
819
+ */
820
+ export const anyKeyword: AnyKeyword = new AnyKeyword({
821
+ [TitleAnnotationId]: "any"
822
+ })
823
+
824
+ /**
825
+ * @category guards
826
+ * @since 3.10.0
827
+ */
828
+ export const isAnyKeyword: (ast: AST) => ast is AnyKeyword = createASTGuard("AnyKeyword")
829
+
830
+ /**
831
+ * @category model
832
+ * @since 3.10.0
833
+ */
834
+ export class StringKeyword implements Annotated {
835
+ /**
836
+ * @since 3.10.0
837
+ */
838
+ readonly _tag = "StringKeyword"
839
+ constructor(readonly annotations: Annotations = {}) {}
840
+ /**
841
+ * @since 3.10.0
842
+ */
843
+ toString() {
844
+ return formatKeyword(this)
845
+ }
846
+ /**
847
+ * @since 3.10.0
848
+ */
849
+ toJSON(): object {
850
+ return {
851
+ _tag: this._tag,
852
+ annotations: toJSONAnnotations(this.annotations)
853
+ }
854
+ }
855
+ }
856
+
857
+ /**
858
+ * @category constructors
859
+ * @since 3.10.0
860
+ */
861
+ export const stringKeyword: StringKeyword = new StringKeyword({
862
+ [TitleAnnotationId]: "string",
863
+ [DescriptionAnnotationId]: "a string"
864
+ })
865
+
866
+ /**
867
+ * @category guards
868
+ * @since 3.10.0
869
+ */
870
+ export const isStringKeyword: (ast: AST) => ast is StringKeyword = createASTGuard("StringKeyword")
871
+
872
+ /**
873
+ * @category model
874
+ * @since 3.10.0
875
+ */
876
+ export class NumberKeyword implements Annotated {
877
+ /**
878
+ * @since 3.10.0
879
+ */
880
+ readonly _tag = "NumberKeyword"
881
+ constructor(readonly annotations: Annotations = {}) {}
882
+ /**
883
+ * @since 3.10.0
884
+ */
885
+ toString() {
886
+ return formatKeyword(this)
887
+ }
888
+ /**
889
+ * @since 3.10.0
890
+ */
891
+ toJSON(): object {
892
+ return {
893
+ _tag: this._tag,
894
+ annotations: toJSONAnnotations(this.annotations)
895
+ }
896
+ }
897
+ }
898
+
899
+ /**
900
+ * @category constructors
901
+ * @since 3.10.0
902
+ */
903
+ export const numberKeyword: NumberKeyword = new NumberKeyword({
904
+ [TitleAnnotationId]: "number",
905
+ [DescriptionAnnotationId]: "a number"
906
+ })
907
+
908
+ /**
909
+ * @category guards
910
+ * @since 3.10.0
911
+ */
912
+ export const isNumberKeyword: (ast: AST) => ast is NumberKeyword = createASTGuard("NumberKeyword")
913
+
914
+ /**
915
+ * @category model
916
+ * @since 3.10.0
917
+ */
918
+ export class BooleanKeyword implements Annotated {
919
+ /**
920
+ * @since 3.10.0
921
+ */
922
+ readonly _tag = "BooleanKeyword"
923
+ constructor(readonly annotations: Annotations = {}) {}
924
+ /**
925
+ * @since 3.10.0
926
+ */
927
+ toString() {
928
+ return formatKeyword(this)
929
+ }
930
+ /**
931
+ * @since 3.10.0
932
+ */
933
+ toJSON(): object {
934
+ return {
935
+ _tag: this._tag,
936
+ annotations: toJSONAnnotations(this.annotations)
937
+ }
938
+ }
939
+ }
940
+
941
+ /**
942
+ * @category constructors
943
+ * @since 3.10.0
944
+ */
945
+ export const booleanKeyword: BooleanKeyword = new BooleanKeyword({
946
+ [TitleAnnotationId]: "boolean",
947
+ [DescriptionAnnotationId]: "a boolean"
948
+ })
949
+
950
+ /**
951
+ * @category guards
952
+ * @since 3.10.0
953
+ */
954
+ export const isBooleanKeyword: (ast: AST) => ast is BooleanKeyword = createASTGuard("BooleanKeyword")
955
+
956
+ /**
957
+ * @category model
958
+ * @since 3.10.0
959
+ */
960
+ export class BigIntKeyword implements Annotated {
961
+ /**
962
+ * @since 3.10.0
963
+ */
964
+ readonly _tag = "BigIntKeyword"
965
+ constructor(readonly annotations: Annotations = {}) {}
966
+ /**
967
+ * @since 3.10.0
968
+ */
969
+ toString() {
970
+ return formatKeyword(this)
971
+ }
972
+ /**
973
+ * @since 3.10.0
974
+ */
975
+ toJSON(): object {
976
+ return {
977
+ _tag: this._tag,
978
+ annotations: toJSONAnnotations(this.annotations)
979
+ }
980
+ }
981
+ }
982
+
983
+ /**
984
+ * @category constructors
985
+ * @since 3.10.0
986
+ */
987
+ export const bigIntKeyword: BigIntKeyword = new BigIntKeyword({
988
+ [TitleAnnotationId]: "bigint",
989
+ [DescriptionAnnotationId]: "a bigint"
990
+ })
991
+
992
+ /**
993
+ * @category guards
994
+ * @since 3.10.0
995
+ */
996
+ export const isBigIntKeyword: (ast: AST) => ast is BigIntKeyword = createASTGuard("BigIntKeyword")
997
+
998
+ /**
999
+ * @category model
1000
+ * @since 3.10.0
1001
+ */
1002
+ export class SymbolKeyword implements Annotated {
1003
+ /**
1004
+ * @since 3.10.0
1005
+ */
1006
+ readonly _tag = "SymbolKeyword"
1007
+ constructor(readonly annotations: Annotations = {}) {}
1008
+ /**
1009
+ * @since 3.10.0
1010
+ */
1011
+ toString() {
1012
+ return formatKeyword(this)
1013
+ }
1014
+ /**
1015
+ * @since 3.10.0
1016
+ */
1017
+ toJSON(): object {
1018
+ return {
1019
+ _tag: this._tag,
1020
+ annotations: toJSONAnnotations(this.annotations)
1021
+ }
1022
+ }
1023
+ }
1024
+
1025
+ /**
1026
+ * @category constructors
1027
+ * @since 3.10.0
1028
+ */
1029
+ export const symbolKeyword: SymbolKeyword = new SymbolKeyword({
1030
+ [TitleAnnotationId]: "symbol",
1031
+ [DescriptionAnnotationId]: "a symbol"
1032
+ })
1033
+
1034
+ /**
1035
+ * @category guards
1036
+ * @since 3.10.0
1037
+ */
1038
+ export const isSymbolKeyword: (ast: AST) => ast is SymbolKeyword = createASTGuard("SymbolKeyword")
1039
+
1040
+ /**
1041
+ * @category model
1042
+ * @since 3.10.0
1043
+ */
1044
+ export class ObjectKeyword implements Annotated {
1045
+ /**
1046
+ * @since 3.10.0
1047
+ */
1048
+ readonly _tag = "ObjectKeyword"
1049
+ constructor(readonly annotations: Annotations = {}) {}
1050
+ /**
1051
+ * @since 3.10.0
1052
+ */
1053
+ toString() {
1054
+ return formatKeyword(this)
1055
+ }
1056
+ /**
1057
+ * @since 3.10.0
1058
+ */
1059
+ toJSON(): object {
1060
+ return {
1061
+ _tag: this._tag,
1062
+ annotations: toJSONAnnotations(this.annotations)
1063
+ }
1064
+ }
1065
+ }
1066
+
1067
+ /**
1068
+ * @category constructors
1069
+ * @since 3.10.0
1070
+ */
1071
+ export const objectKeyword: ObjectKeyword = new ObjectKeyword({
1072
+ [TitleAnnotationId]: "object",
1073
+ [DescriptionAnnotationId]: "an object in the TypeScript meaning, i.e. the `object` type"
1074
+ })
1075
+
1076
+ /**
1077
+ * @category guards
1078
+ * @since 3.10.0
1079
+ */
1080
+ export const isObjectKeyword: (ast: AST) => ast is ObjectKeyword = createASTGuard("ObjectKeyword")
1081
+
1082
+ /**
1083
+ * @category model
1084
+ * @since 3.10.0
1085
+ */
1086
+ export class Enums implements Annotated {
1087
+ /**
1088
+ * @since 3.10.0
1089
+ */
1090
+ readonly _tag = "Enums"
1091
+ constructor(
1092
+ readonly enums: ReadonlyArray<readonly [string, string | number]>,
1093
+ readonly annotations: Annotations = {}
1094
+ ) {}
1095
+ /**
1096
+ * @since 3.10.0
1097
+ */
1098
+ toString() {
1099
+ return Option.getOrElse(
1100
+ getExpected(this),
1101
+ () => `<enum ${this.enums.length} value(s): ${this.enums.map(([_, value]) => JSON.stringify(value)).join(" | ")}>`
1102
+ )
1103
+ }
1104
+ /**
1105
+ * @since 3.10.0
1106
+ */
1107
+ toJSON(): object {
1108
+ return {
1109
+ _tag: this._tag,
1110
+ enums: this.enums,
1111
+ annotations: toJSONAnnotations(this.annotations)
1112
+ }
1113
+ }
1114
+ }
1115
+
1116
+ /**
1117
+ * @category guards
1118
+ * @since 3.10.0
1119
+ */
1120
+ export const isEnums: (ast: AST) => ast is Enums = createASTGuard("Enums")
1121
+
1122
+ type TemplateLiteralSpanBaseType = StringKeyword | NumberKeyword | Literal | TemplateLiteral
1123
+
1124
+ type TemplateLiteralSpanType = TemplateLiteralSpanBaseType | Union<TemplateLiteralSpanType>
1125
+
1126
+ const isTemplateLiteralSpanType = (ast: AST): ast is TemplateLiteralSpanType => {
1127
+ switch (ast._tag) {
1128
+ case "Literal":
1129
+ case "NumberKeyword":
1130
+ case "StringKeyword":
1131
+ case "TemplateLiteral":
1132
+ return true
1133
+ case "Union":
1134
+ return ast.types.every(isTemplateLiteralSpanType)
1135
+ }
1136
+ return false
1137
+ }
1138
+
1139
+ const templateLiteralSpanUnionTypeToString = (type: TemplateLiteralSpanType): string => {
1140
+ switch (type._tag) {
1141
+ case "Literal":
1142
+ return JSON.stringify(String(type.literal))
1143
+ case "StringKeyword":
1144
+ return "string"
1145
+ case "NumberKeyword":
1146
+ return "number"
1147
+ case "TemplateLiteral":
1148
+ return String(type)
1149
+ case "Union":
1150
+ return type.types.map(templateLiteralSpanUnionTypeToString).join(" | ")
1151
+ }
1152
+ }
1153
+
1154
+ const templateLiteralSpanTypeToString = (type: TemplateLiteralSpanType): string => {
1155
+ switch (type._tag) {
1156
+ case "Literal":
1157
+ return String(type.literal)
1158
+ case "StringKeyword":
1159
+ return "${string}"
1160
+ case "NumberKeyword":
1161
+ return "${number}"
1162
+ case "TemplateLiteral":
1163
+ return "${" + String(type) + "}"
1164
+ case "Union":
1165
+ return "${" + type.types.map(templateLiteralSpanUnionTypeToString).join(" | ") + "}"
1166
+ }
1167
+ }
1168
+
1169
+ /**
1170
+ * @category model
1171
+ * @since 3.10.0
1172
+ */
1173
+ export class TemplateLiteralSpan {
1174
+ /**
1175
+ * @since 3.10.0
1176
+ */
1177
+ readonly type: TemplateLiteralSpanType
1178
+ constructor(type: AST, readonly literal: string) {
1179
+ if (isTemplateLiteralSpanType(type)) {
1180
+ this.type = type
1181
+ } else {
1182
+ throw new Error(errors_.getSchemaUnsupportedLiteralSpanErrorMessage(type))
1183
+ }
1184
+ }
1185
+ /**
1186
+ * @since 3.10.0
1187
+ */
1188
+ toString() {
1189
+ return templateLiteralSpanTypeToString(this.type) + this.literal
1190
+ }
1191
+ /**
1192
+ * @since 3.10.0
1193
+ */
1194
+ toJSON(): object {
1195
+ return {
1196
+ type: this.type.toJSON(),
1197
+ literal: this.literal
1198
+ }
1199
+ }
1200
+ }
1201
+
1202
+ /**
1203
+ * @category model
1204
+ * @since 3.10.0
1205
+ */
1206
+ export class TemplateLiteral implements Annotated {
1207
+ /**
1208
+ * @since 3.10.0
1209
+ */
1210
+ readonly _tag = "TemplateLiteral"
1211
+ constructor(
1212
+ readonly head: string,
1213
+ readonly spans: Arr.NonEmptyReadonlyArray<TemplateLiteralSpan>,
1214
+ readonly annotations: Annotations = {}
1215
+ ) {}
1216
+ /**
1217
+ * @since 3.10.0
1218
+ */
1219
+ toString() {
1220
+ return Option.getOrElse(getExpected(this), () => formatTemplateLiteral(this))
1221
+ }
1222
+ /**
1223
+ * @since 3.10.0
1224
+ */
1225
+ toJSON(): object {
1226
+ return {
1227
+ _tag: this._tag,
1228
+ head: this.head,
1229
+ spans: this.spans.map((span) => span.toJSON()),
1230
+ annotations: toJSONAnnotations(this.annotations)
1231
+ }
1232
+ }
1233
+ }
1234
+
1235
+ const formatTemplateLiteral = (ast: TemplateLiteral): string =>
1236
+ "`" + ast.head + ast.spans.map(String).join("") +
1237
+ "`"
1238
+
1239
+ /**
1240
+ * @category guards
1241
+ * @since 3.10.0
1242
+ */
1243
+ export const isTemplateLiteral: (ast: AST) => ast is TemplateLiteral = createASTGuard("TemplateLiteral")
1244
+
1245
+ /**
1246
+ * @category model
1247
+ * @since 3.10.0
1248
+ */
1249
+ export class Type implements Annotated {
1250
+ constructor(
1251
+ readonly type: AST,
1252
+ readonly annotations: Annotations = {}
1253
+ ) {}
1254
+ /**
1255
+ * @since 3.10.0
1256
+ */
1257
+ toJSON(): object {
1258
+ return {
1259
+ type: this.type.toJSON(),
1260
+ annotations: toJSONAnnotations(this.annotations)
1261
+ }
1262
+ }
1263
+ /**
1264
+ * @since 3.10.0
1265
+ */
1266
+ toString() {
1267
+ return String(this.type)
1268
+ }
1269
+ }
1270
+
1271
+ /**
1272
+ * @category model
1273
+ * @since 3.10.0
1274
+ */
1275
+ export class OptionalType extends Type {
1276
+ constructor(
1277
+ type: AST,
1278
+ readonly isOptional: boolean,
1279
+ annotations: Annotations = {}
1280
+ ) {
1281
+ super(type, annotations)
1282
+ }
1283
+ /**
1284
+ * @since 3.10.0
1285
+ */
1286
+ toJSON(): object {
1287
+ return {
1288
+ type: this.type.toJSON(),
1289
+ isOptional: this.isOptional,
1290
+ annotations: toJSONAnnotations(this.annotations)
1291
+ }
1292
+ }
1293
+ /**
1294
+ * @since 3.10.0
1295
+ */
1296
+ toString() {
1297
+ return String(this.type) + (this.isOptional ? "?" : "")
1298
+ }
1299
+ }
1300
+
1301
+ const getRestASTs = (rest: ReadonlyArray<Type>): ReadonlyArray<AST> => rest.map((annotatedAST) => annotatedAST.type)
1302
+
1303
+ /**
1304
+ * @category model
1305
+ * @since 3.10.0
1306
+ */
1307
+ export class TupleType implements Annotated {
1308
+ /**
1309
+ * @since 3.10.0
1310
+ */
1311
+ readonly _tag = "TupleType"
1312
+ constructor(
1313
+ readonly elements: ReadonlyArray<OptionalType>,
1314
+ readonly rest: ReadonlyArray<Type>,
1315
+ readonly isReadonly: boolean,
1316
+ readonly annotations: Annotations = {}
1317
+ ) {
1318
+ let hasOptionalElement = false
1319
+ let hasIllegalRequiredElement = false
1320
+ for (const e of elements) {
1321
+ if (e.isOptional) {
1322
+ hasOptionalElement = true
1323
+ } else if (hasOptionalElement) {
1324
+ hasIllegalRequiredElement = true
1325
+ break
1326
+ }
1327
+ }
1328
+ if (hasIllegalRequiredElement || (hasOptionalElement && rest.length > 1)) {
1329
+ throw new Error(errors_.getASTRequiredElementFollowinAnOptionalElementErrorMessage)
1330
+ }
1331
+ }
1332
+ /**
1333
+ * @since 3.10.0
1334
+ */
1335
+ toString() {
1336
+ return Option.getOrElse(getExpected(this), () => formatTuple(this))
1337
+ }
1338
+ /**
1339
+ * @since 3.10.0
1340
+ */
1341
+ toJSON(): object {
1342
+ return {
1343
+ _tag: this._tag,
1344
+ elements: this.elements.map((e) => e.toJSON()),
1345
+ rest: this.rest.map((ast) => ast.toJSON()),
1346
+ isReadonly: this.isReadonly,
1347
+ annotations: toJSONAnnotations(this.annotations)
1348
+ }
1349
+ }
1350
+ }
1351
+
1352
+ const formatTuple = (ast: TupleType): string => {
1353
+ const formattedElements = ast.elements.map(String)
1354
+ .join(", ")
1355
+ return Arr.matchLeft(ast.rest, {
1356
+ onEmpty: () => `readonly [${formattedElements}]`,
1357
+ onNonEmpty: (head, tail) => {
1358
+ const formattedHead = String(head)
1359
+ const wrappedHead = formattedHead.includes(" | ") ? `(${formattedHead})` : formattedHead
1360
+
1361
+ if (tail.length > 0) {
1362
+ const formattedTail = tail.map(String).join(", ")
1363
+ if (ast.elements.length > 0) {
1364
+ return `readonly [${formattedElements}, ...${wrappedHead}[], ${formattedTail}]`
1365
+ } else {
1366
+ return `readonly [...${wrappedHead}[], ${formattedTail}]`
1367
+ }
1368
+ } else {
1369
+ if (ast.elements.length > 0) {
1370
+ return `readonly [${formattedElements}, ...${wrappedHead}[]]`
1371
+ } else {
1372
+ return `ReadonlyArray<${formattedHead}>`
1373
+ }
1374
+ }
1375
+ }
1376
+ })
1377
+ }
1378
+
1379
+ /**
1380
+ * @category guards
1381
+ * @since 3.10.0
1382
+ */
1383
+ export const isTupleType: (ast: AST) => ast is TupleType = createASTGuard("TupleType")
1384
+
1385
+ /**
1386
+ * @category model
1387
+ * @since 3.10.0
1388
+ */
1389
+ export class PropertySignature extends OptionalType {
1390
+ constructor(
1391
+ readonly name: PropertyKey,
1392
+ type: AST,
1393
+ isOptional: boolean,
1394
+ readonly isReadonly: boolean,
1395
+ annotations?: Annotations
1396
+ ) {
1397
+ super(type, isOptional, annotations)
1398
+ }
1399
+ /**
1400
+ * @since 3.10.0
1401
+ */
1402
+ toString(): string {
1403
+ return (this.isReadonly ? "readonly " : "") + String(this.name) + (this.isOptional ? "?" : "") + ": " +
1404
+ this.type
1405
+ }
1406
+ /**
1407
+ * @since 3.10.0
1408
+ */
1409
+ toJSON(): object {
1410
+ return {
1411
+ name: String(this.name),
1412
+ type: this.type.toJSON(),
1413
+ isOptional: this.isOptional,
1414
+ isReadonly: this.isReadonly,
1415
+ annotations: toJSONAnnotations(this.annotations)
1416
+ }
1417
+ }
1418
+ }
1419
+
1420
+ /**
1421
+ * @since 3.10.0
1422
+ */
1423
+ export type Parameter = StringKeyword | SymbolKeyword | TemplateLiteral | Refinement<Parameter>
1424
+
1425
+ /**
1426
+ * @since 3.10.0
1427
+ */
1428
+ export const isParameter = (ast: AST): ast is Parameter => {
1429
+ switch (ast._tag) {
1430
+ case "StringKeyword":
1431
+ case "SymbolKeyword":
1432
+ case "TemplateLiteral":
1433
+ return true
1434
+ case "Refinement":
1435
+ return isParameter(ast.from)
1436
+ }
1437
+ return false
1438
+ }
1439
+
1440
+ /**
1441
+ * @category model
1442
+ * @since 3.10.0
1443
+ */
1444
+ export class IndexSignature {
1445
+ /**
1446
+ * @since 3.10.0
1447
+ */
1448
+ readonly parameter: Parameter
1449
+ constructor(
1450
+ parameter: AST,
1451
+ readonly type: AST,
1452
+ readonly isReadonly: boolean
1453
+ ) {
1454
+ if (isParameter(parameter)) {
1455
+ this.parameter = parameter
1456
+ } else {
1457
+ throw new Error(errors_.getASTIndexSignatureParameterErrorMessage)
1458
+ }
1459
+ }
1460
+ /**
1461
+ * @since 3.10.0
1462
+ */
1463
+ toString(): string {
1464
+ return (this.isReadonly ? "readonly " : "") + `[x: ${this.parameter}]: ${this.type}`
1465
+ }
1466
+ /**
1467
+ * @since 3.10.0
1468
+ */
1469
+ toJSON(): object {
1470
+ return {
1471
+ parameter: this.parameter.toJSON(),
1472
+ type: this.type.toJSON(),
1473
+ isReadonly: this.isReadonly
1474
+ }
1475
+ }
1476
+ }
1477
+
1478
+ /**
1479
+ * @category model
1480
+ * @since 3.10.0
1481
+ */
1482
+ export class TypeLiteral implements Annotated {
1483
+ /**
1484
+ * @since 3.10.0
1485
+ */
1486
+ readonly _tag = "TypeLiteral"
1487
+ /**
1488
+ * @since 3.10.0
1489
+ */
1490
+ readonly propertySignatures: ReadonlyArray<PropertySignature>
1491
+ /**
1492
+ * @since 3.10.0
1493
+ */
1494
+ readonly indexSignatures: ReadonlyArray<IndexSignature>
1495
+ constructor(
1496
+ propertySignatures: ReadonlyArray<PropertySignature>,
1497
+ indexSignatures: ReadonlyArray<IndexSignature>,
1498
+ readonly annotations: Annotations = {}
1499
+ ) {
1500
+ // check for duplicate property signatures
1501
+ const keys: Record<PropertyKey, null> = {}
1502
+ for (let i = 0; i < propertySignatures.length; i++) {
1503
+ const name = propertySignatures[i].name
1504
+ if (Object.prototype.hasOwnProperty.call(keys, name)) {
1505
+ throw new Error(errors_.getASTDuplicatePropertySignatureErrorMessage(name))
1506
+ }
1507
+ keys[name] = null
1508
+ }
1509
+ // check for duplicate index signatures
1510
+ const parameters = {
1511
+ string: false,
1512
+ symbol: false
1513
+ }
1514
+ for (let i = 0; i < indexSignatures.length; i++) {
1515
+ const encodedParameter = getEncodedParameter(indexSignatures[i].parameter)
1516
+ if (isStringKeyword(encodedParameter)) {
1517
+ if (parameters.string) {
1518
+ throw new Error(errors_.getASTDuplicateIndexSignatureErrorMessage("string"))
1519
+ }
1520
+ parameters.string = true
1521
+ } else if (isSymbolKeyword(encodedParameter)) {
1522
+ if (parameters.symbol) {
1523
+ throw new Error(errors_.getASTDuplicateIndexSignatureErrorMessage("symbol"))
1524
+ }
1525
+ parameters.symbol = true
1526
+ }
1527
+ }
1528
+
1529
+ this.propertySignatures = propertySignatures
1530
+ this.indexSignatures = indexSignatures
1531
+ }
1532
+ /**
1533
+ * @since 3.10.0
1534
+ */
1535
+ toString() {
1536
+ return Option.getOrElse(getExpected(this), () => formatTypeLiteral(this))
1537
+ }
1538
+ /**
1539
+ * @since 3.10.0
1540
+ */
1541
+ toJSON(): object {
1542
+ return {
1543
+ _tag: this._tag,
1544
+ propertySignatures: this.propertySignatures.map((ps) => ps.toJSON()),
1545
+ indexSignatures: this.indexSignatures.map((ps) => ps.toJSON()),
1546
+ annotations: toJSONAnnotations(this.annotations)
1547
+ }
1548
+ }
1549
+ }
1550
+
1551
+ const formatIndexSignatures = (iss: ReadonlyArray<IndexSignature>): string => iss.map(String).join("; ")
1552
+
1553
+ const formatTypeLiteral = (ast: TypeLiteral): string => {
1554
+ if (ast.propertySignatures.length > 0) {
1555
+ const pss = ast.propertySignatures.map(String).join("; ")
1556
+ if (ast.indexSignatures.length > 0) {
1557
+ return `{ ${pss}; ${formatIndexSignatures(ast.indexSignatures)} }`
1558
+ } else {
1559
+ return `{ ${pss} }`
1560
+ }
1561
+ } else {
1562
+ if (ast.indexSignatures.length > 0) {
1563
+ return `{ ${formatIndexSignatures(ast.indexSignatures)} }`
1564
+ } else {
1565
+ return "{}"
1566
+ }
1567
+ }
1568
+ }
1569
+
1570
+ /**
1571
+ * @category guards
1572
+ * @since 3.10.0
1573
+ */
1574
+ export const isTypeLiteral: (ast: AST) => ast is TypeLiteral = createASTGuard("TypeLiteral")
1575
+
1576
+ /**
1577
+ * @since 3.10.0
1578
+ */
1579
+ export type Members<A> = readonly [A, A, ...Array<A>]
1580
+
1581
+ const sortCandidates = Arr.sort(
1582
+ Order.mapInput(Number.Order, (ast: AST) => {
1583
+ switch (ast._tag) {
1584
+ case "AnyKeyword":
1585
+ return 0
1586
+ case "UnknownKeyword":
1587
+ return 1
1588
+ case "ObjectKeyword":
1589
+ return 2
1590
+ case "StringKeyword":
1591
+ case "NumberKeyword":
1592
+ case "BooleanKeyword":
1593
+ case "BigIntKeyword":
1594
+ case "SymbolKeyword":
1595
+ return 3
1596
+ }
1597
+ return 4
1598
+ })
1599
+ )
1600
+
1601
+ const literalMap = {
1602
+ string: "StringKeyword",
1603
+ number: "NumberKeyword",
1604
+ boolean: "BooleanKeyword",
1605
+ bigint: "BigIntKeyword"
1606
+ } as const
1607
+
1608
+ /** @internal */
1609
+ export const flatten = (candidates: ReadonlyArray<AST>): Array<AST> =>
1610
+ Arr.flatMap(candidates, (ast) => isUnion(ast) ? flatten(ast.types) : [ast])
1611
+
1612
+ /** @internal */
1613
+ export const unify = (candidates: ReadonlyArray<AST>): Array<AST> => {
1614
+ const cs = sortCandidates(candidates)
1615
+ const out: Array<AST> = []
1616
+ const uniques: { [K in AST["_tag"] | "{}"]?: AST } = {}
1617
+ const literals: Array<LiteralValue | symbol> = []
1618
+ for (const ast of cs) {
1619
+ switch (ast._tag) {
1620
+ case "NeverKeyword":
1621
+ break
1622
+ case "AnyKeyword":
1623
+ return [anyKeyword]
1624
+ case "UnknownKeyword":
1625
+ return [unknownKeyword]
1626
+ // uniques
1627
+ case "ObjectKeyword":
1628
+ case "UndefinedKeyword":
1629
+ case "VoidKeyword":
1630
+ case "StringKeyword":
1631
+ case "NumberKeyword":
1632
+ case "BooleanKeyword":
1633
+ case "BigIntKeyword":
1634
+ case "SymbolKeyword": {
1635
+ if (!uniques[ast._tag]) {
1636
+ uniques[ast._tag] = ast
1637
+ out.push(ast)
1638
+ }
1639
+ break
1640
+ }
1641
+ case "Literal": {
1642
+ const type = typeof ast.literal
1643
+ switch (type) {
1644
+ case "string":
1645
+ case "number":
1646
+ case "bigint":
1647
+ case "boolean": {
1648
+ const _tag = literalMap[type]
1649
+ if (!uniques[_tag] && !literals.includes(ast.literal)) {
1650
+ literals.push(ast.literal)
1651
+ out.push(ast)
1652
+ }
1653
+ break
1654
+ }
1655
+ // null
1656
+ case "object": {
1657
+ if (!literals.includes(ast.literal)) {
1658
+ literals.push(ast.literal)
1659
+ out.push(ast)
1660
+ }
1661
+ break
1662
+ }
1663
+ }
1664
+ break
1665
+ }
1666
+ case "UniqueSymbol": {
1667
+ if (!uniques["SymbolKeyword"] && !literals.includes(ast.symbol)) {
1668
+ literals.push(ast.symbol)
1669
+ out.push(ast)
1670
+ }
1671
+ break
1672
+ }
1673
+ case "TupleType": {
1674
+ if (!uniques["ObjectKeyword"]) {
1675
+ out.push(ast)
1676
+ }
1677
+ break
1678
+ }
1679
+ case "TypeLiteral": {
1680
+ if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
1681
+ if (!uniques["{}"]) {
1682
+ uniques["{}"] = ast
1683
+ out.push(ast)
1684
+ }
1685
+ } else if (!uniques["ObjectKeyword"]) {
1686
+ out.push(ast)
1687
+ }
1688
+ break
1689
+ }
1690
+ default:
1691
+ out.push(ast)
1692
+ }
1693
+ }
1694
+ return out
1695
+ }
1696
+
1697
+ /**
1698
+ * @category model
1699
+ * @since 3.10.0
1700
+ */
1701
+ export class Union<M extends AST = AST> implements Annotated {
1702
+ static make = (types: ReadonlyArray<AST>, annotations?: Annotations): AST => {
1703
+ return isMembers(types) ? new Union(types, annotations) : types.length === 1 ? types[0] : neverKeyword
1704
+ }
1705
+ /** @internal */
1706
+ static unify = (candidates: ReadonlyArray<AST>, annotations?: Annotations): AST => {
1707
+ return Union.make(unify(flatten(candidates)), annotations)
1708
+ }
1709
+ /**
1710
+ * @since 3.10.0
1711
+ */
1712
+ readonly _tag = "Union"
1713
+ private constructor(readonly types: Members<M>, readonly annotations: Annotations = {}) {}
1714
+ /**
1715
+ * @since 3.10.0
1716
+ */
1717
+ toString() {
1718
+ return Option.getOrElse(getExpected(this), () => this.types.map(String).join(" | "))
1719
+ }
1720
+ /**
1721
+ * @since 3.10.0
1722
+ */
1723
+ toJSON(): object {
1724
+ return {
1725
+ _tag: this._tag,
1726
+ types: this.types.map((ast) => ast.toJSON()),
1727
+ annotations: toJSONAnnotations(this.annotations)
1728
+ }
1729
+ }
1730
+ }
1731
+
1732
+ /** @internal */
1733
+ export const mapMembers = <A, B>(members: Members<A>, f: (a: A) => B): Members<B> => members.map(f) as any
1734
+
1735
+ /** @internal */
1736
+ export const isMembers = <A>(as: ReadonlyArray<A>): as is Members<A> => as.length > 1
1737
+
1738
+ /**
1739
+ * @category guards
1740
+ * @since 3.10.0
1741
+ */
1742
+ export const isUnion: (ast: AST) => ast is Union = createASTGuard("Union")
1743
+
1744
+ const toJSONMemoMap = globalValue(
1745
+ Symbol.for("effect/Schema/AST/toJSONMemoMap"),
1746
+ () => new WeakMap<AST, object>()
1747
+ )
1748
+
1749
+ /**
1750
+ * @category model
1751
+ * @since 3.10.0
1752
+ */
1753
+ export class Suspend implements Annotated {
1754
+ /**
1755
+ * @since 3.10.0
1756
+ */
1757
+ readonly _tag = "Suspend"
1758
+ constructor(readonly f: () => AST, readonly annotations: Annotations = {}) {
1759
+ this.f = util_.memoizeThunk(f)
1760
+ }
1761
+ /**
1762
+ * @since 3.10.0
1763
+ */
1764
+ toString() {
1765
+ return getExpected(this).pipe(
1766
+ Option.orElse(() =>
1767
+ Option.flatMap(
1768
+ Option.liftThrowable(this.f)(),
1769
+ (ast) => getExpected(ast)
1770
+ )
1771
+ ),
1772
+ Option.getOrElse(() => "<suspended schema>")
1773
+ )
1774
+ }
1775
+ /**
1776
+ * @since 3.10.0
1777
+ */
1778
+ toJSON(): object {
1779
+ const ast = this.f()
1780
+ let out = toJSONMemoMap.get(ast)
1781
+ if (out) {
1782
+ return out
1783
+ }
1784
+ toJSONMemoMap.set(ast, { _tag: this._tag })
1785
+ out = {
1786
+ _tag: this._tag,
1787
+ ast: ast.toJSON(),
1788
+ annotations: toJSONAnnotations(this.annotations)
1789
+ }
1790
+ toJSONMemoMap.set(ast, out)
1791
+ return out
1792
+ }
1793
+ }
1794
+
1795
+ /**
1796
+ * @category guards
1797
+ * @since 3.10.0
1798
+ */
1799
+ export const isSuspend: (ast: AST) => ast is Suspend = createASTGuard("Suspend")
1800
+
1801
+ /**
1802
+ * @category model
1803
+ * @since 3.10.0
1804
+ */
1805
+ export class Refinement<From extends AST = AST> implements Annotated {
1806
+ /**
1807
+ * @since 3.10.0
1808
+ */
1809
+ readonly _tag = "Refinement"
1810
+ constructor(
1811
+ readonly from: From,
1812
+ readonly filter: (
1813
+ input: any,
1814
+ options: ParseOptions,
1815
+ self: Refinement
1816
+ ) => Option.Option<ParseIssue>,
1817
+ readonly annotations: Annotations = {}
1818
+ ) {}
1819
+ /**
1820
+ * @since 3.10.0
1821
+ */
1822
+ toString() {
1823
+ return getIdentifierAnnotation(this).pipe(Option.getOrElse(() =>
1824
+ Option.match(getOrElseExpected(this), {
1825
+ onNone: () => `{ ${this.from} | filter }`,
1826
+ onSome: (expected) => isRefinement(this.from) ? String(this.from) + " & " + expected : expected
1827
+ })
1828
+ ))
1829
+ }
1830
+ /**
1831
+ * @since 3.10.0
1832
+ */
1833
+ toJSON(): object {
1834
+ return {
1835
+ _tag: this._tag,
1836
+ from: this.from.toJSON(),
1837
+ annotations: toJSONAnnotations(this.annotations)
1838
+ }
1839
+ }
1840
+ }
1841
+
1842
+ /**
1843
+ * @category guards
1844
+ * @since 3.10.0
1845
+ */
1846
+ export const isRefinement: (ast: AST) => ast is Refinement<AST> = createASTGuard("Refinement")
1847
+
1848
+ /**
1849
+ * @category model
1850
+ * @since 3.10.0
1851
+ */
1852
+ export interface ParseOptions {
1853
+ /**
1854
+ * The `errors` option allows you to receive all parsing errors when
1855
+ * attempting to parse a value using a schema. By default only the first error
1856
+ * is returned, but by setting the `errors` option to `"all"`, you can receive
1857
+ * all errors that occurred during the parsing process. This can be useful for
1858
+ * debugging or for providing more comprehensive error messages to the user.
1859
+ *
1860
+ * default: "first"
1861
+ *
1862
+ * @since 3.10.0
1863
+ */
1864
+ readonly errors?: "first" | "all" | undefined
1865
+ /**
1866
+ * When using a `Schema` to parse a value, by default any properties that are
1867
+ * not specified in the `Schema` will be stripped out from the output. This is
1868
+ * because the `Schema` is expecting a specific shape for the parsed value,
1869
+ * and any excess properties do not conform to that shape.
1870
+ *
1871
+ * However, you can use the `onExcessProperty` option (default value:
1872
+ * `"ignore"`) to trigger a parsing error. This can be particularly useful in
1873
+ * cases where you need to detect and handle potential errors or unexpected
1874
+ * values.
1875
+ *
1876
+ * If you want to allow excess properties to remain, you can use
1877
+ * `onExcessProperty` set to `"preserve"`.
1878
+ *
1879
+ * default: "ignore"
1880
+ *
1881
+ * @since 3.10.0
1882
+ */
1883
+ readonly onExcessProperty?: "ignore" | "error" | "preserve" | undefined
1884
+ /**
1885
+ * The `propertyOrder` option provides control over the order of object fields
1886
+ * in the output. This feature is particularly useful when the sequence of
1887
+ * keys is important for the consuming processes or when maintaining the input
1888
+ * order enhances readability and usability.
1889
+ *
1890
+ * By default, the `propertyOrder` option is set to `"none"`. This means that
1891
+ * the internal system decides the order of keys to optimize parsing speed.
1892
+ * The order of keys in this mode should not be considered stable, and it's
1893
+ * recommended not to rely on key ordering as it may change in future updates
1894
+ * without notice.
1895
+ *
1896
+ * Setting `propertyOrder` to `"original"` ensures that the keys are ordered
1897
+ * as they appear in the input during the decoding/encoding process.
1898
+ *
1899
+ * default: "none"
1900
+ *
1901
+ * @since 3.10.0
1902
+ */
1903
+ readonly propertyOrder?: "none" | "original" | undefined
1904
+ /**
1905
+ * Handles missing properties in data structures. By default, missing
1906
+ * properties are treated as if present with an `undefined` value. To treat
1907
+ * missing properties as errors, set the `exact` option to `true`. This
1908
+ * setting is already enabled by default for `is` and `asserts` functions,
1909
+ * treating absent properties strictly unless overridden.
1910
+ *
1911
+ * default: false
1912
+ *
1913
+ * @since 3.10.0
1914
+ */
1915
+ readonly exact?: boolean | undefined
1916
+ }
1917
+
1918
+ /**
1919
+ * @since 3.10.0
1920
+ */
1921
+ export const defaultParseOption: ParseOptions = {}
1922
+
1923
+ /**
1924
+ * @category model
1925
+ * @since 3.10.0
1926
+ */
1927
+ export class Transformation implements Annotated {
1928
+ /**
1929
+ * @since 3.10.0
1930
+ */
1931
+ readonly _tag = "Transformation"
1932
+ constructor(
1933
+ readonly from: AST,
1934
+ readonly to: AST,
1935
+ readonly transformation: TransformationKind,
1936
+ readonly annotations: Annotations = {}
1937
+ ) {}
1938
+ /**
1939
+ * @since 3.10.0
1940
+ */
1941
+ toString() {
1942
+ return Option.getOrElse(
1943
+ getExpected(this),
1944
+ () => `(${String(this.from)} <-> ${String(this.to)})`
1945
+ )
1946
+ }
1947
+ /**
1948
+ * @since 3.10.0
1949
+ */
1950
+ toJSON(): object {
1951
+ return {
1952
+ _tag: this._tag,
1953
+ from: this.from.toJSON(),
1954
+ to: this.to.toJSON(),
1955
+ annotations: toJSONAnnotations(this.annotations)
1956
+ }
1957
+ }
1958
+ }
1959
+
1960
+ /**
1961
+ * @category guards
1962
+ * @since 3.10.0
1963
+ */
1964
+ export const isTransformation: (ast: AST) => ast is Transformation = createASTGuard("Transformation")
1965
+
1966
+ /**
1967
+ * @category model
1968
+ * @since 3.10.0
1969
+ */
1970
+ export type TransformationKind =
1971
+ | FinalTransformation
1972
+ | ComposeTransformation
1973
+ | TypeLiteralTransformation
1974
+
1975
+ /**
1976
+ * @category model
1977
+ * @since 3.10.0
1978
+ */
1979
+ export class FinalTransformation {
1980
+ /**
1981
+ * @since 3.10.0
1982
+ */
1983
+ readonly _tag = "FinalTransformation"
1984
+ constructor(
1985
+ readonly decode: (
1986
+ fromA: any,
1987
+ options: ParseOptions,
1988
+ self: Transformation,
1989
+ fromI: any
1990
+ ) => Effect<any, ParseIssue, any>,
1991
+ readonly encode: (toI: any, options: ParseOptions, self: Transformation, toA: any) => Effect<any, ParseIssue, any>
1992
+ ) {}
1993
+ }
1994
+
1995
+ const createTransformationGuard =
1996
+ <T extends TransformationKind["_tag"]>(tag: T) =>
1997
+ (ast: TransformationKind): ast is Extract<TransformationKind, { _tag: T }> => ast._tag === tag
1998
+
1999
+ /**
2000
+ * @category guards
2001
+ * @since 3.10.0
2002
+ */
2003
+ export const isFinalTransformation: (ast: TransformationKind) => ast is FinalTransformation = createTransformationGuard(
2004
+ "FinalTransformation"
2005
+ )
2006
+
2007
+ /**
2008
+ * @category model
2009
+ * @since 3.10.0
2010
+ */
2011
+ export class ComposeTransformation {
2012
+ /**
2013
+ * @since 3.10.0
2014
+ */
2015
+ readonly _tag = "ComposeTransformation"
2016
+ }
2017
+
2018
+ /**
2019
+ * @category constructors
2020
+ * @since 3.10.0
2021
+ */
2022
+ export const composeTransformation: ComposeTransformation = new ComposeTransformation()
2023
+
2024
+ /**
2025
+ * @category guards
2026
+ * @since 3.10.0
2027
+ */
2028
+ export const isComposeTransformation: (ast: TransformationKind) => ast is ComposeTransformation =
2029
+ createTransformationGuard(
2030
+ "ComposeTransformation"
2031
+ )
2032
+
2033
+ /**
2034
+ * Represents a `PropertySignature -> PropertySignature` transformation
2035
+ *
2036
+ * The semantic of `decode` is:
2037
+ * - `none()` represents the absence of the key/value pair
2038
+ * - `some(value)` represents the presence of the key/value pair
2039
+ *
2040
+ * The semantic of `encode` is:
2041
+ * - `none()` you don't want to output the key/value pair
2042
+ * - `some(value)` you want to output the key/value pair
2043
+ *
2044
+ * @category model
2045
+ * @since 3.10.0
2046
+ */
2047
+ export class PropertySignatureTransformation {
2048
+ constructor(
2049
+ readonly from: PropertyKey,
2050
+ readonly to: PropertyKey,
2051
+ readonly decode: (o: Option.Option<any>) => Option.Option<any>,
2052
+ readonly encode: (o: Option.Option<any>) => Option.Option<any>
2053
+ ) {}
2054
+ }
2055
+
2056
+ const isRenamingPropertySignatureTransformation = (t: PropertySignatureTransformation) =>
2057
+ t.decode === identity && t.encode === identity
2058
+
2059
+ /**
2060
+ * @category model
2061
+ * @since 3.10.0
2062
+ */
2063
+ export class TypeLiteralTransformation {
2064
+ /**
2065
+ * @since 3.10.0
2066
+ */
2067
+ readonly _tag = "TypeLiteralTransformation"
2068
+ constructor(
2069
+ readonly propertySignatureTransformations: ReadonlyArray<
2070
+ PropertySignatureTransformation
2071
+ >
2072
+ ) {
2073
+ // check for duplicate property signature transformations
2074
+ const fromKeys: Record<PropertyKey, true> = {}
2075
+ const toKeys: Record<PropertyKey, true> = {}
2076
+ for (const pst of propertySignatureTransformations) {
2077
+ const from = pst.from
2078
+ if (fromKeys[from]) {
2079
+ throw new Error(errors_.getASTDuplicatePropertySignatureTransformationErrorMessage(from))
2080
+ }
2081
+ fromKeys[from] = true
2082
+ const to = pst.to
2083
+ if (toKeys[to]) {
2084
+ throw new Error(errors_.getASTDuplicatePropertySignatureTransformationErrorMessage(to))
2085
+ }
2086
+ toKeys[to] = true
2087
+ }
2088
+ }
2089
+ }
2090
+
2091
+ /**
2092
+ * @category guards
2093
+ * @since 3.10.0
2094
+ */
2095
+ export const isTypeLiteralTransformation: (ast: TransformationKind) => ast is TypeLiteralTransformation =
2096
+ createTransformationGuard("TypeLiteralTransformation")
2097
+
2098
+ // -------------------------------------------------------------------------------------
2099
+ // API
2100
+ // -------------------------------------------------------------------------------------
2101
+
2102
+ /**
2103
+ * Merges a set of new annotations with existing ones, potentially overwriting
2104
+ * any duplicates.
2105
+ *
2106
+ * Any previously existing identifier annotations are deleted.
2107
+ *
2108
+ * @since 3.10.0
2109
+ */
2110
+ export const annotations = (ast: AST, overrides: Annotations): AST => {
2111
+ const d = Object.getOwnPropertyDescriptors(ast)
2112
+ const base: any = { ...ast.annotations }
2113
+ delete base[IdentifierAnnotationId]
2114
+ const value = { ...base, ...overrides }
2115
+ const surrogate = getSurrogateAnnotation(ast)
2116
+ if (Option.isSome(surrogate)) {
2117
+ value[SurrogateAnnotationId] = annotations(surrogate.value, overrides)
2118
+ }
2119
+ d.annotations.value = value
2120
+ return Object.create(Object.getPrototypeOf(ast), d)
2121
+ }
2122
+
2123
+ /**
2124
+ * Equivalent at runtime to the TypeScript type-level `keyof` operator.
2125
+ *
2126
+ * @since 3.10.0
2127
+ */
2128
+ export const keyof = (ast: AST): AST => Union.unify(_keyof(ast))
2129
+
2130
+ const STRING_KEYWORD_PATTERN = "[\\s\\S]*?" // any string, including newlines
2131
+ const NUMBER_KEYWORD_PATTERN = "[+-]?\\d*\\.?\\d+(?:[Ee][+-]?\\d+)?"
2132
+
2133
+ const getTemplateLiteralSpanTypePattern = (type: TemplateLiteralSpanType, capture: boolean): string => {
2134
+ switch (type._tag) {
2135
+ case "Literal":
2136
+ return regexp.escape(String(type.literal))
2137
+ case "StringKeyword":
2138
+ return STRING_KEYWORD_PATTERN
2139
+ case "NumberKeyword":
2140
+ return NUMBER_KEYWORD_PATTERN
2141
+ case "TemplateLiteral":
2142
+ return getTemplateLiteralPattern(type, capture, false)
2143
+ case "Union":
2144
+ return type.types.map((type) => getTemplateLiteralSpanTypePattern(type, capture)).join("|")
2145
+ }
2146
+ }
2147
+
2148
+ const handleTemplateLiteralSpanTypeParens = (
2149
+ type: TemplateLiteralSpanType,
2150
+ s: string,
2151
+ capture: boolean,
2152
+ top: boolean
2153
+ ) => {
2154
+ if (isUnion(type)) {
2155
+ if (capture && !top) {
2156
+ return `(?:${s})`
2157
+ }
2158
+ } else if (!capture || !top) {
2159
+ return s
2160
+ }
2161
+ return `(${s})`
2162
+ }
2163
+
2164
+ const getTemplateLiteralPattern = (ast: TemplateLiteral, capture: boolean, top: boolean): string => {
2165
+ let pattern = ``
2166
+ if (ast.head !== "") {
2167
+ const head = regexp.escape(ast.head)
2168
+ pattern += capture && top ? `(${head})` : head
2169
+ }
2170
+
2171
+ for (const span of ast.spans) {
2172
+ const spanPattern = getTemplateLiteralSpanTypePattern(span.type, capture)
2173
+ pattern += handleTemplateLiteralSpanTypeParens(span.type, spanPattern, capture, top)
2174
+ if (span.literal !== "") {
2175
+ const literal = regexp.escape(span.literal)
2176
+ pattern += capture && top ? `(${literal})` : literal
2177
+ }
2178
+ }
2179
+
2180
+ return pattern
2181
+ }
2182
+
2183
+ /**
2184
+ * Generates a regular expression from a `TemplateLiteral` AST node.
2185
+ *
2186
+ * @see {@link getTemplateLiteralCapturingRegExp} for a variant that captures the pattern.
2187
+ *
2188
+ * @since 3.10.0
2189
+ */
2190
+ export const getTemplateLiteralRegExp = (ast: TemplateLiteral): RegExp =>
2191
+ new RegExp(`^${getTemplateLiteralPattern(ast, false, true)}$`)
2192
+
2193
+ /**
2194
+ * Generates a regular expression that captures the pattern defined by the given `TemplateLiteral` AST.
2195
+ *
2196
+ * @see {@link getTemplateLiteralRegExp} for a variant that does not capture the pattern.
2197
+ *
2198
+ * @since 3.10.0
2199
+ */
2200
+ export const getTemplateLiteralCapturingRegExp = (ast: TemplateLiteral): RegExp =>
2201
+ new RegExp(`^${getTemplateLiteralPattern(ast, true, true)}$`)
2202
+
2203
+ /**
2204
+ * @since 3.10.0
2205
+ */
2206
+ export const getPropertySignatures = (ast: AST): Array<PropertySignature> => {
2207
+ const annotation = getSurrogateAnnotation(ast)
2208
+ if (Option.isSome(annotation)) {
2209
+ return getPropertySignatures(annotation.value)
2210
+ }
2211
+ switch (ast._tag) {
2212
+ case "TypeLiteral":
2213
+ return ast.propertySignatures.slice()
2214
+ case "Suspend":
2215
+ return getPropertySignatures(ast.f())
2216
+ case "Refinement":
2217
+ return getPropertySignatures(ast.from)
2218
+ }
2219
+ return getPropertyKeys(ast).map((name) => getPropertyKeyIndexedAccess(ast, name))
2220
+ }
2221
+
2222
+ const getIndexSignatures = (ast: AST): Array<IndexSignature> => {
2223
+ const annotation = getSurrogateAnnotation(ast)
2224
+ if (Option.isSome(annotation)) {
2225
+ return getIndexSignatures(annotation.value)
2226
+ }
2227
+ switch (ast._tag) {
2228
+ case "TypeLiteral":
2229
+ return ast.indexSignatures.slice()
2230
+ case "Suspend":
2231
+ return getIndexSignatures(ast.f())
2232
+ case "Refinement":
2233
+ return getIndexSignatures(ast.from)
2234
+ }
2235
+ return []
2236
+ }
2237
+
2238
+ /** @internal */
2239
+ export const getNumberIndexedAccess = (ast: AST): AST => {
2240
+ switch (ast._tag) {
2241
+ case "TupleType": {
2242
+ let hasOptional = false
2243
+ let out: Array<AST> = []
2244
+ for (const e of ast.elements) {
2245
+ if (e.isOptional) {
2246
+ hasOptional = true
2247
+ }
2248
+ out.push(e.type)
2249
+ }
2250
+ if (hasOptional) {
2251
+ out.push(undefinedKeyword)
2252
+ }
2253
+ out = out.concat(getRestASTs(ast.rest))
2254
+ return Union.make(out)
2255
+ }
2256
+ case "Refinement":
2257
+ return getNumberIndexedAccess(ast.from)
2258
+ case "Union":
2259
+ return Union.make(ast.types.map(getNumberIndexedAccess))
2260
+ case "Suspend":
2261
+ return getNumberIndexedAccess(ast.f())
2262
+ }
2263
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2264
+ }
2265
+
2266
+ const getTypeLiteralPropertySignature = (ast: TypeLiteral, name: PropertyKey): PropertySignature | undefined => {
2267
+ // from property signatures...
2268
+ const ops = Arr.findFirst(ast.propertySignatures, (ps) => ps.name === name)
2269
+ if (Option.isSome(ops)) {
2270
+ return ops.value
2271
+ }
2272
+
2273
+ // from index signatures...
2274
+ if (Predicate.isString(name)) {
2275
+ let out: PropertySignature | undefined = undefined
2276
+ for (const is of ast.indexSignatures) {
2277
+ const encodedParameter = getEncodedParameter(is.parameter)
2278
+ switch (encodedParameter._tag) {
2279
+ case "TemplateLiteral": {
2280
+ const regex = getTemplateLiteralRegExp(encodedParameter)
2281
+ if (regex.test(name)) {
2282
+ return new PropertySignature(name, is.type, false, true)
2283
+ }
2284
+ break
2285
+ }
2286
+ case "StringKeyword": {
2287
+ if (out === undefined) {
2288
+ out = new PropertySignature(name, is.type, false, true)
2289
+ }
2290
+ }
2291
+ }
2292
+ }
2293
+ if (out) {
2294
+ return out
2295
+ }
2296
+ } else if (Predicate.isSymbol(name)) {
2297
+ for (const is of ast.indexSignatures) {
2298
+ const encodedParameter = getEncodedParameter(is.parameter)
2299
+ if (isSymbolKeyword(encodedParameter)) {
2300
+ return new PropertySignature(name, is.type, false, true)
2301
+ }
2302
+ }
2303
+ }
2304
+ }
2305
+
2306
+ /** @internal */
2307
+ export const getPropertyKeyIndexedAccess = (ast: AST, name: PropertyKey): PropertySignature => {
2308
+ const annotation = getSurrogateAnnotation(ast)
2309
+ if (Option.isSome(annotation)) {
2310
+ return getPropertyKeyIndexedAccess(annotation.value, name)
2311
+ }
2312
+ switch (ast._tag) {
2313
+ case "TypeLiteral": {
2314
+ const ps = getTypeLiteralPropertySignature(ast, name)
2315
+ if (ps) {
2316
+ return ps
2317
+ }
2318
+ break
2319
+ }
2320
+ case "Union":
2321
+ return new PropertySignature(
2322
+ name,
2323
+ Union.make(ast.types.map((ast) => getPropertyKeyIndexedAccess(ast, name).type)),
2324
+ false,
2325
+ true
2326
+ )
2327
+ case "Suspend":
2328
+ return getPropertyKeyIndexedAccess(ast.f(), name)
2329
+ case "Refinement":
2330
+ return getPropertyKeyIndexedAccess(ast.from, name)
2331
+ }
2332
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2333
+ }
2334
+
2335
+ const getPropertyKeys = (ast: AST): Array<PropertyKey> => {
2336
+ const annotation = getSurrogateAnnotation(ast)
2337
+ if (Option.isSome(annotation)) {
2338
+ return getPropertyKeys(annotation.value)
2339
+ }
2340
+ switch (ast._tag) {
2341
+ case "TypeLiteral":
2342
+ return ast.propertySignatures.map((ps) => ps.name)
2343
+ case "Union":
2344
+ return ast.types.slice(1).reduce(
2345
+ (out: Array<PropertyKey>, ast) => Arr.intersection(out, getPropertyKeys(ast)),
2346
+ getPropertyKeys(ast.types[0])
2347
+ )
2348
+ case "Suspend":
2349
+ return getPropertyKeys(ast.f())
2350
+ case "Refinement":
2351
+ return getPropertyKeys(ast.from)
2352
+ case "Transformation":
2353
+ return getPropertyKeys(ast.to)
2354
+ }
2355
+ return []
2356
+ }
2357
+
2358
+ /** @internal */
2359
+ export const record = (key: AST, value: AST): {
2360
+ propertySignatures: Array<PropertySignature>
2361
+ indexSignatures: Array<IndexSignature>
2362
+ } => {
2363
+ const propertySignatures: Array<PropertySignature> = []
2364
+ const indexSignatures: Array<IndexSignature> = []
2365
+ const go = (key: AST): void => {
2366
+ switch (key._tag) {
2367
+ case "NeverKeyword":
2368
+ break
2369
+ case "StringKeyword":
2370
+ case "SymbolKeyword":
2371
+ case "TemplateLiteral":
2372
+ case "Refinement":
2373
+ indexSignatures.push(new IndexSignature(key, value, true))
2374
+ break
2375
+ case "Literal":
2376
+ if (Predicate.isString(key.literal) || Predicate.isNumber(key.literal)) {
2377
+ propertySignatures.push(new PropertySignature(key.literal, value, false, true))
2378
+ } else {
2379
+ throw new Error(errors_.getASTUnsupportedLiteralErrorMessage(key.literal))
2380
+ }
2381
+ break
2382
+ case "Enums": {
2383
+ for (const [_, name] of key.enums) {
2384
+ propertySignatures.push(new PropertySignature(name, value, false, true))
2385
+ }
2386
+ break
2387
+ }
2388
+ case "UniqueSymbol":
2389
+ propertySignatures.push(new PropertySignature(key.symbol, value, false, true))
2390
+ break
2391
+ case "Union":
2392
+ key.types.forEach(go)
2393
+ break
2394
+ default:
2395
+ throw new Error(errors_.getASTUnsupportedKeySchemaErrorMessage(key))
2396
+ }
2397
+ }
2398
+ go(key)
2399
+ return { propertySignatures, indexSignatures }
2400
+ }
2401
+
2402
+ /**
2403
+ * Equivalent at runtime to the built-in TypeScript utility type `Pick`.
2404
+ *
2405
+ * @since 3.10.0
2406
+ */
2407
+ export const pick = (ast: AST, keys: ReadonlyArray<PropertyKey>): TypeLiteral | Transformation => {
2408
+ const annotation = getSurrogateAnnotation(ast)
2409
+ if (Option.isSome(annotation)) {
2410
+ return pick(annotation.value, keys)
2411
+ }
2412
+ switch (ast._tag) {
2413
+ case "TypeLiteral": {
2414
+ const pss: Array<PropertySignature> = []
2415
+ const names: Record<PropertyKey, null> = {}
2416
+ for (const ps of ast.propertySignatures) {
2417
+ names[ps.name] = null
2418
+ if (keys.includes(ps.name)) {
2419
+ pss.push(ps)
2420
+ }
2421
+ }
2422
+ for (const key of keys) {
2423
+ if (!(key in names)) {
2424
+ const ps = getTypeLiteralPropertySignature(ast, key)
2425
+ if (ps) {
2426
+ pss.push(ps)
2427
+ }
2428
+ }
2429
+ }
2430
+ return new TypeLiteral(pss, [])
2431
+ }
2432
+ case "Union":
2433
+ return new TypeLiteral(keys.map((name) => getPropertyKeyIndexedAccess(ast, name)), [])
2434
+ case "Suspend":
2435
+ return pick(ast.f(), keys)
2436
+ case "Refinement":
2437
+ return pick(ast.from, keys)
2438
+ case "Transformation": {
2439
+ switch (ast.transformation._tag) {
2440
+ case "ComposeTransformation":
2441
+ return new Transformation(
2442
+ pick(ast.from, keys),
2443
+ pick(ast.to, keys),
2444
+ composeTransformation
2445
+ )
2446
+ case "TypeLiteralTransformation": {
2447
+ const ts: Array<PropertySignatureTransformation> = []
2448
+ const fromKeys: Array<PropertyKey> = []
2449
+ for (const k of keys) {
2450
+ const t = ast.transformation.propertySignatureTransformations.find((t) => t.to === k)
2451
+ if (t) {
2452
+ ts.push(t)
2453
+ fromKeys.push(t.from)
2454
+ } else {
2455
+ fromKeys.push(k)
2456
+ }
2457
+ }
2458
+ return Arr.isNonEmptyReadonlyArray(ts) ?
2459
+ new Transformation(
2460
+ pick(ast.from, fromKeys),
2461
+ pick(ast.to, keys),
2462
+ new TypeLiteralTransformation(ts)
2463
+ ) :
2464
+ pick(ast.from, fromKeys)
2465
+ }
2466
+ }
2467
+ }
2468
+ }
2469
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2470
+ }
2471
+
2472
+ /**
2473
+ * Equivalent at runtime to the built-in TypeScript utility type `Omit`.
2474
+ *
2475
+ * @since 3.10.0
2476
+ */
2477
+ export const omit = (ast: AST, keys: ReadonlyArray<PropertyKey>): TypeLiteral | Transformation => {
2478
+ let indexSignatures = getIndexSignatures(ast)
2479
+ if (indexSignatures.length > 0) {
2480
+ if (indexSignatures.some((is) => isStringKeyword(getEncodedParameter(is.parameter)))) {
2481
+ indexSignatures = indexSignatures.filter((is) => !isTemplateLiteral(getEncodedParameter(is.parameter)))
2482
+ }
2483
+ return new TypeLiteral([], indexSignatures)
2484
+ }
2485
+ return pick(ast, getPropertyKeys(ast).filter((name) => !keys.includes(name)))
2486
+ }
2487
+
2488
+ /** @internal */
2489
+ export const orUndefined = (ast: AST): AST => Union.make([ast, undefinedKeyword])
2490
+
2491
+ /**
2492
+ * Equivalent at runtime to the built-in TypeScript utility type `Partial`.
2493
+ *
2494
+ * @since 3.10.0
2495
+ */
2496
+ export const partial = (ast: AST, options?: { readonly exact: true }): AST => {
2497
+ const exact = options?.exact === true
2498
+ switch (ast._tag) {
2499
+ case "TupleType":
2500
+ return new TupleType(
2501
+ ast.elements.map((e) => new OptionalType(exact ? e.type : orUndefined(e.type), true)),
2502
+ Arr.match(ast.rest, {
2503
+ onEmpty: () => ast.rest,
2504
+ onNonEmpty: (rest) => [new Type(Union.make([...getRestASTs(rest), undefinedKeyword]))]
2505
+ }),
2506
+ ast.isReadonly
2507
+ )
2508
+ case "TypeLiteral":
2509
+ return new TypeLiteral(
2510
+ ast.propertySignatures.map((ps) =>
2511
+ new PropertySignature(ps.name, exact ? ps.type : orUndefined(ps.type), true, ps.isReadonly, ps.annotations)
2512
+ ),
2513
+ ast.indexSignatures.map((is) => new IndexSignature(is.parameter, orUndefined(is.type), is.isReadonly))
2514
+ )
2515
+ case "Union":
2516
+ return Union.make(ast.types.map((member) => partial(member, options)))
2517
+ case "Suspend":
2518
+ return new Suspend(() => partial(ast.f(), options))
2519
+ case "Declaration":
2520
+ case "Refinement":
2521
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2522
+ case "Transformation": {
2523
+ if (
2524
+ isTypeLiteralTransformation(ast.transformation) &&
2525
+ ast.transformation.propertySignatureTransformations.every(isRenamingPropertySignatureTransformation)
2526
+ ) {
2527
+ return new Transformation(partial(ast.from, options), partial(ast.to, options), ast.transformation)
2528
+ }
2529
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2530
+ }
2531
+ }
2532
+ return ast
2533
+ }
2534
+
2535
+ /**
2536
+ * Equivalent at runtime to the built-in TypeScript utility type `Required`.
2537
+ *
2538
+ * @since 3.10.0
2539
+ */
2540
+ export const required = (ast: AST): AST => {
2541
+ switch (ast._tag) {
2542
+ case "TupleType":
2543
+ return new TupleType(
2544
+ ast.elements.map((e) => new OptionalType(e.type, false)),
2545
+ ast.rest,
2546
+ ast.isReadonly
2547
+ )
2548
+ case "TypeLiteral":
2549
+ return new TypeLiteral(
2550
+ ast.propertySignatures.map((f) => new PropertySignature(f.name, f.type, false, f.isReadonly, f.annotations)),
2551
+ ast.indexSignatures
2552
+ )
2553
+ case "Union":
2554
+ return Union.make(ast.types.map((member) => required(member)))
2555
+ case "Suspend":
2556
+ return new Suspend(() => required(ast.f()))
2557
+ case "Declaration":
2558
+ case "Refinement":
2559
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2560
+ case "Transformation": {
2561
+ if (
2562
+ isTypeLiteralTransformation(ast.transformation) &&
2563
+ ast.transformation.propertySignatureTransformations.every(isRenamingPropertySignatureTransformation)
2564
+ ) {
2565
+ return new Transformation(required(ast.from), required(ast.to), ast.transformation)
2566
+ }
2567
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2568
+ }
2569
+ }
2570
+ return ast
2571
+ }
2572
+
2573
+ /**
2574
+ * Creates a new AST with shallow mutability applied to its properties.
2575
+ *
2576
+ * @since 3.10.0
2577
+ */
2578
+ export const mutable = (ast: AST): AST => {
2579
+ switch (ast._tag) {
2580
+ case "TupleType":
2581
+ return ast.isReadonly === false ? ast : new TupleType(ast.elements, ast.rest, false, ast.annotations)
2582
+ case "TypeLiteral": {
2583
+ const propertySignatures = changeMap(
2584
+ ast.propertySignatures,
2585
+ (ps) =>
2586
+ ps.isReadonly === false ? ps : new PropertySignature(ps.name, ps.type, ps.isOptional, false, ps.annotations)
2587
+ )
2588
+ const indexSignatures = changeMap(
2589
+ ast.indexSignatures,
2590
+ (is) => is.isReadonly === false ? is : new IndexSignature(is.parameter, is.type, false)
2591
+ )
2592
+ return propertySignatures === ast.propertySignatures && indexSignatures === ast.indexSignatures ?
2593
+ ast :
2594
+ new TypeLiteral(propertySignatures, indexSignatures, ast.annotations)
2595
+ }
2596
+ case "Union": {
2597
+ const types = changeMap(ast.types, mutable)
2598
+ return types === ast.types ? ast : Union.make(types, ast.annotations)
2599
+ }
2600
+ case "Suspend":
2601
+ return new Suspend(() => mutable(ast.f()), ast.annotations)
2602
+ case "Refinement": {
2603
+ const from = mutable(ast.from)
2604
+ return from === ast.from ? ast : new Refinement(from, ast.filter, ast.annotations)
2605
+ }
2606
+ case "Transformation": {
2607
+ const from = mutable(ast.from)
2608
+ const to = mutable(ast.to)
2609
+ return from === ast.from && to === ast.to ?
2610
+ ast :
2611
+ new Transformation(from, to, ast.transformation, ast.annotations)
2612
+ }
2613
+ }
2614
+ return ast
2615
+ }
2616
+
2617
+ // -------------------------------------------------------------------------------------
2618
+ // compiler harness
2619
+ // -------------------------------------------------------------------------------------
2620
+
2621
+ /**
2622
+ * @since 3.10.0
2623
+ */
2624
+ export type Compiler<A> = (ast: AST, path: ReadonlyArray<PropertyKey>) => A
2625
+
2626
+ /**
2627
+ * @since 3.10.0
2628
+ */
2629
+ export type Match<A> = {
2630
+ [K in AST["_tag"]]: (ast: Extract<AST, { _tag: K }>, compile: Compiler<A>, path: ReadonlyArray<PropertyKey>) => A
2631
+ }
2632
+
2633
+ /**
2634
+ * @since 3.10.0
2635
+ */
2636
+ export const getCompiler = <A>(match: Match<A>): Compiler<A> => {
2637
+ const compile = (ast: AST, path: ReadonlyArray<PropertyKey>): A => match[ast._tag](ast as any, compile, path)
2638
+ return compile
2639
+ }
2640
+
2641
+ /** @internal */
2642
+ export const pickAnnotations =
2643
+ (annotationIds: ReadonlyArray<symbol>) => (annotated: Annotated): Annotations | undefined => {
2644
+ let out: { [_: symbol]: unknown } | undefined = undefined
2645
+ for (const id of annotationIds) {
2646
+ if (Object.prototype.hasOwnProperty.call(annotated.annotations, id)) {
2647
+ if (out === undefined) {
2648
+ out = {}
2649
+ }
2650
+ out[id] = annotated.annotations[id]
2651
+ }
2652
+ }
2653
+ return out
2654
+ }
2655
+
2656
+ /** @internal */
2657
+ export const omitAnnotations =
2658
+ (annotationIds: ReadonlyArray<symbol>) => (annotated: Annotated): Annotations | undefined => {
2659
+ const out = { ...annotated.annotations }
2660
+ for (const id of annotationIds) {
2661
+ delete out[id]
2662
+ }
2663
+ return out
2664
+ }
2665
+
2666
+ const preserveTransformationAnnotations = pickAnnotations([
2667
+ ExamplesAnnotationId,
2668
+ DefaultAnnotationId,
2669
+ JSONSchemaAnnotationId,
2670
+ ArbitraryAnnotationId,
2671
+ PrettyAnnotationId,
2672
+ EquivalenceAnnotationId
2673
+ ])
2674
+
2675
+ /**
2676
+ * @since 3.10.0
2677
+ */
2678
+ export const typeAST = (ast: AST): AST => {
2679
+ switch (ast._tag) {
2680
+ case "Declaration": {
2681
+ const typeParameters = changeMap(ast.typeParameters, typeAST)
2682
+ return typeParameters === ast.typeParameters ?
2683
+ ast :
2684
+ new Declaration(typeParameters, ast.decodeUnknown, ast.encodeUnknown, ast.annotations)
2685
+ }
2686
+ case "TupleType": {
2687
+ const elements = changeMap(ast.elements, (e) => {
2688
+ const type = typeAST(e.type)
2689
+ return type === e.type ? e : new OptionalType(type, e.isOptional)
2690
+ })
2691
+ const restASTs = getRestASTs(ast.rest)
2692
+ const rest = changeMap(restASTs, typeAST)
2693
+ return elements === ast.elements && rest === restASTs ?
2694
+ ast :
2695
+ new TupleType(elements, rest.map((type) => new Type(type)), ast.isReadonly, ast.annotations)
2696
+ }
2697
+ case "TypeLiteral": {
2698
+ const propertySignatures = changeMap(ast.propertySignatures, (p) => {
2699
+ const type = typeAST(p.type)
2700
+ return type === p.type ? p : new PropertySignature(p.name, type, p.isOptional, p.isReadonly)
2701
+ })
2702
+ const indexSignatures = changeMap(ast.indexSignatures, (is) => {
2703
+ const type = typeAST(is.type)
2704
+ return type === is.type ? is : new IndexSignature(is.parameter, type, is.isReadonly)
2705
+ })
2706
+ return propertySignatures === ast.propertySignatures && indexSignatures === ast.indexSignatures ?
2707
+ ast :
2708
+ new TypeLiteral(propertySignatures, indexSignatures, ast.annotations)
2709
+ }
2710
+ case "Union": {
2711
+ const types = changeMap(ast.types, typeAST)
2712
+ return types === ast.types ? ast : Union.make(types, ast.annotations)
2713
+ }
2714
+ case "Suspend":
2715
+ return new Suspend(() => typeAST(ast.f()), ast.annotations)
2716
+ case "Refinement": {
2717
+ const from = typeAST(ast.from)
2718
+ return from === ast.from ?
2719
+ ast :
2720
+ new Refinement(from, ast.filter, ast.annotations)
2721
+ }
2722
+ case "Transformation": {
2723
+ const preserve = preserveTransformationAnnotations(ast)
2724
+ return typeAST(
2725
+ preserve !== undefined ?
2726
+ annotations(ast.to, preserve) :
2727
+ ast.to
2728
+ )
2729
+ }
2730
+ }
2731
+ return ast
2732
+ }
2733
+
2734
+ function changeMap<A>(
2735
+ as: Arr.NonEmptyReadonlyArray<A>,
2736
+ f: (a: A) => A
2737
+ ): Arr.NonEmptyReadonlyArray<A>
2738
+ function changeMap<A>(as: ReadonlyArray<A>, f: (a: A) => A): ReadonlyArray<A>
2739
+ function changeMap<A>(as: ReadonlyArray<A>, f: (a: A) => A): ReadonlyArray<A> {
2740
+ let changed = false
2741
+ const out = Arr.allocate(as.length) as Array<A>
2742
+ for (let i = 0; i < as.length; i++) {
2743
+ const a = as[i]
2744
+ const fa = f(a)
2745
+ if (fa !== a) {
2746
+ changed = true
2747
+ }
2748
+ out[i] = fa
2749
+ }
2750
+ return changed ? out : as
2751
+ }
2752
+
2753
+ /**
2754
+ * Returns the from part of a transformation if it exists
2755
+ *
2756
+ * @internal
2757
+ */
2758
+ export const getTransformationFrom = (ast: AST): AST | undefined => {
2759
+ switch (ast._tag) {
2760
+ case "Transformation":
2761
+ return ast.from
2762
+ case "Refinement":
2763
+ return getTransformationFrom(ast.from)
2764
+ case "Suspend":
2765
+ return getTransformationFrom(ast.f())
2766
+ }
2767
+ }
2768
+
2769
+ const encodedAST_ = (ast: AST, isBound: boolean): AST => {
2770
+ switch (ast._tag) {
2771
+ case "Declaration": {
2772
+ const typeParameters = changeMap(ast.typeParameters, (ast) => encodedAST_(ast, isBound))
2773
+ return typeParameters === ast.typeParameters ?
2774
+ ast :
2775
+ new Declaration(typeParameters, ast.decodeUnknown, ast.encodeUnknown)
2776
+ }
2777
+ case "TupleType": {
2778
+ const elements = changeMap(ast.elements, (e) => {
2779
+ const type = encodedAST_(e.type, isBound)
2780
+ return type === e.type ? e : new OptionalType(type, e.isOptional)
2781
+ })
2782
+ const restASTs = getRestASTs(ast.rest)
2783
+ const rest = changeMap(restASTs, (ast) => encodedAST_(ast, isBound))
2784
+ return elements === ast.elements && rest === restASTs ?
2785
+ ast :
2786
+ new TupleType(elements, rest.map((ast) => new Type(ast)), ast.isReadonly)
2787
+ }
2788
+ case "TypeLiteral": {
2789
+ const propertySignatures = changeMap(ast.propertySignatures, (ps) => {
2790
+ const type = encodedAST_(ps.type, isBound)
2791
+ return type === ps.type
2792
+ ? ps
2793
+ : new PropertySignature(ps.name, type, ps.isOptional, ps.isReadonly)
2794
+ })
2795
+ const indexSignatures = changeMap(ast.indexSignatures, (is) => {
2796
+ const type = encodedAST_(is.type, isBound)
2797
+ return type === is.type ? is : new IndexSignature(is.parameter, type, is.isReadonly)
2798
+ })
2799
+ return propertySignatures === ast.propertySignatures && indexSignatures === ast.indexSignatures ?
2800
+ ast :
2801
+ new TypeLiteral(propertySignatures, indexSignatures)
2802
+ }
2803
+ case "Union": {
2804
+ const types = changeMap(ast.types, (ast) => encodedAST_(ast, isBound))
2805
+ return types === ast.types ? ast : Union.make(types)
2806
+ }
2807
+ case "Suspend": {
2808
+ let borrowedAnnotations = undefined
2809
+ const identifier = getJSONIdentifier(ast)
2810
+ if (Option.isSome(identifier)) {
2811
+ const suffix = isBound ? "Bound" : ""
2812
+ borrowedAnnotations = { [JSONIdentifierAnnotationId]: `${identifier.value}Encoded${suffix}` }
2813
+ }
2814
+ return new Suspend(() => encodedAST_(ast.f(), isBound), borrowedAnnotations)
2815
+ }
2816
+ case "Refinement": {
2817
+ const from = encodedAST_(ast.from, isBound)
2818
+ if (isBound) {
2819
+ if (from === ast.from) return ast
2820
+ if (getTransformationFrom(ast.from) === undefined && hasStableFilter(ast)) {
2821
+ return new Refinement(from, ast.filter, ast.annotations)
2822
+ }
2823
+ return from
2824
+ } else {
2825
+ return from
2826
+ }
2827
+ }
2828
+ case "Transformation":
2829
+ return encodedAST_(ast.from, isBound)
2830
+ }
2831
+ return ast
2832
+ }
2833
+
2834
+ /**
2835
+ * @since 3.10.0
2836
+ */
2837
+ export const encodedAST = (ast: AST): AST => encodedAST_(ast, false)
2838
+
2839
+ /**
2840
+ * @since 3.10.0
2841
+ */
2842
+ export const encodedBoundAST = (ast: AST): AST => encodedAST_(ast, true)
2843
+
2844
+ const toJSONAnnotations = (annotations: Annotations): object => {
2845
+ const out: Record<string, unknown> = {}
2846
+ for (const k of Object.getOwnPropertySymbols(annotations)) {
2847
+ out[String(k)] = annotations[k]
2848
+ }
2849
+ return out
2850
+ }
2851
+
2852
+ /** @internal */
2853
+ export const getEncodedParameter = (
2854
+ ast: Parameter
2855
+ ): StringKeyword | SymbolKeyword | TemplateLiteral => {
2856
+ switch (ast._tag) {
2857
+ case "StringKeyword":
2858
+ case "SymbolKeyword":
2859
+ case "TemplateLiteral":
2860
+ return ast
2861
+ case "Refinement":
2862
+ return getEncodedParameter(ast.from)
2863
+ }
2864
+ }
2865
+
2866
+ /** @internal */
2867
+ export const equals = (self: AST, that: AST): boolean => {
2868
+ switch (self._tag) {
2869
+ case "Literal":
2870
+ return isLiteral(that) && that.literal === self.literal
2871
+ case "UniqueSymbol":
2872
+ return isUniqueSymbol(that) && that.symbol === self.symbol
2873
+ case "UndefinedKeyword":
2874
+ case "VoidKeyword":
2875
+ case "NeverKeyword":
2876
+ case "UnknownKeyword":
2877
+ case "AnyKeyword":
2878
+ case "StringKeyword":
2879
+ case "NumberKeyword":
2880
+ case "BooleanKeyword":
2881
+ case "BigIntKeyword":
2882
+ case "SymbolKeyword":
2883
+ case "ObjectKeyword":
2884
+ return that._tag === self._tag
2885
+ case "TemplateLiteral":
2886
+ return isTemplateLiteral(that) && that.head === self.head && equalsTemplateLiteralSpan(that.spans, self.spans)
2887
+ case "Enums":
2888
+ return isEnums(that) && equalsEnums(that.enums, self.enums)
2889
+ case "Union":
2890
+ return isUnion(that) && equalsUnion(self.types, that.types)
2891
+ case "Refinement":
2892
+ case "TupleType":
2893
+ case "TypeLiteral":
2894
+ case "Suspend":
2895
+ case "Transformation":
2896
+ case "Declaration":
2897
+ return self === that
2898
+ }
2899
+ }
2900
+
2901
+ const equalsTemplateLiteralSpan = Arr.getEquivalence<TemplateLiteralSpan>((self, that): boolean => {
2902
+ return self.literal === that.literal && equals(self.type, that.type)
2903
+ })
2904
+
2905
+ const equalsEnums = Arr.getEquivalence<readonly [string, string | number]>((self, that) =>
2906
+ that[0] === self[0] && that[1] === self[1]
2907
+ )
2908
+
2909
+ const equalsUnion = Arr.getEquivalence<AST>(equals)
2910
+
2911
+ const intersection = Arr.intersectionWith(equals)
2912
+
2913
+ const _keyof = (ast: AST): Array<AST> => {
2914
+ switch (ast._tag) {
2915
+ case "Declaration": {
2916
+ const annotation = getSurrogateAnnotation(ast)
2917
+ if (Option.isSome(annotation)) {
2918
+ return _keyof(annotation.value)
2919
+ }
2920
+ break
2921
+ }
2922
+ case "TypeLiteral":
2923
+ return ast.propertySignatures.map((p): AST =>
2924
+ Predicate.isSymbol(p.name) ? new UniqueSymbol(p.name) : new Literal(p.name)
2925
+ ).concat(ast.indexSignatures.map((is) => getEncodedParameter(is.parameter)))
2926
+ case "Suspend":
2927
+ return _keyof(ast.f())
2928
+ case "Union":
2929
+ return ast.types.slice(1).reduce(
2930
+ (out: Array<AST>, ast) => intersection(out, _keyof(ast)),
2931
+ _keyof(ast.types[0])
2932
+ )
2933
+ case "Transformation":
2934
+ return _keyof(ast.to)
2935
+ }
2936
+ throw new Error(errors_.getASTUnsupportedSchemaErrorMessage(ast))
2937
+ }
2938
+
2939
+ /** @internal */
2940
+ export const compose = (ab: AST, cd: AST): AST => new Transformation(ab, cd, composeTransformation)
2941
+
2942
+ /** @internal */
2943
+ export const rename = (ast: AST, mapping: { readonly [K in PropertyKey]?: PropertyKey }): AST => {
2944
+ switch (ast._tag) {
2945
+ case "TypeLiteral": {
2946
+ const propertySignatureTransformations: Array<PropertySignatureTransformation> = []
2947
+ for (const key of Reflect.ownKeys(mapping)) {
2948
+ const name = mapping[key]
2949
+ if (name !== undefined) {
2950
+ propertySignatureTransformations.push(
2951
+ new PropertySignatureTransformation(
2952
+ key,
2953
+ name,
2954
+ identity,
2955
+ identity
2956
+ )
2957
+ )
2958
+ }
2959
+ }
2960
+ if (propertySignatureTransformations.length === 0) {
2961
+ return ast
2962
+ }
2963
+ return new Transformation(
2964
+ ast,
2965
+ new TypeLiteral(
2966
+ ast.propertySignatures.map((ps) => {
2967
+ const name = mapping[ps.name]
2968
+ return new PropertySignature(
2969
+ name === undefined ? ps.name : name,
2970
+ typeAST(ps.type),
2971
+ ps.isOptional,
2972
+ ps.isReadonly,
2973
+ ps.annotations
2974
+ )
2975
+ }),
2976
+ ast.indexSignatures
2977
+ ),
2978
+ new TypeLiteralTransformation(propertySignatureTransformations)
2979
+ )
2980
+ }
2981
+ case "Union":
2982
+ return Union.make(ast.types.map((ast) => rename(ast, mapping)))
2983
+ case "Suspend":
2984
+ return new Suspend(() => rename(ast.f(), mapping))
2985
+ case "Transformation":
2986
+ return compose(ast, rename(typeAST(ast), mapping))
2987
+ }
2988
+ throw new Error(errors_.getASTUnsupportedRenameSchemaErrorMessage(ast))
2989
+ }
2990
+
2991
+ const formatKeyword = (ast: AST): string => Option.getOrElse(getExpected(ast), () => ast._tag)
2992
+
2993
+ function getBrands(ast: Annotated): string {
2994
+ return Option.match(getBrandAnnotation(ast), {
2995
+ onNone: () => "",
2996
+ onSome: (brands) => brands.map((brand) => ` & Brand<${Inspectable.formatUnknown(brand)}>`).join("")
2997
+ })
2998
+ }
2999
+
3000
+ const getOrElseExpected = (ast: Annotated): Option.Option<string> =>
3001
+ getTitleAnnotation(ast).pipe(
3002
+ Option.orElse(() => getDescriptionAnnotation(ast)),
3003
+ Option.orElse(() => getAutoTitleAnnotation(ast)),
3004
+ Option.map((s) => s + getBrands(ast))
3005
+ )
3006
+
3007
+ const getExpected = (ast: Annotated): Option.Option<string> =>
3008
+ Option.orElse(getIdentifierAnnotation(ast), () => getOrElseExpected(ast))
3009
+
3010
+ /** @internal */
3011
+ export const pruneUndefined = (
3012
+ ast: AST,
3013
+ self: (ast: AST) => AST | undefined,
3014
+ onTransformation: (ast: Transformation) => AST | undefined
3015
+ ): AST | undefined => {
3016
+ switch (ast._tag) {
3017
+ case "UndefinedKeyword":
3018
+ return neverKeyword
3019
+ case "Union": {
3020
+ const types: Array<AST> = []
3021
+ let hasUndefined = false
3022
+ for (const type of ast.types) {
3023
+ const pruned = self(type)
3024
+ if (pruned) {
3025
+ hasUndefined = true
3026
+ if (!isNeverKeyword(pruned)) {
3027
+ types.push(pruned)
3028
+ }
3029
+ } else {
3030
+ types.push(type)
3031
+ }
3032
+ }
3033
+ if (hasUndefined) {
3034
+ return Union.make(types)
3035
+ }
3036
+ break
3037
+ }
3038
+ case "Suspend":
3039
+ return self(ast.f())
3040
+ case "Transformation":
3041
+ return onTransformation(ast)
3042
+ }
3043
+ }