effect-app 4.0.0-beta.3 → 4.0.0-beta.300

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 (371) hide show
  1. package/CHANGELOG.md +1592 -0
  2. package/dist/Array.d.ts +2 -1
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +4 -4
  5. package/dist/Chunk.d.ts.map +1 -1
  6. package/dist/Config/SecretURL.d.ts +3 -1
  7. package/dist/Config/SecretURL.d.ts.map +1 -1
  8. package/dist/Config/SecretURL.js +3 -6
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config/internal/configSecretURL.js +2 -2
  11. package/dist/Config.d.ts +2 -0
  12. package/dist/Config.d.ts.map +1 -0
  13. package/dist/Config.js +8 -0
  14. package/dist/ConfigProvider.d.ts +2 -0
  15. package/dist/ConfigProvider.d.ts.map +1 -0
  16. package/dist/ConfigProvider.js +6 -0
  17. package/dist/Context.d.ts +42 -0
  18. package/dist/Context.d.ts.map +1 -0
  19. package/dist/Context.js +67 -0
  20. package/dist/DataDependencies.d.ts +388 -0
  21. package/dist/DataDependencies.d.ts.map +1 -0
  22. package/dist/DataDependencies.js +64 -0
  23. package/dist/Effect.d.ts +10 -9
  24. package/dist/Effect.d.ts.map +1 -1
  25. package/dist/Effect.js +5 -7
  26. package/dist/Emailer.d.ts +51 -0
  27. package/dist/Emailer.d.ts.map +1 -0
  28. package/dist/Emailer.js +7 -0
  29. package/dist/Function.d.ts.map +1 -1
  30. package/dist/Layer.d.ts +10 -6
  31. package/dist/Layer.d.ts.map +1 -1
  32. package/dist/Layer.js +3 -2
  33. package/dist/Model/Repository/Registry.d.ts +22 -0
  34. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  35. package/dist/Model/Repository/Registry.js +18 -0
  36. package/dist/Model/Repository/ext.d.ts +60 -0
  37. package/dist/Model/Repository/ext.d.ts.map +1 -0
  38. package/dist/Model/Repository/ext.js +122 -0
  39. package/dist/Model/Repository/internal/internal.d.ts +63 -0
  40. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  41. package/dist/Model/Repository/internal/internal.js +438 -0
  42. package/dist/Model/Repository/legacy.d.ts +21 -0
  43. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  44. package/dist/Model/Repository/legacy.js +2 -0
  45. package/dist/Model/Repository/makeRepo.d.ts +54 -0
  46. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  47. package/dist/Model/Repository/makeRepo.js +27 -0
  48. package/dist/Model/Repository/service.d.ts +121 -0
  49. package/dist/Model/Repository/service.d.ts.map +1 -0
  50. package/dist/Model/Repository/service.js +2 -0
  51. package/dist/Model/Repository/validation.d.ts +58 -0
  52. package/dist/Model/Repository/validation.d.ts.map +1 -0
  53. package/dist/Model/Repository/validation.js +32 -0
  54. package/dist/Model/Repository.d.ts +7 -0
  55. package/dist/Model/Repository.d.ts.map +1 -0
  56. package/dist/Model/Repository.js +7 -0
  57. package/dist/Model/dsl.d.ts +33 -0
  58. package/dist/Model/dsl.d.ts.map +1 -0
  59. package/dist/Model/dsl.js +43 -0
  60. package/dist/Model/filter/filterApi.d.ts +30 -0
  61. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  62. package/dist/Model/filter/filterApi.js +2 -0
  63. package/dist/Model/filter/types/errors.d.ts +29 -0
  64. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  65. package/dist/Model/filter/types/errors.js +2 -0
  66. package/dist/Model/filter/types/fields.d.ts +15 -0
  67. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  68. package/dist/Model/filter/types/fields.js +2 -0
  69. package/dist/Model/filter/types/path/common.d.ts +316 -0
  70. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  71. package/dist/Model/filter/types/path/common.js +2 -0
  72. package/dist/Model/filter/types/path/eager.d.ts +94 -0
  73. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  74. package/dist/Model/filter/types/path/eager.js +36 -0
  75. package/dist/Model/filter/types/path/index.d.ts +4 -0
  76. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  77. package/dist/Model/filter/types/path/index.js +3 -0
  78. package/dist/Model/filter/types/utils.d.ts +79 -0
  79. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  80. package/dist/Model/filter/types/utils.js +2 -0
  81. package/dist/Model/filter/types/validator.d.ts +30 -0
  82. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  83. package/dist/Model/filter/types/validator.js +2 -0
  84. package/dist/Model/filter/types.d.ts +5 -0
  85. package/dist/Model/filter/types.d.ts.map +1 -0
  86. package/dist/Model/filter/types.js +7 -0
  87. package/dist/Model/query/dsl.d.ts +514 -0
  88. package/dist/Model/query/dsl.d.ts.map +1 -0
  89. package/dist/Model/query/dsl.js +376 -0
  90. package/dist/Model/query/new-kid-interpreter.d.ts +132 -0
  91. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  92. package/dist/Model/query/new-kid-interpreter.js +361 -0
  93. package/dist/Model/query.d.ts +15 -0
  94. package/dist/Model/query.d.ts.map +1 -0
  95. package/dist/Model/query.js +3 -0
  96. package/dist/Model.d.ts +5 -0
  97. package/dist/Model.d.ts.map +1 -0
  98. package/dist/Model.js +5 -0
  99. package/dist/NonEmptySet.d.ts +3 -1
  100. package/dist/NonEmptySet.d.ts.map +1 -1
  101. package/dist/NonEmptySet.js +2 -2
  102. package/dist/Option.d.ts +1 -0
  103. package/dist/Option.d.ts.map +1 -1
  104. package/dist/Option.js +3 -1
  105. package/dist/Pure.d.ts +7 -5
  106. package/dist/Pure.d.ts.map +1 -1
  107. package/dist/Pure.js +17 -14
  108. package/dist/QueueMaker.d.ts +11 -0
  109. package/dist/QueueMaker.d.ts.map +1 -0
  110. package/dist/QueueMaker.js +11 -0
  111. package/dist/RequestContext.d.ts +87 -0
  112. package/dist/RequestContext.d.ts.map +1 -0
  113. package/dist/RequestContext.js +45 -0
  114. package/dist/RequestScopedDependencies.d.ts +21 -0
  115. package/dist/RequestScopedDependencies.d.ts.map +1 -0
  116. package/dist/RequestScopedDependencies.js +16 -0
  117. package/dist/Schema/Class.d.ts +188 -19
  118. package/dist/Schema/Class.d.ts.map +1 -1
  119. package/dist/Schema/Class.js +259 -22
  120. package/dist/Schema/FastCheck.d.ts.map +1 -1
  121. package/dist/Schema/SchemaParser.d.ts +5 -0
  122. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  123. package/dist/Schema/SchemaParser.js +6 -0
  124. package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
  125. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  126. package/dist/Schema/SpecialJsonSchema.js +118 -0
  127. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  128. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  129. package/dist/Schema/SpecialOpenApi.js +123 -0
  130. package/dist/Schema/brand.d.ts +11 -6
  131. package/dist/Schema/brand.d.ts.map +1 -1
  132. package/dist/Schema/brand.js +3 -1
  133. package/dist/Schema/email.d.ts.map +1 -1
  134. package/dist/Schema/email.js +9 -5
  135. package/dist/Schema/ext.d.ts +340 -56
  136. package/dist/Schema/ext.d.ts.map +1 -1
  137. package/dist/Schema/ext.js +361 -63
  138. package/dist/Schema/moreStrings.d.ts +82 -36
  139. package/dist/Schema/moreStrings.d.ts.map +1 -1
  140. package/dist/Schema/moreStrings.js +53 -44
  141. package/dist/Schema/numbers.d.ts +34 -21
  142. package/dist/Schema/numbers.d.ts.map +1 -1
  143. package/dist/Schema/numbers.js +55 -12
  144. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  145. package/dist/Schema/phoneNumber.js +8 -4
  146. package/dist/Schema/schema.d.ts +1 -1
  147. package/dist/Schema/schema.d.ts.map +1 -1
  148. package/dist/Schema/schema.js +2 -2
  149. package/dist/Schema/strings.d.ts +18 -4
  150. package/dist/Schema/strings.d.ts.map +1 -1
  151. package/dist/Schema/strings.js +1 -5
  152. package/dist/Schema.d.ts +238 -58
  153. package/dist/Schema.d.ts.map +1 -1
  154. package/dist/Schema.js +227 -69
  155. package/dist/SchemaAST.d.ts +2 -0
  156. package/dist/SchemaAST.d.ts.map +1 -0
  157. package/dist/SchemaAST.js +2 -0
  158. package/dist/Set.d.ts +4 -1
  159. package/dist/Set.d.ts.map +1 -1
  160. package/dist/Set.js +3 -2
  161. package/dist/Store.d.ts +163 -0
  162. package/dist/Store.d.ts.map +1 -0
  163. package/dist/Store.js +113 -0
  164. package/dist/_ext/Array.d.ts +1 -1
  165. package/dist/_ext/Array.d.ts.map +1 -1
  166. package/dist/_ext/Array.js +4 -2
  167. package/dist/_ext/misc.d.ts +4 -1
  168. package/dist/_ext/misc.d.ts.map +1 -1
  169. package/dist/_ext/misc.js +4 -2
  170. package/dist/_ext/ord.ext.d.ts +2 -1
  171. package/dist/_ext/ord.ext.d.ts.map +1 -1
  172. package/dist/_ext/ord.ext.js +2 -2
  173. package/dist/builtin.d.ts +2 -14
  174. package/dist/builtin.d.ts.map +1 -1
  175. package/dist/builtin.js +1 -1
  176. package/dist/client/InvalidationKeys.d.ts +30 -0
  177. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  178. package/dist/client/InvalidationKeys.js +37 -0
  179. package/dist/client/apiClientFactory.d.ts +19 -31
  180. package/dist/client/apiClientFactory.d.ts.map +1 -1
  181. package/dist/client/apiClientFactory.js +160 -41
  182. package/dist/client/clientFor.d.ts +54 -18
  183. package/dist/client/clientFor.d.ts.map +1 -1
  184. package/dist/client/clientFor.js +9 -1
  185. package/dist/client/errors.d.ts +82 -27
  186. package/dist/client/errors.d.ts.map +1 -1
  187. package/dist/client/errors.js +75 -19
  188. package/dist/client/makeClient.d.ts +492 -32
  189. package/dist/client/makeClient.d.ts.map +1 -1
  190. package/dist/client/makeClient.js +62 -38
  191. package/dist/client.d.ts +2 -0
  192. package/dist/client.d.ts.map +1 -1
  193. package/dist/client.js +3 -1
  194. package/dist/faker.d.ts.map +1 -1
  195. package/dist/http/Request.d.ts +1 -1
  196. package/dist/http/Request.d.ts.map +1 -1
  197. package/dist/http/Request.js +5 -5
  198. package/dist/ids.d.ts +42 -14
  199. package/dist/ids.d.ts.map +1 -1
  200. package/dist/ids.js +30 -5
  201. package/dist/index.d.ts +6 -8
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +8 -9
  204. package/dist/middleware.d.ts +13 -7
  205. package/dist/middleware.d.ts.map +1 -1
  206. package/dist/middleware.js +14 -8
  207. package/dist/rpc/Invalidation.d.ts +3140 -0
  208. package/dist/rpc/Invalidation.d.ts.map +1 -0
  209. package/dist/rpc/Invalidation.js +178 -0
  210. package/dist/rpc/MiddlewareMaker.d.ts +11 -7
  211. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  212. package/dist/rpc/MiddlewareMaker.js +59 -38
  213. package/dist/rpc/RpcContextMap.d.ts +3 -3
  214. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  215. package/dist/rpc/RpcContextMap.js +4 -4
  216. package/dist/rpc/RpcMiddleware.d.ts +14 -10
  217. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  218. package/dist/rpc/RpcMiddleware.js +1 -1
  219. package/dist/rpc.d.ts +1 -1
  220. package/dist/rpc.d.ts.map +1 -1
  221. package/dist/rpc.js +2 -2
  222. package/dist/runtime.d.ts +19 -0
  223. package/dist/runtime.d.ts.map +1 -0
  224. package/dist/runtime.js +40 -0
  225. package/dist/setupRequest.d.ts +20 -0
  226. package/dist/setupRequest.d.ts.map +1 -0
  227. package/dist/setupRequest.js +72 -0
  228. package/dist/toast.d.ts +51 -0
  229. package/dist/toast.d.ts.map +1 -0
  230. package/dist/toast.js +34 -0
  231. package/dist/transform.d.ts +1 -1
  232. package/dist/transform.d.ts.map +1 -1
  233. package/dist/transform.js +4 -5
  234. package/dist/utils/effectify.d.ts +1 -1
  235. package/dist/utils/effectify.d.ts.map +1 -1
  236. package/dist/utils/effectify.js +2 -2
  237. package/dist/utils/extend.d.ts.map +1 -1
  238. package/dist/utils/gen.d.ts +4 -4
  239. package/dist/utils/gen.d.ts.map +1 -1
  240. package/dist/utils/logLevel.d.ts +2 -2
  241. package/dist/utils/logLevel.d.ts.map +1 -1
  242. package/dist/utils/logger.d.ts +4 -3
  243. package/dist/utils/logger.d.ts.map +1 -1
  244. package/dist/utils/logger.js +4 -4
  245. package/dist/utils.d.ts +50 -37
  246. package/dist/utils.d.ts.map +1 -1
  247. package/dist/utils.js +51 -36
  248. package/dist/validation/validators.d.ts.map +1 -1
  249. package/dist/validation.d.ts.map +1 -1
  250. package/dist/withToast.d.ts +30 -0
  251. package/dist/withToast.d.ts.map +1 -0
  252. package/dist/withToast.js +64 -0
  253. package/package.json +27 -255
  254. package/src/Array.ts +5 -5
  255. package/src/Chunk.ts +3 -3
  256. package/src/Config/SecretURL.ts +6 -3
  257. package/src/Config/internal/configSecretURL.ts +2 -2
  258. package/src/Config.ts +7 -0
  259. package/src/ConfigProvider.ts +5 -0
  260. package/src/{ServiceMap.ts → Context.ts} +59 -65
  261. package/src/DataDependencies.ts +114 -0
  262. package/src/Effect.ts +15 -16
  263. package/src/Emailer.ts +51 -0
  264. package/src/Inputify.type.ts +1 -1
  265. package/src/Layer.ts +11 -7
  266. package/src/Model/Repository/Registry.ts +35 -0
  267. package/src/Model/Repository/ext.ts +375 -0
  268. package/src/Model/Repository/internal/internal.ts +755 -0
  269. package/src/Model/Repository/legacy.ts +29 -0
  270. package/src/Model/Repository/makeRepo.ts +145 -0
  271. package/src/Model/Repository/service.ts +676 -0
  272. package/src/Model/Repository/validation.ts +31 -0
  273. package/src/Model/Repository.ts +6 -0
  274. package/src/Model/dsl.ts +129 -0
  275. package/src/Model/filter/filterApi.ts +60 -0
  276. package/src/Model/filter/types/errors.ts +47 -0
  277. package/src/Model/filter/types/fields.ts +50 -0
  278. package/src/Model/filter/types/path/common.ts +404 -0
  279. package/src/Model/filter/types/path/eager.ts +329 -0
  280. package/src/Model/filter/types/path/index.ts +4 -0
  281. package/src/Model/filter/types/utils.ts +128 -0
  282. package/src/Model/filter/types/validator.ts +46 -0
  283. package/src/Model/filter/types.ts +6 -0
  284. package/src/Model/query/dsl.ts +2770 -0
  285. package/src/Model/query/new-kid-interpreter.ts +526 -0
  286. package/src/Model/query.ts +13 -0
  287. package/src/Model.ts +4 -0
  288. package/src/NonEmptySet.ts +6 -4
  289. package/src/Option.ts +2 -0
  290. package/src/Pure.ts +22 -20
  291. package/src/QueueMaker.ts +11 -0
  292. package/src/RequestContext.ts +48 -0
  293. package/src/RequestScopedDependencies.ts +45 -0
  294. package/src/Schema/Class.ts +631 -63
  295. package/src/Schema/SchemaParser.ts +12 -0
  296. package/src/Schema/SpecialJsonSchema.ts +139 -0
  297. package/src/Schema/SpecialOpenApi.ts +130 -0
  298. package/src/Schema/brand.ts +34 -8
  299. package/src/Schema/email.ts +12 -5
  300. package/src/Schema/ext.ts +469 -106
  301. package/src/Schema/moreStrings.ts +155 -73
  302. package/src/Schema/numbers.ts +97 -28
  303. package/src/Schema/phoneNumber.ts +12 -6
  304. package/src/Schema/schema.ts +1 -1
  305. package/src/Schema/strings.ts +23 -14
  306. package/src/Schema.ts +468 -121
  307. package/src/SchemaAST.ts +1 -0
  308. package/src/Set.ts +6 -2
  309. package/src/Store.ts +273 -0
  310. package/src/_ext/Array.ts +4 -2
  311. package/src/_ext/misc.ts +4 -1
  312. package/src/_ext/ord.ext.ts +2 -1
  313. package/src/builtin-json.d.ts +24 -0
  314. package/src/builtin.ts +16 -21
  315. package/src/client/InvalidationKeys.ts +55 -0
  316. package/src/client/apiClientFactory.ts +306 -144
  317. package/src/client/clientFor.ts +107 -34
  318. package/src/client/errors.ts +109 -29
  319. package/src/client/makeClient.ts +593 -87
  320. package/src/client.ts +6 -4
  321. package/src/http/Request.ts +9 -6
  322. package/src/http.ts +1 -1
  323. package/src/ids.ts +34 -7
  324. package/src/index.ts +20 -24
  325. package/src/middleware.ts +13 -9
  326. package/src/rpc/Invalidation.ts +278 -0
  327. package/src/rpc/MiddlewareMaker.ts +88 -80
  328. package/src/rpc/README.md +2 -2
  329. package/src/rpc/RpcContextMap.ts +7 -6
  330. package/src/rpc/RpcMiddleware.ts +19 -13
  331. package/src/rpc.ts +4 -4
  332. package/src/runtime.ts +56 -0
  333. package/src/setupRequest.ts +138 -0
  334. package/src/toast.ts +54 -0
  335. package/src/transform.ts +4 -4
  336. package/src/utils/effectify.ts +1 -1
  337. package/src/utils/gen.ts +8 -8
  338. package/src/utils/logLevel.ts +1 -1
  339. package/src/utils/logger.ts +4 -3
  340. package/src/utils.ts +105 -156
  341. package/src/validation.ts +2 -2
  342. package/src/withToast.ts +133 -0
  343. package/test/dist/moreStrings.test.d.ts.map +1 -0
  344. package/test/dist/rpc.test.d.ts.map +1 -1
  345. package/test/dist/rpcMiddlewareContext.test.d.ts.map +1 -0
  346. package/test/dist/secretURL.test.d.ts.map +1 -0
  347. package/test/dist/special.test.d.ts.map +1 -0
  348. package/test/moreStrings.test.ts +17 -0
  349. package/test/rpc.test.ts +45 -6
  350. package/test/rpcMiddlewareContext.test.ts +63 -0
  351. package/test/schema.test.ts +613 -7
  352. package/test/secretURL.test.ts +160 -0
  353. package/test/special.test.ts +1258 -0
  354. package/test/utils.test.ts +7 -7
  355. package/tsconfig.base.json +6 -5
  356. package/tsconfig.json +3 -1
  357. package/tsconfig.src.json +29 -29
  358. package/tsconfig.test.json +2 -2
  359. package/dist/Operations.d.ts +0 -87
  360. package/dist/Operations.d.ts.map +0 -1
  361. package/dist/Operations.js +0 -29
  362. package/dist/ServiceMap.d.ts +0 -44
  363. package/dist/ServiceMap.d.ts.map +0 -1
  364. package/dist/ServiceMap.js +0 -91
  365. package/dist/Struct.d.ts +0 -44
  366. package/dist/Struct.d.ts.map +0 -1
  367. package/dist/Struct.js +0 -29
  368. package/eslint.config.mjs +0 -26
  369. package/src/Operations.ts +0 -55
  370. package/src/Struct.ts +0 -54
  371. package/tsconfig.json.bak +0 -12
