@bytecodealliance/jco 1.11.2-rc.2 → 1.11.3-rc.1

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/src/jco.js CHANGED
@@ -6,236 +6,439 @@ import { program, Option } from 'commander';
6
6
  import { opt } from './cmd/opt.js';
7
7
  import { transpile, types, guestTypes } from './cmd/transpile.js';
8
8
  import { run as runCmd, serve as serveCmd } from './cmd/run.js';
9
- import { parse, print, componentNew, componentEmbed, metadataAdd, metadataShow, componentWit } from './cmd/wasm-tools.js';
9
+ import {
10
+ parse,
11
+ print,
12
+ componentNew,
13
+ componentEmbed,
14
+ metadataAdd,
15
+ metadataShow,
16
+ componentWit,
17
+ } from './cmd/wasm-tools.js';
10
18
  import { componentize } from './cmd/componentize.js';
11
19
 
12
20
  program
13
- .name('jco')
14
- .description(c`{bold jco - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`)
15
- .usage('<command> [options]')
16
- .version('1.11.2-rc.2');
21
+ .name('jco')
22
+ .description(
23
+ c`{bold jco - WebAssembly JS Component Tools}\n JS Component Transpilation Bindgen & Wasm Tools for JS`
24
+ )
25
+ .usage('<command> [options]')
26
+ .version('1.11.3-rc.1');
17
27
 
18
28
  function myParseInt(value) {
19
- return parseInt(value, 10);
29
+ return parseInt(value, 10);
20
30
  }
21
31
 
22
32
  /**
23
- * Option parsing that allows for collecting repeated arguments
24
- *
25
- * @param {string} value - the new value that is added
26
- * @param {string[]} previous - the existing list of values
27
- */
33
+ * Option parsing that allows for collecting repeated arguments
34
+ *
35
+ * @param {string} value - the new value that is added
36
+ * @param {string[]} previous - the existing list of values
37
+ */
28
38
  function collectOptions(value, previous) {
29
- return previous.concat([value]);
39
+ return previous.concat([value]);
30
40
  }
31
41
 
