effect-start 0.25.0 → 0.26.0

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 (117) hide show
  1. package/package.json +18 -86
  2. package/dist/ChildProcess.js +0 -42
  3. package/dist/Commander.js +0 -410
  4. package/dist/ContentNegotiation.js +0 -465
  5. package/dist/Cookies.js +0 -371
  6. package/dist/Development.js +0 -94
  7. package/dist/Effectify.js +0 -27
  8. package/dist/Entity.js +0 -289
  9. package/dist/Fetch.js +0 -192
  10. package/dist/FilePathPattern.js +0 -97
  11. package/dist/FileRouter.js +0 -204
  12. package/dist/FileRouterCodegen.js +0 -298
  13. package/dist/FileSystem.js +0 -132
  14. package/dist/Http.js +0 -107
  15. package/dist/PathPattern.js +0 -451
  16. package/dist/PlatformError.js +0 -40
  17. package/dist/PlatformRuntime.js +0 -71
  18. package/dist/Route.js +0 -143
  19. package/dist/RouteBody.js +0 -92
  20. package/dist/RouteError.js +0 -76
  21. package/dist/RouteHook.js +0 -64
  22. package/dist/RouteHttp.js +0 -367
  23. package/dist/RouteHttpTracer.js +0 -90
  24. package/dist/RouteMount.js +0 -86
  25. package/dist/RouteSchema.js +0 -271
  26. package/dist/RouteSse.js +0 -94
  27. package/dist/RouteTree.js +0 -119
  28. package/dist/RouteTrie.js +0 -179
  29. package/dist/SchemaExtra.js +0 -99
  30. package/dist/Socket.js +0 -40
  31. package/dist/SqlIntrospect.js +0 -515
  32. package/dist/Start.js +0 -79
  33. package/dist/StartApp.js +0 -3
  34. package/dist/StreamExtra.js +0 -135
  35. package/dist/System.js +0 -38
  36. package/dist/TuplePathPattern.js +0 -74
  37. package/dist/Unique.js +0 -226
  38. package/dist/Values.js +0 -52
  39. package/dist/bun/BunBundle.js +0 -186
  40. package/dist/bun/BunChildProcessSpawner.js +0 -142
  41. package/dist/bun/BunImportTrackerPlugin.js +0 -91
  42. package/dist/bun/BunRoute.js +0 -157
  43. package/dist/bun/BunRuntime.js +0 -41
  44. package/dist/bun/BunServer.js +0 -285
  45. package/dist/bun/BunVirtualFilesPlugin.js +0 -54
  46. package/dist/bun/_BunEnhancedResolve.js +0 -127
  47. package/dist/bun/index.js +0 -5
  48. package/dist/bundler/Bundle.js +0 -92
  49. package/dist/bundler/BundleFiles.js +0 -154
  50. package/dist/bundler/BundleRoute.js +0 -62
  51. package/dist/client/Overlay.js +0 -33
  52. package/dist/client/ScrollState.js +0 -106
  53. package/dist/client/index.js +0 -97
  54. package/dist/console/Console.js +0 -42
  55. package/dist/console/ConsoleErrors.js +0 -211
  56. package/dist/console/ConsoleLogger.js +0 -56
  57. package/dist/console/ConsoleMetrics.js +0 -72
  58. package/dist/console/ConsoleProcess.js +0 -59
  59. package/dist/console/ConsoleStore.js +0 -72
  60. package/dist/console/ConsoleTracer.js +0 -107
  61. package/dist/console/Simulation.js +0 -784
  62. package/dist/console/index.js +0 -3
  63. package/dist/console/routes/tree.js +0 -30
  64. package/dist/datastar/actions/fetch.js +0 -536
  65. package/dist/datastar/actions/peek.js +0 -13
  66. package/dist/datastar/actions/setAll.js +0 -19
  67. package/dist/datastar/actions/toggleAll.js +0 -19
  68. package/dist/datastar/attributes/attr.js +0 -49
  69. package/dist/datastar/attributes/bind.js +0 -194
  70. package/dist/datastar/attributes/class.js +0 -54
  71. package/dist/datastar/attributes/computed.js +0 -25
  72. package/dist/datastar/attributes/effect.js +0 -10
  73. package/dist/datastar/attributes/indicator.js +0 -33
  74. package/dist/datastar/attributes/init.js +0 -27
  75. package/dist/datastar/attributes/jsonSignals.js +0 -33
  76. package/dist/datastar/attributes/on.js +0 -81
  77. package/dist/datastar/attributes/onIntersect.js +0 -53
  78. package/dist/datastar/attributes/onInterval.js +0 -31
  79. package/dist/datastar/attributes/onSignalPatch.js +0 -51
  80. package/dist/datastar/attributes/ref.js +0 -11
  81. package/dist/datastar/attributes/show.js +0 -32
  82. package/dist/datastar/attributes/signals.js +0 -18
  83. package/dist/datastar/attributes/style.js +0 -57
  84. package/dist/datastar/attributes/text.js +0 -29
  85. package/dist/datastar/engine.js +0 -1145
  86. package/dist/datastar/index.js +0 -25
  87. package/dist/datastar/utils.js +0 -250
  88. package/dist/datastar/watchers/patchElements.js +0 -486
  89. package/dist/datastar/watchers/patchSignals.js +0 -14
  90. package/dist/experimental/EncryptedCookies.js +0 -328
  91. package/dist/experimental/index.js +0 -1
  92. package/dist/hyper/Hyper.js +0 -28
  93. package/dist/hyper/HyperHtml.js +0 -165
  94. package/dist/hyper/HyperNode.js +0 -13
  95. package/dist/hyper/HyperRoute.js +0 -45
  96. package/dist/hyper/html.js +0 -30
  97. package/dist/hyper/index.js +0 -5
  98. package/dist/hyper/jsx-runtime.js +0 -14
  99. package/dist/index.js +0 -8
  100. package/dist/node/NodeFileSystem.js +0 -675
  101. package/dist/node/NodeUtils.js +0 -23
  102. package/dist/sql/Sql.js +0 -8
  103. package/dist/sql/bun/index.js +0 -142
  104. package/dist/sql/index.js +0 -1
  105. package/dist/sql/libsql/index.js +0 -156
  106. package/dist/sql/mssql/docker.js +0 -110
  107. package/dist/sql/mssql/index.js +0 -194
  108. package/dist/testing/TestLogger.js +0 -42
  109. package/dist/testing/index.js +0 -2
  110. package/dist/testing/utils.js +0 -61
  111. package/dist/x/cloudflare/CloudflareTunnel.js +0 -63
  112. package/dist/x/cloudflare/index.js +0 -1
  113. package/dist/x/tailscale/TailscaleTunnel.js +0 -94
  114. package/dist/x/tailscale/index.js +0 -1
  115. package/dist/x/tailwind/TailwindPlugin.js +0 -294
  116. package/dist/x/tailwind/compile.js +0 -210
  117. package/dist/x/tailwind/plugin.js +0 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-start",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "src/",