package/src/Schema.ts CHANGED
@@ -1,37 +1,344 @@
1
- import { Array, Option, pipe, SchemaAST, type Tracer } from "effect"
2
1
  import * as S from "effect/Schema"
3
- import type { NonEmptyReadonlyArray } from "./Array.js"
4
- import { fakerArb } from "./faker.js"
5
- import { Email as EmailT } from "./Schema/email.js"
6
- import { withDefaultMake } from "./Schema/ext.js"
7
- import { PhoneNumber as PhoneNumberT } from "./Schema/phoneNumber.js"
8
- import type { AST } from "./Schema/schema.js"
9
- import { extendM } from "./utils.js"
2
+ import { type Simplify } from "effect/Struct"
3
+ import type * as Tracer from "effect/Tracer"
4
+ import type { RequiredKeys } from "effect/Types"
5
+ import type { NonEmptyReadonlyArray } from "./Array.ts"
6
+ import { fakerArb } from "./faker.ts"
7
+ import { Email as EmailT, type Email as EmailType } from "./Schema/email.ts"
8
+ import { concurrencyUnbounded, withDefaultMake, withDefaultParseOptions } from "./Schema/ext.ts"
9
+ import { PhoneNumber as PhoneNumberT, type PhoneNumber as PhoneNumberType } from "./Schema/phoneNumber.ts"
10
+ import { type AST } from "./Schema/schema.ts"
11
+ import * as SchemaAST from "./SchemaAST.ts"
12
+ import { copy, extendM, type StructuralCopyOrigin } from "./utils.ts"
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Default helpers — re-exported from effect/Schema
16
+ //
17
+ // The five helpers below are surfaced explicitly so the (important) policy
18
+ // around them lives next to the export. See also the file-level note in
19
+ // `./Schema/ext.ts` and the documented wrappers in
20
+ // `./Schema/ext.ts`, `./Schema/numbers.ts`, `./Schema/moreStrings.ts`,
21
+ // and `./ids.ts`.
22
+ //
23
+ // **Construction-only**: `withConstructorDefault` fills the field when it
24
+ // is omitted from `.make(...)` input. It is NOT applied during decode, so
25
+ // it CANNOT be used to just-in-time migrate database fields. A stored
26
+ // record missing the field will still fail to decode.
27
+ //
28
+ // **`withDecodingDefault*` is discouraged**: a missing field in persisted
29
+ // data is just as likely to be data corruption as it is an old-shape
30
+ // document; silently substituting a default hides the problem and can
31
+ // poison downstream aggregates. Prefer an explicit, preferably versioned
32
+ // migration of database data over shoving missing fields under the rug.
33
+ // ---------------------------------------------------------------------------
34
+
35
+ /**
36
+ * Attach a default value used **only** when constructing a value (e.g. via
37
+ * `.make(...)` or struct constructors) and the field is omitted from input.
38
+ *
39
+ * **Not applied during decode.** Decoding a payload that is missing the
40
+ * field will still raise a parse error. Do **not** rely on this to migrate
41
+ * database fields just-in-time — see the section header above.
42
+ *
43
+ * @see {@link withDecodingDefault} / {@link withDecodingDefaultType} —
44
+ * decode-time variants (discouraged for persisted data; use explicit,
45
+ * versioned migrations instead).
46
+ */
47
+ export { withConstructorDefault } from "effect/Schema"
48
+
49
+ /**
50
+ * Attach a default value used during decode when the field's `Encoded` value
51
+ * is missing **or** `undefined`. The default is specified as an `Encoded`
52
+ * value and threaded through the schema's decode step.
53
+ *
54
+ * **Discouraged for persisted data.** A missing field in a stored record is
55
+ * just as likely to be data corruption as it is an old-shape document;
56
+ * silently substituting a default hides the problem. Prefer an explicit,
57
+ * preferably versioned migration of database data — see the section header
58
+ * above.
59
+ *
60
+ * @see {@link withDecodingDefaultKey} — key-absent-only variant
61
+ * @see {@link withDecodingDefaultType} — `Type`-side variant
62
+ * @see {@link withConstructorDefault} — for `.make(...)`-time defaults
63
+ */
64
+ export { withDecodingDefault } from "effect/Schema"
65
+
66
+ /**
67
+ * Attach a default value used during decode when the field **key is absent**
68
+ * (note: not when present and `undefined`). The default is an `Encoded`
69
+ * value.
70
+ *
71
+ * **Discouraged for persisted data** — same reasoning as
72
+ * {@link withDecodingDefault}. Use explicit, preferably versioned migrations
73
+ * over decode-time fallbacks.
74
+ *
75
+ * @see {@link withDecodingDefault} — value-absent-or-undefined variant
76
+ * @see {@link withDecodingDefaultTypeKey} — `Type`-side variant
77
+ * @see {@link withConstructorDefault} — for `.make(...)`-time defaults
78
+ */
79
+ export { withDecodingDefaultKey } from "effect/Schema"
80
+
81
+ /**
82
+ * Attach a default value used during decode when the field is missing **or**
83
+ * `undefined`. The default is specified as a `Type` value (i.e. on the
84
+ * decoded side).
85
+ *
86
+ * **Discouraged for persisted data** — same reasoning as
87
+ * {@link withDecodingDefault}. Use explicit, preferably versioned migrations
88
+ * over decode-time fallbacks.
89
+ *
90
+ * @see {@link withDecodingDefault} — `Encoded`-side variant
91
+ * @see {@link withDecodingDefaultTypeKey} — key-absent-only variant
92
+ * @see {@link withConstructorDefault} — for `.make(...)`-time defaults
93
+ */
94
+ export { withDecodingDefaultType } from "effect/Schema"
95
+
96
+ /**
97
+ * Attach a default value used during decode when the field **key is absent**
98
+ * (note: not when present and `undefined`). The default is a `Type` value.
99
+ *
100
+ * **Discouraged for persisted data** — same reasoning as
101
+ * {@link withDecodingDefault}. Use explicit, preferably versioned migrations
102
+ * over decode-time fallbacks.
103
+ *
104
+ * @see {@link withDecodingDefaultKey} — `Encoded`-side variant
105
+ * @see {@link withDecodingDefaultType} — value-absent-or-undefined variant
106
+ * @see {@link withConstructorDefault} — for `.make(...)`-time defaults
107
+ */
108
+ export { withDecodingDefaultTypeKey } from "effect/Schema"
10
109
 