32
- program.command('componentize')
33
- .description('Create a component from a JavaScript module')
34
- .usage('<js-source> --wit wit-world.wit -o <component-path>')
35
- .argument('<js-source>', 'JS source file to build')
36
- .requiredOption('-w, --wit <path>', 'WIT path to build with')
37
- .option('-n, --world-name <name>', 'WIT world to build')
38
- .option('--aot', 'Enable Weval AOT compilation of JS')
39
- .option('--aot-min-stack-size-bytes <number>', 'Set the min stack size to be used during AOT')
40
- .option('--weval-bin <path>', 'Specify a custom weval binary to use')
41
- .addOption(new Option('-d, --disable <feature...>', 'disable WASI features').choices(['clocks', 'http', 'random', 'stdio', 'all']))
42
- // .addOption(new Option('-e, --enable <feature...>', 'enable WASI features').choices(['http']))
43
- .option('--preview2-adapter <adapter>', 'provide a custom preview2 adapter path')
44
- .option('--debug-starlingmonkey-build', 'use a debug build of StarlingMonkey')
45
- .requiredOption('-o, --out <out>', 'output component file')
46
- .action(asyncAction(componentize));
47
-
48
- program.command('transpile')
49
- .description('Transpile a WebAssembly Component to JS + core Wasm for JavaScript execution')
50
- .usage('<component-path> -o <out-dir>')
51
- .argument('<component-path>', 'Wasm component binary filepath')
52
- .option('--name <name>', 'custom output name')
53
- .requiredOption('-o, --out-dir <out-dir>', 'output directory')
54
- .option('-m, --minify', 'minify the JS output (--optimize / opt cmd still required)')
55
- .option('-O, --optimize', 'optimize the component first')
56
- .option('--no-typescript', 'do not output TypeScript .d.ts types')
57
- .option('--valid-lifting-optimization', 'optimize component binary validations assuming all lifted values are valid')
58
- .addOption(new Option('--import-bindings [mode]', 'bindings mode for imports').choices(['js', 'optimized', 'hybrid', 'direct-optimized']).preset('js'))
59
- .addOption(new Option('--async-mode [mode]', 'EXPERIMENTAL: use async imports and exports').choices(['sync', 'jspi']).preset('sync'))
60
- .option('--async-wasi-imports', 'EXPERIMENTAL: async component imports from WASI interfaces')
61
- .option('--async-wasi-exports', 'EXPERIMENTAL: async component exports from WASI interfaces')
62
- .option('--async-imports <imports...>', 'EXPERIMENTAL: async component imports (examples: "wasi:io/poll@0.2.0#poll", "wasi:io/poll#[method]pollable.block")')
63
- .option('--async-exports <exports...>', 'EXPERIMENTAL: async component exports (examples: "wasi:cli/run@#run", "handle")')
64
- .option('--tracing', 'emit `tracing` calls on function entry/exit')
65
- .option('-b, --base64-cutoff <bytes>', 'set the byte size under which core Wasm binaries will be inlined as base64', myParseInt)
66
- .option('--tla-compat', 'enables compatibility for JS environments without top-level await support via an async $init promise export')
67
- .option('--no-nodejs-compat', 'disables compatibility in Node.js without a fetch global')
68
- .option('-M, --map <mappings...>', 'specifier=./output custom mappings for the component imports')
69
- .option('--no-wasi-shim', 'disable automatic rewriting of WASI imports to use @bytecodealliance/preview2-shim')
70
- .option('--stub', 'generate a stub implementation from a WIT file directly')
71
- .option('--js', 'output JS instead of core WebAssembly')
72
- .addOption(new Option('-I, --instantiation [mode]', 'output for custom module instantiation').choices(['async', 'sync']).preset('async'))
73
- .option('-q, --quiet', 'disable output summary')
74
- .option('--no-namespaced-exports', 'disable namespaced exports for typescript compatibility')
75
- .option('--multi-memory', 'optimized output for Wasm multi-memory')
76
- .option('--', 'for --optimize, custom wasm-opt arguments (defaults to best size optimization)')
77
- .action(asyncAction(transpile));
78
-
79
- program.command('types')
80
- .description('Generate types for the given WIT')
81
- .usage('<wit-path> -o <out-dir>')
82
- .argument('<wit-path>', 'path to a WIT file or directory')
83
- .option('--name <name>', 'custom output name')
84
- .option('-n, --world-name <world>', 'WIT world to generate types for')
85
- .requiredOption('-o, --out-dir <out-dir>', 'output directory')
86
- .option('--tla-compat', 'generates types for the TLA compat output with an async $init promise export')
87
- .addOption(new Option('-I, --instantiation [mode]', 'type output for custom module instantiation').choices(['async', 'sync']).preset('async'))
88
- .addOption(new Option('--async-mode [mode]', 'EXPERIMENTAL: use async imports and exports').choices(['sync', 'jspi']).preset('sync'))
89
- .option('--async-wasi-imports', 'EXPERIMENTAL: async component imports from WASI interfaces')
90
- .option('--async-wasi-exports', 'EXPERIMENTAL: async component exports from WASI interfaces')
91
- .option('--async-imports <imports...>', 'EXPERIMENTAL: async component imports (examples: "wasi:io/poll@0.2.0#poll", "wasi:io/poll#[method]pollable.block")')
92
- .option('--async-exports <exports...>', 'EXPERIMENTAL: async component exports (examples: "wasi:cli/run@#run", "handle")')
93
- .option('-q, --quiet', 'disable output summary')
94
- .option('--feature <feature>', 'enable one specific WIT feature (repeatable)', collectOptions, [])
95
- .option('--all-features', 'enable all features')
96
- .action(asyncAction(types));
97
-
98
- program.command('guest-types')
99
- .description('(experimental) Generate guest types for the given WIT')
100
- .usage('<wit-path> -o <out-dir>')
101
- .argument('<wit-path>', 'path to a WIT file or directory')
102
- .option('--name <name>', 'custom output name')
103
- .option('-n, --world-name <world>', 'WIT world to generate types for')
104
- .requiredOption('-o, --out-dir <out-dir>', 'output directory')
105
- .option('-q, --quiet', 'disable output summary')
106
- .option('--feature <feature>', 'enable one specific WIT feature (repeatable)', collectOptions, [])
107
- .option('--all-features', 'enable all features')
108
- .action(asyncAction(guestTypes));
109
-
110
- program.command('run')
111
- .description('Run a WASI Command component')
112
- .usage('<command.wasm> <args...>')
113
- .helpOption(false)
114
- .allowUnknownOption(true)
115
- .allowExcessArguments(true)
116
- .argument('<command>', 'WASI command binary to run')
117
- .option('--jco-dir <dir>', 'Instead of using a temporary dir, set the output directory for the run command')
118
- .option('--jco-trace', 'Enable call tracing')
119
- .option('--jco-import <module>', 'Custom module to import before the run executes to support custom environment setup')
120
- .option('--jco-map <mappings...>', 'specifier=./output custom mappings for the component imports')
121
- .addOption(new Option('--jco-import-bindings [mode]', 'bindings mode for imports').choices(['js', 'optimized', 'hybrid', 'direct-optimized']).preset('js'))
122
- .argument('[args...]', 'Any CLI arguments for the component')
123
- .action(asyncAction(async function run (cmd, args, opts, command) {
124
- // specially only allow help option in first position
125
- if (cmd === '--help' || cmd === '-h') {
126
- command.help();
127
- } else {
128
- return runCmd(cmd, args, opts);
129
- }
130
- }));
131
-
132
- program.command('serve')
133
- .description('Serve a WASI HTTP component')
134
- .usage('<server.wasm> <args...>')
135
- .helpOption(false)
136
- .allowUnknownOption(true)
137
- .allowExcessArguments(true)
138
- .argument('<server>', 'WASI server binary to run')
139
- .option('--port <number>')
140
- .option('--host <host>')
141
- .option('--jco-dir <dir>', 'Instead of using a temporary dir, set the output directory for the transpiled code')
142
- .option('--jco-trace', 'Enable call tracing')
143
- .option('--jco-import <module>', 'Custom module to import before the server executes to support custom environment setup')
144
- .addOption(new Option('--jco-import-bindings [mode]', 'bindings mode for imports').choices(['js', 'optimized', 'hybrid', 'direct-optimized']).preset('js'))
145
- .option('--jco-map <mappings...>', 'specifier=./output custom mappings for the component imports')
146
- .argument('[args...]', 'Any CLI arguments for the component')
147
- .action(asyncAction(async function serve (cmd, args, opts, command) {
148
- // specially only allow help option in first position
149
- if (cmd === '--help' || cmd === '-h') {
150
- command.help();
151
- } else {
152
- return serveCmd(cmd, args, opts);
153
- }
154
- }));
155
-
156
- program.command('opt')
157
- .description('optimizes a Wasm component, including running wasm-opt Binaryen optimizations')
158
- .usage('<component-file> -o <output-file>')
159
- .argument('<component-file>', 'Wasm component binary filepath')
160
- .requiredOption('-o, --output <output-file>', 'optimized component output filepath')
161
- .option('--asyncify', 'runs Asyncify pass in wasm-opt')
162
- .option('-q, --quiet')
163
- .option('--', 'custom wasm-opt arguments (defaults to best size optimization)')
164
- .action(asyncAction(opt));
165
-
166
- program.command('wit')
167
- .description('extract the WIT from a WebAssembly Component [wasm-tools component wit]')
168
- .argument('<component-path>', 'Wasm component binary filepath')
169
- .option('-d, --document <name>', 'WIT document of a package to print')
170
- .option('-o, --output <output-file>', 'WIT output file path')
171
- .action(asyncAction(componentWit));
172
-
173
- program.command('print')
174
- .description('print the WebAssembly WAT text for a binary file [wasm-tools print]')
175
- .argument('<input>', 'input file to process')
176
- .option('-o, --output <output-file>', 'output file path')
177
- .action(asyncAction(print));
178
-
179
- program.command('metadata-show')
180
- .description('extract the producer metadata for a Wasm binary [wasm-tools metadata show]')
181
- .argument('[module]', 'Wasm component or core module filepath')
182
- .option('--json', 'output component metadata as JSON')
183
- .action(asyncAction(metadataShow));
184
-
185
- program.command('metadata-add')
186
- .description('add producer metadata for a Wasm binary [wasm-tools metadata add]')
187
- .argument('[module]', 'Wasm component or core module filepath')
188
- .requiredOption('-m, --metadata <metadata...>', 'field=name[@version] producer metadata to add with the embedding')
189
- .requiredOption('-o, --output <output-file>', 'output binary path')
190
- .action(asyncAction(metadataAdd));
191
-
192
- program.command('parse')
193
- .description('parses the Wasm text format into a binary file [wasm-tools parse]')
194
- .argument('<input>', 'input file to process')
195
- .requiredOption('-o, --output <output-file>', 'output binary file path')
196
- .action(asyncAction(parse));
197
-
198
- program.command('new')
199
- .description('create a WebAssembly component adapted from a component core Wasm [wasm-tools component new]')
200
- .argument('<core-module>', 'Wasm core module filepath')
201
- .requiredOption('-o, --output <output-file>', 'Wasm component output filepath')
202
- .option('--name <name>', 'custom output name')
203
- .option('--adapt <[NAME=]adapter...>', 'component adapters to apply')
204
- .option('--wasi-reactor', 'build with the WASI Reactor adapter')
205
- .option('--wasi-command', 'build with the WASI Command adapter')
206
- .action(asyncAction(componentNew));
207
-
208
- program.command('embed')
209
- .description('embed the component typing section into a core Wasm module [wasm-tools component embed]')
210
- .argument('[core-module]', 'Wasm core module filepath')
211
- .requiredOption('-o, --output <output-file>', 'Wasm component output filepath')
212
- .requiredOption('--wit <wit-world>', 'WIT world path')
213
- .option('--dummy', 'generate a dummy component')
214
- .option('--string-encoding <utf8|utf16|compact-utf16>', 'set the component string encoding')
215
- .option('-n, --world-name <world-name>', 'world name to embed')
216
- .option('-m, --metadata <metadata...>', 'field=name[@version] producer metadata to add with the embedding')
217
- .action(asyncAction(componentEmbed));
42
+ program
43
+ .command('componentize')
44
+ .description('Create a component from a JavaScript module')
45
+ .usage('<js-source> --wit wit-world.wit -o <component-path>')
46
+ .argument('<js-source>', 'JS source file to build')
47
+ .requiredOption('-w, --wit <path>', 'WIT path to build with')
48
+ .option('-n, --world-name <name>', 'WIT world to build')
49
+ .option('--aot', 'Enable Weval AOT compilation of JS')
50
+ .option(
51
+ '--aot-min-stack-size-bytes <number>',
52
+ 'Set the min stack size to be used during AOT'
53
+ )
54
+ .option('--weval-bin <path>', 'Specify a custom weval binary to use')
55
+ .addOption(
56
+ new Option(
57
+ '-d, --disable <feature...>',
58
+ 'disable WASI features'
59
+ ).choices(['clocks', 'http', 'random', 'stdio', 'all'])
60
+ )
61
+ // .addOption(new Option('-e, --enable <feature...>', 'enable WASI features').choices(['http']))
62
+ .option(
63
+ '--preview2-adapter <adapter>',
64
+ 'provide a custom preview2 adapter path'
65
+ )
66
+ .option(
67
+ '--debug-starlingmonkey-build',
68
+ 'use a debug build of StarlingMonkey'
69
+ )
70
+ .requiredOption('-o, --out <out>', 'output component file')
71
+ .action(asyncAction(componentize));
72
+
73
+ program
74
+ .command('transpile')
75
+ .description(
76
+ 'Transpile a WebAssembly Component to JS + core Wasm for JavaScript execution'
77
+ )
78
+ .usage('<component-path> -o <out-dir>')
79
+ .argument('<component-path>', 'Wasm component binary filepath')
80
+ .option('--name <name>', 'custom output name')
81
+ .requiredOption('-o, --out-dir <out-dir>', 'output directory')
82
+ .option(
83
+ '-m, --minify',
84
+ 'minify the JS output (--optimize / opt cmd still required)'
85
+ )
86
+ .option('-O, --optimize', 'optimize the component first')
87
+ .option('--no-typescript', 'do not output TypeScript .d.ts types')
88
+ .option(
89
+ '--valid-lifting-optimization',
90
+ 'optimize component binary validations assuming all lifted values are valid'
91
+ )
92
+ .addOption(
93
+ new Option('--import-bindings [mode]', 'bindings mode for imports')
94
+ .choices(['js', 'optimized', 'hybrid', 'direct-optimized'])
95
+ .preset('js')
96
+ )
97
+ .addOption(
98
+ new Option(
99
+ '--async-mode [mode]',
100
+ 'EXPERIMENTAL: use async imports and exports'
101
+ )
102
+ .choices(['sync', 'jspi'])
103
+ .preset('sync')
104
+ )
105
+ .option(
106
+ '--async-wasi-imports',
107
+ 'EXPERIMENTAL: async component imports from WASI interfaces'
108
+ )
109
+ .option(
110
+ '--async-wasi-exports',
111
+ 'EXPERIMENTAL: async component exports from WASI interfaces'
112
+ )
113
+ .option(
114
+ '--async-imports <imports...>',
115
+ 'EXPERIMENTAL: async component imports (examples: "wasi:io/poll@0.2.0#poll", "wasi:io/poll#[method]pollable.block")'
116
+ )
117
+ .option(
118
+ '--async-exports <exports...>',
119
+ 'EXPERIMENTAL: async component exports (examples: "wasi:cli/run@#run", "handle")'
120
+ )
121
+ .option('--tracing', 'emit `tracing` calls on function entry/exit')
122
+ .option(
123
+ '-b, --base64-cutoff <bytes>',
124
+ 'set the byte size under which core Wasm binaries will be inlined as base64',
125
+ myParseInt
126
+ )
127
+ .option(
128
+ '--tla-compat',
129
+ 'enables compatibility for JS environments without top-level await support via an async $init promise export'
130
+ )
131
+ .option(
132
+ '--no-nodejs-compat',
133
+ 'disables compatibility in Node.js without a fetch global'
134
+ )
135
+ .option(
136
+ '-M, --map <mappings...>',
137
+ 'specifier=./output custom mappings for the component imports'
138
+ )
139
+ .option(
140
+ '--no-wasi-shim',
141
+ 'disable automatic rewriting of WASI imports to use @bytecodealliance/preview2-shim'
142
+ )
143
+ .option('--stub', 'generate a stub implementation from a WIT file directly')
144
+ .option('--js', 'output JS instead of core WebAssembly')
145
+ .addOption(
146
+ new Option(
147
+ '-I, --instantiation [mode]',
148
+ 'output for custom module instantiation'
149
+ )
150
+ .choices(['async', 'sync'])
151
+ .preset('async')
152
+ )
153
+ .option('-q, --quiet', 'disable output summary')
154
+ .option(
155
+ '--no-namespaced-exports',
156
+ 'disable namespaced exports for typescript compatibility'
157
+ )
158
+ .option('--multi-memory', 'optimized output for Wasm multi-memory')
159
+ .option(
160
+ '--',
161
+ 'for --optimize, custom wasm-opt arguments (defaults to best size optimization)'
162
+ )
163
+ .action(asyncAction(transpile));
164
+
165
+ program
166
+ .command('types')
167
+ .description('Generate types for the given WIT')
168
+ .usage('<wit-path> -o <out-dir>')
169
+ .argument('<wit-path>', 'path to a WIT file or directory')
170
+ .option('--name <name>', 'custom output name')
171
+ .option('-n, --world-name <world>', 'WIT world to generate types for')
172
+ .requiredOption('-o, --out-dir <out-dir>', 'output directory')
173
+ .option(
174
+ '--tla-compat',
175
+ 'generates types for the TLA compat output with an async $init promise export'
176
+ )
177
+ .addOption(
178
+ new Option(
179
+ '-I, --instantiation [mode]',
180
+ 'type output for custom module instantiation'
181
+ )
182
+ .choices(['async', 'sync'])
183
+ .preset('async')
184
+ )
185
+ .addOption(
186
+ new Option(
187
+ '--async-mode [mode]',
188
+ 'EXPERIMENTAL: use async imports and exports'
189
+ )
190
+ .choices(['sync', 'jspi'])
191
+ .preset('sync')
192
+ )
193
+ .option(
194
+ '--async-wasi-imports',
195
+ 'EXPERIMENTAL: async component imports from WASI interfaces'
196
+ )
197
+ .option(
198
+ '--async-wasi-exports',
199
+ 'EXPERIMENTAL: async component exports from WASI interfaces'
200
+ )
201
+ .option(
202
+ '--async-imports <imports...>',
203
+ 'EXPERIMENTAL: async component imports (examples: "wasi:io/poll@0.2.0#poll", "wasi:io/poll#[method]pollable.block")'
204
+ )
205
+ .option(
206
+ '--async-exports <exports...>',
207
+ 'EXPERIMENTAL: async component exports (examples: "wasi:cli/run@#run", "handle")'
208
+ )
209
+ .option('-q, --quiet', 'disable output summary')
210
+ .option(
211
+ '--feature <feature>',
212
+ 'enable one specific WIT feature (repeatable)',
213
+ collectOptions,
214
+ []
215
+ )
216
+ .option('--all-features', 'enable all features')
217
+ .action(asyncAction(types));
218
+
219
+ program
220
+ .command('guest-types')
221
+ .description('(experimental) Generate guest types for the given WIT')
222
+ .usage('<wit-path> -o <out-dir>')
223
+ .argument('<wit-path>', 'path to a WIT file or directory')
224
+ .option('--name <name>', 'custom output name')
225
+ .option('-n, --world-name <world>', 'WIT world to generate types for')
226
+ .requiredOption('-o, --out-dir <out-dir>', 'output directory')
227
+ .option('-q, --quiet', 'disable output summary')
228
+ .option(
229
+ '--feature <feature>',
230
+ 'enable one specific WIT feature (repeatable)',
231
+ collectOptions,
232
+ []
233
+ )
234
+ .option('--all-features', 'enable all features')
235
+ .action(asyncAction(guestTypes));
236
+
237
+ program
238
+ .command('run')
239
+ .description('Run a WASI Command component')
240
+ .usage('<command.wasm> <args...>')
241
+ .helpOption(false)
242
+ .allowUnknownOption(true)
243
+ .allowExcessArguments(true)
244
+ .argument('<command>', 'WASI command binary to run')
245
+ .option(
246
+ '--jco-dir <dir>',
247
+ 'Instead of using a temporary dir, set the output directory for the run command'
248
+ )
249
+ .option('--jco-trace', 'Enable call tracing')
250
+ .option(
251
+ '--jco-import <module>',
252
+ 'Custom module to import before the run executes to support custom environment setup'
253
+ )
254
+ .option(
255
+ '--jco-map <mappings...>',
256
+ 'specifier=./output custom mappings for the component imports'
257
+ )
258
+ .addOption(
259
+ new Option('--jco-import-bindings [mode]', 'bindings mode for imports')
260
+ .choices(['js', 'optimized', 'hybrid', 'direct-optimized'])
261
+ .preset('js')
262
+ )
263
+ .argument('[args...]', 'Any CLI arguments for the component')
264
+ .action(
265
+ asyncAction(async function run(cmd, args, opts, command) {
266
+ // specially only allow help option in first position
267
+ if (cmd === '--help' || cmd === '-h') {
268
+ command.help();
269
+ } else {
270
+ return runCmd(cmd, args, opts);
271
+ }
272
+ })
273
+ );
274
+
275
+ program
276
+ .command('serve')
277
+ .description('Serve a WASI HTTP component')
278
+ .usage('<server.wasm> <args...>')
279
+ .helpOption(false)
280
+ .allowUnknownOption(true)
281
+ .allowExcessArguments(true)
282
+ .argument('<server>', 'WASI server binary to run')
283
+ .option('--port <number>')
284
+ .option('--host <host>')
285
+ .option(
286
+ '--jco-dir <dir>',
287
+ 'Instead of using a temporary dir, set the output directory for the transpiled code'
288
+ )
289
+ .option('--jco-trace', 'Enable call tracing')
290
+ .option(
291
+ '--jco-import <module>',
292
+ 'Custom module to import before the server executes to support custom environment setup'
293
+ )
294
+ .addOption(
295
+ new Option('--jco-import-bindings [mode]', 'bindings mode for imports')
296
+ .choices(['js', 'optimized', 'hybrid', 'direct-optimized'])
297
+ .preset('js')
298
+ )
299
+ .option(
300
+ '--jco-map <mappings...>',
301
+ 'specifier=./output custom mappings for the component imports'
302
+ )
303
+ .argument('[args...]', 'Any CLI arguments for the component')
304
+ .action(
305
+ asyncAction(async function serve(cmd, args, opts, command) {
306
+ // specially only allow help option in first position
307
+ if (cmd === '--help' || cmd === '-h') {
308
+ command.help();
309
+ } else {
310
+ return serveCmd(cmd, args, opts);
311
+ }
312
+ })
313
+ );
314
+
315
+ program
316
+ .command('opt')
317
+ .description(
318
+ 'optimizes a Wasm component, including running wasm-opt Binaryen optimizations'
319
+ )
320
+ .usage('<component-file> -o <output-file>')
321
+ .argument('<component-file>', 'Wasm component binary filepath')
322
+ .requiredOption(
323
+ '-o, --output <output-file>',
324
+ 'optimized component output filepath'
325
+ )
326
+ .option('--asyncify', 'runs Asyncify pass in wasm-opt')
327
+ .option('-q, --quiet')
328
+ .option(
329
+ '--',
330
+ 'custom wasm-opt arguments (defaults to best size optimization)'
331
+ )
332
+ .action(asyncAction(opt));
333
+
334
+ program
335
+ .command('wit')
336
+ .description(
337
+ 'extract the WIT from a WebAssembly Component [wasm-tools component wit]'
338
+ )
339
+ .argument('<component-path>', 'Wasm component binary filepath')
340
+ .option('-d, --document <name>', 'WIT document of a package to print')
341
+ .option('-o, --output <output-file>', 'WIT output file path')
342
+ .action(asyncAction(componentWit));
343
+
344
+ program
345
+ .command('print')
346
+ .description(
347
+ 'print the WebAssembly WAT text for a binary file [wasm-tools print]'
348
+ )
349
+ .argument('<input>', 'input file to process')
350
+ .option('-o, --output <output-file>', 'output file path')
351
+ .action(asyncAction(print));
352
+
353
+ program
354
+ .command('metadata-show')
355
+ .description(
356
+ 'extract the producer metadata for a Wasm binary [wasm-tools metadata show]'
357
+ )
358
+ .argument('[module]', 'Wasm component or core module filepath')
359
+ .option('--json', 'output component metadata as JSON')
360
+ .action(asyncAction(metadataShow));
361
+
362
+ program
363
+ .command('metadata-add')
364
+ .description(
365
+ 'add producer metadata for a Wasm binary [wasm-tools metadata add]'
366
+ )
367
+ .argument('[module]', 'Wasm component or core module filepath')
368
+ .requiredOption(
369
+ '-m, --metadata <metadata...>',
370
+ 'field=name[@version] producer metadata to add with the embedding'
371
+ )
372
+ .requiredOption('-o, --output <output-file>', 'output binary path')
373
+ .action(asyncAction(metadataAdd));
374
+
375
+ program
376
+ .command('parse')
377
+ .description(
378
+ 'parses the Wasm text format into a binary file [wasm-tools parse]'
379
+ )
380
+ .argument('<input>', 'input file to process')
381
+ .requiredOption('-o, --output <output-file>', 'output binary file path')
382
+ .action(asyncAction(parse));
383
+
384
+ program
385
+ .command('new')
386
+ .description(
387
+ 'create a WebAssembly component adapted from a component core Wasm [wasm-tools component new]'
388
+ )
389
+ .argument('<core-module>', 'Wasm core module filepath')
390
+ .requiredOption(
391
+ '-o, --output <output-file>',
392
+ 'Wasm component output filepath'
393
+ )
394
+ .option('--name <name>', 'custom output name')
395
+ .option('--adapt <[NAME=]adapter...>', 'component adapters to apply')
396
+ .option('--wasi-reactor', 'build with the WASI Reactor adapter')
397
+ .option('--wasi-command', 'build with the WASI Command adapter')
398
+ .action(asyncAction(componentNew));
399
+
400
+ program
401
+ .command('embed')
402
+ .description(
403
+ 'embed the component typing section into a core Wasm module [wasm-tools component embed]'
404
+ )
405
+ .argument('[core-module]', 'Wasm core module filepath')
406
+ .requiredOption(
407
+ '-o, --output <output-file>',
408
+ 'Wasm component output filepath'
409
+ )
410
+ .requiredOption('--wit <wit-world>', 'WIT world path')
411
+ .option('--dummy', 'generate a dummy component')
412
+ .option(
413
+ '--string-encoding <utf8|utf16|compact-utf16>',
414
+ 'set the component string encoding'
415
+ )
416
+ .option('-n, --world-name <world-name>', 'world name to embed')
417
+ .option(
418
+ '-m, --metadata <metadata...>',
419
+ 'field=name[@version] producer metadata to add with the embedding'
420
+ )
421
+ .action(asyncAction(componentEmbed));
218
422
 
219
423
  program.showHelpAfterError();
220
424
 
221
425
  program.parse();
222
426
 
223
- function asyncAction (cmd) {
224
- return function () {
225
- const args = [...arguments];
226
- (async () => {
227
- try {
228
- await cmd.apply(null, args);
229
- }
230
- catch (e) {
231
- process.stdout.write(`(jco ${cmd.name}) `);
232
- if (typeof e === 'string') {
233
- console.error(c`{red.bold Error}: ${e}\n`);
234
- } else {
235
- console.error(e);
236
- }
237
- process.exit(1);
238
- }
239
- })();
240
- };
427
+ function asyncAction(cmd) {
428
+ return function() {
429
+ const args = [...arguments];
430
+ (async () => {
431
+ try {
432
+ await cmd.apply(null, args);
433
+ } catch (e) {
434
+ process.stdout.write(`(jco ${cmd.name}) `);
435
+ if (typeof e === 'string') {
436
+ console.error(c`{red.bold Error}: ${e}\n`);
437
+ } else {
438
+ console.error(e);
439
+ }
440
+ process.exit(1);
441
+ }
442
+ })();
443
+ };
241
444
  }