@@ -12,92 +12,24 @@
12
12
  ],
13
13
  "type": "module",
14
14
  "exports": {
15
- ".": {
16
- "types": "./dist/index.d.ts",
17
- "bun": "./src/index.ts",
18
- "default": "./dist/index.js"
19
- },
20
- "./bun": {
21
- "types": "./dist/bun/index.d.ts",
22
- "bun": "./src/bun/index.ts",
23
- "default": "./dist/bun/index.js"
24
- },
25
- "./client": {
26
- "types": "./dist/client/index.d.ts",
27
- "bun": "./src/client/index.ts",
28
- "default": "./dist/client/index.js"
29
- },
30
- "./testing": {
31
- "types": "./dist/testing/index.d.ts",
32
- "bun": "./src/testing/index.ts",
33
- "default": "./dist/testing/index.js"
34
- },
35
- "./console": {
36
- "types": "./dist/console/index.d.ts",
37
- "bun": "./src/console/index.ts",
38
- "default": "./dist/console/index.js"
39
- },
40
- "./sql/*": {
41
- "types": "./dist/sql/*/index.d.ts",
42
- "bun": "./src/sql/*/index.ts",
43
- "default": "./dist/sql/*/index.js"
44
- },
45
- "./x/*": {
46
- "types": "./dist/x/*/index.d.ts",
47
- "bun": "./src/x/*/index.ts",
48
- "default": "./dist/x/*/index.js"
49
- },
50
- "./x/tailwind/plugin": {
51
- "types": "./dist/x/tailwind/plugin.d.ts",
52
- "bun": "./src/x/tailwind/plugin.ts",
53
- "default": "./dist/x/tailwind/plugin.js"
54
- },
55
- "./System": {
56
- "types": "./dist/System.d.ts",
57
- "bun": "./src/System.ts",
58
- "default": "./dist/System.js"
59
- },
60
- "./Unique": {
61
- "types": "./dist/Unique.d.ts",
62
- "bun": "./src/Unique.ts",
63
- "default": "./dist/Unique.js"
64
- },
65
- "./FileRouter": {
66
- "types": "./dist/FileRouter.d.ts",
67
- "bun": "./src/FileRouter.ts",
68
- "default": "./dist/FileRouter.js"
69
- },
70
- "./FileSystem": {
71
- "types": "./dist/FileSystem.d.ts",
72
- "bun": "./src/FileSystem.ts",
73
- "default": "./dist/FileSystem.js"
74
- },
75
- "./experimental": {
76
- "types": "./dist/experimental/index.d.ts",
77
- "bun": "./src/experimental/index.ts",
78
- "default": "./dist/experimental/index.js"
79
- },
15
+ ".": "./src/index.ts",
16
+ "./bun": "./src/bun/index.ts",
17
+ "./client": "./src/client/index.ts",
18
+ "./testing": "./src/testing/index.ts",
19
+ "./console": "./src/console/index.ts",
20
+ "./sql/*": "./src/sql/*/index.ts",
21
+ "./x/*": "./src/x/*/index.ts",
22
+ "./x/tailwind/plugin": "./src/x/tailwind/plugin.ts",
23
+ "./System": "./src/System.ts",
24
+ "./Unique": "./src/Unique.ts",
25
+ "./FileRouter": "./src/FileRouter.ts",
26
+ "./FileSystem": "./src/FileSystem.ts",
27
+ "./experimental": "./src/experimental/index.ts",
80
28
  "./client/assets.d.ts": "./src/assets.d.ts",
81
- "./hyper": {
82
- "types": "./dist/hyper/index.d.ts",
83
- "bun": "./src/hyper/index.ts",
84
- "default": "./dist/hyper/index.js"
85
- },
86
- "./jsx-runtime": {
87
- "types": "./src/hyper/jsx-runtime.ts",
88
- "bun": "./src/hyper/jsx-runtime.ts",
89
- "default": "./dist/hyper/jsx-runtime.js"
90
- },
91
- "./jsx-dev-runtime": {
92
- "types": "./src/hyper/jsx-runtime.ts",
93
- "bun": "./src/hyper/jsx-runtime.ts",
94
- "default": "./dist/hyper/jsx-runtime.js"
95
- },
96
- "./datastar": {
97
- "types": "./dist/datastar/index.d.ts",
98
- "bun": "./src/datastar/index.ts",
99
- "default": "./dist/datastar/index.js"
100
- },
29
+ "./hyper": "./src/hyper/index.ts",
30
+ "./jsx-runtime": "./src/hyper/jsx-runtime.ts",
31
+ "./jsx-dev-runtime": "./src/hyper/jsx-runtime.ts",
32
+ "./datastar": "./src/datastar/index.ts",
101
33
  "./lint/plugin": "./src/lint/plugin.js",
102
34
  "./package.json": "./package.json"
103
35
  },
