@knighted/jsx 1.3.0 → 1.3.2
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 +66 -189
- package/dist/cjs/cli/init.cjs +56 -24
- package/dist/cjs/cli/init.d.cts +20 -5
- package/dist/cli/init.d.ts +20 -5
- package/dist/cli/init.js +64 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ A runtime JSX template tag backed by the [`oxc-parser`](https://github.com/oxc-p
|
|
|
18
18
|
- [React runtime](#react-runtime-reactjsx)
|
|
19
19
|
- [Loader integration](#loader-integration)
|
|
20
20
|
- [Node / SSR usage](#node--ssr-usage)
|
|
21
|
-
- [Next.js integration](#nextjs-integration)
|
|
22
21
|
- [Browser usage](#browser-usage)
|
|
23
|
-
- [
|
|
22
|
+
- [TypeScript plugin](docs/ts-plugin.md)
|
|
23
|
+
- [Component testing](docs/testing.md)
|
|
24
24
|
- [CLI setup](docs/cli.md)
|
|
25
25
|
|
|
26
26
|
## Installation
|
|
@@ -30,7 +30,7 @@ npm install @knighted/jsx
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
> [!IMPORTANT]
|
|
33
|
-
>
|
|
33
|
+
> `@knighted/jsx` ships as ESM-only. The dual-mode `.cjs` artifacts we build internally are not published.
|
|
34
34
|
|
|
35
35
|
> [!NOTE]
|
|
36
36
|
> Planning to use the React runtime (`@knighted/jsx/react`)? Install `react@>=18` and `react-dom@>=18` alongside this package so the helper can create elements and render them through ReactDOM.
|
|
@@ -94,6 +94,51 @@ createRoot(document.getElementById('root')!).render(reactJsx`<${App} />`)
|
|
|
94
94
|
|
|
95
95
|
The React runtime shares the same template semantics as `jsx`, except it returns React elements (via `React.createElement`) so you can embed other React components with `<${MyComponent} />` and use hooks/state as usual. The helper lives in a separate subpath so DOM-only consumers never pay the React dependency cost.
|
|
96
96
|
|
|
97
|
+
### DOM-specific props
|
|
98
|
+
|
|
99
|
+
- `style` accepts either a string or an object. Object values handle CSS custom properties (`--token`) automatically.
|
|
100
|
+
- `class` and `className` both work and can be strings or arrays.
|
|
101
|
+
- Event handlers use the `on<Event>` naming convention (e.g. `onClick`).
|
|
102
|
+
- `ref` supports callback refs as well as mutable `{ current }` objects.
|
|
103
|
+
- `dangerouslySetInnerHTML` expects an object with an `__html` field, mirroring React.
|
|
104
|
+
|
|
105
|
+
### Fragments & SVG
|
|
106
|
+
|
|
107
|
+
Use JSX fragments (`<>...</>`) for multi-root templates. SVG trees automatically switch to the `http://www.w3.org/2000/svg` namespace once they enter an `<svg>` tag, and fall back inside `<foreignObject>`.
|
|
108
|
+
|
|
109
|
+
### Interpolations and components
|
|
110
|
+
|
|
111
|
+
- `${...}` works exactly like JSX braces: drop expressions anywhere (text, attributes, spreads, conditionals) and the runtime keeps the original syntax. Text nodes do not need extra wrapping—`Count is ${value}` already works.
|
|
112
|
+
- Interpolated values can be primitives, DOM nodes, arrays/iterables, other `jsx` trees, or component functions. Resolve Promises before passing them in.
|
|
113
|
+
- Inline components are just functions/classes you interpolate as the tag name; they receive props plus optional `children` and can return anything `jsx` accepts.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const Button = ({ variant = 'primary' }) => {
|
|
117
|
+
let count = 3
|
|
118
|
+
|
|
119
|
+
return jsx`
|
|
120
|
+
<button
|
|
121
|
+
data-variant=${variant}
|
|
122
|
+
onClick=${() => {
|
|
123
|
+
count += 1
|
|
124
|
+
console.log(`Count is now ${count}`)
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
Count is ${count}
|
|
128
|
+
</button>
|
|
129
|
+
`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const view = jsx`
|
|
133
|
+
<section>
|
|
134
|
+
<p>Inline components can manage their own state.</p>
|
|
135
|
+
<${Button} variant="ghost" />
|
|
136
|
+
</section>
|
|
137
|
+
`
|
|
138
|
+
|
|
139
|
+
document.body.append(view)
|
|
140
|
+
```
|
|
141
|
+
|
|
97
142
|
## Loader integration
|
|
98
143
|
|
|
99
144
|
Use the published loader entry (`@knighted/jsx/loader`) when you want your bundler to rewrite tagged template literals at build time. The loader finds every ` jsx`` ` (and, by default, ` reactJsx`` ` ) invocation, rebuilds the template with real JSX semantics, and hands back transformed source that can run in any environment.
|
|
@@ -121,24 +166,9 @@ export default {
|
|
|
121
166
|
}
|
|
122
167
|
```
|
|
123
168
|
|
|
124
|
-
Pair the loader with your existing TypeScript/JSX transpiler (SWC, Babel, Rspack’s builtin loader, etc.) so regular React components and the tagged templates can live side by side.
|
|
125
|
-
|
|
126
|
-
```sh
|
|
127
|
-
npm run build
|
|
128
|
-
npm run setup:wasm
|
|
129
|
-
npm run build:fixture
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Then point a static server at the fixture root (which serves `index.html` plus the bundled `dist/hybrid.js` and `dist/reactMode.js`) to see it in a browser:
|
|
133
|
-
|
|
134
|
-
```sh
|
|
135
|
-
# Serve the rspack fixture from the repo root
|
|
136
|
-
npx http-server test/fixtures/rspack-app -p 4173
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Visit `http://localhost:4173` (or whichever port you pick) to interact with both the Lit + React hybrid demo and the React-mode bundle.
|
|
169
|
+
Pair the loader with your existing TypeScript/JSX transpiler (SWC, Babel, Rspack’s builtin loader, etc.) so regular React components and the tagged templates can live side by side.
|
|
140
170
|
|
|
141
|
-
Need a deeper dive into loader behavior and options? Check out [`src/loader/README.md`](src/loader/README.md)
|
|
171
|
+
Need a deeper dive into loader behavior and options? Check out [`src/loader/README.md`](src/loader/README.md). There is also a standalone walkthrough at [morganney/jsx-loader-demo](https://github.com/morganney/jsx-loader-demo).
|
|
142
172
|
|
|
143
173
|
## Node / SSR usage
|
|
144
174
|
|
|
@@ -174,126 +204,7 @@ console.log(shell.outerHTML)
|
|
|
174
204
|
|
|
175
205
|
This repository ships a ready-to-run fixture under `test/fixtures/node-ssr` that uses the Node entry to render a Lit shell plus a React subtree through `ReactDOMServer.renderToString`. Run `npm run build` once to emit `dist/`, then execute `npm run demo:node-ssr` to log the generated markup.
|
|
176
206
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
> [!IMPORTANT]
|
|
180
|
-
> Next already compiles `.tsx/.jsx` files, so you do not need this helper to author regular components. The loader only adds value when you want to reuse the tagged template runtime during SSR—mixing DOM nodes built by `jsx` with React markup, rendering shared utilities on the server, or processing tagged templates outside the usual component pipeline.
|
|
181
|
-
|
|
182
|
-
Next (and Remix/other Webpack-based SSR stacks) can run the loader by adding a post-loader to the framework config so the template tags are rewritten after SWC/Babel transpilation. The fixture under `test/fixtures/next-app` ships a complete example that mixes DOM and React helpers during SSR so you can pre-render DOM snippets (for emails, HTML streams, CMS content, etc.) while still returning React components from your pages. The important bits live in `next.config.mjs`:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
import path from 'node:path'
|
|
186
|
-
import { fileURLToPath } from 'node:url'
|
|
187
|
-
|
|
188
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
189
|
-
const repoRoot = path.resolve(__dirname, '../../..')
|
|
190
|
-
const distDir = path.join(repoRoot, 'dist')
|
|
191
|
-
|
|
192
|
-
export default {
|
|
193
|
-
output: 'export',
|
|
194
|
-
webpack(config) {
|
|
195
|
-
config.resolve.alias = {
|
|
196
|
-
...(config.resolve.alias ?? {}),
|
|
197
|
-
'@knighted/jsx': path.join(distDir, 'index.js'),
|
|
198
|
-
'@knighted/jsx/react': path.join(distDir, 'react/index.js'),
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
config.module.rules.push({
|
|
202
|
-
test: /\.[jt]sx?$/,
|
|
203
|
-
include: path.join(__dirname, 'pages'),
|
|
204
|
-
enforce: 'post',
|
|
205
|
-
use: [{ loader: path.join(distDir, 'loader/jsx.js') }],
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
return config
|
|
209
|
-
},
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Inside `pages/index.tsx` you can freely mix the helpers. The snippet below uses `jsx` on the server to prebuild a DOM fragment and then injects that HTML alongside a normal React component on the client:
|
|
214
|
-
|
|
215
|
-
```ts
|
|
216
|
-
import type { GetServerSideProps } from 'next'
|
|
217
|
-
import { jsx } from '@knighted/jsx'
|
|
218
|
-
import { reactJsx } from '@knighted/jsx/react'
|
|
219
|
-
|
|
220
|
-
const buildDomShell = () =>
|
|
221
|
-
jsx`
|
|
222
|
-
<section data-kind="dom-runtime">
|
|
223
|
-
<h2>DOM runtime</h2>
|
|
224
|
-
<p>Rendered as static HTML on the server</p>
|
|
225
|
-
</section>
|
|
226
|
-
`
|
|
227
|
-
|
|
228
|
-
export const getServerSideProps: GetServerSideProps = async () => {
|
|
229
|
-
return {
|
|
230
|
-
props: {
|
|
231
|
-
domShell: buildDomShell().outerHTML,
|
|
232
|
-
},
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const ReactBadge = () =>
|
|
237
|
-
reactJsx`
|
|
238
|
-
<button type="button">React badge</button>
|
|
239
|
-
`
|
|
240
|
-
|
|
241
|
-
type PageProps = { domShell: string }
|
|
242
|
-
|
|
243
|
-
export default function Page({ domShell }: PageProps) {
|
|
244
|
-
return reactJsx`
|
|
245
|
-
<main>
|
|
246
|
-
<${ReactBadge} />
|
|
247
|
-
<div dangerouslySetInnerHTML={${{ __html: domShell }}}></div>
|
|
248
|
-
</main>
|
|
249
|
-
`
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Build the fixture locally with `npx next build test/fixtures/next-app` (or run `npx vitest run test/next-fixture.test.ts`) to verify the integration end to end. You can adapt the same pattern in `app/` routes, API handlers, or server actions whenever you need DOM output generated by the tagged template runtime.
|
|
254
|
-
|
|
255
|
-
### Interpolations
|
|
256
|
-
|
|
257
|
-
- All dynamic values are provided through standard template literal expressions (`${...}`) and map to JSX exactly where they appear. Interpolations used as text children no longer need an extra `{...}` wrapper—the runtime automatically recognizes placeholders inside text segments (so `Count is ${value}` just works). Use the usual JSX braces when the syntax requires them (`className={${value}}`, `{...props}`, conditionals, etc.).
|
|
258
|
-
- Every expression can be any JavaScript value: primitives, arrays/iterables, DOM nodes, functions, other `jsx` results, or custom component references.
|
|
259
|
-
- Async values (Promises) are not supported. Resolve them before passing into the template.
|
|
260
|
-
|
|
261
|
-
### Components
|
|
262
|
-
|
|
263
|
-
You can inline components by interpolating the function used for the tag name. The component receives a props object plus the optional `children` prop and can return anything that `jsx` can render (DOM nodes, strings, fragments, other arrays, ...).
|
|
264
|
-
|
|
265
|
-
```ts
|
|
266
|
-
const Button = ({ children, variant = 'primary' }) => {
|
|
267
|
-
const el = document.createElement('button')
|
|
268
|
-
el.dataset.variant = variant
|
|
269
|
-
el.append(children ?? '')
|
|
270
|
-
return el
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const label = 'Tap me'
|
|
274
|
-
|
|
275
|
-
const view = jsx`
|
|
276
|
-
<section>
|
|
277
|
-
<${Button} variant="ghost">
|
|
278
|
-
${label}
|
|
279
|
-
</${Button}>
|
|
280
|
-
</section>
|
|
281
|
-
`
|
|
282
|
-
|
|
283
|
-
document.body.append(view)
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Fragments & SVG
|
|
287
|
-
|
|
288
|
-
Use JSX fragments (`<>...</>`) for multi-root templates. SVG trees automatically switch to the `http://www.w3.org/2000/svg` namespace once they enter an `<svg>` tag, and fall back inside `<foreignObject>`.
|
|
289
|
-
|
|
290
|
-
### DOM-specific props
|
|
291
|
-
|
|
292
|
-
- `style` accepts either a string or an object. Object values handle CSS custom properties (`--token`) automatically.
|
|
293
|
-
- `class` and `className` both work and can be strings or arrays.
|
|
294
|
-
- Event handlers use the `on<Event>` naming convention (e.g. `onClick`).
|
|
295
|
-
- `ref` supports callback refs as well as mutable `{ current }` objects.
|
|
296
|
-
- `dangerouslySetInnerHTML` expects an object with an `__html` field, mirroring React.
|
|
207
|
+
See how to [integrate with Next.js](./docs/nextjs-integration.md).
|
|
297
208
|
|
|
298
209
|
## Browser usage
|
|
299
210
|
|
|
@@ -302,26 +213,26 @@ When you are not using a bundler, load the module directly from a CDN that under
|
|
|
302
213
|
```html
|
|
303
214
|
<script type="module">
|
|
304
215
|
import { jsx } from 'https://esm.sh/@knighted/jsx'
|
|
216
|
+
import { reactJsx } from 'https://esm.sh/@knighted/jsx/react'
|
|
217
|
+
import { useState } from 'https://esm.sh/react@19'
|
|
218
|
+
import { createRoot } from 'https://esm.sh/react-dom@19/client'
|
|
305
219
|
|
|
306
|
-
const
|
|
307
|
-
document.body.append(message)
|
|
308
|
-
</script>
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
If you are building locally with Vite/Rollup/Webpack make sure the WASM binding is installable so the bundler can resolve `@oxc-parser/binding-wasm32-wasi` (details below).
|
|
220
|
+
const reactMount = jsx`<div data-kind="react-mount" />`
|
|
312
221
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
222
|
+
const CounterButton = () => {
|
|
223
|
+
const [count, setCount] = useState(0)
|
|
224
|
+
return reactJsx`
|
|
225
|
+
<button type="button" onClick={${() => setCount(value => value + 1)}}>
|
|
226
|
+
Count is ${count}
|
|
227
|
+
</button>
|
|
228
|
+
`
|
|
229
|
+
}
|
|
316
230
|
|
|
317
|
-
|
|
318
|
-
|
|
231
|
+
document.body.append(reactMount)
|
|
232
|
+
createRoot(reactMount).render(reactJsx`<${CounterButton} />`)
|
|
233
|
+
</script>
|
|
319
234
|
```
|
|
320
235
|
|
|
321
|
-
The script downloads the published tarball via `npm pack`, extracts it into `node_modules/@oxc-parser/binding-wasm32-wasi`, and removes the temporary archive so your lockfile stays untouched. If you need to test a different binding build, set `WASM_BINDING_PACKAGE` before running the script (for example, `WASM_BINDING_PACKAGE=@oxc-parser/binding-wasm32-wasi@0.100.0 npm run setup:wasm`).
|
|
322
|
-
|
|
323
|
-
Prefer the manual route? You can still run `npm_config_ignore_platform=true npm install --no-save @oxc-parser/binding-wasm32-wasi@^0.99.0`, but the script above replicates the vendored behavior with less ceremony.
|
|
324
|
-
|
|
325
236
|
### Lite bundle entry
|
|
326
237
|
|
|
327
238
|
If you already run this package through your own bundler you can trim a few extra kilobytes by importing the minified entries:
|
|
@@ -335,40 +246,6 @@ import { reactJsx as nodeReactJsx } from '@knighted/jsx/node/react/lite'
|
|
|
335
246
|
|
|
336
247
|
Each lite subpath ships the same API as its standard counterpart but is pre-minified and scoped to just that runtime (DOM, React, Node DOM, or Node React). Swap them in when you want the smallest possible bundles; otherwise the default exports keep working as-is.
|
|
337
248
|
|
|
338
|
-
## Testing
|
|
339
|
-
|
|
340
|
-
Run the Vitest suite (powered by jsdom) to exercise the DOM runtime and component support:
|
|
341
|
-
|
|
342
|
-
```sh
|
|
343
|
-
npm run test
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
Tests live in `test/jsx.test.ts` and cover DOM props/events, custom components, fragments, and iterable children so you can see exactly how the template tag is meant to be used.
|
|
347
|
-
|
|
348
|
-
Need full end-to-end coverage? The Playwright suite boots the CDN demo (`examples/esm-demo.html`) and the loader-backed Rspack fixture to verify nested trees, sibling structures, and interop with Lit/React:
|
|
349
|
-
|
|
350
|
-
```sh
|
|
351
|
-
npm run test:e2e
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
> [!NOTE]
|
|
355
|
-
> The e2e script builds the library, installs the WASM parser binding, bundles the loader fixture, and then runs `playwright test`. Make sure Playwright browsers are installed locally (`npx playwright install --with-deps chromium`).
|
|
356
|
-
|
|
357
|
-
## Browser demo / Vite build
|
|
358
|
-
|
|
359
|
-
This repo ships with a ready-to-run Vite demo under `examples/browser` that bundles the library (make sure you have installed the WASM binding via the command above first). Use it for a full end-to-end verification in a real browser (the demo imports `@knighted/jsx/lite` so you can confirm the lighter entry behaves identically):
|
|
360
|
-
|
|
361
|
-
```sh
|
|
362
|
-
# Start a dev server at http://localhost:5173
|
|
363
|
-
npm run dev
|
|
364
|
-
|
|
365
|
-
# Produce a production Rollup build and preview it
|
|
366
|
-
npm run build:demo
|
|
367
|
-
npm run preview
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
For a zero-build verification of the lite bundle, open `examples/esm-demo-lite.html` locally (double-click or run `open examples/esm-demo-lite.html`) or visit the deployed GitHub Pages build produced by `.github/workflows/deploy-demo.yml` (it serves that same lite HTML demo).
|
|
371
|
-
|
|
372
249
|
## Limitations
|
|
373
250
|
|
|
374
251
|
- Requires a DOM-like environment (it throws when `document` is missing).
|
package/dist/cjs/cli/init.cjs
CHANGED
|
@@ -26,6 +26,21 @@ const tar_1 = require("tar");
|
|
|
26
26
|
const DEFAULT_BINDING_SPEC = process.env.WASM_BINDING_PACKAGE ?? '@oxc-parser/binding-wasm32-wasi@^0.99.0';
|
|
27
27
|
const RUNTIME_DEPS = ['@napi-rs/wasm-runtime', '@emnapi/runtime', '@emnapi/core'];
|
|
28
28
|
const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun'];
|
|
29
|
+
// Node emits a noisy ExperimentalWarning whenever the WASI shim loads; silence just that message.
|
|
30
|
+
const WASI_WARNING_SNIPPET = 'WASI is an experimental feature';
|
|
31
|
+
const LOADER_CONFIG_EXAMPLE = [
|
|
32
|
+
'// Example loader entry to drop into your bundler rules array:',
|
|
33
|
+
'{',
|
|
34
|
+
" loader: '@knighted/jsx/loader',",
|
|
35
|
+
' options: {',
|
|
36
|
+
" tags: ['jsx', 'reactJsx'],",
|
|
37
|
+
' tagModes: {',
|
|
38
|
+
" reactJsx: 'react',",
|
|
39
|
+
' },',
|
|
40
|
+
' },',
|
|
41
|
+
'}',
|
|
42
|
+
].join('\n');
|
|
43
|
+
suppressExperimentalWasiWarning();
|
|
29
44
|
function parseArgs(argv) {
|
|
30
45
|
const options = {
|
|
31
46
|
cwd: process.cwd(),
|
|
@@ -114,11 +129,11 @@ function ensurePackageJson(cwd) {
|
|
|
114
129
|
throw new Error('No package.json found. Run this inside a project with package.json.');
|
|
115
130
|
}
|
|
116
131
|
}
|
|
117
|
-
function runNpmPack(spec, cwd, dryRun, verbose) {
|
|
132
|
+
function runNpmPack(spec, cwd, dryRun, verbose, execFn = node_child_process_1.execFileSync) {
|
|
118
133
|
logVerbose(`> npm pack ${spec}`, verbose);
|
|
119
134
|
if (dryRun)
|
|
120
135
|
return `${spec.replace(/\W+/g, '_')}.tgz`;
|
|
121
|
-
const output = (
|
|
136
|
+
const output = execFn('npm', ['pack', spec], {
|
|
122
137
|
cwd,
|
|
123
138
|
encoding: 'utf8',
|
|
124
139
|
stdio: ['ignore', 'pipe', 'inherit'],
|
|
@@ -133,9 +148,9 @@ function parsePackageName(spec) {
|
|
|
133
148
|
const [, name, version] = match;
|
|
134
149
|
return { name, version };
|
|
135
150
|
}
|
|
136
|
-
async function installBinding(spec, cwd, dryRun, verbose) {
|
|
151
|
+
async function installBinding(spec, cwd, dryRun, verbose, pack = runNpmPack) {
|
|
137
152
|
const { name, version } = parsePackageName(spec);
|
|
138
|
-
const tarballName =
|
|
153
|
+
const tarballName = pack(spec, cwd, dryRun, verbose);
|
|
139
154
|
const tarballPath = node_path_1.default.resolve(cwd, tarballName);
|
|
140
155
|
const targetDir = node_path_1.default.resolve(cwd, 'node_modules', ...name.split('/'));
|
|
141
156
|
log(`> Installing ${spec} into ${targetDir}`);
|
|
@@ -147,7 +162,7 @@ async function installBinding(spec, cwd, dryRun, verbose) {
|
|
|
147
162
|
}
|
|
148
163
|
return { targetDir, tarballPath: dryRun ? undefined : tarballPath, name, version };
|
|
149
164
|
}
|
|
150
|
-
function installRuntimeDeps(pm, deps, cwd, dryRun, verbose) {
|
|
165
|
+
function installRuntimeDeps(pm, deps, cwd, dryRun, verbose, spawner = node_child_process_1.spawnSync) {
|
|
151
166
|
const missing = deps.filter(dep => !isDependencyInstalled(dep, cwd));
|
|
152
167
|
if (missing.length === 0) {
|
|
153
168
|
log('> Runtime dependencies already present; skipping install');
|
|
@@ -162,7 +177,7 @@ function installRuntimeDeps(pm, deps, cwd, dryRun, verbose) {
|
|
|
162
177
|
const [command, args] = commands[pm];
|
|
163
178
|
logVerbose(`> ${command} ${args.join(' ')}`, verbose);
|
|
164
179
|
if (!dryRun) {
|
|
165
|
-
const result = (
|
|
180
|
+
const result = spawner(command, args, { cwd, stdio: 'inherit' });
|
|
166
181
|
if (result.status !== 0) {
|
|
167
182
|
throw new Error(`Failed to install runtime dependencies with ${pm}`);
|
|
168
183
|
}
|
|
@@ -194,11 +209,11 @@ function persistBindingSpec(cwd, name, version, dryRun, verbose) {
|
|
|
194
209
|
node_fs_1.default.writeFileSync(pkgPath, `${JSON.stringify(pkgJson, null, 2)}\n`, 'utf8');
|
|
195
210
|
}
|
|
196
211
|
}
|
|
197
|
-
async function verifyBinding(name, cwd, verbose) {
|
|
212
|
+
async function verifyBinding(name, cwd, verbose, importer = specifier => import(specifier)) {
|
|
198
213
|
const requireFromCwd = (0, node_module_1.createRequire)(node_path_1.default.join(cwd, 'package.json'));
|
|
199
214
|
const resolved = requireFromCwd.resolve(name);
|
|
200
215
|
logVerbose(`> Resolved ${name} to ${resolved}`, verbose);
|
|
201
|
-
const imported = await
|
|
216
|
+
const imported = await importer((0, node_url_1.pathToFileURL)(resolved).href);
|
|
202
217
|
if (!imported) {
|
|
203
218
|
throw new Error(`Imported ${name} is empty; verification failed`);
|
|
204
219
|
}
|
|
@@ -229,27 +244,30 @@ async function maybeHandleConfigPrompt(skipConfig, force) {
|
|
|
229
244
|
return;
|
|
230
245
|
}
|
|
231
246
|
log('> Loader assistance is interactive and not applied automatically yet. See docs at docs/cli.md for next steps.');
|
|
247
|
+
log('> Example loader config (webpack / rspack):');
|
|
248
|
+
console.log(LOADER_CONFIG_EXAMPLE);
|
|
232
249
|
}
|
|
233
|
-
async function main() {
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
250
|
+
async function main(overrides = {}) {
|
|
251
|
+
const { parseArgs: parseArgsImpl = parseArgs, ensurePackageJson: ensurePackageJsonImpl = ensurePackageJson, detectPackageManager: detectPackageManagerImpl = detectPackageManager, installRuntimeDeps: installRuntimeDepsImpl = installRuntimeDeps, installBinding: installBindingImpl = installBinding, persistBindingSpec: persistBindingSpecImpl = persistBindingSpec, verifyBinding: verifyBindingImpl = verifyBinding, maybeHandleConfigPrompt: maybeHandleConfigPromptImpl = maybeHandleConfigPrompt, log: logImpl = log, } = overrides;
|
|
252
|
+
const options = parseArgsImpl(process.argv.slice(2));
|
|
253
|
+
ensurePackageJsonImpl(options.cwd);
|
|
254
|
+
const packageManager = detectPackageManagerImpl(options.cwd, options.packageManager);
|
|
255
|
+
logImpl(`> Using package manager: ${packageManager}`);
|
|
256
|
+
const installedRuntimeDeps = installRuntimeDepsImpl(packageManager, RUNTIME_DEPS, options.cwd, options.dryRun, options.verbose);
|
|
257
|
+
const binding = await installBindingImpl(options.wasmPackage, options.cwd, options.dryRun, options.verbose);
|
|
258
|
+
persistBindingSpecImpl(options.cwd, binding.name, binding.version, options.dryRun, options.verbose);
|
|
241
259
|
let resolvedPath;
|
|
242
260
|
if (!options.dryRun) {
|
|
243
|
-
resolvedPath = await
|
|
244
|
-
|
|
261
|
+
resolvedPath = await verifyBindingImpl(binding.name, options.cwd, options.verbose);
|
|
262
|
+
logImpl(`> Verified ${binding.name} at ${resolvedPath}`);
|
|
245
263
|
}
|
|
246
|
-
await
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
await maybeHandleConfigPromptImpl(options.skipConfig, options.force);
|
|
265
|
+
logImpl('\nDone!');
|
|
266
|
+
logImpl(`- Binding: ${binding.name}${binding.version ? `@${binding.version}` : ''}`);
|
|
267
|
+
logImpl(`- Target: ${binding.targetDir}`);
|
|
268
|
+
logImpl(`- Runtime deps installed: ${installedRuntimeDeps.join(', ') || 'none (already present)'}`);
|
|
251
269
|
if (resolvedPath)
|
|
252
|
-
|
|
270
|
+
logImpl(`- Verified import: ${resolvedPath}`);
|
|
253
271
|
}
|
|
254
272
|
if (process.env.KNIGHTED_JSX_CLI_TEST !== '1') {
|
|
255
273
|
main().catch(error => {
|
|
@@ -257,3 +275,17 @@ if (process.env.KNIGHTED_JSX_CLI_TEST !== '1') {
|
|
|
257
275
|
process.exitCode = 1;
|
|
258
276
|
});
|
|
259
277
|
}
|
|
278
|
+
function suppressExperimentalWasiWarning() {
|
|
279
|
+
const originalEmitWarning = process.emitWarning.bind(process);
|
|
280
|
+
process.emitWarning = ((warning, ...args) => {
|
|
281
|
+
const [typeMaybe] = args;
|
|
282
|
+
const message = typeof warning === 'string' ? warning : warning.message;
|
|
283
|
+
const name = typeof warning === 'string' ? undefined : warning.name;
|
|
284
|
+
const type = typeof typeMaybe === 'string' ? typeMaybe : undefined;
|
|
285
|
+
if (message.includes(WASI_WARNING_SNIPPET) &&
|
|
286
|
+
(name === 'ExperimentalWarning' || type === 'ExperimentalWarning')) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
return originalEmitWarning(warning, ...args);
|
|
290
|
+
});
|
|
291
|
+
}
|
package/dist/cjs/cli/init.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
1
2
|
declare const SUPPORTED_PACKAGE_MANAGERS: readonly ["npm", "pnpm", "yarn", "bun"];
|
|
2
3
|
type PackageManager = (typeof SUPPORTED_PACKAGE_MANAGERS)[number];
|
|
3
4
|
type CliOptions = {
|
|
@@ -10,9 +11,10 @@ type CliOptions = {
|
|
|
10
11
|
wasmPackage: string;
|
|
11
12
|
};
|
|
12
13
|
declare function parseArgs(argv: string[]): CliOptions;
|
|
14
|
+
declare function log(message: string): void;
|
|
13
15
|
declare function detectPackageManager(cwd: string, explicit?: PackageManager): PackageManager;
|
|
14
16
|
declare function ensurePackageJson(cwd: string): void;
|
|
15
|
-
declare function runNpmPack(spec: string, cwd: string, dryRun: boolean, verbose: boolean): string;
|
|
17
|
+
declare function runNpmPack(spec: string, cwd: string, dryRun: boolean, verbose: boolean, execFn?: typeof execFileSync): string;
|
|
16
18
|
declare function parsePackageName(spec: string): {
|
|
17
19
|
name: string;
|
|
18
20
|
version: undefined;
|
|
@@ -20,17 +22,30 @@ declare function parsePackageName(spec: string): {
|
|
|
20
22
|
name: string;
|
|
21
23
|
version: string;
|
|
22
24
|
};
|
|
23
|
-
|
|
25
|
+
type PackFunction = (spec: string, cwd: string, dryRun: boolean, verbose: boolean) => string;
|
|
26
|
+
declare function installBinding(spec: string, cwd: string, dryRun: boolean, verbose: boolean, pack?: PackFunction): Promise<{
|
|
24
27
|
targetDir: string;
|
|
25
28
|
tarballPath?: string;
|
|
26
29
|
name: string;
|
|
27
30
|
version?: string;
|
|
28
31
|
}>;
|
|
29
|
-
declare function installRuntimeDeps(pm: PackageManager, deps: string[], cwd: string, dryRun: boolean, verbose: boolean): string[];
|
|
32
|
+
declare function installRuntimeDeps(pm: PackageManager, deps: string[], cwd: string, dryRun: boolean, verbose: boolean, spawner?: typeof spawnSync): string[];
|
|
30
33
|
declare function isDependencyInstalled(dep: string, cwd: string): boolean;
|
|
31
34
|
declare function persistBindingSpec(cwd: string, name: string, version: string | undefined, dryRun: boolean, verbose: boolean): void;
|
|
32
|
-
|
|
35
|
+
type BindingImporter = (specifier: string) => Promise<unknown>;
|
|
36
|
+
declare function verifyBinding(name: string, cwd: string, verbose: boolean, importer?: BindingImporter): Promise<string>;
|
|
33
37
|
declare function promptYesNo(prompt: string, defaultValue: boolean, force: boolean): Promise<boolean>;
|
|
34
38
|
declare function maybeHandleConfigPrompt(skipConfig: boolean, force: boolean): Promise<void>;
|
|
35
|
-
|
|
39
|
+
type MainDeps = {
|
|
40
|
+
parseArgs: typeof parseArgs;
|
|
41
|
+
ensurePackageJson: typeof ensurePackageJson;
|
|
42
|
+
detectPackageManager: typeof detectPackageManager;
|
|
43
|
+
installRuntimeDeps: typeof installRuntimeDeps;
|
|
44
|
+
installBinding: typeof installBinding;
|
|
45
|
+
persistBindingSpec: typeof persistBindingSpec;
|
|
46
|
+
verifyBinding: typeof verifyBinding;
|
|
47
|
+
maybeHandleConfigPrompt: typeof maybeHandleConfigPrompt;
|
|
48
|
+
log: typeof log;
|
|
49
|
+
};
|
|
50
|
+
declare function main(overrides?: Partial<MainDeps>): Promise<void>;
|
|
36
51
|
export { parseArgs, detectPackageManager, ensurePackageJson, runNpmPack, parsePackageName, installBinding, installRuntimeDeps, isDependencyInstalled, persistBindingSpec, verifyBinding, promptYesNo, maybeHandleConfigPrompt, main, };
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
1
2
|
declare const SUPPORTED_PACKAGE_MANAGERS: readonly ["npm", "pnpm", "yarn", "bun"];
|
|
2
3
|
type PackageManager = (typeof SUPPORTED_PACKAGE_MANAGERS)[number];
|
|
3
4
|
type CliOptions = {
|
|
@@ -10,9 +11,10 @@ type CliOptions = {
|
|
|
10
11
|
wasmPackage: string;
|
|
11
12
|
};
|
|
12
13
|
declare function parseArgs(argv: string[]): CliOptions;
|
|
14
|
+
declare function log(message: string): void;
|
|
13
15
|
declare function detectPackageManager(cwd: string, explicit?: PackageManager): PackageManager;
|
|
14
16
|
declare function ensurePackageJson(cwd: string): void;
|
|
15
|
-
declare function runNpmPack(spec: string, cwd: string, dryRun: boolean, verbose: boolean): string;
|
|
17
|
+
declare function runNpmPack(spec: string, cwd: string, dryRun: boolean, verbose: boolean, execFn?: typeof execFileSync): string;
|
|
16
18
|
declare function parsePackageName(spec: string): {
|
|
17
19
|
name: string;
|
|
18
20
|
version: undefined;
|
|
@@ -20,17 +22,30 @@ declare function parsePackageName(spec: string): {
|
|
|
20
22
|
name: string;
|
|
21
23
|
version: string;
|
|
22
24
|
};
|
|
23
|
-
|
|
25
|
+
type PackFunction = (spec: string, cwd: string, dryRun: boolean, verbose: boolean) => string;
|
|
26
|
+
declare function installBinding(spec: string, cwd: string, dryRun: boolean, verbose: boolean, pack?: PackFunction): Promise<{
|
|
24
27
|
targetDir: string;
|
|
25
28
|
tarballPath?: string;
|
|
26
29
|
name: string;
|
|
27
30
|
version?: string;
|
|
28
31
|
}>;
|
|
29
|
-
declare function installRuntimeDeps(pm: PackageManager, deps: string[], cwd: string, dryRun: boolean, verbose: boolean): string[];
|
|
32
|
+
declare function installRuntimeDeps(pm: PackageManager, deps: string[], cwd: string, dryRun: boolean, verbose: boolean, spawner?: typeof spawnSync): string[];
|
|
30
33
|
declare function isDependencyInstalled(dep: string, cwd: string): boolean;
|
|
31
34
|
declare function persistBindingSpec(cwd: string, name: string, version: string | undefined, dryRun: boolean, verbose: boolean): void;
|
|
32
|
-
|
|
35
|
+
type BindingImporter = (specifier: string) => Promise<unknown>;
|
|
36
|
+
declare function verifyBinding(name: string, cwd: string, verbose: boolean, importer?: BindingImporter): Promise<string>;
|
|
33
37
|
declare function promptYesNo(prompt: string, defaultValue: boolean, force: boolean): Promise<boolean>;
|
|
34
38
|
declare function maybeHandleConfigPrompt(skipConfig: boolean, force: boolean): Promise<void>;
|
|
35
|
-
|
|
39
|
+
type MainDeps = {
|
|
40
|
+
parseArgs: typeof parseArgs;
|
|
41
|
+
ensurePackageJson: typeof ensurePackageJson;
|
|
42
|
+
detectPackageManager: typeof detectPackageManager;
|
|
43
|
+
installRuntimeDeps: typeof installRuntimeDeps;
|
|
44
|
+
installBinding: typeof installBinding;
|
|
45
|
+
persistBindingSpec: typeof persistBindingSpec;
|
|
46
|
+
verifyBinding: typeof verifyBinding;
|
|
47
|
+
maybeHandleConfigPrompt: typeof maybeHandleConfigPrompt;
|
|
48
|
+
log: typeof log;
|
|
49
|
+
};
|
|
50
|
+
declare function main(overrides?: Partial<MainDeps>): Promise<void>;
|
|
36
51
|
export { parseArgs, detectPackageManager, ensurePackageJson, runNpmPack, parsePackageName, installBinding, installRuntimeDeps, isDependencyInstalled, persistBindingSpec, verifyBinding, promptYesNo, maybeHandleConfigPrompt, main, };
|
package/dist/cli/init.js
CHANGED
|
@@ -10,6 +10,20 @@ import { extract } from 'tar';
|
|
|
10
10
|
var DEFAULT_BINDING_SPEC = process.env.WASM_BINDING_PACKAGE ?? "@oxc-parser/binding-wasm32-wasi@^0.99.0";
|
|
11
11
|
var RUNTIME_DEPS = ["@napi-rs/wasm-runtime", "@emnapi/runtime", "@emnapi/core"];
|
|
12
12
|
var SUPPORTED_PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
|
|
13
|
+
var WASI_WARNING_SNIPPET = "WASI is an experimental feature";
|
|
14
|
+
var LOADER_CONFIG_EXAMPLE = [
|
|
15
|
+
"// Example loader entry to drop into your bundler rules array:",
|
|
16
|
+
"{",
|
|
17
|
+
" loader: '@knighted/jsx/loader',",
|
|
18
|
+
" options: {",
|
|
19
|
+
" tags: ['jsx', 'reactJsx'],",
|
|
20
|
+
" tagModes: {",
|
|
21
|
+
" reactJsx: 'react',",
|
|
22
|
+
" },",
|
|
23
|
+
" },",
|
|
24
|
+
"}"
|
|
25
|
+
].join("\n");
|
|
26
|
+
suppressExperimentalWasiWarning();
|
|
13
27
|
function parseArgs(argv) {
|
|
14
28
|
const options = {
|
|
15
29
|
cwd: process.cwd(),
|
|
@@ -97,10 +111,10 @@ function ensurePackageJson(cwd) {
|
|
|
97
111
|
throw new Error("No package.json found. Run this inside a project with package.json.");
|
|
98
112
|
}
|
|
99
113
|
}
|
|
100
|
-
function runNpmPack(spec, cwd, dryRun, verbose) {
|
|
114
|
+
function runNpmPack(spec, cwd, dryRun, verbose, execFn = execFileSync) {
|
|
101
115
|
logVerbose(`> npm pack ${spec}`, verbose);
|
|
102
116
|
if (dryRun) return `${spec.replace(/\W+/g, "_")}.tgz`;
|
|
103
|
-
const output =
|
|
117
|
+
const output = execFn("npm", ["pack", spec], {
|
|
104
118
|
cwd,
|
|
105
119
|
encoding: "utf8",
|
|
106
120
|
stdio: ["ignore", "pipe", "inherit"]
|
|
@@ -114,9 +128,9 @@ function parsePackageName(spec) {
|
|
|
114
128
|
const [, name, version] = match;
|
|
115
129
|
return { name, version };
|
|
116
130
|
}
|
|
117
|
-
async function installBinding(spec, cwd, dryRun, verbose) {
|
|
131
|
+
async function installBinding(spec, cwd, dryRun, verbose, pack = runNpmPack) {
|
|
118
132
|
const { name, version } = parsePackageName(spec);
|
|
119
|
-
const tarballName =
|
|
133
|
+
const tarballName = pack(spec, cwd, dryRun, verbose);
|
|
120
134
|
const tarballPath = path.resolve(cwd, tarballName);
|
|
121
135
|
const targetDir = path.resolve(cwd, "node_modules", ...name.split("/"));
|
|
122
136
|
log(`> Installing ${spec} into ${targetDir}`);
|
|
@@ -128,7 +142,7 @@ async function installBinding(spec, cwd, dryRun, verbose) {
|
|
|
128
142
|
}
|
|
129
143
|
return { targetDir, tarballPath: dryRun ? void 0 : tarballPath, name, version };
|
|
130
144
|
}
|
|
131
|
-
function installRuntimeDeps(pm, deps, cwd, dryRun, verbose) {
|
|
145
|
+
function installRuntimeDeps(pm, deps, cwd, dryRun, verbose, spawner = spawnSync) {
|
|
132
146
|
const missing = deps.filter((dep) => !isDependencyInstalled(dep, cwd));
|
|
133
147
|
if (missing.length === 0) {
|
|
134
148
|
log("> Runtime dependencies already present; skipping install");
|
|
@@ -143,7 +157,7 @@ function installRuntimeDeps(pm, deps, cwd, dryRun, verbose) {
|
|
|
143
157
|
const [command, args] = commands[pm];
|
|
144
158
|
logVerbose(`> ${command} ${args.join(" ")}`, verbose);
|
|
145
159
|
if (!dryRun) {
|
|
146
|
-
const result =
|
|
160
|
+
const result = spawner(command, args, { cwd, stdio: "inherit" });
|
|
147
161
|
if (result.status !== 0) {
|
|
148
162
|
throw new Error(`Failed to install runtime dependencies with ${pm}`);
|
|
149
163
|
}
|
|
@@ -175,11 +189,11 @@ function persistBindingSpec(cwd, name, version, dryRun, verbose) {
|
|
|
175
189
|
`, "utf8");
|
|
176
190
|
}
|
|
177
191
|
}
|
|
178
|
-
async function verifyBinding(name, cwd, verbose) {
|
|
192
|
+
async function verifyBinding(name, cwd, verbose, importer = (specifier) => import(specifier)) {
|
|
179
193
|
const requireFromCwd = createRequire(path.join(cwd, "package.json"));
|
|
180
194
|
const resolved = requireFromCwd.resolve(name);
|
|
181
195
|
logVerbose(`> Resolved ${name} to ${resolved}`, verbose);
|
|
182
|
-
const imported = await
|
|
196
|
+
const imported = await importer(pathToFileURL(resolved).href);
|
|
183
197
|
if (!imported) {
|
|
184
198
|
throw new Error(`Imported ${name} is empty; verification failed`);
|
|
185
199
|
}
|
|
@@ -213,26 +227,39 @@ async function maybeHandleConfigPrompt(skipConfig, force) {
|
|
|
213
227
|
log(
|
|
214
228
|
"> Loader assistance is interactive and not applied automatically yet. See docs at docs/cli.md for next steps."
|
|
215
229
|
);
|
|
230
|
+
log("> Example loader config (webpack / rspack):");
|
|
231
|
+
console.log(LOADER_CONFIG_EXAMPLE);
|
|
216
232
|
}
|
|
217
|
-
async function main() {
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
233
|
+
async function main(overrides = {}) {
|
|
234
|
+
const {
|
|
235
|
+
parseArgs: parseArgsImpl = parseArgs,
|
|
236
|
+
ensurePackageJson: ensurePackageJsonImpl = ensurePackageJson,
|
|
237
|
+
detectPackageManager: detectPackageManagerImpl = detectPackageManager,
|
|
238
|
+
installRuntimeDeps: installRuntimeDepsImpl = installRuntimeDeps,
|
|
239
|
+
installBinding: installBindingImpl = installBinding,
|
|
240
|
+
persistBindingSpec: persistBindingSpecImpl = persistBindingSpec,
|
|
241
|
+
verifyBinding: verifyBindingImpl = verifyBinding,
|
|
242
|
+
maybeHandleConfigPrompt: maybeHandleConfigPromptImpl = maybeHandleConfigPrompt,
|
|
243
|
+
log: logImpl = log
|
|
244
|
+
} = overrides;
|
|
245
|
+
const options = parseArgsImpl(process.argv.slice(2));
|
|
246
|
+
ensurePackageJsonImpl(options.cwd);
|
|
247
|
+
const packageManager = detectPackageManagerImpl(options.cwd, options.packageManager);
|
|
248
|
+
logImpl(`> Using package manager: ${packageManager}`);
|
|
249
|
+
const installedRuntimeDeps = installRuntimeDepsImpl(
|
|
223
250
|
packageManager,
|
|
224
251
|
RUNTIME_DEPS,
|
|
225
252
|
options.cwd,
|
|
226
253
|
options.dryRun,
|
|
227
254
|
options.verbose
|
|
228
255
|
);
|
|
229
|
-
const binding = await
|
|
256
|
+
const binding = await installBindingImpl(
|
|
230
257
|
options.wasmPackage,
|
|
231
258
|
options.cwd,
|
|
232
259
|
options.dryRun,
|
|
233
260
|
options.verbose
|
|
234
261
|
);
|
|
235
|
-
|
|
262
|
+
persistBindingSpecImpl(
|
|
236
263
|
options.cwd,
|
|
237
264
|
binding.name,
|
|
238
265
|
binding.version,
|
|
@@ -241,17 +268,17 @@ async function main() {
|
|
|
241
268
|
);
|
|
242
269
|
let resolvedPath;
|
|
243
270
|
if (!options.dryRun) {
|
|
244
|
-
resolvedPath = await
|
|
245
|
-
|
|
271
|
+
resolvedPath = await verifyBindingImpl(binding.name, options.cwd, options.verbose);
|
|
272
|
+
logImpl(`> Verified ${binding.name} at ${resolvedPath}`);
|
|
246
273
|
}
|
|
247
|
-
await
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
274
|
+
await maybeHandleConfigPromptImpl(options.skipConfig, options.force);
|
|
275
|
+
logImpl("\nDone!");
|
|
276
|
+
logImpl(`- Binding: ${binding.name}${binding.version ? `@${binding.version}` : ""}`);
|
|
277
|
+
logImpl(`- Target: ${binding.targetDir}`);
|
|
278
|
+
logImpl(
|
|
252
279
|
`- Runtime deps installed: ${installedRuntimeDeps.join(", ") || "none (already present)"}`
|
|
253
280
|
);
|
|
254
|
-
if (resolvedPath)
|
|
281
|
+
if (resolvedPath) logImpl(`- Verified import: ${resolvedPath}`);
|
|
255
282
|
}
|
|
256
283
|
if (process.env.KNIGHTED_JSX_CLI_TEST !== "1") {
|
|
257
284
|
main().catch((error) => {
|
|
@@ -262,5 +289,18 @@ if (process.env.KNIGHTED_JSX_CLI_TEST !== "1") {
|
|
|
262
289
|
process.exitCode = 1;
|
|
263
290
|
});
|
|
264
291
|
}
|
|
292
|
+
function suppressExperimentalWasiWarning() {
|
|
293
|
+
const originalEmitWarning = process.emitWarning.bind(process);
|
|
294
|
+
process.emitWarning = ((warning, ...args) => {
|
|
295
|
+
const [typeMaybe] = args;
|
|
296
|
+
const message = typeof warning === "string" ? warning : warning.message;
|
|
297
|
+
const name = typeof warning === "string" ? void 0 : warning.name;
|
|
298
|
+
const type = typeof typeMaybe === "string" ? typeMaybe : void 0;
|
|
299
|
+
if (message.includes(WASI_WARNING_SNIPPET) && (name === "ExperimentalWarning" || type === "ExperimentalWarning")) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
return originalEmitWarning(warning, ...args);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
265
305
|
|
|
266
306
|
export { detectPackageManager, ensurePackageJson, installBinding, installRuntimeDeps, isDependencyInstalled, main, maybeHandleConfigPrompt, parseArgs, parsePackageName, persistBindingSpec, promptYesNo, runNpmPack, verifyBinding };
|