feat(arcrun): mira wiki page with tag filter + accumulated WIP
- landing/app/mira/wiki: tag=mira-wiki list now shows all wiki paragraphs (depends on KBDB tag filter exposed in matrix/kbdb commit, separate repo) - landing: app/mira hub + feed split + various WIP from prior sessions - registry/components: claude_api / kbdb_create_block / kbdb_get / km_writer / platform_crypto / auth_oauth2 contracts + main.go (accumulated) - .component-builds: pkg-lock updates + index.ts adjustments (WIP) - .agents/specs/arcrun/frontend-redesign: design notes - docs/test_credentials, docs/user_requirements/arcrun-landing-page: WIP docs - cypher-executor: auth-dispatcher / wasi-shim adjustments (WIP) Includes accumulated work from prior sessions plus the wiki UI tag-filter update that surfaces the AI-generated wiki paragraphs at /mira/wiki. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
+1539
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-auth-oauth2",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* arcrun auth_oauth2 Worker
|
||||
*
|
||||
* POST / → JSON input {action, api_key, service} → WASM (WASI preview1 stdin/stdout) → JSON output
|
||||
*
|
||||
* 額外 host functions(相較 auth_static_key):
|
||||
* - kv_put:快取 access_token(短效,TTL 跟隨 expires_in)
|
||||
* - http_request:POST token endpoint 換 access_token
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import {
|
||||
createWasiShim,
|
||||
createArcrunHostFunctions,
|
||||
type ArcrunHostEnv,
|
||||
} from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
type Env = ArcrunHostEnv;
|
||||
|
||||
const app = new Hono<{ Bindings: Env }>();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'auth_oauth2' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: Record<string, unknown>;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
const apiKey = typeof input.api_key === 'string' ? input.api_key : '';
|
||||
if (!apiKey) {
|
||||
return c.json({ success: false, error: 'api_key 必填' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(c.env, apiKey, input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
// ── WASM runner ──────────────────────────────────────────────────────────────
|
||||
|
||||
async function runWasm(env: Env, apiKey: string, input: unknown): Promise<unknown> {
|
||||
const stdinData = JSON.stringify(input);
|
||||
const hostFunctions = createArcrunHostFunctions(env, apiKey);
|
||||
|
||||
// 加入 http_request(token endpoint 用)
|
||||
hostFunctions.http_request = async (url, method, headersJSON, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
try {
|
||||
Object.assign(headers, JSON.parse(headersJSON || '{}'));
|
||||
} catch { /* ignore */ }
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers,
|
||||
body: body || undefined,
|
||||
});
|
||||
return res.text();
|
||||
};
|
||||
|
||||
const shim = createWasiShim(stdinData, hostFunctions);
|
||||
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
name = "arcrun-auth-oauth2"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "auth_oauth2"
|
||||
|
||||
[[routes]]
|
||||
pattern = "auth-oauth2.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "CREDENTIALS_KV"
|
||||
id = "e7f4320f88d343f187e35e3543dd74c9"
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "RECIPES"
|
||||
id = "9cf9db905c6241f78503199e58b2ffe0"
|
||||
|
||||
# ENCRYPTION_KEY 透過 wrangler secret put 設定
|
||||
@@ -97,17 +97,7 @@ async function runWasm(env: Env, apiKey: string, input: unknown): Promise<unknow
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -65,17 +65,7 @@ async function runWasm(env: Env, apiKey: string, input: unknown): Promise<unknow
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
+1539
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-claude-api",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* arcrun WASM 零件 Worker (claude_api v2)
|
||||
* POST / → JSON input → WASM (WASI preview1) → JSON output
|
||||
* SDD: polaris/mira/.agents/specs/mira-app/design.md §6
|
||||
*
|
||||
* v2 改打 Mira daemon (Hetzner) 而非直打 Anthropic Messages API
|
||||
* 理由:OAuth token 在 Messages API 限制 system prompt → rate_limit
|
||||
* Mira daemon 用 Claude Agent SDK,已內建 Mira persona
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
type Env = {
|
||||
MIRA_TOKEN?: string; // Mira daemon Bearer token
|
||||
MIRA_URL?: string; // 預設 https://mira.uncle6.me
|
||||
COMPONENT_ID: string;
|
||||
};
|
||||
|
||||
const app = new Hono<{ Bindings: Env }>();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'claude_api', version: 'v2-mira-daemon' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: Record<string, unknown>;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
// 用戶沒帶 token → 用 Worker secret fallback
|
||||
if (!input.mira_token && c.env.MIRA_TOKEN) {
|
||||
input.mira_token = c.env.MIRA_TOKEN;
|
||||
}
|
||||
if (!input.mira_url && c.env.MIRA_URL) {
|
||||
input.mira_url = c.env.MIRA_URL;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
async function runWasm(input: unknown): Promise<unknown> {
|
||||
const hostFunctions: WasiHostFunctions = {
|
||||
http_request: async (url, method, headersJson, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
if (headersJson) {
|
||||
try {
|
||||
const parsed = JSON.parse(headersJson);
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
||||
if (typeof v === 'string') headers[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
|
||||
const shim = createWasiShim(JSON.stringify(input), hostFunctions);
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
const stderr = shim.getStderr().trim();
|
||||
if (stderr) console.error('[claude_api wasm stderr]', stderr);
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "arcrun-claude-api"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "claude_api"
|
||||
|
||||
[[routes]]
|
||||
pattern = "claude-api.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
@@ -49,17 +49,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,17 +77,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -77,17 +77,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
*
|
||||
* POST / → JSON input → WASM (WASI preview1 stdin/stdout) → JSON output
|
||||
*
|
||||
* 方案 A:import cypher-executor/src/lib/wasi-shim.ts 的 `createWasiShim`
|
||||
* 提供單一 `http_request` host function(fetch → 回 response body 原文)。
|
||||
* 這個 Worker 不需要 crypto / kv_get(無 credential 解密職責)。
|
||||
*
|
||||
* Credential 注入路徑:cypher-executor auth-dispatcher 會先 POST 到對應 auth primitive Worker,
|
||||
* 把 auth headers 合進本 Worker 的 input(例:`_auth_headers`)。
|
||||
* host function: http_request(fetch → 回 response body 原文)
|
||||
* 此 Worker 不做 credential 注入,只提供通用 HTTP 能力。
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
@@ -57,7 +53,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 忽略 header parse 錯誤
|
||||
// ignore header parse errors
|
||||
}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
@@ -65,7 +61,6 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
// WASM 端直接 json.Unmarshal 回傳內容,這裡回 response body 原文
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
@@ -77,19 +72,11 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
const stderr = shim.getStderr().trim();
|
||||
if (stderr) console.error('[http_request wasm stderr]', stderr);
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
+1539
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-kbdb-create-block",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* arcrun WASM 零件 Worker (kbdb_create_block)
|
||||
* POST / → JSON input → WASM (WASI preview1) → JSON output
|
||||
* SDD: polaris/mira/.agents/specs/mira-app/design.md §6
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
const app = new Hono();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'kbdb_create_block' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: unknown;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
async function runWasm(input: unknown): Promise<unknown> {
|
||||
const hostFunctions: WasiHostFunctions = {
|
||||
http_request: async (url, method, headersJson, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
if (headersJson) {
|
||||
try {
|
||||
const parsed = JSON.parse(headersJson);
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
||||
if (typeof v === 'string') headers[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
|
||||
const shim = createWasiShim(JSON.stringify(input), hostFunctions);
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
const stderr = shim.getStderr().trim();
|
||||
if (stderr) console.error('[kbdb_create_block wasm stderr]', stderr);
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "arcrun-kbdb-create-block"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "kbdb_create_block"
|
||||
|
||||
[[routes]]
|
||||
pattern = "kbdb-create-block.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
+1539
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-kbdb-ingest",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* arcrun WASM 零件 Worker (kbdb_ingest)
|
||||
*
|
||||
* POST / → JSON input → WASM (WASI preview1 stdin/stdout) → JSON output
|
||||
*
|
||||
* host function: http_request(用於呼叫 KBDB API)
|
||||
* SDD: polaris/mira/.agents/specs/mira-app/design.md §6(五個 P0 零件)
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
const app = new Hono();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'kbdb_ingest' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: unknown;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
// ── WASM runner ──────────────────────────────────────────────────────────────
|
||||
|
||||
async function runWasm(input: unknown): Promise<unknown> {
|
||||
const hostFunctions: WasiHostFunctions = {
|
||||
http_request: async (url, method, headersJson, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
if (headersJson) {
|
||||
try {
|
||||
const parsed = JSON.parse(headersJson);
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
||||
if (typeof v === 'string') headers[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore header parse errors
|
||||
}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
|
||||
const shim = createWasiShim(JSON.stringify(input), hostFunctions);
|
||||
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
const stderr = shim.getStderr().trim();
|
||||
if (stderr) console.error('[kbdb_ingest wasm stderr]', stderr);
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "arcrun-kbdb-ingest"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "kbdb_ingest"
|
||||
|
||||
[[routes]]
|
||||
pattern = "kbdb-ingest.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
+1539
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-kbdb-patch-block",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* arcrun WASM 零件 Worker (kbdb_patch_block)
|
||||
*
|
||||
* POST / → JSON input → WASM (WASI preview1 stdin/stdout) → JSON output
|
||||
*
|
||||
* host function: http_request(用於呼叫 KBDB PATCH /blocks/:id)
|
||||
* SDD: polaris/mira/.agents/specs/mira-app/design.md §6(五個 P0 零件)
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
const app = new Hono();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'kbdb_patch_block' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: unknown;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
async function runWasm(input: unknown): Promise<unknown> {
|
||||
const hostFunctions: WasiHostFunctions = {
|
||||
http_request: async (url, method, headersJson, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
if (headersJson) {
|
||||
try {
|
||||
const parsed = JSON.parse(headersJson);
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
||||
if (typeof v === 'string') headers[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore header parse errors
|
||||
}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
|
||||
const shim = createWasiShim(JSON.stringify(input), hostFunctions);
|
||||
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
const stderr = shim.getStderr().trim();
|
||||
if (stderr) console.error('[kbdb_patch_block wasm stderr]', stderr);
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "arcrun-kbdb-patch-block"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "kbdb_patch_block"
|
||||
|
||||
[[routes]]
|
||||
pattern = "kbdb-patch-block.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-km-writer",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
+898
@@ -0,0 +1,898 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
hono:
|
||||
specifier: ^4.7.0
|
||||
version: 4.12.14
|
||||
devDependencies:
|
||||
'@cloudflare/workers-types':
|
||||
specifier: ^4.20250408.0
|
||||
version: 4.20260420.1
|
||||
typescript:
|
||||
specifier: ^5.4.0
|
||||
version: 5.9.3
|
||||
wrangler:
|
||||
specifier: ^4.0.0
|
||||
version: 4.83.0(@cloudflare/workers-types@4.20260420.1)
|
||||
|
||||
packages:
|
||||
|
||||
'@cloudflare/kv-asset-handler@0.4.2':
|
||||
resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@cloudflare/unenv-preset@2.16.0':
|
||||
resolution: {integrity: sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg==}
|
||||
peerDependencies:
|
||||
unenv: 2.0.0-rc.24
|
||||
workerd: 1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0
|
||||
peerDependenciesMeta:
|
||||
workerd:
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-darwin-64@1.20260415.1':
|
||||
resolution: {integrity: sha512-dsxaKsQm3LnPGNPEdsRv09QN3Y4DqCw7kX5j6noKqbAtro2jTr95sVlYM1jUxZ5FkOl1f7SXgaKKB9t5H5Nkbg==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@cloudflare/workerd-darwin-arm64@1.20260415.1':
|
||||
resolution: {integrity: sha512-+JgSgVA49KyKteHRA1SnonE4Zn5Ei5zdAp5FQMxFmXI8qulZw4Hl7safXxRyK4i9sTO8gl7TFOKO5Q64VPvSDQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@cloudflare/workerd-linux-64@1.20260415.1':
|
||||
resolution: {integrity: sha512-tU+9pwsqCy8afOVlGtiWrWQc/fedQK4SRm4KPIAt+zOiQWDxWASm6YGBUJis5c648WN80yz47qnmdDi8DQNOcA==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@cloudflare/workerd-linux-arm64@1.20260415.1':
|
||||
resolution: {integrity: sha512-bR9uITnV19r5NQ14xnypi2xHXu2iQvfYV8cVgx0JouFUmWwTEEAwFVojDdssGq93VHX9hr/pi2IRUZeegbYBog==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@cloudflare/workerd-windows-64@1.20260415.1':
|
||||
resolution: {integrity: sha512-4NuMLlerI0Ijua3Ir8HXQ+qyNvCUDEG5gDco5Om+sAiK6rnWiz+aGoSlbB8W16yW9QAgzCstbmXLiVknUBflfQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@cloudflare/workers-types@4.20260420.1':
|
||||
resolution: {integrity: sha512-DHT9JnSn9cIiCSdL76OxW+Xvc1+ml1CWzWvgVwreoHQ+E604aeFxPPHp9X7nE+XRWm2NH4l0OgtxUI5T/nuI3g==}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@emnapi/runtime@1.10.0':
|
||||
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.27.3':
|
||||
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/android-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.27.3':
|
||||
resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.27.3':
|
||||
resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/darwin-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.27.3':
|
||||
resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/linux-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.27.3':
|
||||
resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.27.3':
|
||||
resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.27.3':
|
||||
resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.27.3':
|
||||
resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.27.3':
|
||||
resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.27.3':
|
||||
resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.27.3':
|
||||
resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.27.3':
|
||||
resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/netbsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/netbsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/openbsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openharmony-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@esbuild/sunos-x64@0.27.3':
|
||||
resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/win32-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.27.3':
|
||||
resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.27.3':
|
||||
resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@img/colour@1.1.0':
|
||||
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5':
|
||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@poppinss/colors@4.1.6':
|
||||
resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==}
|
||||
|
||||
'@poppinss/dumper@0.6.5':
|
||||
resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==}
|
||||
|
||||
'@poppinss/exception@1.2.3':
|
||||
resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==}
|
||||
|
||||
'@sindresorhus/is@7.2.0':
|
||||
resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@speed-highlight/core@1.2.15':
|
||||
resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==}
|
||||
|
||||
blake3-wasm@2.1.5:
|
||||
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
|
||||
|
||||
cookie@1.1.1:
|
||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
error-stack-parser-es@1.0.5:
|
||||
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
|
||||
|
||||
esbuild@0.27.3:
|
||||
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
hono@4.12.14:
|
||||
resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
miniflare@4.20260415.0:
|
||||
resolution: {integrity: sha512-JoExRWN4YBI2luA5BoSMFEgi8rQWXUGzo3mtE+58VXCLV3jj/Xnk5Yeqs/IXWz8Es5GJIaq6BtsixDvAxXSIng==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
path-to-regexp@6.3.0:
|
||||
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
|
||||
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
sharp@0.34.5:
|
||||
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
supports-color@10.2.2:
|
||||
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici@7.24.8:
|
||||
resolution: {integrity: sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
|
||||
unenv@2.0.0-rc.24:
|
||||
resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
|
||||
|
||||
workerd@1.20260415.1:
|
||||
resolution: {integrity: sha512-phyPjRnx+mQDfkhN9ENPioL1L0SdhYs4S0YmJK/xF9Oga+ykNfdSy1MHnsOj8yqnOV96zcVQMx32dJ0r3pq0jQ==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
|
||||
wrangler@4.83.0:
|
||||
resolution: {integrity: sha512-gw5g3LCiuAqVWxaoKY6+quE0HzAUEFb/FV3oAlNkE1ttd4XP3FiV91XDkkzUCcdqxS4WjhQvPhIDBNdhEi8P0A==}
|
||||
engines: {node: '>=20.3.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@cloudflare/workers-types': ^4.20260415.1
|
||||
peerDependenciesMeta:
|
||||
'@cloudflare/workers-types':
|
||||
optional: true
|
||||
|
||||
ws@8.18.0:
|
||||
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
youch-core@0.3.3:
|
||||
resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
|
||||
|
||||
youch@4.1.0-beta.10:
|
||||
resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@cloudflare/kv-asset-handler@0.4.2': {}
|
||||
|
||||
'@cloudflare/unenv-preset@2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260415.1)':
|
||||
dependencies:
|
||||
unenv: 2.0.0-rc.24
|
||||
optionalDependencies:
|
||||
workerd: 1.20260415.1
|
||||
|
||||
'@cloudflare/workerd-darwin-64@1.20260415.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-darwin-arm64@1.20260415.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-linux-64@1.20260415.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-linux-arm64@1.20260415.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-windows-64@1.20260415.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workers-types@4.20260420.1': {}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@emnapi/runtime@1.10.0':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@esbuild/aix-ppc64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openharmony-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@img/colour@1.1.0': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.10.0
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@poppinss/colors@4.1.6':
|
||||
dependencies:
|
||||
kleur: 4.1.5
|
||||
|
||||
'@poppinss/dumper@0.6.5':
|
||||
dependencies:
|
||||
'@poppinss/colors': 4.1.6
|
||||
'@sindresorhus/is': 7.2.0
|
||||
supports-color: 10.2.2
|
||||
|
||||
'@poppinss/exception@1.2.3': {}
|
||||
|
||||
'@sindresorhus/is@7.2.0': {}
|
||||
|
||||
'@speed-highlight/core@1.2.15': {}
|
||||
|
||||
blake3-wasm@2.1.5: {}
|
||||
|
||||
cookie@1.1.1: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
error-stack-parser-es@1.0.5: {}
|
||||
|
||||
esbuild@0.27.3:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.27.3
|
||||
'@esbuild/android-arm': 0.27.3
|
||||
'@esbuild/android-arm64': 0.27.3
|
||||
'@esbuild/android-x64': 0.27.3
|
||||
'@esbuild/darwin-arm64': 0.27.3
|
||||
'@esbuild/darwin-x64': 0.27.3
|
||||
'@esbuild/freebsd-arm64': 0.27.3
|
||||
'@esbuild/freebsd-x64': 0.27.3
|
||||
'@esbuild/linux-arm': 0.27.3
|
||||
'@esbuild/linux-arm64': 0.27.3
|
||||
'@esbuild/linux-ia32': 0.27.3
|
||||
'@esbuild/linux-loong64': 0.27.3
|
||||
'@esbuild/linux-mips64el': 0.27.3
|
||||
'@esbuild/linux-ppc64': 0.27.3
|
||||
'@esbuild/linux-riscv64': 0.27.3
|
||||
'@esbuild/linux-s390x': 0.27.3
|
||||
'@esbuild/linux-x64': 0.27.3
|
||||
'@esbuild/netbsd-arm64': 0.27.3
|
||||
'@esbuild/netbsd-x64': 0.27.3
|
||||
'@esbuild/openbsd-arm64': 0.27.3
|
||||
'@esbuild/openbsd-x64': 0.27.3
|
||||
'@esbuild/openharmony-arm64': 0.27.3
|
||||
'@esbuild/sunos-x64': 0.27.3
|
||||
'@esbuild/win32-arm64': 0.27.3
|
||||
'@esbuild/win32-ia32': 0.27.3
|
||||
'@esbuild/win32-x64': 0.27.3
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
hono@4.12.14: {}
|
||||
|
||||
kleur@4.1.5: {}
|
||||
|
||||
miniflare@4.20260415.0:
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
sharp: 0.34.5
|
||||
undici: 7.24.8
|
||||
workerd: 1.20260415.1
|
||||
ws: 8.18.0
|
||||
youch: 4.1.0-beta.10
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
path-to-regexp@6.3.0: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
|
||||
sharp@0.34.5:
|
||||
dependencies:
|
||||
'@img/colour': 1.1.0
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.4
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.5
|
||||
'@img/sharp-darwin-x64': 0.34.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
'@img/sharp-linux-arm': 0.34.5
|
||||
'@img/sharp-linux-arm64': 0.34.5
|
||||
'@img/sharp-linux-ppc64': 0.34.5
|
||||
'@img/sharp-linux-riscv64': 0.34.5
|
||||
'@img/sharp-linux-s390x': 0.34.5
|
||||
'@img/sharp-linux-x64': 0.34.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||
'@img/sharp-wasm32': 0.34.5
|
||||
'@img/sharp-win32-arm64': 0.34.5
|
||||
'@img/sharp-win32-ia32': 0.34.5
|
||||
'@img/sharp-win32-x64': 0.34.5
|
||||
|
||||
supports-color@10.2.2: {}
|
||||
|
||||
tslib@2.8.1:
|
||||
optional: true
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
undici@7.24.8: {}
|
||||
|
||||
unenv@2.0.0-rc.24:
|
||||
dependencies:
|
||||
pathe: 2.0.3
|
||||
|
||||
workerd@1.20260415.1:
|
||||
optionalDependencies:
|
||||
'@cloudflare/workerd-darwin-64': 1.20260415.1
|
||||
'@cloudflare/workerd-darwin-arm64': 1.20260415.1
|
||||
'@cloudflare/workerd-linux-64': 1.20260415.1
|
||||
'@cloudflare/workerd-linux-arm64': 1.20260415.1
|
||||
'@cloudflare/workerd-windows-64': 1.20260415.1
|
||||
|
||||
wrangler@4.83.0(@cloudflare/workers-types@4.20260420.1):
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.4.2
|
||||
'@cloudflare/unenv-preset': 2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260415.1)
|
||||
blake3-wasm: 2.1.5
|
||||
esbuild: 0.27.3
|
||||
miniflare: 4.20260415.0
|
||||
path-to-regexp: 6.3.0
|
||||
unenv: 2.0.0-rc.24
|
||||
workerd: 1.20260415.1
|
||||
optionalDependencies:
|
||||
'@cloudflare/workers-types': 4.20260420.1
|
||||
fsevents: 2.3.3
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
ws@8.18.0: {}
|
||||
|
||||
youch-core@0.3.3:
|
||||
dependencies:
|
||||
'@poppinss/exception': 1.2.3
|
||||
error-stack-parser-es: 1.0.5
|
||||
|
||||
youch@4.1.0-beta.10:
|
||||
dependencies:
|
||||
'@poppinss/colors': 4.1.6
|
||||
'@poppinss/dumper': 0.6.5
|
||||
'@speed-highlight/core': 1.2.15
|
||||
cookie: 1.1.1
|
||||
youch-core: 0.3.3
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* arcrun API component Worker (km_writer)
|
||||
*
|
||||
* POST / → JSON input → WASM (WASI preview1 stdin/stdout) → JSON output
|
||||
*
|
||||
* 提供 http_request host function,讓 WASM 零件呼叫 Mira /km/* API。
|
||||
*/
|
||||
|
||||
import componentWasm from '../component.wasm' assert { type: 'webassembly' };
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';
|
||||
|
||||
const app = new Hono();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'km_writer' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: unknown;
|
||||
try {
|
||||
input = await c.req.json();
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await runWasm(input);
|
||||
return c.json(result);
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
async function runWasm(input: unknown): Promise<unknown> {
|
||||
const hostFunctions: WasiHostFunctions = {
|
||||
http_request: async (url, method, headersJson, body) => {
|
||||
const headers: Record<string, string> = {};
|
||||
if (headersJson) {
|
||||
try {
|
||||
const parsed = JSON.parse(headersJson);
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
|
||||
if (typeof v === 'string') headers[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore header parse errors
|
||||
}
|
||||
}
|
||||
const init: RequestInit = { method, headers };
|
||||
if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
|
||||
init.body = body;
|
||||
}
|
||||
const res = await fetch(url, init);
|
||||
return await res.text();
|
||||
},
|
||||
};
|
||||
|
||||
const shim = createWasiShim(JSON.stringify(input), hostFunctions);
|
||||
|
||||
const instance = await WebAssembly.instantiate(
|
||||
componentWasm as WebAssembly.Module,
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "arcrun-km-writer"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "km_writer"
|
||||
|
||||
[[routes]]
|
||||
pattern = "km-writer.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
@@ -77,17 +77,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "arcrun-platform-crypto",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"hono": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250408.0",
|
||||
"typescript": "^5.4.0",
|
||||
"wrangler": "^4.0.0"
|
||||
}
|
||||
}
|
||||
+898
@@ -0,0 +1,898 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
hono:
|
||||
specifier: ^4.7.0
|
||||
version: 4.12.17
|
||||
devDependencies:
|
||||
'@cloudflare/workers-types':
|
||||
specifier: ^4.20250408.0
|
||||
version: 4.20260505.1
|
||||
typescript:
|
||||
specifier: ^5.4.0
|
||||
version: 5.9.3
|
||||
wrangler:
|
||||
specifier: ^4.0.0
|
||||
version: 4.87.0(@cloudflare/workers-types@4.20260505.1)
|
||||
|
||||
packages:
|
||||
|
||||
'@cloudflare/kv-asset-handler@0.5.0':
|
||||
resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==}
|
||||
engines: {node: '>=22.0.0'}
|
||||
|
||||
'@cloudflare/unenv-preset@2.16.1':
|
||||
resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==}
|
||||
peerDependencies:
|
||||
unenv: 2.0.0-rc.24
|
||||
workerd: '>1.20260305.0 <2.0.0-0'
|
||||
peerDependenciesMeta:
|
||||
workerd:
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-darwin-64@1.20260430.1':
|
||||
resolution: {integrity: sha512-ADohZUHf7NBvPp2PdZig2Opxx+hDkk3ve7jrTne3JRx9kDSB73zc4LzcEeEN8LKkbAcqZmvfRJfpChSlusu0lA==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@cloudflare/workerd-darwin-arm64@1.20260430.1':
|
||||
resolution: {integrity: sha512-/DoYC/1wHs+YRZzzqSQg1/EHB4hiv1yV5U8FnmapRRIzVaPtnt+ApeOXeMrIdKidgKOI8TqQzgBU8xbIM7Cl4Q==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@cloudflare/workerd-linux-64@1.20260430.1':
|
||||
resolution: {integrity: sha512-koJhBWvEVZPKCVFtMLp2iMHlYr+lFCF47wGbnlKdHVlemV0zTxJEyHI8aLlrhPLhBmOmYLp46rXw09/qJkRIhQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@cloudflare/workerd-linux-arm64@1.20260430.1':
|
||||
resolution: {integrity: sha512-hMdapNAzNQZDXGGkg4Slydc3fRJP5FUZLJVVcZCW/+imhhJro9Z1rv5n/wfR+txKoSWhTYR8eOp8Pyi2bzLzlw==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@cloudflare/workerd-windows-64@1.20260430.1':
|
||||
resolution: {integrity: sha512-jS3ffixjb5USOwz4frw4WzCz0HrjVxkgyU3WiYb06N7hBAfN6eOrveAJ4QRef0+suK4V1vQFoB1oKdRBsXe9Dw==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@cloudflare/workers-types@4.20260505.1':
|
||||
resolution: {integrity: sha512-Uz9D2hcwB4/pdnmCU7RsgknY8TQ5st0cQMMN6h/hvWt1TCt99GUkbi6dMgWdP7jXfIfh+S/EI5zQugI9RZn4Bw==}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@emnapi/runtime@1.10.0':
|
||||
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.27.3':
|
||||
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/android-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.27.3':
|
||||
resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.27.3':
|
||||
resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/darwin-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.27.3':
|
||||
resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/linux-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.27.3':
|
||||
resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.27.3':
|
||||
resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.27.3':
|
||||
resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.27.3':
|
||||
resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.27.3':
|
||||
resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.27.3':
|
||||
resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.27.3':
|
||||
resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.27.3':
|
||||
resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/netbsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/netbsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/openbsd-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.27.3':
|
||||
resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openharmony-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@esbuild/sunos-x64@0.27.3':
|
||||
resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/win32-arm64@0.27.3':
|
||||
resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.27.3':
|
||||
resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.27.3':
|
||||
resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@img/colour@1.1.0':
|
||||
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5':
|
||||
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@poppinss/colors@4.1.6':
|
||||
resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==}
|
||||
|
||||
'@poppinss/dumper@0.6.5':
|
||||
resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==}
|
||||
|
||||
'@poppinss/exception@1.2.3':
|
||||
resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==}
|
||||
|
||||
'@sindresorhus/is@7.2.0':
|
||||
resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@speed-highlight/core@1.2.15':
|
||||
resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==}
|
||||
|
||||
blake3-wasm@2.1.5:
|
||||
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
|
||||
|
||||
cookie@1.1.1:
|
||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
error-stack-parser-es@1.0.5:
|
||||
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
|
||||
|
||||
esbuild@0.27.3:
|
||||
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
hono@4.12.17:
|
||||
resolution: {integrity: sha512-FbJJNb/XgX7YW0hX/V8w5oYLztKEsRLykCMZWt1WdLtsfjzMvmoqWBA4H4t5norinq8/rh20oiZYr+WSl4UzAQ==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
miniflare@4.20260430.0:
|
||||
resolution: {integrity: sha512-MWvMm3Siho9Yj7lbJZidLs8hbrRvIcOrif2mnsHQZdvoKfedpea+GaN8XJxbpRcq0B2WzNI1BB1ihdnqes3/ZA==}
|
||||
engines: {node: '>=22.0.0'}
|
||||
hasBin: true
|
||||
|
||||
path-to-regexp@6.3.0:
|
||||
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
|
||||
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
sharp@0.34.5:
|
||||
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
supports-color@10.2.2:
|
||||
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici@7.24.8:
|
||||
resolution: {integrity: sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
|
||||
unenv@2.0.0-rc.24:
|
||||
resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
|
||||
|
||||
workerd@1.20260430.1:
|
||||
resolution: {integrity: sha512-KEgIWyiw3Jmn+DCd/L3ePo5fmiiYb/UcwKvDWPf/nLLOiwShDFzDSsegU5NY/JcwgvO/QsLHVi2FYrbkcXNY5Q==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
|
||||
wrangler@4.87.0:
|
||||
resolution: {integrity: sha512-lfhfKwLfQlowwgV0xhlYgE9fU3n0I30d4ccGY/rTCEm/n42Mjvlr0Ng3ZPNqlsrsKBcDR531V7dsPkgELvrk/Q==}
|
||||
engines: {node: '>=22.0.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@cloudflare/workers-types': ^4.20260430.1
|
||||
peerDependenciesMeta:
|
||||
'@cloudflare/workers-types':
|
||||
optional: true
|
||||
|
||||
ws@8.18.0:
|
||||
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
youch-core@0.3.3:
|
||||
resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
|
||||
|
||||
youch@4.1.0-beta.10:
|
||||
resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@cloudflare/kv-asset-handler@0.5.0': {}
|
||||
|
||||
'@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260430.1)':
|
||||
dependencies:
|
||||
unenv: 2.0.0-rc.24
|
||||
optionalDependencies:
|
||||
workerd: 1.20260430.1
|
||||
|
||||
'@cloudflare/workerd-darwin-64@1.20260430.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-darwin-arm64@1.20260430.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-linux-64@1.20260430.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-linux-arm64@1.20260430.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workerd-windows-64@1.20260430.1':
|
||||
optional: true
|
||||
|
||||
'@cloudflare/workers-types@4.20260505.1': {}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@emnapi/runtime@1.10.0':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@esbuild/aix-ppc64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openharmony-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@img/colour@1.1.0': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.10.0
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@poppinss/colors@4.1.6':
|
||||
dependencies:
|
||||
kleur: 4.1.5
|
||||
|
||||
'@poppinss/dumper@0.6.5':
|
||||
dependencies:
|
||||
'@poppinss/colors': 4.1.6
|
||||
'@sindresorhus/is': 7.2.0
|
||||
supports-color: 10.2.2
|
||||
|
||||
'@poppinss/exception@1.2.3': {}
|
||||
|
||||
'@sindresorhus/is@7.2.0': {}
|
||||
|
||||
'@speed-highlight/core@1.2.15': {}
|
||||
|
||||
blake3-wasm@2.1.5: {}
|
||||
|
||||
cookie@1.1.1: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
error-stack-parser-es@1.0.5: {}
|
||||
|
||||
esbuild@0.27.3:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.27.3
|
||||
'@esbuild/android-arm': 0.27.3
|
||||
'@esbuild/android-arm64': 0.27.3
|
||||
'@esbuild/android-x64': 0.27.3
|
||||
'@esbuild/darwin-arm64': 0.27.3
|
||||
'@esbuild/darwin-x64': 0.27.3
|
||||
'@esbuild/freebsd-arm64': 0.27.3
|
||||
'@esbuild/freebsd-x64': 0.27.3
|
||||
'@esbuild/linux-arm': 0.27.3
|
||||
'@esbuild/linux-arm64': 0.27.3
|
||||
'@esbuild/linux-ia32': 0.27.3
|
||||
'@esbuild/linux-loong64': 0.27.3
|
||||
'@esbuild/linux-mips64el': 0.27.3
|
||||
'@esbuild/linux-ppc64': 0.27.3
|
||||
'@esbuild/linux-riscv64': 0.27.3
|
||||
'@esbuild/linux-s390x': 0.27.3
|
||||
'@esbuild/linux-x64': 0.27.3
|
||||
'@esbuild/netbsd-arm64': 0.27.3
|
||||
'@esbuild/netbsd-x64': 0.27.3
|
||||
'@esbuild/openbsd-arm64': 0.27.3
|
||||
'@esbuild/openbsd-x64': 0.27.3
|
||||
'@esbuild/openharmony-arm64': 0.27.3
|
||||
'@esbuild/sunos-x64': 0.27.3
|
||||
'@esbuild/win32-arm64': 0.27.3
|
||||
'@esbuild/win32-ia32': 0.27.3
|
||||
'@esbuild/win32-x64': 0.27.3
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
hono@4.12.17: {}
|
||||
|
||||
kleur@4.1.5: {}
|
||||
|
||||
miniflare@4.20260430.0:
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
sharp: 0.34.5
|
||||
undici: 7.24.8
|
||||
workerd: 1.20260430.1
|
||||
ws: 8.18.0
|
||||
youch: 4.1.0-beta.10
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
path-to-regexp@6.3.0: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
|
||||
sharp@0.34.5:
|
||||
dependencies:
|
||||
'@img/colour': 1.1.0
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.4
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.5
|
||||
'@img/sharp-darwin-x64': 0.34.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
'@img/sharp-linux-arm': 0.34.5
|
||||
'@img/sharp-linux-arm64': 0.34.5
|
||||
'@img/sharp-linux-ppc64': 0.34.5
|
||||
'@img/sharp-linux-riscv64': 0.34.5
|
||||
'@img/sharp-linux-s390x': 0.34.5
|
||||
'@img/sharp-linux-x64': 0.34.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||
'@img/sharp-wasm32': 0.34.5
|
||||
'@img/sharp-win32-arm64': 0.34.5
|
||||
'@img/sharp-win32-ia32': 0.34.5
|
||||
'@img/sharp-win32-x64': 0.34.5
|
||||
|
||||
supports-color@10.2.2: {}
|
||||
|
||||
tslib@2.8.1:
|
||||
optional: true
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
undici@7.24.8: {}
|
||||
|
||||
unenv@2.0.0-rc.24:
|
||||
dependencies:
|
||||
pathe: 2.0.3
|
||||
|
||||
workerd@1.20260430.1:
|
||||
optionalDependencies:
|
||||
'@cloudflare/workerd-darwin-64': 1.20260430.1
|
||||
'@cloudflare/workerd-darwin-arm64': 1.20260430.1
|
||||
'@cloudflare/workerd-linux-64': 1.20260430.1
|
||||
'@cloudflare/workerd-linux-arm64': 1.20260430.1
|
||||
'@cloudflare/workerd-windows-64': 1.20260430.1
|
||||
|
||||
wrangler@4.87.0(@cloudflare/workers-types@4.20260505.1):
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.5.0
|
||||
'@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260430.1)
|
||||
blake3-wasm: 2.1.5
|
||||
esbuild: 0.27.3
|
||||
miniflare: 4.20260430.0
|
||||
path-to-regexp: 6.3.0
|
||||
unenv: 2.0.0-rc.24
|
||||
workerd: 1.20260430.1
|
||||
optionalDependencies:
|
||||
'@cloudflare/workers-types': 4.20260505.1
|
||||
fsevents: 2.3.3
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
ws@8.18.0: {}
|
||||
|
||||
youch-core@0.3.3:
|
||||
dependencies:
|
||||
'@poppinss/exception': 1.2.3
|
||||
error-stack-parser-es: 1.0.5
|
||||
|
||||
youch@4.1.0-beta.10:
|
||||
dependencies:
|
||||
'@poppinss/colors': 4.1.6
|
||||
'@poppinss/dumper': 0.6.5
|
||||
'@speed-highlight/core': 1.2.15
|
||||
cookie: 1.1.1
|
||||
youch-core: 0.3.3
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* arcrun platform_crypto Worker
|
||||
*
|
||||
* POST / → JSON input {action, ...} → JSON output
|
||||
*
|
||||
* Actions:
|
||||
* generate_api_key — HMAC-SHA256(email, ENCRYPTION_KEY) → ak_{hex[:32]}
|
||||
* encrypt — AES-GCM(plaintext, ENCRYPTION_KEY) → {encrypted, iv}(base64)
|
||||
* random_token — crypto random bytes → hex string
|
||||
*
|
||||
* 安全邊界:ENCRYPTION_KEY 只存在於 closure,永不進入外部(rule 02 §2.2)。
|
||||
* 此 Worker 直接用 crypto.subtle 實作,不走 WASM runner。
|
||||
* TinyGo WASM async host function 在 Cloudflare Workers 的 u6u namespace 不支援 Promise.
|
||||
* WASM 零件 (registry/components/platform_crypto/) 保留作為 edge-Go 移植時的參考。
|
||||
*/
|
||||
|
||||
import { Hono } from 'hono';
|
||||
import { cors } from 'hono/cors';
|
||||
|
||||
type Env = {
|
||||
ENCRYPTION_KEY: string;
|
||||
};
|
||||
|
||||
type Input = {
|
||||
action: string;
|
||||
email?: string;
|
||||
plaintext?: string;
|
||||
bytes?: number;
|
||||
};
|
||||
|
||||
const app = new Hono<{ Bindings: Env }>();
|
||||
app.use('*', cors());
|
||||
|
||||
app.get('/', (c) => c.json({ ok: true, component: 'platform_crypto' }));
|
||||
|
||||
app.post('/', async (c) => {
|
||||
let input: Input;
|
||||
try {
|
||||
input = await c.req.json() as Input;
|
||||
} catch {
|
||||
return c.json({ success: false, error: 'request body must be JSON' }, 400);
|
||||
}
|
||||
|
||||
const encryptionKey = c.env.ENCRYPTION_KEY;
|
||||
if (!encryptionKey) {
|
||||
return c.json({ success: false, error: 'ENCRYPTION_KEY not configured' }, 503);
|
||||
}
|
||||
|
||||
try {
|
||||
switch (input.action) {
|
||||
case 'generate_api_key': {
|
||||
if (!input.email) return c.json({ success: false, error: 'email 必填' }, 400);
|
||||
const apiKey = await generateApiKey(input.email, encryptionKey);
|
||||
return c.json({ success: true, api_key: apiKey });
|
||||
}
|
||||
case 'encrypt': {
|
||||
if (!input.plaintext) return c.json({ success: false, error: 'plaintext 必填' }, 400);
|
||||
const { encrypted, iv } = await aesEncrypt(input.plaintext, encryptionKey);
|
||||
return c.json({ success: true, encrypted, iv });
|
||||
}
|
||||
case 'random_token': {
|
||||
const numBytes = (input.bytes ?? 32) > 0 ? (input.bytes ?? 32) : 32;
|
||||
const token = randomHex(numBytes);
|
||||
return c.json({ success: true, token });
|
||||
}
|
||||
default:
|
||||
return c.json({ success: false, error: `不支援的 action: ${input.action}` }, 400);
|
||||
}
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ success: false, error: e instanceof Error ? e.message : String(e) },
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
// ── Crypto implementations (rule 02 §2.2: crypto.subtle 只准在 wasi-shim.ts 或 platform_crypto) ──
|
||||
|
||||
async function generateApiKey(email: string, encryptionKey: string): Promise<string> {
|
||||
const keyBytes = new TextEncoder().encode(encryptionKey.slice(0, 32));
|
||||
const cryptoKey = await crypto.subtle.importKey(
|
||||
'raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'],
|
||||
);
|
||||
const sig = await crypto.subtle.sign('HMAC', cryptoKey, new TextEncoder().encode(email));
|
||||
const hex = Array.from(new Uint8Array(sig)).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
return 'ak_' + hex.slice(0, 32);
|
||||
}
|
||||
|
||||
async function aesEncrypt(plaintext: string, encryptionKey: string): Promise<{ encrypted: string; iv: string }> {
|
||||
const keyBytes = new TextEncoder().encode(encryptionKey.slice(0, 32));
|
||||
const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt']);
|
||||
const iv = crypto.getRandomValues(new Uint8Array(12));
|
||||
const enc = await crypto.subtle.encrypt(
|
||||
{ name: 'AES-GCM', iv },
|
||||
cryptoKey,
|
||||
new TextEncoder().encode(plaintext),
|
||||
);
|
||||
const toB64 = (buf: ArrayBuffer | Uint8Array) =>
|
||||
btoa(String.fromCharCode(...new Uint8Array(buf instanceof ArrayBuffer ? buf : buf)));
|
||||
return { encrypted: toB64(enc), iv: toB64(iv) };
|
||||
}
|
||||
|
||||
function randomHex(numBytes: number): string {
|
||||
const arr = crypto.getRandomValues(new Uint8Array(numBytes));
|
||||
return Array.from(arr).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"strict": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
name = "arcrun-platform-crypto"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2025-02-19"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
COMPONENT_ID = "platform_crypto"
|
||||
|
||||
[[routes]]
|
||||
pattern = "platform-crypto.arcrun.dev/*"
|
||||
zone_name = "arcrun.dev"
|
||||
|
||||
# ENCRYPTION_KEY 透過 wrangler secret set 設定
|
||||
# wrangler secret put ENCRYPTION_KEY
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,17 +77,7 @@ async function runWasm(input: unknown): Promise<unknown> {
|
||||
shim.imports,
|
||||
);
|
||||
shim.setMemory(instance.exports.memory as WebAssembly.Memory);
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') {
|
||||
throw new Error('WASM missing _start or main export');
|
||||
}
|
||||
|
||||
try {
|
||||
start();
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
await shim.run(instance);
|
||||
|
||||
const stdout = shim.getStdout().trim();
|
||||
if (!stdout) throw new Error('WASM component produced no output');
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@ async function runWasm(wasmModule: WebAssembly.Module, input: unknown): Promise<
|
||||
const instance = await WebAssembly.instantiate(wasmModule, wasi);
|
||||
memory = instance.exports.memory as WebAssembly.Memory;
|
||||
|
||||
const start = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof start !== 'function') throw new Error('WASM missing _start or main export');
|
||||
|
||||
try { start(); } catch (e) {
|
||||
const promising = (WebAssembly as unknown as Record<string, unknown>)['promising'] as
|
||||
((fn: () => void) => () => Promise<void>) | undefined;
|
||||
const startFn = (instance.exports._start ?? instance.exports.main) as () => void;
|
||||
if (typeof startFn !== 'function') throw new Error('WASM missing _start or main export');
|
||||
try {
|
||||
if (promising) { await promising(startFn)(); } else { startFn(); }
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error && e.message === 'wasm exit: 0')) throw e;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user