11
110
  export * from "effect/Schema"
12
- // v4: TaggedError renamed to TaggedErrorClass
13
- export { TaggedErrorClass as TaggedError } from "effect/Schema"
14
111
 
15
- export * from "./Schema/Class.js"
16
- export { Class, TaggedClass } from "./Schema/Class.js"
112
+ export * from "./Schema/Class.ts"
113
+ export { Class, ErrorClass, Opaque, OpaqueErrorFacadeClass, OpaqueFacade, OpaqueShape, OpaqueType, TaggedClass, TaggedErrorClass } from "./Schema/Class.ts"
17
114
 
18
- export { fromBrand, nominal } from "./Schema/brand.js"
19
- export { Array, Boolean, Date, Literal, Map, NullOr, Number, ReadonlyMap, ReadonlySet } from "./Schema/ext.js"
20
- export { Int, NonNegativeInt } from "./Schema/numbers.js"
115
+ export { fromBrand, nominal } from "./Schema/brand.ts"
116
+ export { Array, Boolean, Date, DateFromString, DateValid, Finite, Literals, NullOr, Number, ReadonlyMap, ReadonlySet } from "./Schema/ext.ts"
117
+ export { Int, NonNegativeInt } from "./Schema/numbers.ts"
21
118
 
22
- export * from "./Schema/email.js"
23
- export * from "./Schema/ext.js"
24
- export * from "./Schema/moreStrings.js"
25
- export * from "./Schema/numbers.js"
26
- export * from "./Schema/phoneNumber.js"
27
- export * from "./Schema/schema.js"
28
- export * from "./Schema/strings.js"
29
- export { NonEmptyString } from "./Schema/strings.js"
119
+ export * from "./Schema/email.ts"
120
+ export * from "./Schema/ext.ts"
121
+ export * from "./Schema/moreStrings.ts"
122
+ export * from "./Schema/numbers.ts"
123
+ export * from "./Schema/phoneNumber.ts"
124
+ export * from "./Schema/schema.ts"
125
+ export * from "./Schema/SpecialJsonSchema.ts"
126
+ export * from "./Schema/SpecialOpenApi.ts"
127
+ export * from "./Schema/strings.ts"
128
+ export { NonEmptyString } from "./Schema/strings.ts"
30
129
 
