@optique/core 0.1.0-dev.1 → 0.1.0-dev.27
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.
- package/README.md +34 -445
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/parser.cjs +55 -0
- package/dist/parser.d.cts +35 -1
- package/dist/parser.d.ts +35 -1
- package/dist/parser.js +55 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,475 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
@optique/core
|
|
2
|
+
=============
|
|
3
3
|
|
|
4
4
|
> [!CAUTION]
|
|
5
|
-
> Optique is currently in early development
|
|
6
|
-
>
|
|
7
|
-
> and there may be bugs or missing features.
|
|
5
|
+
> Optique is currently in early development and may change significantly.
|
|
6
|
+
> Expect breaking changes as we refine the API and features.
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
> [!NOTE]
|
|
15
|
-
> Optique is a parsing library that focuses on extracting and
|
|
16
|
-
> validating command-line arguments. It doesn't dictate your application's
|
|
17
|
-
> structure, handle command execution, or provide scaffolding—it simply
|
|
18
|
-
> transforms command-line input into well-typed data structures that your
|
|
19
|
-
> application can use.
|
|
20
|
-
|
|
21
|
-
Unlike traditional CLI parsers that rely on configuration objects or
|
|
22
|
-
string-based definitions, Optique uses a functional approach where parsers
|
|
23
|
-
are first-class values that can be combined, transformed, and reused.
|
|
24
|
-
This compositional design makes it easy to express complex argument structures
|
|
25
|
-
while maintaining complete type safety throughout your application.
|
|
8
|
+
The core package of Optique which provides the shared types and parser
|
|
9
|
+
combinators. It is designed to be used in universal JavaScript runtimes,
|
|
10
|
+
including Node.js, Deno, Bun, edge functions, and web browsers—although
|
|
11
|
+
you usually won't use it directly in browsers.
|
|
26
12
|
|
|
27
13
|
> [!TIP]
|
|
28
14
|
> *Building CLI apps?* Consider *@optique/run* for automatic `process.argv`
|
|
29
15
|
> handling and `process.exit()` integration. This core package is perfect for
|
|
30
16
|
> libraries, web apps, or when you need full control over argument parsing.
|
|
31
17
|
|
|
32
|
-
[optparse-applicative]: https://github.com/pcapriotti/optparse-applicative
|
|
33
|
-
[Zod]: https://zod.dev/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Core concepts
|
|
37
|
-
-------------
|
|
38
|
-
|
|
39
|
-
Optique is built around several key concepts:
|
|
40
|
-
|
|
41
|
-
- *Value parsers* convert strings to typed values
|
|
42
|
-
(`string()`, `integer()`, `url()`, etc.)
|
|
43
|
-
|
|
44
|
-
- *Primitive parsers* handle the basic building blocks:
|
|
45
|
-
|
|
46
|
-
- `option()` for command-line flags and their arguments
|
|
47
|
-
- `argument()` for positional arguments
|
|
48
|
-
- `command()` for subcommands
|
|
49
|
-
|
|
50
|
-
- *Modifying combinators* transform and combine parsers:
|
|
51
|
-
- `optional()` makes parsers optional
|
|
52
|
-
- `withDefault()` provides default values for optional parsers
|
|
53
|
-
- `multiple()` allows repetition
|
|
54
|
-
- `or()` creates alternatives
|
|
55
|
-
- `merge()` combines object parsers
|
|
56
|
-
|
|
57
|
-
- *Construct combinators* build structured results:
|
|
58
|
-
|
|
59
|
-
- `object()` groups parsers into objects
|
|
60
|
-
- `tuple()` combines parsers into tuples
|
|
61
|
-
|
|
62
|
-
The library automatically infers the result type of your parser composition,
|
|
63
|
-
ensuring that your parsed CLI arguments are fully typed without manual type
|
|
64
|
-
annotations. When parsing fails, you get detailed error messages that help
|
|
65
|
-
users understand what went wrong.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Example
|
|
69
|
-
-------
|
|
70
|
-
|
|
71
|
-
~~~~ typescript
|
|
72
|
-
import { run } from "@optique/core/facade";
|
|
73
|
-
import { formatMessage } from "@optique/core/message";
|
|
74
|
-
import {
|
|
75
|
-
argument,
|
|
76
|
-
merge,
|
|
77
|
-
multiple,
|
|
78
|
-
object,
|
|
79
|
-
option,
|
|
80
|
-
optional,
|
|
81
|
-
or,
|
|
82
|
-
withDefault
|
|
83
|
-
} from "@optique/core/parser";
|
|
84
|
-
import { choice, integer, locale, string, url } from "@optique/core/valueparser";
|
|
85
|
-
import process from "node:process";
|
|
86
|
-
|
|
87
|
-
// Define a sophisticated CLI with grouped and reusable option sets
|
|
88
|
-
const networkOptions = object("Network", {
|
|
89
|
-
port: option("-p", "--port", integer({ min: 1, max: 65535 })),
|
|
90
|
-
host: withDefault(
|
|
91
|
-
option("-h", "--host", string({ metavar: "HOST" })),
|
|
92
|
-
"localhost",
|
|
93
|
-
),
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const loggingOptions = object("Logging", {
|
|
97
|
-
verbose: optional(option("-v", "--verbose")),
|
|
98
|
-
logFile: optional(option("--log-file", string({ metavar: "FILE" }))),
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const parser = or(
|
|
102
|
-
// Server mode: merge network and logging options with server-specific config
|
|
103
|
-
merge(
|
|
104
|
-
networkOptions,
|
|
105
|
-
loggingOptions,
|
|
106
|
-
object("Server", {
|
|
107
|
-
locales: multiple(option("-l", "--locale", locale())),
|
|
108
|
-
config: argument(string({ metavar: "CONFIG_FILE" })),
|
|
109
|
-
}),
|
|
110
|
-
),
|
|
111
|
-
object("Client mode", {
|
|
112
|
-
connect: option(
|
|
113
|
-
"-c", "--connect",
|
|
114
|
-
url({ allowedProtocols: ["http:", "https:"] }),
|
|
115
|
-
),
|
|
116
|
-
headers: multiple(option("-H", "--header", string())),
|
|
117
|
-
timeout: withDefault(option("-t", "--timeout", integer({ min: 0 })), 30000),
|
|
118
|
-
files: multiple(argument(string({ metavar: "FILE" })), { min: 1, max: 5 }),
|
|
119
|
-
}),
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const result = run(parser, "myapp", process.argv.slice(2), {
|
|
123
|
-
colors: true,
|
|
124
|
-
help: "both",
|
|
125
|
-
onError: process.exit,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// TypeScript automatically infers the complex union type with optional fields
|
|
129
|
-
if ("port" in result) {
|
|
130
|
-
const server = result;
|
|
131
|
-
console.log(`Starting server on ${server.host}:${server.port}`);
|
|
132
|
-
console.log(`Supported locales: ${server.locales.join(", ") || "default"}`);
|
|
133
|
-
if (server.verbose) console.log("Verbose mode enabled");
|
|
134
|
-
if (server.logFile) console.log(`Logging to: ${server.logFile}`);
|
|
135
|
-
} else {
|
|
136
|
-
const client = result;
|
|
137
|
-
console.log(`Connecting to ${client.connect}`);
|
|
138
|
-
console.log(`Processing ${client.files.length} files`);
|
|
139
|
-
console.log(`Timeout: ${client.timeout}ms`);
|
|
140
|
-
}
|
|
141
|
-
~~~~
|
|
142
|
-
|
|
143
|
-
This example demonstrates Optique's powerful combinators:
|
|
144
|
-
|
|
145
|
-
- **`merge()`** combines multiple `object()` parsers into a single unified
|
|
146
|
-
parser, enabling modular and reusable option groups
|
|
147
|
-
- **`optional()`** makes parsers optional, returning `undefined` when not
|
|
148
|
-
provided
|
|
149
|
-
- **`withDefault()`** provides default values instead of `undefined` for
|
|
150
|
-
optional parameters, improving usability
|
|
151
|
-
- **`multiple()`** allows repeating options/arguments with configurable
|
|
152
|
-
constraints
|
|
153
|
-
- **`or()`** creates mutually exclusive alternatives
|
|
154
|
-
- **`object()`** groups related options into structured data
|
|
155
|
-
|
|
156
|
-
The parser demonstrates modular design by:
|
|
157
|
-
|
|
158
|
-
- Separating network options (`--port`, `--host`) for reusability
|
|
159
|
-
- Grouping logging configuration (`--verbose`, `--log-file`) separately
|
|
160
|
-
- Merging reusable groups with server-specific options using `merge()`
|
|
161
|
-
- Supporting complex scenarios like multiple locales: `-l en-US -l fr-FR`
|
|
162
|
-
|
|
163
|
-
All with full type safety and automatic inference!
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
Parser combinators
|
|
167
|
-
------------------
|
|
168
|
-
|
|
169
|
-
Optique provides several types of parsers and combinators for building sophisticated CLI interfaces:
|
|
170
|
-
|
|
171
|
-
### Primitive parsers
|
|
172
|
-
|
|
173
|
-
- **`option()`**: Handles command-line flags and their arguments
|
|
174
|
-
|
|
175
|
-
~~~~ typescript
|
|
176
|
-
option("-p", "--port", integer({ min: 1, max: 65535 }))
|
|
177
|
-
option("-v", "--verbose") // Boolean flag
|
|
178
|
-
~~~~
|
|
179
|
-
|
|
180
|
-
- **`argument()`**: Handles positional arguments
|
|
181
|
-
|
|
182
|
-
~~~~ typescript
|
|
183
|
-
argument(string({ metavar: "FILE" }))
|
|
184
|
-
~~~~
|
|
185
|
-
|
|
186
|
-
- **`command()`**: Matches subcommands for `git`-like CLI interfaces
|
|
187
|
-
|
|
188
|
-
~~~~ typescript
|
|
189
|
-
command("add", object({ file: argument(string()) }))
|
|
190
|
-
~~~~
|
|
191
|
-
|
|
192
|
-
### Modifying combinators
|
|
193
|
-
|
|
194
|
-
- **`optional()`**: Makes any parser optional, returning `undefined` if not
|
|
195
|
-
matched
|
|
196
|
-
|
|
197
|
-
~~~~ typescript
|
|
198
|
-
const parser = object({
|
|
199
|
-
name: option("-n", "--name", string()),
|
|
200
|
-
verbose: optional(option("-v", "--verbose")), // undefined if not provided
|
|
201
|
-
});
|
|
202
|
-
~~~~
|
|
203
|
-
|
|
204
|
-
- **`withDefault()`**: Makes any parser provide a default value instead of
|
|
205
|
-
`undefined` when not matched
|
|
206
|
-
|
|
207
|
-
~~~~ typescript
|
|
208
|
-
const parser = object({
|
|
209
|
-
name: option("-n", "--name", string()),
|
|
210
|
-
port: withDefault(option("-p", "--port", integer()), 8080), // 8080 if not provided
|
|
211
|
-
host: withDefault(option("-h", "--host", string()), "localhost"),
|
|
212
|
-
});
|
|
213
|
-
~~~~
|
|
214
18
|
|
|
215
|
-
|
|
19
|
+
When to use @optique/core
|
|
20
|
+
------------------------
|
|
216
21
|
|
|
217
|
-
|
|
218
|
-
const parser = object({
|
|
219
|
-
// Multiple locales: -l en -l fr
|
|
220
|
-
locales: multiple(option("-l", "--locale", locale())),
|
|
221
|
-
// 1-3 input files required
|
|
222
|
-
files: multiple(argument(string()), { min: 1, max: 3 }),
|
|
223
|
-
});
|
|
224
|
-
~~~~
|
|
22
|
+
Use *@optique/core* instead when:
|
|
225
23
|
|
|
226
|
-
-
|
|
227
|
-
|
|
24
|
+
- Building web applications or libraries
|
|
25
|
+
- You need full control over argument sources and error handling
|
|
26
|
+
- Working in environments without `process` (browsers, web workers)
|
|
27
|
+
- Building reusable parser components
|
|
228
28
|
|
|
229
|
-
|
|
230
|
-
or(
|
|
231
|
-
command("add", addParser),
|
|
232
|
-
command("remove", removeParser)
|
|
233
|
-
)
|
|
234
|
-
~~~~
|
|
29
|
+
Use *@optique/run* when:
|
|
235
30
|
|
|
236
|
-
-
|
|
237
|
-
|
|
31
|
+
- Building CLI applications for Node.js, Bun, or Deno
|
|
32
|
+
- You want automatic `process.argv` parsing and `process.exit()` handling
|
|
33
|
+
- You need automatic terminal capability detection (colors, width)
|
|
34
|
+
- You prefer a simple, batteries-included approach
|
|
238
35
|
|
|
239
|
-
~~~~ typescript
|
|
240
|
-
merge(networkOptions, loggingOptions, serverOptions)
|
|
241
|
-
~~~~
|
|
242
36
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
- **`object()`**: Combines multiple parsers into a structured object
|
|
246
|
-
|
|
247
|
-
~~~~ typescript
|
|
248
|
-
object("Server", {
|
|
249
|
-
port: option("-p", "--port", integer()),
|
|
250
|
-
host: option("-h", "--host", string()),
|
|
251
|
-
})
|
|
252
|
-
~~~~
|
|
253
|
-
|
|
254
|
-
- **`tuple()`**: Combines multiple parsers into a tuple with preserved order
|
|
255
|
-
|
|
256
|
-
~~~~ typescript
|
|
257
|
-
tuple(
|
|
258
|
-
option("-u", "--user", string()),
|
|
259
|
-
option("-p", "--port", integer())
|
|
260
|
-
)
|
|
261
|
-
~~~~
|
|
262
|
-
|
|
263
|
-
### Advanced patterns
|
|
264
|
-
|
|
265
|
-
The `merge()` combinator enables powerful modular designs by separating concerns
|
|
266
|
-
into reusable option groups:
|
|
267
|
-
|
|
268
|
-
~~~~ typescript
|
|
269
|
-
// Define reusable option groups
|
|
270
|
-
const databaseOptions = object("Database", {
|
|
271
|
-
dbHost: option("--db-host", string()),
|
|
272
|
-
dbPort: option("--db-port", integer({ min: 1, max: 65535 })),
|
|
273
|
-
dbName: option("--db-name", string()),
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
const authOptions = object("Authentication", {
|
|
277
|
-
username: option("-u", "--user", string()),
|
|
278
|
-
password: optional(option("-p", "--password", string())),
|
|
279
|
-
token: optional(option("-t", "--token", string())),
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
const loggingOptions = object("Logging", {
|
|
283
|
-
logLevel: option("--log-level", choice(["debug", "info", "warn", "error"])),
|
|
284
|
-
logFile: optional(option("--log-file", string())),
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
// Combine groups differently for different modes
|
|
288
|
-
const parser = or(
|
|
289
|
-
// Development: all options available
|
|
290
|
-
merge(
|
|
291
|
-
object("Dev", { dev: option("--dev") }),
|
|
292
|
-
databaseOptions,
|
|
293
|
-
authOptions,
|
|
294
|
-
loggingOptions
|
|
295
|
-
),
|
|
296
|
-
// Production: database and auth required, enhanced logging
|
|
297
|
-
merge(
|
|
298
|
-
object("Prod", { config: option("-c", "--config", string()) }),
|
|
299
|
-
databaseOptions,
|
|
300
|
-
authOptions,
|
|
301
|
-
loggingOptions,
|
|
302
|
-
object("Production", {
|
|
303
|
-
workers: multiple(option("-w", "--worker", integer({ min: 1 }))),
|
|
304
|
-
})
|
|
305
|
-
),
|
|
306
|
-
);
|
|
307
|
-
~~~~
|
|
308
|
-
|
|
309
|
-
This approach promotes:
|
|
310
|
-
|
|
311
|
-
- *Reusability*: Option groups can be shared across different command modes
|
|
312
|
-
- *Maintainability*: Changes to option groups automatically propagate
|
|
313
|
-
- *Modularity*: Each concern is separated into its own focused parser
|
|
314
|
-
- *Flexibility*: Different combinations for different use cases
|
|
315
|
-
|
|
316
|
-
The `multiple()` combinator is especially powerful when combined with `object()`
|
|
317
|
-
parsers, as it provides empty arrays as defaults when no matches are found,
|
|
318
|
-
allowing for clean optional repeated arguments.
|
|
319
|
-
|
|
320
|
-
### Quick subcommand example
|
|
321
|
-
|
|
322
|
-
For a quick introduction to subcommands, here's a simple `git`-like interface:
|
|
37
|
+
Quick example
|
|
38
|
+
-------------
|
|
323
39
|
|
|
324
40
|
~~~~ typescript
|
|
325
41
|
import { run } from "@optique/core/facade";
|
|
326
|
-
import {
|
|
327
|
-
import { string } from "@optique/core/valueparser";
|
|
42
|
+
import { object, option, argument } from "@optique/core/parser";
|
|
43
|
+
import { string, integer } from "@optique/core/valueparser";
|
|
328
44
|
import process from "node:process";
|
|
329
45
|
|
|
330
|
-
const parser =
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
file: argument(string()),
|
|
335
|
-
})),
|
|
336
|
-
command("commit", object({
|
|
337
|
-
type: constant("commit"),
|
|
338
|
-
message: option("-m", "--message", string()),
|
|
339
|
-
amend: option("--amend"),
|
|
340
|
-
})),
|
|
341
|
-
);
|
|
342
|
-
|
|
343
|
-
const result = run(parser, "git", ["commit", "-m", "Fix parser bug"], {
|
|
344
|
-
help: "both",
|
|
345
|
-
onError: process.exit,
|
|
46
|
+
const parser = object({
|
|
47
|
+
name: argument(string()),
|
|
48
|
+
age: option("-a", "--age", integer()),
|
|
49
|
+
verbose: option("-v", "--verbose"),
|
|
346
50
|
});
|
|
347
|
-
// result.type === "commit"
|
|
348
|
-
// result.message === "Fix parser bug"
|
|
349
|
-
// result.amend === false
|
|
350
|
-
~~~~
|
|
351
|
-
|
|
352
|
-
### Subcommands
|
|
353
|
-
|
|
354
|
-
The `command()` combinator enables building git-like CLI interfaces with
|
|
355
|
-
subcommands. Each subcommand can have its own set of options and arguments:
|
|
356
|
-
|
|
357
|
-
~~~~ typescript
|
|
358
|
-
import { run } from "@optique/core/facade";
|
|
359
|
-
import {
|
|
360
|
-
argument,
|
|
361
|
-
command,
|
|
362
|
-
constant,
|
|
363
|
-
multiple,
|
|
364
|
-
object,
|
|
365
|
-
option,
|
|
366
|
-
optional,
|
|
367
|
-
or,
|
|
368
|
-
} from "@optique/core/parser";
|
|
369
|
-
import { string } from "@optique/core/valueparser";
|
|
370
|
-
import process from "node:process";
|
|
371
51
|
|
|
372
|
-
const
|
|
373
|
-
command("show", object({
|
|
374
|
-
type: constant("show"),
|
|
375
|
-
progress: option("-p", "--progress"),
|
|
376
|
-
verbose: optional(option("-v", "--verbose")),
|
|
377
|
-
id: argument(string({ metavar: "ITEM_ID" })),
|
|
378
|
-
})),
|
|
379
|
-
command("edit", object({
|
|
380
|
-
type: constant("edit"),
|
|
381
|
-
editor: optional(option("-e", "--editor", string({ metavar: "EDITOR" }))),
|
|
382
|
-
backup: option("-b", "--backup"),
|
|
383
|
-
id: argument(string({ metavar: "ITEM_ID" })),
|
|
384
|
-
})),
|
|
385
|
-
command("delete", object({
|
|
386
|
-
type: constant("delete"),
|
|
387
|
-
force: option("-f", "--force"),
|
|
388
|
-
recursive: optional(option("-r", "--recursive")),
|
|
389
|
-
items: multiple(argument(string({ metavar: "ITEM_ID" })), { min: 1 }),
|
|
390
|
-
})),
|
|
391
|
-
);
|
|
392
|
-
|
|
393
|
-
const result = run(parser, "myapp", process.argv.slice(2), {
|
|
394
|
-
colors: true,
|
|
52
|
+
const config = run(parser, "myapp", process.argv.slice(2), {
|
|
395
53
|
help: "both",
|
|
396
54
|
onError: process.exit,
|
|
397
55
|
});
|
|
398
56
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
console.log(`Showing item: ${result.id}`);
|
|
403
|
-
if (result.progress) console.log("Progress enabled");
|
|
404
|
-
if (result.verbose) console.log("Verbose mode enabled");
|
|
405
|
-
break;
|
|
406
|
-
case "edit":
|
|
407
|
-
console.log(`Editing item: ${result.id}`);
|
|
408
|
-
if (result.editor) console.log(`Using editor: ${result.editor}`);
|
|
409
|
-
if (result.backup) console.log("Backup enabled");
|
|
410
|
-
break;
|
|
411
|
-
case "delete":
|
|
412
|
-
console.log(`Deleting items: ${result.items.join(", ")}`);
|
|
413
|
-
if (result.force) console.log("Force delete enabled");
|
|
414
|
-
if (result.recursive) console.log("Recursive delete enabled");
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
57
|
+
console.log(`Hello ${config.name}!`);
|
|
58
|
+
if (config.age) console.log(`You are ${config.age} years old.`);
|
|
59
|
+
if (config.verbose) console.log("Verbose mode enabled.");
|
|
417
60
|
~~~~
|
|
418
61
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
- *Subcommand routing*: `command("show", ...)` matches the first argument
|
|
422
|
-
and applies the inner parser to remaining arguments
|
|
423
|
-
- *Type discrimination*: Using `constant()` with unique values enables
|
|
424
|
-
TypeScript to discriminate between subcommand types
|
|
425
|
-
- *Per-subcommand options*: Each subcommand can have its own unique set
|
|
426
|
-
of options and arguments
|
|
427
|
-
- *Complex arguments*: The `delete` command shows multiple required arguments
|
|
428
|
-
|
|
429
|
-
Example usage:
|
|
430
|
-
|
|
431
|
-
~~~~ bash
|
|
432
|
-
# Show command with options
|
|
433
|
-
$ myapp show --progress --verbose item123
|
|
434
|
-
|
|
435
|
-
# Edit command with optional editor
|
|
436
|
-
$ myapp edit --editor vim --backup item456
|
|
437
|
-
|
|
438
|
-
# Delete command with multiple items
|
|
439
|
-
$ myapp delete --force item1 item2 item3
|
|
440
|
-
~~~~
|
|
441
|
-
|
|
442
|
-
### Advanced subcommand patterns
|
|
443
|
-
|
|
444
|
-
You can also combine subcommands with global options using `object()`:
|
|
445
|
-
|
|
446
|
-
~~~~ typescript
|
|
447
|
-
const parser = object({
|
|
448
|
-
// Global options available to all subcommands
|
|
449
|
-
debug: optional(option("--debug")),
|
|
450
|
-
config: optional(option("-c", "--config", string())),
|
|
451
|
-
|
|
452
|
-
// Subcommand with its own options
|
|
453
|
-
command: or(
|
|
454
|
-
command("server", object({
|
|
455
|
-
type: constant("server" as const),
|
|
456
|
-
port: option("-p", "--port", integer({ min: 1, max: 65535 })),
|
|
457
|
-
daemon: option("-d", "--daemon"),
|
|
458
|
-
})),
|
|
459
|
-
command("client", object({
|
|
460
|
-
type: constant("client" as const),
|
|
461
|
-
connect: option("--connect", url()),
|
|
462
|
-
timeout: optional(option("-t", "--timeout", integer())),
|
|
463
|
-
})),
|
|
464
|
-
),
|
|
465
|
-
});
|
|
466
|
-
~~~~
|
|
467
|
-
|
|
468
|
-
This allows for commands like:
|
|
469
|
-
|
|
470
|
-
~~~~ bash
|
|
471
|
-
$ myapp --debug --config app.json server --port 8080 --daemon
|
|
472
|
-
$ myapp client --connect http://localhost:8080 --timeout 5000
|
|
473
|
-
~~~~
|
|
62
|
+
For more resources, see the [docs] and the [*examples/*](/examples/) directory.
|
|
474
63
|
|
|
475
|
-
|
|
64
|
+
[docs]: https://optique.dev/
|
package/dist/index.cjs
CHANGED
|
@@ -19,6 +19,7 @@ exports.getDocPage = require_parser.getDocPage;
|
|
|
19
19
|
exports.integer = require_valueparser.integer;
|
|
20
20
|
exports.isValueParser = require_valueparser.isValueParser;
|
|
21
21
|
exports.locale = require_valueparser.locale;
|
|
22
|
+
exports.map = require_parser.map;
|
|
22
23
|
exports.merge = require_parser.merge;
|
|
23
24
|
exports.message = require_message.message;
|
|
24
25
|
exports.metavar = require_message.metavar;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,6 @@ import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, met
|
|
|
2
2
|
import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.cjs";
|
|
3
3
|
import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, formatDocPage } from "./doc.cjs";
|
|
4
4
|
import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.cjs";
|
|
5
|
-
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
|
|
5
|
+
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
|
|
6
6
|
import { RunError, RunOptions, run } from "./facade.cjs";
|
|
7
|
-
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
7
|
+
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, met
|
|
|
2
2
|
import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
3
3
|
import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, formatDocPage } from "./doc.js";
|
|
4
4
|
import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
|
|
5
|
-
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
5
|
+
import { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
6
6
|
import { RunError, RunOptions, run } from "./facade.js";
|
|
7
|
-
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
7
|
+
export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { formatMessage, message, metavar, optionName, optionNames, text, value,
|
|
|
2
2
|
import { formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
|
|
3
3
|
import { formatDocPage } from "./doc.js";
|
|
4
4
|
import { choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
|
|
5
|
-
import { argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
5
|
+
import { argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
|
|
6
6
|
import { RunError, run } from "./facade.js";
|
|
7
7
|
|
|
8
|
-
export { RunError, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
|
8
|
+
export { RunError, argument, choice, command, constant, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, integer, isValueParser, locale, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
|
package/dist/parser.cjs
CHANGED
|
@@ -413,6 +413,60 @@ function withDefault(parser, defaultValue) {
|
|
|
413
413
|
};
|
|
414
414
|
}
|
|
415
415
|
/**
|
|
416
|
+
* Creates a parser that transforms the result value of another parser using
|
|
417
|
+
* a mapping function. This enables value transformation while preserving
|
|
418
|
+
* the original parser's parsing logic and state management.
|
|
419
|
+
*
|
|
420
|
+
* The `map()` function is useful for:
|
|
421
|
+
* - Converting parsed values to different types
|
|
422
|
+
* - Applying transformations like string formatting or boolean inversion
|
|
423
|
+
* - Computing derived values from parsed input
|
|
424
|
+
* - Creating reusable transformations that can be applied to any parser
|
|
425
|
+
*
|
|
426
|
+
* @template T The type of the value produced by the original parser.
|
|
427
|
+
* @template U The type of the value produced by the mapping function.
|
|
428
|
+
* @template TState The type of the state used by the original parser.
|
|
429
|
+
* @param parser The {@link Parser} whose result will be transformed.
|
|
430
|
+
* @param transform A function that transforms the parsed value from type T to type U.
|
|
431
|
+
* @returns A {@link Parser} that produces the transformed value of type U
|
|
432
|
+
* while preserving the original parser's state type and parsing behavior.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* // Transform boolean flag to its inverse
|
|
437
|
+
* const parser = object({
|
|
438
|
+
* disallow: map(option("--allow"), b => !b)
|
|
439
|
+
* });
|
|
440
|
+
*
|
|
441
|
+
* // Transform string to uppercase
|
|
442
|
+
* const upperParser = map(argument(string()), s => s.toUpperCase());
|
|
443
|
+
*
|
|
444
|
+
* // Transform number to formatted string
|
|
445
|
+
* const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
function map(parser, transform) {
|
|
449
|
+
return {
|
|
450
|
+
$valueType: [],
|
|
451
|
+
$stateType: parser.$stateType,
|
|
452
|
+
priority: parser.priority,
|
|
453
|
+
usage: parser.usage,
|
|
454
|
+
initialState: parser.initialState,
|
|
455
|
+
parse: parser.parse.bind(parser),
|
|
456
|
+
complete(state) {
|
|
457
|
+
const result = parser.complete(state);
|
|
458
|
+
if (result.success) return {
|
|
459
|
+
success: true,
|
|
460
|
+
value: transform(result.value)
|
|
461
|
+
};
|
|
462
|
+
return result;
|
|
463
|
+
},
|
|
464
|
+
getDocFragments(state, _defaultValue) {
|
|
465
|
+
return parser.getDocFragments(state, void 0);
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
416
470
|
* Creates a parser that allows multiple occurrences of a given parser.
|
|
417
471
|
* This parser can be used to parse multiple values of the same type,
|
|
418
472
|
* such as multiple command-line arguments or options.
|
|
@@ -1054,6 +1108,7 @@ exports.argument = argument;
|
|
|
1054
1108
|
exports.command = command;
|
|
1055
1109
|
exports.constant = constant;
|
|
1056
1110
|
exports.getDocPage = getDocPage;
|
|
1111
|
+
exports.map = map;
|
|
1057
1112
|
exports.merge = merge;
|
|
1058
1113
|
exports.multiple = multiple;
|
|
1059
1114
|
exports.object = object;
|
package/dist/parser.d.cts
CHANGED
|
@@ -238,6 +238,40 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
|
|
|
238
238
|
* or the default value if the wrapped parser fails to match.
|
|
239
239
|
*/
|
|
240
240
|
declare function withDefault<TValue, TState>(parser: Parser<TValue, TState>, defaultValue: TValue | (() => TValue)): Parser<TValue, [TState] | undefined>;
|
|
241
|
+
/**
|
|
242
|
+
* Creates a parser that transforms the result value of another parser using
|
|
243
|
+
* a mapping function. This enables value transformation while preserving
|
|
244
|
+
* the original parser's parsing logic and state management.
|
|
245
|
+
*
|
|
246
|
+
* The `map()` function is useful for:
|
|
247
|
+
* - Converting parsed values to different types
|
|
248
|
+
* - Applying transformations like string formatting or boolean inversion
|
|
249
|
+
* - Computing derived values from parsed input
|
|
250
|
+
* - Creating reusable transformations that can be applied to any parser
|
|
251
|
+
*
|
|
252
|
+
* @template T The type of the value produced by the original parser.
|
|
253
|
+
* @template U The type of the value produced by the mapping function.
|
|
254
|
+
* @template TState The type of the state used by the original parser.
|
|
255
|
+
* @param parser The {@link Parser} whose result will be transformed.
|
|
256
|
+
* @param transform A function that transforms the parsed value from type T to type U.
|
|
257
|
+
* @returns A {@link Parser} that produces the transformed value of type U
|
|
258
|
+
* while preserving the original parser's state type and parsing behavior.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* // Transform boolean flag to its inverse
|
|
263
|
+
* const parser = object({
|
|
264
|
+
* disallow: map(option("--allow"), b => !b)
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* // Transform string to uppercase
|
|
268
|
+
* const upperParser = map(argument(string()), s => s.toUpperCase());
|
|
269
|
+
*
|
|
270
|
+
* // Transform number to formatted string
|
|
271
|
+
* const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
declare function map<T, U, TState>(parser: Parser<T, TState>, transform: (value: T) => U): Parser<U, TState>;
|
|
241
275
|
/**
|
|
242
276
|
* Options for the {@link multiple} parser.
|
|
243
277
|
*/
|
|
@@ -577,4 +611,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
|
|
|
577
611
|
*/
|
|
578
612
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
579
613
|
//#endregion
|
|
580
|
-
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
614
|
+
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
package/dist/parser.d.ts
CHANGED
|
@@ -238,6 +238,40 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
|
|
|
238
238
|
* or the default value if the wrapped parser fails to match.
|
|
239
239
|
*/
|
|
240
240
|
declare function withDefault<TValue, TState>(parser: Parser<TValue, TState>, defaultValue: TValue | (() => TValue)): Parser<TValue, [TState] | undefined>;
|
|
241
|
+
/**
|
|
242
|
+
* Creates a parser that transforms the result value of another parser using
|
|
243
|
+
* a mapping function. This enables value transformation while preserving
|
|
244
|
+
* the original parser's parsing logic and state management.
|
|
245
|
+
*
|
|
246
|
+
* The `map()` function is useful for:
|
|
247
|
+
* - Converting parsed values to different types
|
|
248
|
+
* - Applying transformations like string formatting or boolean inversion
|
|
249
|
+
* - Computing derived values from parsed input
|
|
250
|
+
* - Creating reusable transformations that can be applied to any parser
|
|
251
|
+
*
|
|
252
|
+
* @template T The type of the value produced by the original parser.
|
|
253
|
+
* @template U The type of the value produced by the mapping function.
|
|
254
|
+
* @template TState The type of the state used by the original parser.
|
|
255
|
+
* @param parser The {@link Parser} whose result will be transformed.
|
|
256
|
+
* @param transform A function that transforms the parsed value from type T to type U.
|
|
257
|
+
* @returns A {@link Parser} that produces the transformed value of type U
|
|
258
|
+
* while preserving the original parser's state type and parsing behavior.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* // Transform boolean flag to its inverse
|
|
263
|
+
* const parser = object({
|
|
264
|
+
* disallow: map(option("--allow"), b => !b)
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* // Transform string to uppercase
|
|
268
|
+
* const upperParser = map(argument(string()), s => s.toUpperCase());
|
|
269
|
+
*
|
|
270
|
+
* // Transform number to formatted string
|
|
271
|
+
* const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
declare function map<T, U, TState>(parser: Parser<T, TState>, transform: (value: T) => U): Parser<U, TState>;
|
|
241
275
|
/**
|
|
242
276
|
* Options for the {@link multiple} parser.
|
|
243
277
|
*/
|
|
@@ -577,4 +611,4 @@ declare function parse<T>(parser: Parser<T, unknown>, args: readonly string[]):
|
|
|
577
611
|
*/
|
|
578
612
|
declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
|
|
579
613
|
//#endregion
|
|
580
|
-
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
614
|
+
export { ArgumentOptions, CommandOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
package/dist/parser.js
CHANGED
|
@@ -413,6 +413,60 @@ function withDefault(parser, defaultValue) {
|
|
|
413
413
|
};
|
|
414
414
|
}
|
|
415
415
|
/**
|
|
416
|
+
* Creates a parser that transforms the result value of another parser using
|
|
417
|
+
* a mapping function. This enables value transformation while preserving
|
|
418
|
+
* the original parser's parsing logic and state management.
|
|
419
|
+
*
|
|
420
|
+
* The `map()` function is useful for:
|
|
421
|
+
* - Converting parsed values to different types
|
|
422
|
+
* - Applying transformations like string formatting or boolean inversion
|
|
423
|
+
* - Computing derived values from parsed input
|
|
424
|
+
* - Creating reusable transformations that can be applied to any parser
|
|
425
|
+
*
|
|
426
|
+
* @template T The type of the value produced by the original parser.
|
|
427
|
+
* @template U The type of the value produced by the mapping function.
|
|
428
|
+
* @template TState The type of the state used by the original parser.
|
|
429
|
+
* @param parser The {@link Parser} whose result will be transformed.
|
|
430
|
+
* @param transform A function that transforms the parsed value from type T to type U.
|
|
431
|
+
* @returns A {@link Parser} that produces the transformed value of type U
|
|
432
|
+
* while preserving the original parser's state type and parsing behavior.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* // Transform boolean flag to its inverse
|
|
437
|
+
* const parser = object({
|
|
438
|
+
* disallow: map(option("--allow"), b => !b)
|
|
439
|
+
* });
|
|
440
|
+
*
|
|
441
|
+
* // Transform string to uppercase
|
|
442
|
+
* const upperParser = map(argument(string()), s => s.toUpperCase());
|
|
443
|
+
*
|
|
444
|
+
* // Transform number to formatted string
|
|
445
|
+
* const prefixedParser = map(option("-n", integer()), n => `value: ${n}`);
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
function map(parser, transform) {
|
|
449
|
+
return {
|
|
450
|
+
$valueType: [],
|
|
451
|
+
$stateType: parser.$stateType,
|
|
452
|
+
priority: parser.priority,
|
|
453
|
+
usage: parser.usage,
|
|
454
|
+
initialState: parser.initialState,
|
|
455
|
+
parse: parser.parse.bind(parser),
|
|
456
|
+
complete(state) {
|
|
457
|
+
const result = parser.complete(state);
|
|
458
|
+
if (result.success) return {
|
|
459
|
+
success: true,
|
|
460
|
+
value: transform(result.value)
|
|
461
|
+
};
|
|
462
|
+
return result;
|
|
463
|
+
},
|
|
464
|
+
getDocFragments(state, _defaultValue) {
|
|
465
|
+
return parser.getDocFragments(state, void 0);
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
416
470
|
* Creates a parser that allows multiple occurrences of a given parser.
|
|
417
471
|
* This parser can be used to parse multiple values of the same type,
|
|
418
472
|
* such as multiple command-line arguments or options.
|
|
@@ -1050,4 +1104,4 @@ function getDocPage(parser, args = []) {
|
|
|
1050
1104
|
}
|
|
1051
1105
|
|
|
1052
1106
|
//#endregion
|
|
1053
|
-
export { argument, command, constant, getDocPage, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|
|
1107
|
+
export { argument, command, constant, getDocPage, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
|