brustjs 0.1.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +110 -0
  2. package/package.json +92 -0
  3. package/runtime/actions.ts +65 -0
  4. package/runtime/bun.lock +236 -0
  5. package/runtime/cli/actions-prebuilt-plugin.ts +97 -0
  6. package/runtime/cli/build.ts +252 -0
  7. package/runtime/cli/dev.ts +92 -0
  8. package/runtime/cli/index.ts +30 -0
  9. package/runtime/cli/native-routes-emit.ts +171 -0
  10. package/runtime/cli/native-shim-plugin.ts +85 -0
  11. package/runtime/cli/new.ts +208 -0
  12. package/runtime/cli/templates/minimal/README.md.tmpl +16 -0
  13. package/runtime/cli/templates/minimal/_gitignore +4 -0
  14. package/runtime/cli/templates/minimal/app.css +6 -0
  15. package/runtime/cli/templates/minimal/components/Counter.tsx +13 -0
  16. package/runtime/cli/templates/minimal/components/Layout.tsx +16 -0
  17. package/runtime/cli/templates/minimal/index.ts +4 -0
  18. package/runtime/cli/templates/minimal/package.json.tmpl +21 -0
  19. package/runtime/cli/templates/minimal/pages/Home.tsx.tmpl +16 -0
  20. package/runtime/cli/templates/minimal/routes.tsx +6 -0
  21. package/runtime/cli/templates/minimal/tsconfig.json +20 -0
  22. package/runtime/client/index.ts +121 -0
  23. package/runtime/config.ts +148 -0
  24. package/runtime/css/build.ts +54 -0
  25. package/runtime/css/component-build.ts +78 -0
  26. package/runtime/css/component-loader.ts +27 -0
  27. package/runtime/css/manifest.ts +51 -0
  28. package/runtime/css/process-modules.ts +56 -0
  29. package/runtime/css/route-deps.ts +33 -0
  30. package/runtime/css/scan-imports.ts +79 -0
  31. package/runtime/css.ts +39 -0
  32. package/runtime/dev/client.ts +49 -0
  33. package/runtime/dev/coordinator.ts +127 -0
  34. package/runtime/dev/inject.ts +17 -0
  35. package/runtime/dev/tui.ts +109 -0
  36. package/runtime/dev/watcher.ts +109 -0
  37. package/runtime/dev/worker-registry.ts +96 -0
  38. package/runtime/dev/ws-channel.ts +99 -0
  39. package/runtime/index.d.ts +199 -0
  40. package/runtime/index.js +604 -0
  41. package/runtime/index.ts +618 -0
  42. package/runtime/islands/__fixtures__/NoDefault.tsx +3 -0
  43. package/runtime/islands/__fixtures__/StubIsland.tsx +7 -0
  44. package/runtime/islands/__fixtures__/ThrowingIsland.tsx +9 -0
  45. package/runtime/islands/_entries/react-dom.ts +7 -0
  46. package/runtime/islands/_entries/react.ts +11 -0
  47. package/runtime/islands/bootstrap.ts +241 -0
  48. package/runtime/islands/build.ts +141 -0
  49. package/runtime/islands/importmap.ts +17 -0
  50. package/runtime/islands/island.tsx +58 -0
  51. package/runtime/islands/native-render.ts +153 -0
  52. package/runtime/mcp/extractor.ts +160 -0
  53. package/runtime/mcp/manifest.ts +50 -0
  54. package/runtime/mcp/schema.ts +124 -0
  55. package/runtime/mcp/server.ts +250 -0
  56. package/runtime/render/inject-css-link.ts +59 -0
  57. package/runtime/render/inject-dev-client.ts +49 -0
  58. package/runtime/render/stream.ts +304 -0
  59. package/runtime/routes.ts +1406 -0
  60. package/runtime/scan-actions.ts +172 -0
  61. package/runtime/sse/handler.ts +85 -0
  62. package/runtime/tsconfig.json +14 -0
  63. package/runtime/ws/handler.ts +151 -0
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ <div align="center">
2
+
3
+ # 💥 Brust
4
+
5
+ ### **B**un + **Rust** — an SSR framework that bursts.
6
+
7
+ [![npm](https://img.shields.io/npm/v/brustjs/alpha?logo=npm&logoColor=white&label=brustjs&color=cb3837)](https://www.npmjs.com/package/brustjs)
8
+ [![CI](https://github.com/AssetsArt/brust/actions/workflows/ci.yml/badge.svg)](https://github.com/AssetsArt/brust/actions/workflows/ci.yml)
9
+ [![license](https://img.shields.io/badge/license-MIT-3da639)](#status)
10
+ [![platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20Linux%20(glibc%20%7C%20musl)-1f6feb)](#status)
11
+ [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.4-fbf0df?logo=bun&logoColor=black)](https://bun.sh)
12
+ [![React](https://img.shields.io/badge/React-19-149eca?logo=react&logoColor=white)](https://react.dev)
13
+
14
+ </div>
15
+
16
+ React on the server, Rust everywhere else. One Bun host process; the HTTP accept
17
+ loop and worker pool are pure Rust, loaded as a `.node` native module (napi-rs).
18
+ Renders cross into Bun Worker threads via `ThreadsafeFunction` and return over
19
+ per-worker `SharedArrayBuffer`. `tokio-uring` (io_uring) on Linux, `tokio` on macOS.
20
+
21
+ > Published on npm as [`brustjs`](https://www.npmjs.com/package/brustjs) (the
22
+ > `brust` name is taken). Alpha — see **Status**.
23
+
24
+ ## Quick start
25
+
26
+ **Add to a project** (prebuilt native binary per platform — no Rust toolchain):
27
+
28
+ ```bash
29
+ bun add brustjs@alpha
30
+ ```
31
+
32
+ **Or run from source:**
33
+
34
+ ```bash
35
+ git clone https://github.com/AssetsArt/brust && cd brust
36
+ bun install
37
+ cd runtime && bun run build && cd .. # release addon; NOT build:debug (~2× slower)
38
+ bun run example/hello-world/index.ts # → http://127.0.0.1:3000
39
+ ```
40
+
41
+ ```bash
42
+ curl 127.0.0.1:3000/ping # → pong (pure Rust)
43
+ curl 127.0.0.1:3000/ # → SSR HTML + island
44
+ curl 127.0.0.1:3000/native-profile/World # → Rust jinja, no React
45
+ curl -N 127.0.0.1:3000/sse-counter # → SSE frames
46
+ ```
47
+
48
+ The [`example/hello-world/`](./example/hello-world) app shows each feature in one
49
+ route apiece.
50
+
51
+ ## CLI
52
+
53
+ ```
54
+ brustjs dev <entry> # dev mode: watcher + WS reload + browser auto-reload
55
+ brustjs build <entry> --out-dir D # self-contained ./dist/ (bun run dist/index.js)
56
+ brustjs new <name> # scaffold a project (partial — see Status)
57
+ ```
58
+
59
+ ## Features
60
+
61
+ - **React 19 SSR** via `renderToPipeableStream` (auto-Suspense → chunked streaming).
62
+ - **Islands** — opt-in client hydration with `<Island>`; the rest ships zero JS.
63
+ - **`native: true` routes** — JSX compiled to a jinja template at build time and
64
+ rendered Rust-side (`minijinja`), skipping React on the server entirely.
65
+ - **Server actions** (`"use server"`) → per-action endpoints; client helper rewrites
66
+ form/`fetch` targets.
67
+ - **SSE & WebSockets** as first-class route shapes.
68
+ - Nested routes + dynamic params, per-route typed loaders, request-scoped middleware,
69
+ forms/multipart, SPA-style navigation, in-process LRU cache, Tailwind v4 + CSS Modules.
70
+ - **Agent-first** — server fns and routes expose MCP tool/resource schemas at
71
+ `/_brust/mcp` so agents drive the app without scraping.
72
+
73
+ ## Performance
74
+
75
+ Two tiers, split by the napi crossing: pure-Rust paths (`/ping`, native jinja
76
+ routes) run far faster than routes that cross into a Bun worker for React SSR.
77
+ Full numbers, methodology, and the latency table are in
78
+ [`bench/RESULTS.md`](./bench/RESULTS.md) (`bun run bench`); the request lifecycle
79
+ and SAB protocol are in [`architecture.md`](./architecture.md).
80
+
81
+ ## Development
82
+
83
+ ```bash
84
+ cargo test --workspace # Rust unit tests
85
+ bun test runtime/ # TS unit tests
86
+ bun test tests/integration.test.ts # integration (real server)
87
+ ```
88
+
89
+ ```
90
+ crates/brust/ Rust: accept loop, worker pool, napi exports, SAB
91
+ crates/jsx-rust-compiler/ JSX → jinja compiler for native: true routes
92
+ runtime/ Bun-side: routing, render, actions, CLI
93
+ example/ hello-world demo
94
+ bench/ · docs/ · architecture.md
95
+ ```
96
+
97
+ ## Status
98
+
99
+ Alpha, solo-developed. Linux is tier-1 (io_uring; glibc + musl, 6 prebuilt platform
100
+ binaries). Known partials: `brustjs new` scaffold install, `brustjs dev` TS reload,
101
+ islands + `.module.css`. Deployment note: the io_uring server needs `io_uring_*`
102
+ syscalls permitted — a default-seccomp container (Docker/k8s) must allow them or run
103
+ `--security-opt seccomp=unconfined`. Roadmap and limitations in
104
+ [`architecture.md`](./architecture.md).
105
+
106
+ MIT.
107
+
108
+ ---
109
+
110
+ *Brust — built to burst.*
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "brustjs",
3
+ "version": "0.1.0-alpha",
4
+ "description": "Bun + Rust SSR framework — React on the server, Rust everywhere else (napi cdylib + per-worker SharedArrayBuffer).",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/AssetsArt/brust.git"
9
+ },
10
+ "homepage": "https://github.com/AssetsArt/brust#readme",
11
+ "bugs": "https://github.com/AssetsArt/brust/issues",
12
+ "keywords": [
13
+ "bun",
14
+ "rust",
15
+ "ssr",
16
+ "react",
17
+ "napi",
18
+ "islands",
19
+ "framework"
20
+ ],
21
+ "bin": {
22
+ "brustjs": "./runtime/cli/index.ts"
23
+ },
24
+ "napi": {
25
+ "binaryName": "brust",
26
+ "packageName": "brustjs",
27
+ "targets": [
28
+ "x86_64-apple-darwin",
29
+ "aarch64-apple-darwin",
30
+ "x86_64-unknown-linux-gnu",
31
+ "aarch64-unknown-linux-gnu",
32
+ "x86_64-unknown-linux-musl",
33
+ "aarch64-unknown-linux-musl"
34
+ ]
35
+ },
36
+ "dependencies": {
37
+ "@tailwindcss/node": "^4.3.0",
38
+ "@tailwindcss/oxide": "^4.3.0",
39
+ "smol-toml": "^1.6.1"
40
+ },
41
+ "optionalDependencies": {
42
+ "brustjs-darwin-x64": "0.1.0-alpha",
43
+ "brustjs-darwin-arm64": "0.1.0-alpha",
44
+ "brustjs-linux-x64-gnu": "0.1.0-alpha",
45
+ "brustjs-linux-arm64-gnu": "0.1.0-alpha",
46
+ "brustjs-linux-x64-musl": "0.1.0-alpha",
47
+ "brustjs-linux-arm64-musl": "0.1.0-alpha"
48
+ },
49
+ "peerDependencies": {
50
+ "react": "^19.2.6",
51
+ "react-dom": "^19.2.6"
52
+ },
53
+ "devDependencies": {
54
+ "@biomejs/biome": "2.4.16",
55
+ "@types/bun": "latest",
56
+ "@types/react": "^19.2.15",
57
+ "@types/react-dom": "^19.2.3",
58
+ "happy-dom": "^20.9.0",
59
+ "react": "^19.2.6",
60
+ "react-dom": "^19.2.6",
61
+ "typescript": "^6.0.3"
62
+ },
63
+ "type": "module",
64
+ "types": "./runtime/index.d.ts",
65
+ "exports": {
66
+ ".": "./runtime/index.ts",
67
+ "./routes": "./runtime/routes.ts"
68
+ },
69
+ "files": [
70
+ "runtime",
71
+ "!runtime/node_modules",
72
+ "!runtime/package.json",
73
+ "!runtime/*.node",
74
+ "!runtime/**/*.test.ts"
75
+ ],
76
+ "publishConfig": {
77
+ "access": "public"
78
+ },
79
+ "scripts": {
80
+ "build": "cd runtime && bun run build",
81
+ "build:debug": "cd runtime && bun run build:debug",
82
+ "test": "bun test tests/integration.test.ts",
83
+ "dev": "bun runtime/cli/index.ts dev example/hello-world/index.ts",
84
+ "dev:baseline": "bun run bench/apps/bun-serve/index.ts",
85
+ "bench": "bun run scripts/benchmark.ts",
86
+ "format": "biome format --write .",
87
+ "lint": "biome lint .",
88
+ "check": "biome check .",
89
+ "check:fix": "biome check --write .",
90
+ "ci": "biome ci ."
91
+ }
92
+ }
@@ -0,0 +1,65 @@
1
+ import type { BrustRequest, Middleware } from './routes.ts'
2
+
3
+ /** Server-side action handler. First arg is ALWAYS BrustRequest; the client
4
+ * stub strips it from the call site. Subsequent args are JSON-decoded from
5
+ * the request body (which MUST be a JSON array). */
6
+ export type ActionFn<Args extends unknown[] = unknown[], R = unknown> = (
7
+ req: BrustRequest,
8
+ ...args: Args
9
+ ) => Promise<R>
10
+
11
+ /** Registration shape passed to brust.registerActions. */
12
+ export interface ActionDef<F extends ActionFn = ActionFn> {
13
+ /** Stable id; must match the id used by `action<F>(id)` on the client.
14
+ * Charset: [A-Za-z0-9_-]+ (enforced both in TS and in Rust). */
15
+ id: string
16
+ /** Handler. Receives req + JSON-decoded args. */
17
+ fn: F
18
+ /** Per-action middleware chain. Same Middleware type used by routes. */
19
+ middleware?: Middleware[]
20
+ }
21
+
22
+ /** Mirrors is_safe_action_id in src/lib.rs and src/server.rs.
23
+ * Allowed: [A-Za-z0-9_-]+ only, max 128 chars. */
24
+ export function isValidActionId(id: string): boolean {
25
+ if (id.length === 0 || id.length > 128) return false
26
+ return /^[A-Za-z0-9_-]+$/.test(id)
27
+ }
28
+
29
+ const BRUST_MW_KEY = '__brustMiddleware'
30
+
31
+ /** Attach a middleware chain to a server-action function. The function is
32
+ * returned unchanged so the TypeScript signature is preserved verbatim —
33
+ * callers can still write `typeof srv.deleteNote` on the client.
34
+ *
35
+ * Throws TypeError if `mws` isn't an array of functions.
36
+ * Throws Error if called twice on the same fn (compose mws in one call).
37
+ */
38
+ export function withMiddleware<F extends (...args: never[]) => unknown>(
39
+ mws: readonly Middleware[],
40
+ fn: F,
41
+ ): F {
42
+ if (!Array.isArray(mws) || mws.some((m) => typeof m !== 'function')) {
43
+ throw new TypeError('withMiddleware expects an array of middleware functions')
44
+ }
45
+ if ((fn as { [BRUST_MW_KEY]?: unknown })[BRUST_MW_KEY] !== undefined) {
46
+ throw new Error(
47
+ 'withMiddleware called twice on the same function — compose middleware in a single call instead',
48
+ )
49
+ }
50
+ Object.defineProperty(fn, BRUST_MW_KEY, {
51
+ value: Object.freeze([...mws]),
52
+ enumerable: false,
53
+ writable: false,
54
+ configurable: false,
55
+ })
56
+ return fn
57
+ }
58
+
59
+ /** Read the middleware metadata installed by withMiddleware. Used by the
60
+ * scanner to populate ActionDef.middleware. Returns undefined for plain
61
+ * (un-wrapped) functions. */
62
+ export function getActionMiddleware(fn: unknown): Middleware[] | undefined {
63
+ if (typeof fn !== 'function') return undefined
64
+ return (fn as { [BRUST_MW_KEY]?: Middleware[] })[BRUST_MW_KEY]
65
+ }
@@ -0,0 +1,236 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "brust-runtime",
7
+ "devDependencies": {
8
+ "@napi-rs/cli": "^3.0.0",
9
+ "typescript": "^6.0.3",
10
+ },
11
+ },
12
+ },
13
+ "packages": {
14
+ "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
15
+
16
+ "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
17
+
18
+ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
19
+
20
+ "@inquirer/ansi": ["@inquirer/ansi@2.0.5", "", {}, "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw=="],
21
+
22
+ "@inquirer/checkbox": ["@inquirer/checkbox@5.1.5", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/core": "^11.1.10", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Jmf9tgBHIEK5SAOB7swYfStqmtkZb00xOTpSQmkoGEpdxOTpJi9RS0A8bkfDPHTTItZRJrRdZrEMu25wyj0VfQ=="],
23
+
24
+ "@inquirer/confirm": ["@inquirer/confirm@6.0.13", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw=="],
25
+
26
+ "@inquirer/core": ["@inquirer/core@11.1.10", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", "signal-exit": "^4.1.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A=="],
27
+
28
+ "@inquirer/editor": ["@inquirer/editor@5.1.2", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/external-editor": "^3.0.0", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Y3Nor7S/DhIPo+8Ym/dSY4efwKI4BsflKDwXh0jNeXJsSF3dteS/3Yf+z4wkibVZDvYMyCgknSTQlNahfunGHg=="],
29
+
30
+ "@inquirer/expand": ["@inquirer/expand@5.0.14", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-qyY9zcIX2eKYwaAUiQo9zORd61Lc3sXeM72fVbeHkYnDkqfr8/armcRbmVAIrExeJhI2puk+uomeKtWrpUVUmQ=="],
31
+
32
+ "@inquirer/external-editor": ["@inquirer/external-editor@3.0.0", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-lDSwMgg+M5rq6JKBYaJwSX6T9e/HK2qqZ1oxmOwn4AQoJE5D+7TumsxLGC02PWS//rkIVqbZv3XA3ejsc9FYvg=="],
33
+
34
+ "@inquirer/figures": ["@inquirer/figures@2.0.5", "", {}, "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ=="],
35
+
36
+ "@inquirer/input": ["@inquirer/input@5.0.13", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-0l0jCHlJnXIV8CTxwQC0C+5Ziq8WP22edWgmciW2xYvoeoSck4v5FvCS1ctKdqLLR0dUo93uAHgWHywgBSoRyw=="],
37
+
38
+ "@inquirer/number": ["@inquirer/number@4.0.13", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-WHmkYnnJAou5gx7RgcvAfUggnHNM1zWfoh0dFPl3dxVssuqt+dK5rIbaOYQXNyOegvFnopbKupjnhw2O8gANNg=="],
39
+
40
+ "@inquirer/password": ["@inquirer/password@5.0.13", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-XDGu64ROHZjOOXLAANvJN7iIxWKhOSCG5VakrZ5kaScVR+snVJCFglD/hL3/677awtWcu4pXoWa280CDIYcBeg=="],
41
+
42
+ "@inquirer/prompts": ["@inquirer/prompts@8.4.3", "", { "dependencies": { "@inquirer/checkbox": "^5.1.5", "@inquirer/confirm": "^6.0.13", "@inquirer/editor": "^5.1.2", "@inquirer/expand": "^5.0.14", "@inquirer/input": "^5.0.13", "@inquirer/number": "^4.0.13", "@inquirer/password": "^5.0.13", "@inquirer/rawlist": "^5.2.9", "@inquirer/search": "^4.1.9", "@inquirer/select": "^5.1.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-ai5LseTw9HhegupIgmo4cn7RpnCGznjjXu4OI+7jMR8vu7T1ZCCNMzFFAovUCjL1fl0cceksIN1++yQE59SmZw=="],
43
+
44
+ "@inquirer/rawlist": ["@inquirer/rawlist@5.2.9", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-a1ErXEfgjfPYpyQ89dp+7n2IISjH9oQg3ygvF5adz8B7aHn4n2PjEgu1wpVTp69K3bj3lVLxP0qJ2b1clk1Whw=="],
45
+
46
+ "@inquirer/search": ["@inquirer/search@4.1.9", "", { "dependencies": { "@inquirer/core": "^11.1.10", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-ZlbM28Q9lmLkFPNAIv+ZuY530n5Km8U1WW48oYEvDhe9yc2uL3m3t+JSdRUkQlk5fuIuskgiIVjcb7czFzQpuA=="],
47
+
48
+ "@inquirer/select": ["@inquirer/select@5.1.5", "", { "dependencies": { "@inquirer/ansi": "^2.0.5", "@inquirer/core": "^11.1.10", "@inquirer/figures": "^2.0.5", "@inquirer/type": "^4.0.5" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-6SRg6kHfK/sjLXOsuqNebuir+sjwrf/iWuRUnXgB2slzEewppI1WfzeS16XxDcOQmXBruMmmB9Cgrz7wsAxqMg=="],
49
+
50
+ "@inquirer/type": ["@inquirer/type@4.0.5", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q=="],
51
+
52
+ "@napi-rs/cli": ["@napi-rs/cli@3.6.2", "", { "dependencies": { "@inquirer/prompts": "^8.0.0", "@napi-rs/cross-toolchain": "^1.0.3", "@napi-rs/wasm-tools": "^1.0.1", "@octokit/rest": "^22.0.1", "clipanion": "^4.0.0-rc.4", "colorette": "^2.0.20", "emnapi": "^1.9.1", "es-toolkit": "^1.41.0", "js-yaml": "^4.1.0", "obug": "^2.0.0", "semver": "^7.7.3", "typanion": "^3.14.0" }, "peerDependencies": { "@emnapi/runtime": "^1.7.1" }, "optionalPeers": ["@emnapi/runtime"], "bin": { "napi": "dist/cli.js", "napi-raw": "cli.mjs" } }, "sha512-jy5rABUh9tbE/vPRzw9kGzGuqZiVslyDQUV8LkvjzqVX/oJMN7g0U1uhtr9L3W1H+iRM/urXHXUf+CE4n8FvLA=="],
53
+
54
+ "@napi-rs/cross-toolchain": ["@napi-rs/cross-toolchain@1.0.3", "", { "dependencies": { "@napi-rs/lzma": "^1.4.5", "@napi-rs/tar": "^1.1.0", "debug": "^4.4.1" }, "peerDependencies": { "@napi-rs/cross-toolchain-arm64-target-aarch64": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-armv7": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-ppc64le": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-s390x": "^1.0.3", "@napi-rs/cross-toolchain-arm64-target-x86_64": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-aarch64": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-armv7": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-ppc64le": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-s390x": "^1.0.3", "@napi-rs/cross-toolchain-x64-target-x86_64": "^1.0.3" }, "optionalPeers": ["@napi-rs/cross-toolchain-arm64-target-aarch64", "@napi-rs/cross-toolchain-arm64-target-armv7", "@napi-rs/cross-toolchain-arm64-target-ppc64le", "@napi-rs/cross-toolchain-arm64-target-s390x", "@napi-rs/cross-toolchain-arm64-target-x86_64", "@napi-rs/cross-toolchain-x64-target-aarch64", "@napi-rs/cross-toolchain-x64-target-armv7", "@napi-rs/cross-toolchain-x64-target-ppc64le", "@napi-rs/cross-toolchain-x64-target-s390x", "@napi-rs/cross-toolchain-x64-target-x86_64"] }, "sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg=="],
55
+
56
+ "@napi-rs/lzma": ["@napi-rs/lzma@1.4.5", "", { "optionalDependencies": { "@napi-rs/lzma-android-arm-eabi": "1.4.5", "@napi-rs/lzma-android-arm64": "1.4.5", "@napi-rs/lzma-darwin-arm64": "1.4.5", "@napi-rs/lzma-darwin-x64": "1.4.5", "@napi-rs/lzma-freebsd-x64": "1.4.5", "@napi-rs/lzma-linux-arm-gnueabihf": "1.4.5", "@napi-rs/lzma-linux-arm64-gnu": "1.4.5", "@napi-rs/lzma-linux-arm64-musl": "1.4.5", "@napi-rs/lzma-linux-ppc64-gnu": "1.4.5", "@napi-rs/lzma-linux-riscv64-gnu": "1.4.5", "@napi-rs/lzma-linux-s390x-gnu": "1.4.5", "@napi-rs/lzma-linux-x64-gnu": "1.4.5", "@napi-rs/lzma-linux-x64-musl": "1.4.5", "@napi-rs/lzma-wasm32-wasi": "1.4.5", "@napi-rs/lzma-win32-arm64-msvc": "1.4.5", "@napi-rs/lzma-win32-ia32-msvc": "1.4.5", "@napi-rs/lzma-win32-x64-msvc": "1.4.5" } }, "sha512-zS5LuN1OBPAyZpda2ZZgYOEDC+xecUdAGnrvbYzjnLXkrq/OBC3B9qcRvlxbDR3k5H/gVfvef1/jyUqPknqjbg=="],
57
+
58
+ "@napi-rs/lzma-android-arm-eabi": ["@napi-rs/lzma-android-arm-eabi@1.4.5", "", { "os": "android", "cpu": "arm" }, "sha512-Up4gpyw2SacmyKWWEib06GhiDdF+H+CCU0LAV8pnM4aJIDqKKd5LHSlBht83Jut6frkB0vwEPmAkv4NjQ5u//Q=="],
59
+
60
+ "@napi-rs/lzma-android-arm64": ["@napi-rs/lzma-android-arm64@1.4.5", "", { "os": "android", "cpu": "arm64" }, "sha512-uwa8sLlWEzkAM0MWyoZJg0JTD3BkPknvejAFG2acUA1raXM8jLrqujWCdOStisXhqQjZ2nDMp3FV6cs//zjfuQ=="],
61
+
62
+ "@napi-rs/lzma-darwin-arm64": ["@napi-rs/lzma-darwin-arm64@1.4.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0Y0TQLQ2xAjVabrMDem1NhIssOZzF/y/dqetc6OT8mD3xMTDtF8u5BqZoX3MyPc9FzpsZw4ksol+w7DsxHrpMA=="],
63
+
64
+ "@napi-rs/lzma-darwin-x64": ["@napi-rs/lzma-darwin-x64@1.4.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-vR2IUyJY3En+V1wJkwmbGWcYiT8pHloTAWdW4pG24+51GIq+intst6Uf6D/r46citObGZrlX0QvMarOkQeHWpw=="],
65
+
66
+ "@napi-rs/lzma-freebsd-x64": ["@napi-rs/lzma-freebsd-x64@1.4.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-XpnYQC5SVovO35tF0xGkbHYjsS6kqyNCjuaLQ2dbEblFRr5cAZVvsJ/9h7zj/5FluJPJRDojVNxGyRhTp4z2lw=="],
67
+
68
+ "@napi-rs/lzma-linux-arm-gnueabihf": ["@napi-rs/lzma-linux-arm-gnueabihf@1.4.5", "", { "os": "linux", "cpu": "arm" }, "sha512-ic1ZZMoRfRMwtSwxkyw4zIlbDZGC6davC9r+2oX6x9QiF247BRqqT94qGeL5ZP4Vtz0Hyy7TEViWhx5j6Bpzvw=="],
69
+
70
+ "@napi-rs/lzma-linux-arm64-gnu": ["@napi-rs/lzma-linux-arm64-gnu@1.4.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-asEp7FPd7C1Yi6DQb45a3KPHKOFBSfGuJWXcAd4/bL2Fjetb2n/KK2z14yfW8YC/Fv6x3rBM0VAZKmJuz4tysg=="],
71
+
72
+ "@napi-rs/lzma-linux-arm64-musl": ["@napi-rs/lzma-linux-arm64-musl@1.4.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-yWjcPDgJ2nIL3KNvi4536dlT/CcCWO0DUyEOlBs/SacG7BeD6IjGh6yYzd3/X1Y3JItCbZoDoLUH8iB1lTXo3w=="],
73
+
74
+ "@napi-rs/lzma-linux-ppc64-gnu": ["@napi-rs/lzma-linux-ppc64-gnu@1.4.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-0XRhKuIU/9ZjT4WDIG/qnX7Xz7mSQHYZo9Gb3MP2gcvBgr6BA4zywQ9k3gmQaPn9ECE+CZg2V7DV7kT+x2pUMQ=="],
75
+
76
+ "@napi-rs/lzma-linux-riscv64-gnu": ["@napi-rs/lzma-linux-riscv64-gnu@1.4.5", "", { "os": "linux", "cpu": "none" }, "sha512-QrqDIPEUUB23GCpyQj/QFyMlr8SGxxyExeZz9OWFnHfb70kXdTLWrHS/hEI1Ru+lSbQ/6xRqeoGyQ4Aqdg+/RA=="],
77
+
78
+ "@napi-rs/lzma-linux-s390x-gnu": ["@napi-rs/lzma-linux-s390x-gnu@1.4.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-k8RVM5aMhW86E9H0QXdquwojew4H3SwPxbRVbl49/COJQWCUjGi79X6mYruMnMPEznZinUiT1jgKbFo2A00NdA=="],
79
+
80
+ "@napi-rs/lzma-linux-x64-gnu": ["@napi-rs/lzma-linux-x64-gnu@1.4.5", "", { "os": "linux", "cpu": "x64" }, "sha512-6rMtBgnIq2Wcl1rQdZsnM+rtCcVCbws1nF8S2NzaUsVaZv8bjrPiAa0lwg4Eqnn1d9lgwqT+cZgm5m+//K08Kw=="],
81
+
82
+ "@napi-rs/lzma-linux-x64-musl": ["@napi-rs/lzma-linux-x64-musl@1.4.5", "", { "os": "linux", "cpu": "x64" }, "sha512-eiadGBKi7Vd0bCArBUOO/qqRYPHt/VQVvGyYvDFt6C2ZSIjlD+HuOl+2oS1sjf4CFjK4eDIog6EdXnL0NE6iyQ=="],
83
+
84
+ "@napi-rs/lzma-wasm32-wasi": ["@napi-rs/lzma-wasm32-wasi@1.4.5", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.3" }, "cpu": "none" }, "sha512-+VyHHlr68dvey6fXc2hehw9gHVFIW3TtGF1XkcbAu65qVXsA9D/T+uuoRVqhE+JCyFHFrO0ixRbZDRK1XJt1sA=="],
85
+
86
+ "@napi-rs/lzma-win32-arm64-msvc": ["@napi-rs/lzma-win32-arm64-msvc@1.4.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-eewnqvIyyhHi3KaZtBOJXohLvwwN27gfS2G/YDWdfHlbz1jrmfeHAmzMsP5qv8vGB+T80TMHNkro4kYjeh6Deg=="],
87
+
88
+ "@napi-rs/lzma-win32-ia32-msvc": ["@napi-rs/lzma-win32-ia32-msvc@1.4.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-OeacFVRCJOKNU/a0ephUfYZ2Yt+NvaHze/4TgOwJ0J0P4P7X1mHzN+ig9Iyd74aQDXYqc7kaCXA2dpAOcH87Cg=="],
89
+
90
+ "@napi-rs/lzma-win32-x64-msvc": ["@napi-rs/lzma-win32-x64-msvc@1.4.5", "", { "os": "win32", "cpu": "x64" }, "sha512-T4I1SamdSmtyZgDXGAGP+y5LEK5vxHUFwe8mz6D4R7Sa5/WCxTcCIgPJ9BD7RkpO17lzhlaM2vmVvMy96Lvk9Q=="],
91
+
92
+ "@napi-rs/tar": ["@napi-rs/tar@1.1.0", "", { "optionalDependencies": { "@napi-rs/tar-android-arm-eabi": "1.1.0", "@napi-rs/tar-android-arm64": "1.1.0", "@napi-rs/tar-darwin-arm64": "1.1.0", "@napi-rs/tar-darwin-x64": "1.1.0", "@napi-rs/tar-freebsd-x64": "1.1.0", "@napi-rs/tar-linux-arm-gnueabihf": "1.1.0", "@napi-rs/tar-linux-arm64-gnu": "1.1.0", "@napi-rs/tar-linux-arm64-musl": "1.1.0", "@napi-rs/tar-linux-ppc64-gnu": "1.1.0", "@napi-rs/tar-linux-s390x-gnu": "1.1.0", "@napi-rs/tar-linux-x64-gnu": "1.1.0", "@napi-rs/tar-linux-x64-musl": "1.1.0", "@napi-rs/tar-wasm32-wasi": "1.1.0", "@napi-rs/tar-win32-arm64-msvc": "1.1.0", "@napi-rs/tar-win32-ia32-msvc": "1.1.0", "@napi-rs/tar-win32-x64-msvc": "1.1.0" } }, "sha512-7cmzIu+Vbupriudo7UudoMRH2OA3cTw67vva8MxeoAe5S7vPFI7z0vp0pMXiA25S8IUJefImQ90FeJjl8fjEaQ=="],
93
+
94
+ "@napi-rs/tar-android-arm-eabi": ["@napi-rs/tar-android-arm-eabi@1.1.0", "", { "os": "android", "cpu": "arm" }, "sha512-h2Ryndraj/YiKgMV/r5by1cDusluYIRT0CaE0/PekQ4u+Wpy2iUVqvzVU98ZPnhXaNeYxEvVJHNGafpOfaD0TA=="],
95
+
96
+ "@napi-rs/tar-android-arm64": ["@napi-rs/tar-android-arm64@1.1.0", "", { "os": "android", "cpu": "arm64" }, "sha512-DJFyQHr1ZxNZorm/gzc1qBNLF/FcKzcH0V0Vwan5P+o0aE2keQIGEjJ09FudkF9v6uOuJjHCVDdK6S6uHtShAw=="],
97
+
98
+ "@napi-rs/tar-darwin-arm64": ["@napi-rs/tar-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Zz2sXRzjIX4e532zD6xm2SjXEym6MkvfCvL2RMpG2+UwNVDVscHNcz3d47Pf3sysP2e2af7fBB3TIoK2f6trPw=="],
99
+
100
+ "@napi-rs/tar-darwin-x64": ["@napi-rs/tar-darwin-x64@1.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-EI+CptIMNweT0ms9S3mkP/q+J6FNZ1Q6pvpJOEcWglRfyfQpLqjlC0O+dptruTPE8VamKYuqdjxfqD8hifZDOA=="],
101
+
102
+ "@napi-rs/tar-freebsd-x64": ["@napi-rs/tar-freebsd-x64@1.1.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J0PIqX+pl6lBIAckL/c87gpodLbjZB1OtIK+RDscKC9NLdpVv6VGOxzUV/fYev/hctcE8EfkLbgFOfpmVQPg2g=="],
103
+
104
+ "@napi-rs/tar-linux-arm-gnueabihf": ["@napi-rs/tar-linux-arm-gnueabihf@1.1.0", "", { "os": "linux", "cpu": "arm" }, "sha512-SLgIQo3f3EjkZ82ZwvrEgFvMdDAhsxCYjyoSuWfHCz0U16qx3SuGCp8+FYOPYCECHN3ZlGjXnoAIt9ERd0dEUg=="],
105
+
106
+ "@napi-rs/tar-linux-arm64-gnu": ["@napi-rs/tar-linux-arm64-gnu@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-d014cdle52EGaH6GpYTQOP9Py7glMO1zz/+ynJPjjzYFSxvdYx0byrjumZk2UQdIyGZiJO2MEFpCkEEKFSgPYA=="],
107
+
108
+ "@napi-rs/tar-linux-arm64-musl": ["@napi-rs/tar-linux-arm64-musl@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-L/y1/26q9L/uBqiW/JdOb/Dc94egFvNALUZV2WCGKQXc6UByPBMgdiEyW2dtoYxYYYYc+AKD+jr+wQPcvX2vrQ=="],
109
+
110
+ "@napi-rs/tar-linux-ppc64-gnu": ["@napi-rs/tar-linux-ppc64-gnu@1.1.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EPE1K/80RQvPbLRJDJs1QmCIcH+7WRi0F73+oTe1582y9RtfGRuzAkzeBuAGRXAQEjRQw/RjtNqr6UTJ+8UuWQ=="],
111
+
112
+ "@napi-rs/tar-linux-s390x-gnu": ["@napi-rs/tar-linux-s390x-gnu@1.1.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-B2jhWiB1ffw1nQBqLUP1h4+J1ovAxBOoe5N2IqDMOc63fsPZKNqF1PvO/dIem8z7LL4U4bsfmhy3gBfu547oNQ=="],
113
+
114
+ "@napi-rs/tar-linux-x64-gnu": ["@napi-rs/tar-linux-x64-gnu@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-tbZDHnb9617lTnsDMGo/eAMZxnsQFnaRe+MszRqHguKfMwkisc9CCJnks/r1o84u5fECI+J/HOrKXgczq/3Oww=="],
115
+
116
+ "@napi-rs/tar-linux-x64-musl": ["@napi-rs/tar-linux-x64-musl@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-dV6cODlzbO8u6Anmv2N/ilQHq/AWz0xyltuXoLU3yUyXbZcnWYZuB2rL8OBGPmqNcD+x9NdScBNXh7vWN0naSQ=="],
117
+
118
+ "@napi-rs/tar-wasm32-wasi": ["@napi-rs/tar-wasm32-wasi@1.1.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.3" }, "cpu": "none" }, "sha512-jIa9nb2HzOrfH0F8QQ9g3WE4aMH5vSI5/1NYVNm9ysCmNjCCtMXCAhlI3WKCdm/DwHf0zLqdrrtDFXODcNaqMw=="],
119
+
120
+ "@napi-rs/tar-win32-arm64-msvc": ["@napi-rs/tar-win32-arm64-msvc@1.1.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vfpG71OB0ijtjemp3WTdmBKJm9R70KM8vsSExMsIQtV0lVzP07oM1CW6JbNRPXNLhRoue9ofYLiUDk8bE0Hckg=="],
121
+
122
+ "@napi-rs/tar-win32-ia32-msvc": ["@napi-rs/tar-win32-ia32-msvc@1.1.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-hGPyPW60YSpOSgzfy68DLBHgi6HxkAM+L59ZZZPMQ0TOXjQg+p2EW87+TjZfJOkSpbYiEkULwa/f4a2hcVjsqQ=="],
123
+
124
+ "@napi-rs/tar-win32-x64-msvc": ["@napi-rs/tar-win32-x64-msvc@1.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-L6Ed1DxXK9YSCMyvpR8MiNAyKNkQLjsHsHK9E0qnHa8NzLFqzDKhvs5LfnWxM2kJ+F7m/e5n9zPm24kHb3LsVw=="],
125
+
126
+ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
127
+
128
+ "@napi-rs/wasm-tools": ["@napi-rs/wasm-tools@1.0.1", "", { "optionalDependencies": { "@napi-rs/wasm-tools-android-arm-eabi": "1.0.1", "@napi-rs/wasm-tools-android-arm64": "1.0.1", "@napi-rs/wasm-tools-darwin-arm64": "1.0.1", "@napi-rs/wasm-tools-darwin-x64": "1.0.1", "@napi-rs/wasm-tools-freebsd-x64": "1.0.1", "@napi-rs/wasm-tools-linux-arm64-gnu": "1.0.1", "@napi-rs/wasm-tools-linux-arm64-musl": "1.0.1", "@napi-rs/wasm-tools-linux-x64-gnu": "1.0.1", "@napi-rs/wasm-tools-linux-x64-musl": "1.0.1", "@napi-rs/wasm-tools-wasm32-wasi": "1.0.1", "@napi-rs/wasm-tools-win32-arm64-msvc": "1.0.1", "@napi-rs/wasm-tools-win32-ia32-msvc": "1.0.1", "@napi-rs/wasm-tools-win32-x64-msvc": "1.0.1" } }, "sha512-enkZYyuCdo+9jneCPE/0fjIta4wWnvVN9hBo2HuiMpRF0q3lzv1J6b/cl7i0mxZUKhBrV3aCKDBQnCOhwKbPmQ=="],
129
+
130
+ "@napi-rs/wasm-tools-android-arm-eabi": ["@napi-rs/wasm-tools-android-arm-eabi@1.0.1", "", { "os": "android", "cpu": "arm" }, "sha512-lr07E/l571Gft5v4aA1dI8koJEmF1F0UigBbsqg9OWNzg80H3lDPO+auv85y3T/NHE3GirDk7x/D3sLO57vayw=="],
131
+
132
+ "@napi-rs/wasm-tools-android-arm64": ["@napi-rs/wasm-tools-android-arm64@1.0.1", "", { "os": "android", "cpu": "arm64" }, "sha512-WDR7S+aRLV6LtBJAg5fmjKkTZIdrEnnQxgdsb7Cf8pYiMWBHLU+LC49OUVppQ2YSPY0+GeYm9yuZWW3kLjJ7Bg=="],
133
+
134
+ "@napi-rs/wasm-tools-darwin-arm64": ["@napi-rs/wasm-tools-darwin-arm64@1.0.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-qWTI+EEkiN0oIn/N2gQo7+TVYil+AJ20jjuzD2vATS6uIjVz+Updeqmszi7zq7rdFTLp6Ea3/z4kDKIfZwmR9g=="],
135
+
136
+ "@napi-rs/wasm-tools-darwin-x64": ["@napi-rs/wasm-tools-darwin-x64@1.0.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-bA6hubqtHROR5UI3tToAF/c6TDmaAgF0SWgo4rADHtQ4wdn0JeogvOk50gs2TYVhKPE2ZD2+qqt7oBKB+sxW3A=="],
137
+
138
+ "@napi-rs/wasm-tools-freebsd-x64": ["@napi-rs/wasm-tools-freebsd-x64@1.0.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-90+KLBkD9hZEjPQW1MDfwSt5J1L46EUKacpCZWyRuL6iIEO5CgWU0V/JnEgFsDOGyyYtiTvHc5bUdUTWd4I9Vg=="],
139
+
140
+ "@napi-rs/wasm-tools-linux-arm64-gnu": ["@napi-rs/wasm-tools-linux-arm64-gnu@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-rG0QlS65x9K/u3HrKafDf8cFKj5wV2JHGfl8abWgKew0GVPyp6vfsDweOwHbWAjcHtp2LHi6JHoW80/MTHm52Q=="],
141
+
142
+ "@napi-rs/wasm-tools-linux-arm64-musl": ["@napi-rs/wasm-tools-linux-arm64-musl@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jAasbIvjZXCgX0TCuEFQr+4D6Lla/3AAVx2LmDuMjgG4xoIXzjKWl7c4chuaD+TI+prWT0X6LJcdzFT+ROKGHQ=="],
143
+
144
+ "@napi-rs/wasm-tools-linux-x64-gnu": ["@napi-rs/wasm-tools-linux-x64-gnu@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Plgk5rPqqK2nocBGajkMVbGm010Z7dnUgq0wtnYRZbzWWxwWcXfZMPa8EYxrK4eE8SzpI7VlZP1tdVsdjgGwMw=="],
145
+
146
+ "@napi-rs/wasm-tools-linux-x64-musl": ["@napi-rs/wasm-tools-linux-x64-musl@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GW7AzGuWxtQkyHknHWYFdR0CHmW6is8rG2Rf4V6GNmMpmwtXt/ItWYWtBe4zqJWycMNazpfZKSw/BpT7/MVCXQ=="],
147
+
148
+ "@napi-rs/wasm-tools-wasm32-wasi": ["@napi-rs/wasm-tools-wasm32-wasi@1.0.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.0.3" }, "cpu": "none" }, "sha512-/nQVSTrqSsn7YdAc2R7Ips/tnw5SPUcl3D7QrXCNGPqjbatIspnaexvaOYNyKMU6xPu+pc0BTnKVmqhlJJCPLA=="],
149
+
150
+ "@napi-rs/wasm-tools-win32-arm64-msvc": ["@napi-rs/wasm-tools-win32-arm64-msvc@1.0.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-PFi7oJIBu5w7Qzh3dwFea3sHRO3pojMsaEnUIy22QvsW+UJfNQwJCryVrpoUt8m4QyZXI+saEq/0r4GwdoHYFQ=="],
151
+
152
+ "@napi-rs/wasm-tools-win32-ia32-msvc": ["@napi-rs/wasm-tools-win32-ia32-msvc@1.0.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-gXkuYzxQsgkj05Zaq+KQTkHIN83dFAwMcTKa2aQcpYPRImFm2AQzEyLtpXmyCWzJ0F9ZYAOmbSyrNew8/us6bw=="],
153
+
154
+ "@napi-rs/wasm-tools-win32-x64-msvc": ["@napi-rs/wasm-tools-win32-x64-msvc@1.0.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rEAf05nol3e3eei2sRButmgXP+6ATgm0/38MKhz9Isne82T4rPIMYsCIFj0kOisaGeVwoi2fnm7O9oWp5YVnYQ=="],
155
+
156
+ "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
157
+
158
+ "@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
159
+
160
+ "@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="],
161
+
162
+ "@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
163
+
164
+ "@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
165
+
166
+ "@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@14.0.0", "", { "dependencies": { "@octokit/types": "^16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw=="],
167
+
168
+ "@octokit/plugin-request-log": ["@octokit/plugin-request-log@6.0.0", "", { "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q=="],
169
+
170
+ "@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@17.0.0", "", { "dependencies": { "@octokit/types": "^16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw=="],
171
+
172
+ "@octokit/request": ["@octokit/request@10.0.9", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "content-type": "^2.0.0", "fast-content-type-parse": "^3.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-o8Bi3f608eyM+7BmBiUWxFsdjLb3/ym1cQek5LZOv9KkZcxRrHCPhhRzm6xjO6HVZ85ItD6+sTsjxo821SVa/A=="],
173
+
174
+ "@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
175
+
176
+ "@octokit/rest": ["@octokit/rest@22.0.1", "", { "dependencies": { "@octokit/core": "^7.0.6", "@octokit/plugin-paginate-rest": "^14.0.0", "@octokit/plugin-request-log": "^6.0.0", "@octokit/plugin-rest-endpoint-methods": "^17.0.0" } }, "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw=="],
177
+
178
+ "@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
179
+
180
+ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
181
+
182
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
183
+
184
+ "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
185
+
186
+ "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="],
187
+
188
+ "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="],
189
+
190
+ "clipanion": ["clipanion@4.0.0-rc.4", "", { "dependencies": { "typanion": "^3.8.0" } }, "sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q=="],
191
+
192
+ "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="],
193
+
194
+ "content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
195
+
196
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
197
+
198
+ "emnapi": ["emnapi@1.10.0", "", { "peerDependencies": { "node-addon-api": ">= 6.1.0" }, "optionalPeers": ["node-addon-api"] }, "sha512-swoyZjupDvLoe/KC3HZ4SY1JUN+tviT6eOZ3Px28TZAYdBHtRIiMWWrIUUH+2/9CYY4fNTID1YhYZ+kdFHszHg=="],
199
+
200
+ "es-toolkit": ["es-toolkit@1.46.1", "", {}, "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ=="],
201
+
202
+ "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
203
+
204
+ "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="],
205
+
206
+ "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="],
207
+
208
+ "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="],
209
+
210
+ "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
211
+
212
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
213
+
214
+ "json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="],
215
+
216
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
217
+
218
+ "mute-stream": ["mute-stream@3.0.0", "", {}, "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw=="],
219
+
220
+ "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
221
+
222
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
223
+
224
+ "semver": ["semver@7.8.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg=="],
225
+
226
+ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
227
+
228
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
229
+
230
+ "typanion": ["typanion@3.14.0", "", {}, "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug=="],
231
+
232
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
233
+
234
+ "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],
235
+ }
236
+ }
@@ -0,0 +1,97 @@
1
+ import { writeFile } from 'node:fs/promises'
2
+ import { resolve } from 'node:path'
3
+ import type { BunPlugin } from 'bun'
4
+
5
+ /** Write a TypeScript file that re-exports `scanActions` as a pure function
6
+ * returning a hard-coded ActionDef[]. Bundle this file via `actionsPrebuiltPlugin`
7
+ * below to satisfy `import { scanActions } from './scan-actions.ts'` lookups
8
+ * inside the runtime bundle without walking the filesystem at runtime.
9
+ *
10
+ * `idToSourcePath` maps each discovered action id → absolute path of the
11
+ * `'use server'` file it was exported from. The orchestrator builds this map
12
+ * by calling `collectExports(sourceFile)` for every file in `scan.sourceFiles`.
13
+ *
14
+ * `repoRoot` is the absolute path of the brust repo (where `runtime/` lives).
15
+ * `outPath` is where to write the generated file (e.g. <outDir>/_actions-prebuilt.ts).
16
+ */
17
+ export async function writePrebuiltActionsFileWithMap(
18
+ outPath: string,
19
+ idToSourcePath: Map<string, string>,
20
+ repoRoot: string,
21
+ ): Promise<void> {
22
+ const actionsPath = resolve(repoRoot, 'runtime/actions.ts')
23
+ const scanPath = resolve(repoRoot, 'runtime/scan-actions.ts')
24
+
25
+ // Stable file order = stable import order = deterministic builds.
26
+ const filePaths = [...new Set(idToSourcePath.values())].sort()
27
+ const fileToVar = new Map<string, string>()
28
+ filePaths.forEach((p, i) => {
29
+ fileToVar.set(p, `__mod${i}`)
30
+ })
31
+
32
+ const imports = filePaths
33
+ .map((p, i) => `import * as __mod${i} from ${JSON.stringify(p)}`)
34
+ .join('\n')
35
+
36
+ const sortedIds = [...idToSourcePath.keys()].sort((a, b) => a.localeCompare(b))
37
+ const entries = sortedIds
38
+ .map((id) => {
39
+ const v = fileToVar.get(idToSourcePath.get(id)!)!
40
+ const key = JSON.stringify(id)
41
+ return ` { id: ${key}, fn: (${v}[${key}] as any), middleware: getActionMiddleware(${v}[${key}]) }`
42
+ })
43
+ .join(',\n')
44
+
45
+ const src = `// AUTO-GENERATED by brust build — do not edit.
46
+ import { getActionMiddleware } from ${JSON.stringify(actionsPath)}
47
+ import type { ActionDef } from ${JSON.stringify(actionsPath)}
48
+ import type { ScanOptions, ScanActionsResult } from ${JSON.stringify(scanPath)}
49
+ ${imports}
50
+
51
+ // Re-export auxiliaries so any bundle import from scan-actions.ts still resolves.
52
+ export { stripLeadingTrivia, hasUseServerDirective, collectExports } from ${JSON.stringify(scanPath)}
53
+ export type { ScanOptions, ScanActionsResult } from ${JSON.stringify(scanPath)}
54
+
55
+ const PREBUILT: ActionDef[] = [
56
+ ${entries}
57
+ ]
58
+
59
+ export async function scanActions(_opts: ScanOptions = {}): Promise<ScanActionsResult> {
60
+ return { actions: PREBUILT, sourceFiles: [] }
61
+ }
62
+ `
63
+ await writeFile(outPath, src, 'utf-8')
64
+ }
65
+
66
+ /** Bun.build plugin that aliases `runtime/scan-actions.ts` to the generated
67
+ * prebuilt file. Combined with `writePrebuiltActionsFileWithMap` this makes
68
+ * the bundled `scanActions()` return a hard-coded list. */
69
+ export function actionsPrebuiltPlugin(generatedFilePath: string, repoRoot: string): BunPlugin {
70
+ const targetPath = resolve(repoRoot, 'runtime/scan-actions.ts')
71
+
72
+ return {
73
+ name: 'brust-actions-prebuilt',
74
+ setup(build) {
75
+ build.onResolve({ filter: /.*/ }, (args) => {
76
+ // The generated file re-exports symbols from scan-actions.ts. Without this
77
+ // guard those re-exports would self-redirect back into the generated file,
78
+ // creating a circular module graph where the re-exported bindings resolve
79
+ // to `undefined`.
80
+ if (args.importer === generatedFilePath) return undefined
81
+
82
+ // Match the canonical scan-actions.ts file regardless of how it's
83
+ // imported (relative './scan-actions.ts' from runtime/index.ts, etc.).
84
+ // Resolve the import to an absolute path and compare.
85
+ const resolved = resolve(
86
+ args.importer ? args.importer.replace(/\/[^/]*$/, '') : repoRoot,
87
+ args.path,
88
+ )
89
+ if (resolved === targetPath || resolved + '.ts' === targetPath) {
90
+ return { path: generatedFilePath }
91
+ }
92
+ // Default resolution for everything else.
93
+ return undefined
94
+ })
95
+ },
96
+ }
97
+ }