@@ -1,42 +0,0 @@
1
- /**
2
- * Adapted from upcomnig Effect 4 aka effect-smol.
3
- *
4
- * Kept a minimal interface without tempaltes and file descirptor
5
- * to keep it compatible if it lands in the core (ie. not in seperate platform package.)
6
- */
7
- import * as Context from "effect/Context"
8
- import * as Effect from "effect/Effect"
9
- import * as Pipeable from "effect/Pipeable"
10
- import * as Predicate from "effect/Predicate"
11
- import * as Utils from "effect/Utils"
12
-
13
- const TypeId = Symbol.for("effect-start/ChildProcess/Command")
14
-
15
- const CommandProto = {
16
- [TypeId]: TypeId,
17
- pipe() {
18
- return Pipeable.pipeArguments(this, arguments)
19
- },
20
- [Symbol.iterator]() {
21
- return new Utils.SingleShotGen(new Utils.YieldWrap(spawn(this)))
22
- },
23
- }
24
-
25
- export const isCommand = (u) => Predicate.hasProperty(u, TypeId)
26
-
27
- export const make = (
28
- command,
29
- args,
30
- options,
31
- ) =>
32
- Object.assign(Object.create(CommandProto), {
33
- command,
34
- args: args ?? [],
35
- ...options,
36
- })
37
-
38
- export class ChildProcessSpawner extends Context.Tag("effect-start/ChildProcessSpawner")() {}
39
-
40
- export const spawn = (
41
- command,
42
- ) => Effect.flatMap(ChildProcessSpawner, (spawner) => spawner.spawn(command))
package/dist/Commander.js DELETED
@@ -1,410 +0,0 @@
1
- import * as Data from "effect/Data"
2
- import * as Effect from "effect/Effect"
3
- import * as Pipeable from "effect/Pipeable"
4
- import * as Predicate from "effect/Predicate"
5
- import * as Schema from "effect/Schema"
6
-
7
- export class CommanderError extends Data.TaggedError("CommanderError") {}
8
-
9
- const TypeId = Symbol.for("effect-start/Commander")
10
-
11
- export const option = (
12
- long,
13
- short,
14
- ) => {
15
- const longName = long
16
- const shortName = short ? short.slice(1) : undefined
17
-
18
- return {
19
- schema: (schema) => ({
20
- _tag: /** @type {const} */ "OptionBuilder",
21
- name: longName,
22
- long: longName,
23
- short: shortName,
24
- description: "",
25
- schema,
26
- }),
27
-
28
- description: (desc) => ({
29
- schema: (schema) => ({
30
- _tag: /** @type {const} */ "OptionBuilder",
31
- name: longName,
32
- long: longName,
33
- short: shortName,
34
- description: desc,
35
- schema,
36
- }),
37
-
38
- default: (value) => ({
39
- schema: (schema) => ({
40
- _tag: /** @type {const} */ "OptionBuilder",
41
- name: longName,
42
- long: longName,
43
- short: shortName,
44
- description: desc,
45
- schema,
46
- defaultValue: value,
47
- }),
48
- }),
49
- }),
50
-
51
- default: (value) => ({
52
- schema: (schema) => ({
53
- _tag: /** @type {const} */ "OptionBuilder",
54
- name: longName,
55
- long: longName,
56
- short: shortName,
57
- description: "",
58
- schema,
59
- defaultValue: value,
60
- }),
61
-
62
- description: (desc) => ({
63
- schema: (schema) => ({
64
- _tag: /** @type {const} */ "OptionBuilder",
65
- name: longName,
66
- long: longName,
67
- short: shortName,
68
- description: desc,
69
- schema,
70
- defaultValue: value,
71
- }),
72
- }),
73
- }),
74
- }
75
- }
76
-
77
- const optionMethod = function (
78
- opt,
79
- ) {
80
- const base = (this && typeof this === "object" ? this : {})
81
- const baseName = base.name ?? ""
82
- const baseOptions = base.options ?? {}
83
- const baseSubcommands = base.subcommands ?? []
84
- const baseDescription = base.description
85
- const baseVersion = base.version
86
-
87
- const camelKey = kebabToCamel(stripPrefix(opt.long))
88
-
89
- return makeSet({
90
- name: baseName,
91
- description: baseDescription,
92
- version: baseVersion,
93
- options: { ...baseOptions, [camelKey]: opt },
94
- subcommands: baseSubcommands,
95
- })
96
- }
97
-
98
- export const optionHelp = function (
99
- ) {
100
- const base = (this && typeof this === "object" ? this : {})
101
- const baseName = base.name ?? ""
102
- const baseOptions = base.options ?? {}
103
- const baseSubcommands = base.subcommands ?? []
104
- const baseDescription = base.description
105
- const baseVersion = base.version
106
-
107
- const helpOption = {
108
- _tag: "OptionBuilder",
109
- name: "--help",
110
- long: "--help",
111
- short: "h",
112
- description: "Show help information",
113
- defaultValue: false,
114
- }
115
-
116
- return makeSet({
117
- name: baseName,
118
- description: baseDescription,
119
- version: baseVersion,
120
- options: { ...baseOptions, help: helpOption },
121
- subcommands: baseSubcommands,
122
- })
123
- }
124
-
125
- export const optionVersion = function (
126
- ) {
127
- const base = (this && typeof this === "object" ? this : {})
128
- const baseName = base.name ?? ""
129
- const baseOptions = base.options ?? {}
130
- const baseSubcommands = base.subcommands ?? []
131
- const baseDescription = base.description
132
- const baseVersion = base.version
133
-
134
- const versionOption = {
135
- _tag: "OptionBuilder",
136
- name: "--version",
137
- long: "--version",
138
- short: "V",
139
- description: "Show version information",
140
- defaultValue: false,
141
- }
142
-
143
- return makeSet({
144
- name: baseName,
145
- description: baseDescription,
146
- version: baseVersion,
147
- options: { ...baseOptions, version: versionOption },
148
- subcommands: baseSubcommands,
149
- })
150
- }
151
-
152
- export const subcommand = function (
153
- cmd,
154
- ) {
155
- const base = (this && typeof this === "object" ? this : {})
156
- const baseName = base.name ?? ""
157
- const baseOptions = base.options ?? {}
158
- const baseSubcommands = base.subcommands ?? []
159
- const baseDescription = base.description
160
- const baseVersion = base.version
161
-
162
- const subDef = {
163
- _tag: "SubcommandDef",
164
- command: cmd,
165
- }
166
-
167
- return makeSet({
168
- name: baseName,
169
- description: baseDescription,
170
- version: baseVersion,
171
- options: baseOptions,
172
- subcommands: [...baseSubcommands, subDef],
173
- })
174
- }
175
-
176
- export const handle = function (
177
- handler,
178
- ) {
179
- const base = this
180
-
181
- return makeSet({
182
- name: base.name,
183
- description: base.description,
184
- version: base.version,
185
- options: base.options,
186
- subcommands: base.subcommands,
187
- handler,
188
- })
189
- }
190
-
191
- export const make = (config) =>
192
- makeSet({
193
- name: config.name,
194
- description: config.description,
195
- version: config.version,
196
- options: {},
197
- subcommands: [],
198
- })
199
-
200
- const CommanderProto = {
201
- [TypeId]: TypeId,
202
-
203
- option: optionMethod,
204
- optionHelp,
205
- optionVersion,
206
- subcommand,
207
- handle,
208
-
209
- pipe() {
210
- return Pipeable.pipeArguments(this, arguments)
211
- },
212
- }
213
-
214
- function makeSet(config) {
215
- return Object.assign(Object.create(CommanderProto), config)
216
- }
217
-
218
- export function isCommanderSet(input) {
219
- return Predicate.hasProperty(input, TypeId)
220
- }
221
-
222
- const kebabToCamel = (str) => {
223
- return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
224
- }
225
-
226
- const stripPrefix = (str) => {
227
- if (str.startsWith("--")) return str.slice(2)
228
- if (str.startsWith("-")) return str.slice(1)
229
- return str
230
- }
231
-
232
- const parseRawArgs = (args) =>
233
- Effect.gen(function* () {
234
- const flags = {}
235
- const options = {}
236
- const positional = []
237
-
238
- let i = 0
239
- while (i < args.length) {
240
- const arg = args[i]
241
-
242
- if (arg === "--") {
243
- positional.push(...args.slice(i + 1))
244
- break
245
- }
246
-
247
- if (arg.startsWith("--")) {
248
- const equalIndex = arg.indexOf("=")
249
- if (equalIndex !== -1) {
250
- const key = arg.slice(2, equalIndex)
251
- const value = arg.slice(equalIndex + 1)
252
- options[key] = value
253
- } else {
254
- const key = arg.slice(2)
255
- if (i + 1 < args.length && !args[i + 1].startsWith("-")) {
256
- options[key] = args[i + 1]
257
- i++
258
- } else {
259
- flags[key] = true
260
- }
261
- }
262
- } else if (arg.startsWith("-") && arg.length > 1) {
263
- const chars = arg.slice(1)
264
- for (let j = 0; j < chars.length; j++) {
265
- const char = chars[j]
266
- if (j === chars.length - 1 && i + 1 < args.length && !args[i + 1].startsWith("-")) {
267
- options[char] = args[i + 1]
268
- i++
269
- } else {
270
- flags[char] = true
271
- }
272
- }
273
- } else {
274
- positional.push(arg)
275
- }
276
-
277
- i++
278
- }
279
-
280
- return { flags, options, positional }
281
- })
282
-
283
- export const parse = (
284
- cmd,
285
- args,
286
- ) =>
287
- Effect.gen(function* () {
288
- const parsed = yield* parseRawArgs(args)
289
-
290
- const result = {}
291
-
292
- for (const optBuilder of Object.values(cmd.options)) {
293
- const longName = stripPrefix(optBuilder.long)
294
- const shortName = optBuilder.short
295
-
296
- const longMatch = parsed.options[longName] || parsed.flags[longName]
297
- const shortMatch = shortName
298
- ? parsed.options[shortName] || parsed.flags[shortName]
299
- : undefined
300
-
301
- const rawValue = longMatch ?? shortMatch
302
-
303
- const camelKey = kebabToCamel(stripPrefix(optBuilder.long))
304
-
305
- if (rawValue !== undefined) {
306
- if (typeof rawValue === "boolean") {
307
- result[camelKey] = rawValue
308
- } else if (optBuilder.schema) {
309
- const decoded = yield* Schema.decode(optBuilder.schema)(rawValue).pipe(
310
- Effect.mapError(
311
- (error) =>
312
- new CommanderError({
313
- message: `Invalid value for option ${optBuilder.long}: ${error.message}`,
314
- cause: error,
315
- }),
316
- ),
317
- )
318
- result[camelKey] = decoded
319
- } else {
320
- result[camelKey] = rawValue
321
- }
322
- } else if (optBuilder.defaultValue !== undefined) {
323
- result[camelKey] = optBuilder.defaultValue
324
- }
325
- }
326
-
327
- return result
328
- })
329
-
330
- export const runMain = (
331
- cmd,
332
- ) =>
333
- Effect.gen(function* () {
334
- const args = typeof process !== "undefined" ? process.argv.slice(2) : []
335
-
336
- const parsedOptions = yield* parse(cmd, args)
337
-
338
- if (Predicate.hasProperty(parsedOptions, "help") && parsedOptions.help) {
339
- console.log(generateHelp(cmd))
340
- return
341
- }
342
-
343
- if (Predicate.hasProperty(parsedOptions, "version") && parsedOptions.version && cmd.version) {
344
- console.log(`${cmd.name} v${cmd.version}`)
345
- return
346
- }
347
-
348
- if (cmd.handler) {
349
- yield* cmd.handler(parsedOptions)
350
- }
351
- })
352
-
353
- const generateHelp = (
354
- cmd,
355
- ) => {
356
- const lines = []
357
-
358
- if (cmd.description) {
359
- lines.push(cmd.description)
360
- lines.push("")
361
- }
362
-
363
- lines.push(`Usage: ${cmd.name} [options]`)
364
- lines.push("")
365
-
366
- const optionsArray = Object.values(cmd.options)
367
- if (optionsArray.length > 0) {
368
- lines.push("Options:")
369
-
370
- for (const opt of optionsArray) {
371
- const short = opt.short ? `-${opt.short}, ` : " "
372
- const long = opt.long
373
- const hasValue = opt.schema !== undefined
374
- const name = hasValue ? `${long} <value>` : long
375
- lines.push(` ${short}${name.padEnd(20)} ${opt.description}`)
376
- }
377
-
378
- lines.push("")
379
- }
380
-
381
- if (cmd.subcommands.length > 0) {
382
- lines.push("Commands:")
383
- for (const sub of cmd.subcommands) {
384
- const subCmd = sub.command
385
- lines.push(` ${subCmd.name.padEnd(20)} ${subCmd.description || ""}`)
386
- }
387
- lines.push("")
388
- }
389
-
390
- return lines.join("\n")
391
- }
392
-
393
- export const help = (
394
- cmd,
395
- ) => generateHelp(cmd)
396
-
397
- export const NumberFromString = Schema.NumberFromString
398
-
399
- export const choice = (
400
- choices,
401
- ) => Schema.Literal(...choices)
402
-
403
- export const repeatable = (
404
- schema,
405
- ) =>
406
- Schema.transform(Schema.String, Schema.Array(Schema.String), {
407
- strict: true,
408
- decode: (s) => s.split(",").map((part) => part.trim()),
409
- encode: (arr) => arr.join(","),
410
- }).pipe(Schema.compose(Schema.Array(schema)))