31
130
  export * as SchemaIssue from "effect/SchemaIssue"
32
- export * as SchemaParser from "effect/SchemaParser"
33
131
 
34
- export { Void as Void_ } from "effect/Schema"
132
+ export const decodeEffectConcurrently: typeof S.decodeEffect = withDefaultParseOptions(S.decodeEffect)
133
+ export const decodeUnknownEffectConcurrently: typeof S.decodeUnknownEffect = withDefaultParseOptions(
134
+ S.decodeUnknownEffect
135
+ )
136
+ export * as SchemaParser from "./Schema/SchemaParser.ts"
137
+
138
+ /**
139
+ * Schema for a TypeScript `void` return value — the canonical `Void` used
140
+ * across the app, including RPC success schemas. Accepts **any present value**
141
+ * at runtime and discards it to `undefined`, while keeping the decoded/encoded
142
+ * type as `void`. Use `S.Undefined` when the input must be exactly `undefined`.
143
+ */
144
+ export interface Void extends S.Void {}
145
+ export const Void: Void = S.Void
146
+
147
+ // ---------------------------------------------------------------------------
148
+ // Struct / NonEmptyArray / Record
149
+ // ---------------------------------------------------------------------------
150
+
151
+ export function Struct<const Fields extends S.Struct.Fields>(
152
+ fields: Fields
153
+ ): Struct<Fields> {
154
+ const result = S.Struct(fields).annotate(concurrencyUnbounded)
155
+ const allowVoidMake = (schema: any): any => {
156
+ // Normalize omitted input to an empty object so optional/default-only structs can be constructed with make().
157
+ const origMake: any = schema.make
158
+ const origMakeOption: any = schema.makeOption
159
+ const origMakeEffect: any = schema.makeEffect
160
+ schema.make = function(this: any, input: any, options?: any) {
161
+ return origMake.call(this, input === undefined ? {} : input, options)
162
+ }
163
+ schema.makeOption = function(this: any, input: any, options?: any) {
164
+ return origMakeOption.call(this, input === undefined ? {} : input, options)
165
+ }
166
+ schema.makeEffect = function(this: any, input: any, options?: any) {
167
+ return origMakeEffect.call(this, input === undefined ? {} : input, options)
168
+ }
169
+ return schema
170
+ }
171
+ // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unsafe-assignment
172
+ const origMapFields: any = result.mapFields
173
+ // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unsafe-assignment
174
+ const origAnnotate: any = result.annotate
175
+ // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unsafe-assignment
176
+ const origAnnotateKey: any = result.annotateKey
177
+
178
+ const preserveCopyAndMethods = (schema: any): any => {
179
+ schema.copy = copy
180
+ schema.mapFields = function(this: any, f: any, options?: any) {
181
+ return (result as any).mapFields.call(this, f, options)
182
+ }
183
+ schema.annotate = function(this: any, annotations?: any) {
184
+ return (result as any).annotate.call(this, annotations)
185
+ }
186
+ schema.annotateKey = function(this: any, annotations?: any) {
187
+ return (result as any).annotateKey.call(this, annotations)
188
+ }
189
+ return allowVoidMake(schema)
190
+ }
191
+ ;(result as any).mapFields = function(this: any, f: any, options?: any) {
192
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
193
+ const mapped = origMapFields.call(this, f, options).annotate(concurrencyUnbounded)
194
+ return preserveCopyAndMethods(mapped)
195
+ }
196
+ ;(result as any).annotate = function(this: any, annotations?: any) {
197
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
198
+ const annotated = origAnnotate.call(this, annotations)
199
+ return preserveCopyAndMethods(annotated)
200
+ }
201
+ ;(result as any).annotateKey = function(this: any, annotations?: any) {
202
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
203
+ const annotated = origAnnotateKey.call(this, annotations)
204
+ return preserveCopyAndMethods(annotated)
205
+ }
206
+ ;(result as any).copy = copy
207
+ allowVoidMake(result)
208
+ return result as Struct<Fields>
209
+ }
210
+
211
+ export interface Struct<Fields extends S.Struct.Fields> extends
212
+ S.Bottom<
213
+ Struct.Type<Fields>,
214
+ Struct.Encoded<Fields>,
215
+ Struct.DecodingServices<Fields>,
216
+ Struct.EncodingServices<Fields>,
217
+ AST.Objects,
218
+ // Rebuild is what's returned from annotate etc
219
+ Struct<Fields>,
220
+ Struct.MakeIn<Fields>,
221
+ Struct.Iso<Fields>
222
+ >
223
+ {
224
+ /**
225
+ * The field definitions of this struct. Spread them into a new struct to
226
+ * reuse fields across schemas.
227
+ *
228
+ * **Example** (Reusing fields across structs)
229
+ *
230
+ * ```ts
231
+ * import * as Schema from "effect/Schema"
232
+ *
233
+ * const Timestamped = Schema.Struct({
234
+ * createdAt: Schema.Date,
235
+ * updatedAt: Schema.Date
236
+ * })
237
+ *
238
+ * const User = Schema.Struct({
239
+ * ...Timestamped.fields,
240
+ * name: Schema.String,
241
+ * email: Schema.String
242
+ * })
243
+ * ```
244
+ */
245
+ readonly fields: Fields
246
+ /**
247
+ * Returns a new struct with the fields modified by the provided function.
248
+ *
249
+ * **Options**
250
+ *
251
+ * - `unsafePreserveChecks` - if `true`, keep any `.check(...)` constraints
252
+ * that were attached to the original union. Defaults to `false`.
253
+ *
254
+ * **Warning**: This is an unsafe operation. Since `mapFields`
255
+ * transformations change the schema type, the original refinement functions
256
+ * may no longer be valid or safe to apply to the transformed schema. Only
257
+ * use this option if you have verified that your refinements remain correct
258
+ * after the transformation.
259
+ */
260
+ mapFields<To extends Struct.Fields>(
261
+ f: (fields: Fields) => To,
262
+ options?: {
263
+ readonly unsafePreserveChecks?: boolean | undefined
264
+ } | undefined
265
+ ): Struct<Simplify<Readonly<To>>>
266
+
267
+ // added copy
268
+ readonly copy: StructuralCopyOrigin<Struct.Type<Fields>>
269
+ }
270
+
271
+ export declare namespace Struct {
272
+ export type Fields = S.Struct.Fields
273
+ export type Type<F extends S.Struct.Fields> = S.Struct.Type<F>
274
+ export type Encoded<F extends S.Struct.Fields> = S.Struct.Encoded<F>
275
+ export type DecodingServices<F extends S.Struct.Fields> = S.Struct.DecodingServices<F>
276
+ export type EncodingServices<F extends S.Struct.Fields> = S.Struct.EncodingServices<F>
277
+ // changed; all optional allows void
278
+ export type MakeIn<F extends S.Struct.Fields> = RequiredKeys<S.Struct.MakeIn<F>> extends never
279
+ ? void | S.Struct.MakeIn<F>
280
+ : S.Struct.MakeIn<F>
281
+ export type Iso<F extends S.Struct.Fields> = S.Struct.Iso<F>
282
+ }
283
+
284
+ export type StructNestedEncodedError<T> = {
285
+ readonly _tag: "StructNestedEncodedError"
286
+ readonly message: "Expected a Struct schema or a schema with from.Encoded"
287
+ readonly schema: T
288
+ }
289
+
290
+ export type StructNestedEncoded<T> = T extends { fields: infer Fields extends S.Struct.Fields } ? Struct.Encoded<Fields>
291
+ : T extends { readonly from: { readonly Encoded: infer Encoded } } ? Encoded
292
+ : StructNestedEncodedError<T>
293
+
294
+ export function NonEmptyArray<Value extends S.Top>(value: Value): S.NonEmptyArray<Value> {
295
+ return S.NonEmptyArray(value).annotate(concurrencyUnbounded)
296
+ }
297
+
298
+ export function TaggedStruct<const Tag extends SchemaAST.LiteralValue, const Fields extends S.Struct.Fields>(
299
+ value: Tag,
300
+ fields: Fields
301
+ ): TaggedStruct<Tag, Fields> {
302
+ return Struct({ _tag: S.tag(value), ...fields }) as any
303
+ }
304
+ export interface TaggedStruct<Tag extends SchemaAST.LiteralValue, Fields extends S.Struct.Fields>
305
+ extends Struct<{ readonly _tag: S.tag<Tag> } & Fields>
306
+ {}
307
+ export declare namespace TaggedStruct {
308
+ export type Fields = S.Struct.Fields
309
+ export type Type<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Type<
310
+ { readonly _tag: S.tag<Tag> } & F
311
+ >
312
+ export type Encoded<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Encoded<
313
+ { readonly _tag: S.tag<Tag> } & F
314
+ >
315
+ export type DecodingServices<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> =
316
+ S.Struct.DecodingServices<
317
+ { readonly _tag: S.tag<Tag> } & F
318
+ >
319
+ export type EncodingServices<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> =
320
+ S.Struct.EncodingServices<
321
+ { readonly _tag: S.tag<Tag> } & F
322
+ >
323
+ export type MakeIn<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.MakeIn<
324
+ { readonly _tag: S.tag<Tag> } & F
325
+ >
326
+ export type Iso<Tag extends SchemaAST.LiteralValue, F extends S.Struct.Fields> = S.Struct.Iso<
327
+ { readonly _tag: S.tag<Tag> } & F
328
+ >
329
+ }
330
+
331
+ export function Record<Key extends S.Record.Key, Value extends S.Top>(
332
+ key: Key,
333
+ value: Value
334
+ ): S.$Record<Key, Value> {
335
+ return S.Record(key, value).annotate(concurrencyUnbounded)
336
+ }
337
+ export declare namespace Record {
338
+ export type Key = S.Record.Key
339
+ export type Type<K extends S.Record.Key, V extends S.Top> = S.Record.Type<K, V>
340
+ export type Encoded<K extends S.Record.Key, V extends S.Top> = S.Record.Encoded<K, V>
341
+ }
35
342
 
