effect-app 4.0.0-beta.33 → 4.0.0-beta.331

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