36
343
  export const SpanId = Symbol()
37
344
  export type SpanId = typeof SpanId
@@ -40,127 +347,167 @@ export interface WithOptionalSpan {
40
347
  [SpanId]?: Tracer.Span
41
348
  }
42
349
 
350
+ const makeEmail = S.decodeSync(EmailT as any) as (value: string) => EmailType
351
+ const makePhoneNumber = S.decodeSync(PhoneNumberT as any) as (value: string) => PhoneNumberType
352
+
43
353
  export const Email = EmailT
44
354
  .pipe(
45
355
  S.annotate({
46
356
  // eslint-disable-next-line @typescript-eslint/unbound-method
47
- arbitrary: (): any => (fc: any) => fakerArb((faker) => faker.internet.exampleEmail)(fc).map(Email)
357
+ toArbitrary: () => (fc) => fakerArb((faker) => faker.internet.exampleEmail)(fc).map(makeEmail)
48
358
  }),
49
359
  withDefaultMake
50
360
  )
51
361
 
52
- export type Email = EmailT
362
+ export type Email = EmailType
53
363
 
54
364
  export const PhoneNumber = PhoneNumberT
55
365
  .pipe(
56
366
  S.annotate({
57
- arbitrary: (): any => (fc: any) =>
367
+ toArbitrary: () => (fc) =>
58
368
  // eslint-disable-next-line @typescript-eslint/unbound-method
59
- fakerArb((faker) => faker.phone.number)(fc).map(PhoneNumber)
369
+ fakerArb((faker) => faker.phone.number)(fc).map(makePhoneNumber)
60
370
  }),
61
371
  withDefaultMake
62
372
  )
63
373
 
64
- export const makeIs = <A extends { _tag: string }, I, R>(
65
- schema: S.Codec<A, I, R>
66
- ) => {
67
- // In v4, transformations are stored as encoding on nodes, not as wrapper nodes.
68
- // Union member ASTs are directly Objects (TypeLiteral equivalent).
69
- if (SchemaAST.isUnion(schema.ast)) {
70
- return schema.ast.types.reduce((acc: any, t: AST.AST) => {
71
- if (!SchemaAST.isObjects(t)) return acc
72
- const tag = Array.findFirst(t.propertySignatures, (_: any) => {
73
- if (_.name === "_tag" && SchemaAST.isLiteral(_.type)) {
74
- return Option.some(_.type)
75
- }
76
- return Option.none()
77
- })
78
- const ast = Option.getOrUndefined(tag)
79
- if (!ast) {
80
- return acc
81
- }
82
- return {
83
- ...acc,
84
- [String((ast as SchemaAST.Literal).literal)]: (x: { _tag: string }) =>
85
- x._tag === (ast as SchemaAST.Literal).literal
86
- }
87
- }, {} as Is<A>)
88
- }
89
- throw new Error("Unsupported")
90
- }
374
+ export type PhoneNumber = PhoneNumberType
91
375
 
92
- export const makeIsAnyOf = <A extends { _tag: string }, I, R>(
93
- schema: S.Codec<A, I, R>
94
- ): IsAny<A> => {
95
- if (SchemaAST.isUnion(schema.ast)) {
96
- return <Keys extends A["_tag"][]>(...keys: Keys) => (a: A): a is ExtractUnion<A, ElemType<Keys>> =>
97
- keys.includes(a._tag)
98
- }
99
- throw new Error("Unsupported")
376
+ // Copied from SchemaAST.collectSentinels (marked @internal in effect).
377
+ // Returns all { key, literal } pairs that can discriminate a union member.
378
+ const getTagFromAST = (schema: S.Top): string => {
379
+ const sentinels = collectSentinelsFromAST(schema.ast)
380
+ const sentinel = sentinels.find((s) => s.key === "_tag")
381
+ if (sentinel !== undefined && typeof sentinel.literal === "string") return sentinel.literal
382
+ throw new Error("No _tag literal found on schema member")
100
383
  }
101
384
 
102
- export type ExtractUnion<A extends { _tag: string }, Tags extends A["_tag"]> = Extract<A, Record<"_tag", Tags>>
103
- export type Is<A extends { _tag: string }> = { [K in A as K["_tag"]]: (a: A) => a is K }
104
- export type ElemType<A> = A extends Array<infer E> ? E : never
105
- export interface IsAny<A extends { _tag: string }> {
106
- <Keys extends A["_tag"][]>(...keys: Keys): (a: A) => a is ExtractUnion<A, ElemType<Keys>>
385
+ function collectSentinelsFromAST(
386
+ ast: SchemaAST.AST
387
+ ): Array<{ key: PropertyKey; literal: SchemaAST.LiteralValue | symbol }> {
388
+ switch (ast._tag) {
389
+ case "Declaration": {
390
+ const s = ast.annotations?.["~sentinels"]
391
+ return Array.isArray(s) ? s : []
392
+ }
393
+ case "Objects":
394
+ return ast.propertySignatures.flatMap(
395
+ (ps): Array<{ key: PropertyKey; literal: SchemaAST.LiteralValue | symbol }> => {
396
+ const type = ps.type
397
+ if (!SchemaAST.isOptional(type)) {
398
+ if (SchemaAST.isLiteral(type)) return [{ key: ps.name, literal: type.literal }]
399
+ if (SchemaAST.isUniqueSymbol(type)) return [{ key: ps.name, literal: type.symbol }]
400
+ }
401
+ return []
402
+ }
403
+ )
404
+ case "Suspend":
405
+ return collectSentinelsFromAST(ast.thunk())
406
+ default:
407
+ return []
408
+ }
107
409
  }
108
410
 
109
- export const taggedUnionMap = <
110
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
- Members extends readonly (S.Top & { fields: { _tag: S.tag<string> } })[]
112
- >(
113
- self: Members
114
- ) =>
115
- self.reduce((acc, key) => {
116
- // TODO: v4 migration — PropertySignatureDeclaration removed, need v4 AST traversal
117
- const ast = key.fields._tag.ast as any
118
- const tag = ((ast.type ?? ast) as SchemaAST.Literal).literal as string // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
119
- ;(acc as any)[tag] = key as any
120
- return acc
121
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
- }, {} as any)
123
-
124
411
  export const tags = <
125
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
- Members extends NonEmptyReadonlyArray<(S.Top & { fields: { _tag: S.tag<string> } })>
412
+ Members extends NonEmptyReadonlyArray<(S.Top & { readonly Type: { readonly _tag: string } })>
127
413
  >(
128
414
  self: Members
129
415
  ) =>
130
- S.Literals(self.map((key) => {
131
- // TODO: v4 migration — PropertySignatureDeclaration removed, need v4 AST traversal
132
- const ast = key.fields._tag.ast as any
133
- const tag = ((ast.type ?? ast) as SchemaAST.Literal).literal
134
- return tag
135
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
- })) as any
137
-
138
- export const ExtendTaggedUnion = <A extends { _tag: string }, I, R>(
139
- schema: S.Codec<A, I, R>
140
- ) =>
141
- extendM(
142
- schema,
143
- (_) => ({
144
- is: S.is(schema as any),
145
- isA: makeIs(_ as any),
146
- isAnyOf: makeIsAnyOf(_ as any) /*, map: taggedUnionMap(a) */
147
- })
148
- )
416
+ S.Literals(
417
+ self.map(getTagFromAST) as {
418
+ [Index in keyof Members]: Members[Index]["Type"]["_tag"]
419
+ }
420
+ ) as S.Literals<
421
+ {
422
+ [Index in keyof Members]: Members[Index]["Type"]["_tag"]
423
+ }
424
+ >
149
425
 
150
- export const TaggedUnion = <
151
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
- Members extends readonly (S.Top & { fields: { _tag: S.tag<any> } })[]
153
- >(...a: Members) =>
154
- pipe(
155
- S.Union(a),
156
- (_) =>
157
- extendM(_, (_) => ({
158
- is: S.is(_ as any),
159
- isA: makeIs(_ as any),
160
- isAnyOf: makeIsAnyOf(_ as any),
161
- tagMap: taggedUnionMap(a),
162
- tags: tags(a as any)
163
- }))
164
- )
426
+ type TaggedUnionMembers = NonEmptyReadonlyArray<
427
+ S.Top & { readonly Type: { readonly _tag: string } }
428
+ >
165
429
 
166
- export type PhoneNumber = PhoneNumberT
430
+ type TaggedUnionTags<Members extends TaggedUnionMembers> = S.Literals<
431
+ {
432
+ [Index in keyof Members]: Members[Index]["Type"]["_tag"]
433
+ }
434
+ >
435
+
436
+ type TaggedPropertyKeys<A, Members extends TaggedUnionMembers> = {
437
+ [K in keyof A & string]: A[K] extends Members[number]["Type"] ? K : never
438
+ }[keyof A & string]
439
+
440
+ type PropertyGuardsFor<
441
+ Members extends TaggedUnionMembers,
442
+ K extends string,
443
+ A
444
+ > =
445
+ & {
446
+ readonly [M in Members[number] as `is${M["Type"]["_tag"]}`]: (
447
+ target: A
448
+ ) => target is A & { readonly [P in K]: M["Type"] }
449
+ }
450
+ & {
451
+ readonly isAnyOf: <const Tags extends ReadonlyArray<Members[number]["Type"]["_tag"]>>(
452
+ tags: Tags
453
+ ) => (
454
+ target: A
455
+ ) => target is A & { readonly [P in K]: Extract<Members[number]["Type"], { readonly _tag: Tags[number] }> }
456
+ }
457
+
458
+ type PropertyGuards<
459
+ Members extends TaggedUnionMembers,
460
+ K extends string
461
+ > =
462
+ & {
463
+ readonly [M in Members[number] as `is${M["Type"]["_tag"]}`]: <
464
+ T extends { readonly [P in K]: Members[number]["Type"] }
465
+ >(target: T) => target is T & { readonly [P in K]: M["Type"] }
466
+ }
467
+ & {
468
+ readonly isAnyOf: <const Tags extends ReadonlyArray<Members[number]["Type"]["_tag"]>>(
469
+ tags: Tags
470
+ ) => <T extends { readonly [P in K]: Members[number]["Type"] }>(
471
+ target: T
472
+ ) => target is T & { readonly [P in K]: Extract<Members[number]["Type"], { readonly _tag: Tags[number] }> }
473
+ }
474
+
475
+ type TaggedUnionWithTags<Members extends TaggedUnionMembers> = S.toTaggedUnion<"_tag", Members> & {
476
+ readonly tags: TaggedUnionTags<Members>
477
+ readonly generateGuards: <K extends string>(property: K) => PropertyGuards<Members, K>
478
+ readonly generateGuardsFor: <A>() => <K extends TaggedPropertyKeys<A, Members>>(
479
+ property: K
480
+ ) => PropertyGuardsFor<Members, K, A>
481
+ }
482
+
483
+ const extendTaggedUnionWithTags = <Members extends TaggedUnionMembers>(
484
+ schema: S.Union<Members>
485
+ ): TaggedUnionWithTags<Members> =>
486
+ extendM(schema.pipe(S.toTaggedUnion("_tag")), (tagged) => {
487
+ const makeGuards = (property: string) => {
488
+ const result: any = {}
489
+ const guards: Record<string, (u: unknown) => boolean> = tagged.guards
490
+ for (const tag of Object.keys(guards)) {
491
+ const guard = guards[tag]!
492
+ result[`is${tag}`] = (target: any) => guard(target[property])
493
+ }
494
+ result.isAnyOf = (memberTags: Array<string>) => {
495
+ const check = tagged.isAnyOf(memberTags)
496
+ return (target: any) => check(target[property])
497
+ }
498
+ return result
499
+ }
500
+ return {
501
+ tags: tags(schema.members),
502
+ generateGuards: makeGuards,
503
+ generateGuardsFor: () => makeGuards
504
+ }
505
+ })
506
+
507
+ export const ExtendTaggedUnion = <Members extends TaggedUnionMembers>(
508
+ schema: S.Union<Members>
509
+ ): TaggedUnionWithTags<Members> => extendTaggedUnionWithTags(schema)
510
+
511
+ export const TaggedUnion = <
512
+ Members extends TaggedUnionMembers
513
+ >(members: Members): TaggedUnionWithTags<Members> => extendTaggedUnionWithTags(S.Union(members))
@@ -0,0 +1 @@
1
+ export * from "effect/SchemaAST"
package/src/Set.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  // ets_tracing: off
2
2
 
3
- import { Array, type Equivalence, Option, type Order, type Result } from "effect"
3
+ import * as Array from "effect/Array"
4
+ import type * as Equivalence from "effect/Equivalence"
5
+ import * as Option from "effect/Option"
6
+ import type * as Order from "effect/Order"
4
7
  import { not } from "effect/Predicate"
5
- import { identity, pipe, type Predicate, type Refinement, tuple } from "./Function.js"
8
+ import type * as Result from "effect/Result"
9
+ import { identity, pipe, type Predicate, type Refinement, tuple } from "./Function.ts"
6
10
 
7
11
  export function find_<A, B extends A>(
8
12
  as: ReadonlySet<A>,