Files
arcrun-rag-bundles-staging/tier2/kbdb/index.js
T
Leo 94eb298c17 batch step3/4/5/6 全量重生(Arcrun@eefbed9):步驟5 引擎條件邊+recipe 三層
來源=Arcrun `batch/step3456-20260801`(eefbed9)=step3 最前緣(已含 step4+step6+
t158-t162)合入 step5。**先合流再打包**(bundle 是 worker 粒度,三步同一顆 cypher,
分開建會讓 stage 只拿到一步——08-01 那個坑)。

cypher 產物指紋(步驟5 新增,實查):
  ON_BRANCH 13/ON_TRUE 9/ON_FALSE 11/branch_hint 4
  body_template 8/response_map 8/binding_name 4
步驟3/4/6 迴歸指紋(不得歸零,實查全在):
  trySubstitution 3/input_schema 6/not_found 5/suggestion 2/success_rate 4/bundle_version 1
mcp 教材世代更新:「引擎不支援條件分支」字串歸 0,換成三型分支寫法+branch_hint 指路。

保留未動(本建置腳本不產這兩顆):tier1/code、tier2/ui、daemon 段(仍 v0.15.0,
這批不含新小幫手,leo 不必重下載)。core 條目維持 24。

順手清掉既存污染:上一版 staging 的 tier1/*/index.js 內含建置機器的絕對路徑
(`/Users/youlinhsieh/...`,19 檔命中)=前次以 symlink node_modules 打包的殘留;
本次改為實體複製 node_modules 後重建,路徑回正常相對形式,命中歸 0。
⚠️ 僅 `tier1/code/index.js` 仍有(該檔本腳本不重建、本次未動),留給產它的那條線處理。
2026-07-31 17:05:46 +08:00

4017 lines
125 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/_internal/utils.mjs
// @__NO_SIDE_EFFECTS__
function createNotImplementedError(name) {
return new Error(`[unenv] ${name} is not implemented yet!`);
}
__name(createNotImplementedError, "createNotImplementedError");
// @__NO_SIDE_EFFECTS__
function notImplemented(name) {
const fn = /* @__PURE__ */ __name(() => {
throw /* @__PURE__ */ createNotImplementedError(name);
}, "fn");
return Object.assign(fn, { __unenv__: true });
}
__name(notImplemented, "notImplemented");
// @__NO_SIDE_EFFECTS__
function notImplementedClass(name) {
return class {
__unenv__ = true;
constructor() {
throw new Error(`[unenv] ${name} is not implemented yet!`);
}
};
}
__name(notImplementedClass, "notImplementedClass");
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/perf_hooks/performance.mjs
var _timeOrigin = globalThis.performance?.timeOrigin ?? Date.now();
var _performanceNow = globalThis.performance?.now ? globalThis.performance.now.bind(globalThis.performance) : () => Date.now() - _timeOrigin;
var nodeTiming = {
name: "node",
entryType: "node",
startTime: 0,
duration: 0,
nodeStart: 0,
v8Start: 0,
bootstrapComplete: 0,
environment: 0,
loopStart: 0,
loopExit: 0,
idleTime: 0,
uvMetricsInfo: {
loopCount: 0,
events: 0,
eventsWaiting: 0
},
detail: void 0,
toJSON() {
return this;
}
};
var PerformanceEntry = class {
static {
__name(this, "PerformanceEntry");
}
__unenv__ = true;
detail;
entryType = "event";
name;
startTime;
constructor(name, options) {
this.name = name;
this.startTime = options?.startTime || _performanceNow();
this.detail = options?.detail;
}
get duration() {
return _performanceNow() - this.startTime;
}
toJSON() {
return {
name: this.name,
entryType: this.entryType,
startTime: this.startTime,
duration: this.duration,
detail: this.detail
};
}
};
var PerformanceMark = class PerformanceMark2 extends PerformanceEntry {
static {
__name(this, "PerformanceMark");
}
entryType = "mark";
constructor() {
super(...arguments);
}
get duration() {
return 0;
}
};
var PerformanceMeasure = class extends PerformanceEntry {
static {
__name(this, "PerformanceMeasure");
}
entryType = "measure";
};
var PerformanceResourceTiming = class extends PerformanceEntry {
static {
__name(this, "PerformanceResourceTiming");
}
entryType = "resource";
serverTiming = [];
connectEnd = 0;
connectStart = 0;
decodedBodySize = 0;
domainLookupEnd = 0;
domainLookupStart = 0;
encodedBodySize = 0;
fetchStart = 0;
initiatorType = "";
name = "";
nextHopProtocol = "";
redirectEnd = 0;
redirectStart = 0;
requestStart = 0;
responseEnd = 0;
responseStart = 0;
secureConnectionStart = 0;
startTime = 0;
transferSize = 0;
workerStart = 0;
responseStatus = 0;
};
var PerformanceObserverEntryList = class {
static {
__name(this, "PerformanceObserverEntryList");
}
__unenv__ = true;
getEntries() {
return [];
}
getEntriesByName(_name, _type) {
return [];
}
getEntriesByType(type) {
return [];
}
};
var Performance = class {
static {
__name(this, "Performance");
}
__unenv__ = true;
timeOrigin = _timeOrigin;
eventCounts = /* @__PURE__ */ new Map();
_entries = [];
_resourceTimingBufferSize = 0;
navigation = void 0;
timing = void 0;
timerify(_fn, _options) {
throw createNotImplementedError("Performance.timerify");
}
get nodeTiming() {
return nodeTiming;
}
eventLoopUtilization() {
return {};
}
markResourceTiming() {
return new PerformanceResourceTiming("");
}
onresourcetimingbufferfull = null;
now() {
if (this.timeOrigin === _timeOrigin) {
return _performanceNow();
}
return Date.now() - this.timeOrigin;
}
clearMarks(markName) {
this._entries = markName ? this._entries.filter((e) => e.name !== markName) : this._entries.filter((e) => e.entryType !== "mark");
}
clearMeasures(measureName) {
this._entries = measureName ? this._entries.filter((e) => e.name !== measureName) : this._entries.filter((e) => e.entryType !== "measure");
}
clearResourceTimings() {
this._entries = this._entries.filter((e) => e.entryType !== "resource" || e.entryType !== "navigation");
}
getEntries() {
return this._entries;
}
getEntriesByName(name, type) {
return this._entries.filter((e) => e.name === name && (!type || e.entryType === type));
}
getEntriesByType(type) {
return this._entries.filter((e) => e.entryType === type);
}
mark(name, options) {
const entry = new PerformanceMark(name, options);
this._entries.push(entry);
return entry;
}
measure(measureName, startOrMeasureOptions, endMark) {
let start;
let end;
if (typeof startOrMeasureOptions === "string") {
start = this.getEntriesByName(startOrMeasureOptions, "mark")[0]?.startTime;
end = this.getEntriesByName(endMark, "mark")[0]?.startTime;
} else {
start = Number.parseFloat(startOrMeasureOptions?.start) || this.now();
end = Number.parseFloat(startOrMeasureOptions?.end) || this.now();
}
const entry = new PerformanceMeasure(measureName, {
startTime: start,
detail: {
start,
end
}
});
this._entries.push(entry);
return entry;
}
setResourceTimingBufferSize(maxSize) {
this._resourceTimingBufferSize = maxSize;
}
addEventListener(type, listener, options) {
throw createNotImplementedError("Performance.addEventListener");
}
removeEventListener(type, listener, options) {
throw createNotImplementedError("Performance.removeEventListener");
}
dispatchEvent(event) {
throw createNotImplementedError("Performance.dispatchEvent");
}
toJSON() {
return this;
}
};
var PerformanceObserver = class {
static {
__name(this, "PerformanceObserver");
}
__unenv__ = true;
static supportedEntryTypes = [];
_callback = null;
constructor(callback) {
this._callback = callback;
}
takeRecords() {
return [];
}
disconnect() {
throw createNotImplementedError("PerformanceObserver.disconnect");
}
observe(options) {
throw createNotImplementedError("PerformanceObserver.observe");
}
bind(fn) {
return fn;
}
runInAsyncScope(fn, thisArg, ...args) {
return fn.call(thisArg, ...args);
}
asyncId() {
return 0;
}
triggerAsyncId() {
return 0;
}
emitDestroy() {
return this;
}
};
var performance = globalThis.performance && "addEventListener" in globalThis.performance ? globalThis.performance : new Performance();
// node_modules/.pnpm/@cloudflare+unenv-preset@2.16.1_unenv@2.0.0-rc.24_workerd@1.20260603.1/node_modules/@cloudflare/unenv-preset/dist/runtime/polyfill/performance.mjs
if (!("__unenv__" in performance)) {
const proto = Performance.prototype;
for (const key of Object.getOwnPropertyNames(proto)) {
if (key !== "constructor" && !(key in performance)) {
const desc = Object.getOwnPropertyDescriptor(proto, key);
if (desc) {
Object.defineProperty(performance, key, desc);
}
}
}
}
globalThis.performance = performance;
globalThis.Performance = Performance;
globalThis.PerformanceEntry = PerformanceEntry;
globalThis.PerformanceMark = PerformanceMark;
globalThis.PerformanceMeasure = PerformanceMeasure;
globalThis.PerformanceObserver = PerformanceObserver;
globalThis.PerformanceObserverEntryList = PerformanceObserverEntryList;
globalThis.PerformanceResourceTiming = PerformanceResourceTiming;
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/console.mjs
import { Writable } from "node:stream";
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/mock/noop.mjs
var noop_default = Object.assign(() => {
}, { __unenv__: true });
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/console.mjs
var _console = globalThis.console;
var _ignoreErrors = true;
var _stderr = new Writable();
var _stdout = new Writable();
var log = _console?.log ?? noop_default;
var info = _console?.info ?? log;
var trace = _console?.trace ?? info;
var debug = _console?.debug ?? log;
var table = _console?.table ?? log;
var error = _console?.error ?? log;
var warn = _console?.warn ?? error;
var createTask = _console?.createTask ?? /* @__PURE__ */ notImplemented("console.createTask");
var clear = _console?.clear ?? noop_default;
var count = _console?.count ?? noop_default;
var countReset = _console?.countReset ?? noop_default;
var dir = _console?.dir ?? noop_default;
var dirxml = _console?.dirxml ?? noop_default;
var group = _console?.group ?? noop_default;
var groupEnd = _console?.groupEnd ?? noop_default;
var groupCollapsed = _console?.groupCollapsed ?? noop_default;
var profile = _console?.profile ?? noop_default;
var profileEnd = _console?.profileEnd ?? noop_default;
var time = _console?.time ?? noop_default;
var timeEnd = _console?.timeEnd ?? noop_default;
var timeLog = _console?.timeLog ?? noop_default;
var timeStamp = _console?.timeStamp ?? noop_default;
var Console = _console?.Console ?? /* @__PURE__ */ notImplementedClass("console.Console");
var _times = /* @__PURE__ */ new Map();
var _stdoutErrorHandler = noop_default;
var _stderrErrorHandler = noop_default;
// node_modules/.pnpm/@cloudflare+unenv-preset@2.16.1_unenv@2.0.0-rc.24_workerd@1.20260603.1/node_modules/@cloudflare/unenv-preset/dist/runtime/node/console.mjs
var workerdConsole = globalThis["console"];
var {
assert,
clear: clear2,
// @ts-expect-error undocumented public API
context,
count: count2,
countReset: countReset2,
// @ts-expect-error undocumented public API
createTask: createTask2,
debug: debug2,
dir: dir2,
dirxml: dirxml2,
error: error2,
group: group2,
groupCollapsed: groupCollapsed2,
groupEnd: groupEnd2,
info: info2,
log: log2,
profile: profile2,
profileEnd: profileEnd2,
table: table2,
time: time2,
timeEnd: timeEnd2,
timeLog: timeLog2,
timeStamp: timeStamp2,
trace: trace2,
warn: warn2
} = workerdConsole;
Object.assign(workerdConsole, {
Console,
_ignoreErrors,
_stderr,
_stderrErrorHandler,
_stdout,
_stdoutErrorHandler,
_times
});
var console_default = workerdConsole;
// node_modules/.pnpm/wrangler@4.98.0_@cloudflare+workers-types@4.20260607.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-console
globalThis.console = console_default;
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/process/hrtime.mjs
var hrtime = /* @__PURE__ */ Object.assign(/* @__PURE__ */ __name(function hrtime2(startTime) {
const now = Date.now();
const seconds = Math.trunc(now / 1e3);
const nanos = now % 1e3 * 1e6;
if (startTime) {
let diffSeconds = seconds - startTime[0];
let diffNanos = nanos - startTime[0];
if (diffNanos < 0) {
diffSeconds = diffSeconds - 1;
diffNanos = 1e9 + diffNanos;
}
return [diffSeconds, diffNanos];
}
return [seconds, nanos];
}, "hrtime"), { bigint: /* @__PURE__ */ __name(function bigint() {
return BigInt(Date.now() * 1e6);
}, "bigint") });
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/process/process.mjs
import { EventEmitter } from "node:events";
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/tty/read-stream.mjs
var ReadStream = class {
static {
__name(this, "ReadStream");
}
fd;
isRaw = false;
isTTY = false;
constructor(fd) {
this.fd = fd;
}
setRawMode(mode) {
this.isRaw = mode;
return this;
}
};
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/tty/write-stream.mjs
var WriteStream = class {
static {
__name(this, "WriteStream");
}
fd;
columns = 80;
rows = 24;
isTTY = false;
constructor(fd) {
this.fd = fd;
}
clearLine(dir3, callback) {
callback && callback();
return false;
}
clearScreenDown(callback) {
callback && callback();
return false;
}
cursorTo(x, y, callback) {
callback && typeof callback === "function" && callback();
return false;
}
moveCursor(dx, dy, callback) {
callback && callback();
return false;
}
getColorDepth(env2) {
return 1;
}
hasColors(count3, env2) {
return false;
}
getWindowSize() {
return [this.columns, this.rows];
}
write(str, encoding, cb) {
if (str instanceof Uint8Array) {
str = new TextDecoder().decode(str);
}
try {
console.log(str);
} catch {
}
cb && typeof cb === "function" && cb();
return false;
}
};
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/process/node-version.mjs
var NODE_VERSION = "22.14.0";
// node_modules/.pnpm/unenv@2.0.0-rc.24/node_modules/unenv/dist/runtime/node/internal/process/process.mjs
var Process = class _Process extends EventEmitter {
static {
__name(this, "Process");
}
env;
hrtime;
nextTick;
constructor(impl) {
super();
this.env = impl.env;
this.hrtime = impl.hrtime;
this.nextTick = impl.nextTick;
for (const prop of [...Object.getOwnPropertyNames(_Process.prototype), ...Object.getOwnPropertyNames(EventEmitter.prototype)]) {
const value = this[prop];
if (typeof value === "function") {
this[prop] = value.bind(this);
}
}
}
// --- event emitter ---
emitWarning(warning, type, code) {
console.warn(`${code ? `[${code}] ` : ""}${type ? `${type}: ` : ""}${warning}`);
}
emit(...args) {
return super.emit(...args);
}
listeners(eventName) {
return super.listeners(eventName);
}
// --- stdio (lazy initializers) ---
#stdin;
#stdout;
#stderr;
get stdin() {
return this.#stdin ??= new ReadStream(0);
}
get stdout() {
return this.#stdout ??= new WriteStream(1);
}
get stderr() {
return this.#stderr ??= new WriteStream(2);
}
// --- cwd ---
#cwd = "/";
chdir(cwd2) {
this.#cwd = cwd2;
}
cwd() {
return this.#cwd;
}
// --- dummy props and getters ---
arch = "";
platform = "";
argv = [];
argv0 = "";
execArgv = [];
execPath = "";
title = "";
pid = 200;
ppid = 100;
get version() {
return `v${NODE_VERSION}`;
}
get versions() {
return { node: NODE_VERSION };
}
get allowedNodeEnvironmentFlags() {
return /* @__PURE__ */ new Set();
}
get sourceMapsEnabled() {
return false;
}
get debugPort() {
return 0;
}
get throwDeprecation() {
return false;
}
get traceDeprecation() {
return false;
}
get features() {
return {};
}
get release() {
return {};
}
get connected() {
return false;
}
get config() {
return {};
}
get moduleLoadList() {
return [];
}
constrainedMemory() {
return 0;
}
availableMemory() {
return 0;
}
uptime() {
return 0;
}
resourceUsage() {
return {};
}
// --- noop methods ---
ref() {
}
unref() {
}
// --- unimplemented methods ---
umask() {
throw createNotImplementedError("process.umask");
}
getBuiltinModule() {
return void 0;
}
getActiveResourcesInfo() {
throw createNotImplementedError("process.getActiveResourcesInfo");
}
exit() {
throw createNotImplementedError("process.exit");
}
reallyExit() {
throw createNotImplementedError("process.reallyExit");
}
kill() {
throw createNotImplementedError("process.kill");
}
abort() {
throw createNotImplementedError("process.abort");
}
dlopen() {
throw createNotImplementedError("process.dlopen");
}
setSourceMapsEnabled() {
throw createNotImplementedError("process.setSourceMapsEnabled");
}
loadEnvFile() {
throw createNotImplementedError("process.loadEnvFile");
}
disconnect() {
throw createNotImplementedError("process.disconnect");
}
cpuUsage() {
throw createNotImplementedError("process.cpuUsage");
}
setUncaughtExceptionCaptureCallback() {
throw createNotImplementedError("process.setUncaughtExceptionCaptureCallback");
}
hasUncaughtExceptionCaptureCallback() {
throw createNotImplementedError("process.hasUncaughtExceptionCaptureCallback");
}
initgroups() {
throw createNotImplementedError("process.initgroups");
}
openStdin() {
throw createNotImplementedError("process.openStdin");
}
assert() {
throw createNotImplementedError("process.assert");
}
binding() {
throw createNotImplementedError("process.binding");
}
// --- attached interfaces ---
permission = { has: /* @__PURE__ */ notImplemented("process.permission.has") };
report = {
directory: "",
filename: "",
signal: "SIGUSR2",
compact: false,
reportOnFatalError: false,
reportOnSignal: false,
reportOnUncaughtException: false,
getReport: /* @__PURE__ */ notImplemented("process.report.getReport"),
writeReport: /* @__PURE__ */ notImplemented("process.report.writeReport")
};
finalization = {
register: /* @__PURE__ */ notImplemented("process.finalization.register"),
unregister: /* @__PURE__ */ notImplemented("process.finalization.unregister"),
registerBeforeExit: /* @__PURE__ */ notImplemented("process.finalization.registerBeforeExit")
};
memoryUsage = Object.assign(() => ({
arrayBuffers: 0,
rss: 0,
external: 0,
heapTotal: 0,
heapUsed: 0
}), { rss: /* @__PURE__ */ __name(() => 0, "rss") });
// --- undefined props ---
mainModule = void 0;
domain = void 0;
// optional
send = void 0;
exitCode = void 0;
channel = void 0;
getegid = void 0;
geteuid = void 0;
getgid = void 0;
getgroups = void 0;
getuid = void 0;
setegid = void 0;
seteuid = void 0;
setgid = void 0;
setgroups = void 0;
setuid = void 0;
// internals
_events = void 0;
_eventsCount = void 0;
_exiting = void 0;
_maxListeners = void 0;
_debugEnd = void 0;
_debugProcess = void 0;
_fatalException = void 0;
_getActiveHandles = void 0;
_getActiveRequests = void 0;
_kill = void 0;
_preload_modules = void 0;
_rawDebug = void 0;
_startProfilerIdleNotifier = void 0;
_stopProfilerIdleNotifier = void 0;
_tickCallback = void 0;
_disconnect = void 0;
_handleQueue = void 0;
_pendingMessage = void 0;
_channel = void 0;
_send = void 0;
_linkedBinding = void 0;
};
// node_modules/.pnpm/@cloudflare+unenv-preset@2.16.1_unenv@2.0.0-rc.24_workerd@1.20260603.1/node_modules/@cloudflare/unenv-preset/dist/runtime/node/process.mjs
var globalProcess = globalThis["process"];
var getBuiltinModule = globalProcess.getBuiltinModule;
var workerdProcess = getBuiltinModule("node:process");
var unenvProcess = new Process({
env: globalProcess.env,
hrtime,
// `nextTick` is available from workerd process v1
nextTick: workerdProcess.nextTick
});
var { exit, features, platform } = workerdProcess;
var {
_channel,
_debugEnd,
_debugProcess,
_disconnect,
_events,
_eventsCount,
_exiting,
_fatalException,
_getActiveHandles,
_getActiveRequests,
_handleQueue,
_kill,
_linkedBinding,
_maxListeners,
_pendingMessage,
_preload_modules,
_rawDebug,
_send,
_startProfilerIdleNotifier,
_stopProfilerIdleNotifier,
_tickCallback,
abort,
addListener,
allowedNodeEnvironmentFlags,
arch,
argv,
argv0,
assert: assert2,
availableMemory,
binding,
channel,
chdir,
config,
connected,
constrainedMemory,
cpuUsage,
cwd,
debugPort,
disconnect,
dlopen,
domain,
emit,
emitWarning,
env,
eventNames,
execArgv,
execPath,
exitCode,
finalization,
getActiveResourcesInfo,
getegid,
geteuid,
getgid,
getgroups,
getMaxListeners,
getuid,
hasUncaughtExceptionCaptureCallback,
hrtime: hrtime3,
initgroups,
kill,
listenerCount,
listeners,
loadEnvFile,
mainModule,
memoryUsage,
moduleLoadList,
nextTick,
off,
on,
once,
openStdin,
permission,
pid,
ppid,
prependListener,
prependOnceListener,
rawListeners,
reallyExit,
ref,
release,
removeAllListeners,
removeListener,
report,
resourceUsage,
send,
setegid,
seteuid,
setgid,
setgroups,
setMaxListeners,
setSourceMapsEnabled,
setuid,
setUncaughtExceptionCaptureCallback,
sourceMapsEnabled,
stderr,
stdin,
stdout,
throwDeprecation,
title,
traceDeprecation,
umask,
unref,
uptime,
version,
versions
} = unenvProcess;
var _process = {
abort,
addListener,
allowedNodeEnvironmentFlags,
hasUncaughtExceptionCaptureCallback,
setUncaughtExceptionCaptureCallback,
loadEnvFile,
sourceMapsEnabled,
arch,
argv,
argv0,
chdir,
config,
connected,
constrainedMemory,
availableMemory,
cpuUsage,
cwd,
debugPort,
dlopen,
disconnect,
emit,
emitWarning,
env,
eventNames,
execArgv,
execPath,
exit,
finalization,
features,
getBuiltinModule,
getActiveResourcesInfo,
getMaxListeners,
hrtime: hrtime3,
kill,
listeners,
listenerCount,
memoryUsage,
nextTick,
on,
off,
once,
pid,
platform,
ppid,
prependListener,
prependOnceListener,
rawListeners,
release,
removeAllListeners,
removeListener,
report,
resourceUsage,
setMaxListeners,
setSourceMapsEnabled,
stderr,
stdin,
stdout,
title,
throwDeprecation,
traceDeprecation,
umask,
uptime,
version,
versions,
// @ts-expect-error old API
domain,
initgroups,
moduleLoadList,
reallyExit,
openStdin,
assert: assert2,
binding,
send,
exitCode,
channel,
getegid,
geteuid,
getgid,
getgroups,
getuid,
setegid,
seteuid,
setgid,
setgroups,
setuid,
permission,
mainModule,
_events,
_eventsCount,
_exiting,
_maxListeners,
_debugEnd,
_debugProcess,
_fatalException,
_getActiveHandles,
_getActiveRequests,
_kill,
_preload_modules,
_rawDebug,
_startProfilerIdleNotifier,
_stopProfilerIdleNotifier,
_tickCallback,
_disconnect,
_handleQueue,
_pendingMessage,
_channel,
_send,
_linkedBinding
};
var process_default = _process;
// node_modules/.pnpm/wrangler@4.98.0_@cloudflare+workers-types@4.20260607.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-process
globalThis.process = process_default;
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/compose.js
var compose = /* @__PURE__ */ __name((middleware, onError, onNotFound) => {
return (context2, next) => {
let index = -1;
return dispatch(0);
async function dispatch(i) {
if (i <= index) {
throw new Error("next() called multiple times");
}
index = i;
let res;
let isError = false;
let handler;
if (middleware[i]) {
handler = middleware[i][0][0];
context2.req.routeIndex = i;
} else {
handler = i === middleware.length && next || void 0;
}
if (handler) {
try {
res = await handler(context2, () => dispatch(i + 1));
} catch (err) {
if (err instanceof Error && onError) {
context2.error = err;
res = await onError(err, context2);
isError = true;
} else {
throw err;
}
}
} else {
if (context2.finalized === false && onNotFound) {
res = await onNotFound(context2);
}
}
if (res && (context2.finalized === false || isError)) {
context2.res = res;
}
return context2;
}
__name(dispatch, "dispatch");
};
}, "compose");
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request/constants.js
var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/body.js
var parseBody = /* @__PURE__ */ __name(async (request, options = /* @__PURE__ */ Object.create(null)) => {
const { all = false, dot = false } = options;
const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
const contentType = headers.get("Content-Type");
if (contentType?.startsWith("multipart/form-data") || contentType?.startsWith("application/x-www-form-urlencoded")) {
return parseFormData(request, { all, dot });
}
return {};
}, "parseBody");
async function parseFormData(request, options) {
const formData = await request.formData();
if (formData) {
return convertFormDataToBodyData(formData, options);
}
return {};
}
__name(parseFormData, "parseFormData");
function convertFormDataToBodyData(formData, options) {
const form = /* @__PURE__ */ Object.create(null);
formData.forEach((value, key) => {
const shouldParseAllValues = options.all || key.endsWith("[]");
if (!shouldParseAllValues) {
form[key] = value;
} else {
handleParsingAllValues(form, key, value);
}
});
if (options.dot) {
Object.entries(form).forEach(([key, value]) => {
const shouldParseDotValues = key.includes(".");
if (shouldParseDotValues) {
handleParsingNestedValues(form, key, value);
delete form[key];
}
});
}
return form;
}
__name(convertFormDataToBodyData, "convertFormDataToBodyData");
var handleParsingAllValues = /* @__PURE__ */ __name((form, key, value) => {
if (form[key] !== void 0) {
if (Array.isArray(form[key])) {
;
form[key].push(value);
} else {
form[key] = [form[key], value];
}
} else {
if (!key.endsWith("[]")) {
form[key] = value;
} else {
form[key] = [value];
}
}
}, "handleParsingAllValues");
var handleParsingNestedValues = /* @__PURE__ */ __name((form, key, value) => {
if (/(?:^|\.)__proto__\./.test(key)) {
return;
}
let nestedForm = form;
const keys = key.split(".");
keys.forEach((key2, index) => {
if (index === keys.length - 1) {
nestedForm[key2] = value;
} else {
if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {
nestedForm[key2] = /* @__PURE__ */ Object.create(null);
}
nestedForm = nestedForm[key2];
}
});
}, "handleParsingNestedValues");
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/url.js
var splitPath = /* @__PURE__ */ __name((path) => {
const paths = path.split("/");
if (paths[0] === "") {
paths.shift();
}
return paths;
}, "splitPath");
var splitRoutingPath = /* @__PURE__ */ __name((routePath) => {
const { groups, path } = extractGroupsFromPath(routePath);
const paths = splitPath(path);
return replaceGroupMarks(paths, groups);
}, "splitRoutingPath");
var extractGroupsFromPath = /* @__PURE__ */ __name((path) => {
const groups = [];
path = path.replace(/\{[^}]+\}/g, (match2, index) => {
const mark = `@${index}`;
groups.push([mark, match2]);
return mark;
});
return { groups, path };
}, "extractGroupsFromPath");
var replaceGroupMarks = /* @__PURE__ */ __name((paths, groups) => {
for (let i = groups.length - 1; i >= 0; i--) {
const [mark] = groups[i];
for (let j = paths.length - 1; j >= 0; j--) {
if (paths[j].includes(mark)) {
paths[j] = paths[j].replace(mark, groups[i][1]);
break;
}
}
}
return paths;
}, "replaceGroupMarks");
var patternCache = {};
var getPattern = /* @__PURE__ */ __name((label, next) => {
if (label === "*") {
return "*";
}
const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
if (match2) {
const cacheKey = `${label}#${next}`;
if (!patternCache[cacheKey]) {
if (match2[2]) {
patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
} else {
patternCache[cacheKey] = [label, match2[1], true];
}
}
return patternCache[cacheKey];
}
return null;
}, "getPattern");
var tryDecode = /* @__PURE__ */ __name((str, decoder) => {
try {
return decoder(str);
} catch {
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
try {
return decoder(match2);
} catch {
return match2;
}
});
}
}, "tryDecode");
var tryDecodeURI = /* @__PURE__ */ __name((str) => tryDecode(str, decodeURI), "tryDecodeURI");
var getPath = /* @__PURE__ */ __name((request) => {
const url = request.url;
const start = url.indexOf("/", url.indexOf(":") + 4);
let i = start;
for (; i < url.length; i++) {
const charCode = url.charCodeAt(i);
if (charCode === 37) {
const queryIndex = url.indexOf("?", i);
const hashIndex = url.indexOf("#", i);
const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
const path = url.slice(start, end);
return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
} else if (charCode === 63 || charCode === 35) {
break;
}
}
return url.slice(start, i);
}, "getPath");
var getPathNoStrict = /* @__PURE__ */ __name((request) => {
const result = getPath(request);
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
}, "getPathNoStrict");
var mergePath = /* @__PURE__ */ __name((base, sub, ...rest) => {
if (rest.length) {
sub = mergePath(sub, ...rest);
}
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
}, "mergePath");
var checkOptionalParameter = /* @__PURE__ */ __name((path) => {
if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) {
return null;
}
const segments = path.split("/");
const results = [];
let basePath = "";
segments.forEach((segment) => {
if (segment !== "" && !/\:/.test(segment)) {
basePath += "/" + segment;
} else if (/\:/.test(segment)) {
if (/\?/.test(segment)) {
if (results.length === 0 && basePath === "") {
results.push("/");
} else {
results.push(basePath);
}
const optionalSegment = segment.replace("?", "");
basePath += "/" + optionalSegment;
results.push(basePath);
} else {
basePath += "/" + segment;
}
}
});
return results.filter((v, i, a) => a.indexOf(v) === i);
}, "checkOptionalParameter");
var _decodeURI = /* @__PURE__ */ __name((value) => {
if (!/[%+]/.test(value)) {
return value;
}
if (value.indexOf("+") !== -1) {
value = value.replace(/\+/g, " ");
}
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
}, "_decodeURI");
var _getQueryParam = /* @__PURE__ */ __name((url, key, multiple) => {
let encoded;
if (!multiple && key && !/[%+]/.test(key)) {
let keyIndex2 = url.indexOf("?", 8);
if (keyIndex2 === -1) {
return void 0;
}
if (!url.startsWith(key, keyIndex2 + 1)) {
keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
}
while (keyIndex2 !== -1) {
const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
if (trailingKeyCode === 61) {
const valueIndex = keyIndex2 + key.length + 2;
const endIndex = url.indexOf("&", valueIndex);
return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
return "";
}
keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
}
encoded = /[%+]/.test(url);
if (!encoded) {
return void 0;
}
}
const results = {};
encoded ??= /[%+]/.test(url);
let keyIndex = url.indexOf("?", 8);
while (keyIndex !== -1) {
const nextKeyIndex = url.indexOf("&", keyIndex + 1);
let valueIndex = url.indexOf("=", keyIndex);
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
valueIndex = -1;
}
let name = url.slice(
keyIndex + 1,
valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex
);
if (encoded) {
name = _decodeURI(name);
}
keyIndex = nextKeyIndex;
if (name === "") {
continue;
}
let value;
if (valueIndex === -1) {
value = "";
} else {
value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
if (encoded) {
value = _decodeURI(value);
}
}
if (multiple) {
if (!(results[name] && Array.isArray(results[name]))) {
results[name] = [];
}
;
results[name].push(value);
} else {
results[name] ??= value;
}
}
return key ? results[key] : results;
}, "_getQueryParam");
var getQueryParam = _getQueryParam;
var getQueryParams = /* @__PURE__ */ __name((url, key) => {
return _getQueryParam(url, key, true);
}, "getQueryParams");
var decodeURIComponent_ = decodeURIComponent;
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/request.js
var tryDecodeURIComponent = /* @__PURE__ */ __name((str) => tryDecode(str, decodeURIComponent_), "tryDecodeURIComponent");
var HonoRequest = class {
static {
__name(this, "HonoRequest");
}
/**
* `.raw` can get the raw Request object.
*
* @see {@link https://hono.dev/docs/api/request#raw}
*
* @example
* ```ts
* // For Cloudflare Workers
* app.post('/', async (c) => {
* const metadata = c.req.raw.cf?.hostMetadata?
* ...
* })
* ```
*/
raw;
#validatedData;
// Short name of validatedData
#matchResult;
routeIndex = 0;
/**
* `.path` can get the pathname of the request.
*
* @see {@link https://hono.dev/docs/api/request#path}
*
* @example
* ```ts
* app.get('/about/me', (c) => {
* const pathname = c.req.path // `/about/me`
* })
* ```
*/
path;
bodyCache = {};
constructor(request, path = "/", matchResult = [[]]) {
this.raw = request;
this.path = path;
this.#matchResult = matchResult;
this.#validatedData = {};
}
param(key) {
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
}
#getDecodedParam(key) {
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
const param = this.#getParamValue(paramKey);
return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
}
#getAllDecodedParams() {
const decoded = {};
const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
for (const key of keys) {
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
if (value !== void 0) {
decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
}
}
return decoded;
}
#getParamValue(paramKey) {
return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
}
query(key) {
return getQueryParam(this.url, key);
}
queries(key) {
return getQueryParams(this.url, key);
}
header(name) {
if (name) {
return this.raw.headers.get(name) ?? void 0;
}
const headerData = {};
this.raw.headers.forEach((value, key) => {
headerData[key] = value;
});
return headerData;
}
async parseBody(options) {
return parseBody(this, options);
}
#cachedBody = /* @__PURE__ */ __name((key) => {
const { bodyCache, raw: raw2 } = this;
const cachedBody = bodyCache[key];
if (cachedBody) {
return cachedBody;
}
const anyCachedKey = Object.keys(bodyCache)[0];
if (anyCachedKey) {
return bodyCache[anyCachedKey].then((body) => {
if (anyCachedKey === "json") {
body = JSON.stringify(body);
}
return new Response(body)[key]();
});
}
return bodyCache[key] = raw2[key]();
}, "#cachedBody");
/**
* `.json()` can parse Request body of type `application/json`
*
* @see {@link https://hono.dev/docs/api/request#json}
*
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.json()
* })
* ```
*/
json() {
return this.#cachedBody("text").then((text) => JSON.parse(text));
}
/**
* `.text()` can parse Request body of type `text/plain`
*
* @see {@link https://hono.dev/docs/api/request#text}
*
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.text()
* })
* ```
*/
text() {
return this.#cachedBody("text");
}
/**
* `.arrayBuffer()` parse Request body as an `ArrayBuffer`
*
* @see {@link https://hono.dev/docs/api/request#arraybuffer}
*
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.arrayBuffer()
* })
* ```
*/
arrayBuffer() {
return this.#cachedBody("arrayBuffer");
}
/**
* `.bytes()` parses the request body as a `Uint8Array`.
*
* @see {@link https://hono.dev/docs/api/request#bytes}
*
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.bytes()
* })
* ```
*/
bytes() {
return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
}
/**
* Parses the request body as a `Blob`.
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.blob();
* });
* ```
* @see https://hono.dev/docs/api/request#blob
*/
blob() {
return this.#cachedBody("blob");
}
/**
* Parses the request body as `FormData`.
* @example
* ```ts
* app.post('/entry', async (c) => {
* const body = await c.req.formData();
* });
* ```
* @see https://hono.dev/docs/api/request#formdata
*/
formData() {
return this.#cachedBody("formData");
}
/**
* Adds validated data to the request.
*
* @param target - The target of the validation.
* @param data - The validated data to add.
*/
addValidatedData(target, data) {
this.#validatedData[target] = data;
}
valid(target) {
return this.#validatedData[target];
}
/**
* `.url()` can get the request url strings.
*
* @see {@link https://hono.dev/docs/api/request#url}
*
* @example
* ```ts
* app.get('/about/me', (c) => {
* const url = c.req.url // `http://localhost:8787/about/me`
* ...
* })
* ```
*/
get url() {
return this.raw.url;
}
/**
* `.method()` can get the method name of the request.
*
* @see {@link https://hono.dev/docs/api/request#method}
*
* @example
* ```ts
* app.get('/about/me', (c) => {
* const method = c.req.method // `GET`
* })
* ```
*/
get method() {
return this.raw.method;
}
get [GET_MATCH_RESULT]() {
return this.#matchResult;
}
/**
* `.matchedRoutes()` can return a matched route in the handler
*
* @deprecated
*
* Use matchedRoutes helper defined in "hono/route" instead.
*
* @see {@link https://hono.dev/docs/api/request#matchedroutes}
*
* @example
* ```ts
* app.use('*', async function logger(c, next) {
* await next()
* c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
* console.log(
* method,
* ' ',
* path,
* ' '.repeat(Math.max(10 - path.length, 0)),
* name,
* i === c.req.routeIndex ? '<- respond from here' : ''
* )
* })
* })
* ```
*/
get matchedRoutes() {
return this.#matchResult[0].map(([[, route]]) => route);
}
/**
* `routePath()` can retrieve the path registered within the handler
*
* @deprecated
*
* Use routePath helper defined in "hono/route" instead.
*
* @see {@link https://hono.dev/docs/api/request#routepath}
*
* @example
* ```ts
* app.get('/posts/:id', (c) => {
* return c.json({ path: c.req.routePath })
* })
* ```
*/
get routePath() {
return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/html.js
var HtmlEscapedCallbackPhase = {
Stringify: 1,
BeforeStream: 2,
Stream: 3
};
var raw = /* @__PURE__ */ __name((value, callbacks) => {
const escapedString = new String(value);
escapedString.isEscaped = true;
escapedString.callbacks = callbacks;
return escapedString;
}, "raw");
var resolveCallback = /* @__PURE__ */ __name(async (str, phase, preserveCallbacks, context2, buffer) => {
if (typeof str === "object" && !(str instanceof String)) {
if (!(str instanceof Promise)) {
str = str.toString();
}
if (str instanceof Promise) {
str = await str;
}
}
const callbacks = str.callbacks;
if (!callbacks?.length) {
return Promise.resolve(str);
}
if (buffer) {
buffer[0] += str;
} else {
buffer = [str];
}
const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context: context2 }))).then(
(res) => Promise.all(
res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context2, buffer))
).then(() => buffer[0])
);
if (preserveCallbacks) {
return raw(await resStr, callbacks);
} else {
return resStr;
}
}, "resolveCallback");
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/context.js
var TEXT_PLAIN = "text/plain; charset=UTF-8";
var setDefaultContentType = /* @__PURE__ */ __name((contentType, headers) => {
return {
"Content-Type": contentType,
...headers
};
}, "setDefaultContentType");
var createResponseInstance = /* @__PURE__ */ __name((body, init) => new Response(body, init), "createResponseInstance");
var Context = class {
static {
__name(this, "Context");
}
#rawRequest;
#req;
/**
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
*
* @see {@link https://hono.dev/docs/api/context#env}
*
* @example
* ```ts
* // Environment object for Cloudflare Workers
* app.get('*', async c => {
* const counter = c.env.COUNTER
* })
* ```
*/
env = {};
#var;
finalized = false;
/**
* `.error` can get the error object from the middleware if the Handler throws an error.
*
* @see {@link https://hono.dev/docs/api/context#error}
*
* @example
* ```ts
* app.use('*', async (c, next) => {
* await next()
* if (c.error) {
* // do something...
* }
* })
* ```
*/
error;
#status;
#executionCtx;
#res;
#layout;
#renderer;
#notFoundHandler;
#preparedHeaders;
#matchResult;
#path;
/**
* Creates an instance of the Context class.
*
* @param req - The Request object.
* @param options - Optional configuration options for the context.
*/
constructor(req, options) {
this.#rawRequest = req;
if (options) {
this.#executionCtx = options.executionCtx;
this.env = options.env;
this.#notFoundHandler = options.notFoundHandler;
this.#path = options.path;
this.#matchResult = options.matchResult;
}
}
/**
* `.req` is the instance of {@link HonoRequest}.
*/
get req() {
this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
return this.#req;
}
/**
* @see {@link https://hono.dev/docs/api/context#event}
* The FetchEvent associated with the current request.
*
* @throws Will throw an error if the context does not have a FetchEvent.
*/
get event() {
if (this.#executionCtx && "respondWith" in this.#executionCtx) {
return this.#executionCtx;
} else {
throw Error("This context has no FetchEvent");
}
}
/**
* @see {@link https://hono.dev/docs/api/context#executionctx}
* The ExecutionContext associated with the current request.
*
* @throws Will throw an error if the context does not have an ExecutionContext.
*/
get executionCtx() {
if (this.#executionCtx) {
return this.#executionCtx;
} else {
throw Error("This context has no ExecutionContext");
}
}
/**
* @see {@link https://hono.dev/docs/api/context#res}
* The Response object for the current request.
*/
get res() {
return this.#res ||= createResponseInstance(null, {
headers: this.#preparedHeaders ??= new Headers()
});
}
/**
* Sets the Response object for the current request.
*
* @param _res - The Response object to set.
*/
set res(_res) {
if (this.#res && _res) {
_res = createResponseInstance(_res.body, _res);
for (const [k, v] of this.#res.headers.entries()) {
if (k === "content-type") {
continue;
}
if (k === "set-cookie") {
const cookies = this.#res.headers.getSetCookie();
_res.headers.delete("set-cookie");
for (const cookie of cookies) {
_res.headers.append("set-cookie", cookie);
}
} else {
_res.headers.set(k, v);
}
}
}
this.#res = _res;
this.finalized = true;
}
/**
* `.render()` can create a response within a layout.
*
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
*
* @example
* ```ts
* app.get('/', (c) => {
* return c.render('Hello!')
* })
* ```
*/
render = /* @__PURE__ */ __name((...args) => {
this.#renderer ??= (content) => this.html(content);
return this.#renderer(...args);
}, "render");
/**
* Sets the layout for the response.
*
* @param layout - The layout to set.
* @returns The layout function.
*/
setLayout = /* @__PURE__ */ __name((layout) => this.#layout = layout, "setLayout");
/**
* Gets the current layout for the response.
*
* @returns The current layout function.
*/
getLayout = /* @__PURE__ */ __name(() => this.#layout, "getLayout");
/**
* `.setRenderer()` can set the layout in the custom middleware.
*
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
*
* @example
* ```tsx
* app.use('*', async (c, next) => {
* c.setRenderer((content) => {
* return c.html(
* <html>
* <body>
* <p>{content}</p>
* </body>
* </html>
* )
* })
* await next()
* })
* ```
*/
setRenderer = /* @__PURE__ */ __name((renderer) => {
this.#renderer = renderer;
}, "setRenderer");
/**
* `.header()` can set headers.
*
* @see {@link https://hono.dev/docs/api/context#header}
*
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
*
* return c.body('Thank you for coming')
* })
* ```
*/
header = /* @__PURE__ */ __name((name, value, options) => {
if (this.finalized) {
this.#res = createResponseInstance(this.#res.body, this.#res);
}
const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
if (value === void 0) {
headers.delete(name);
} else if (options?.append) {
headers.append(name, value);
} else {
headers.set(name, value);
}
}, "header");
status = /* @__PURE__ */ __name((status) => {
this.#status = status;
}, "status");
/**
* `.set()` can set the value specified by the key.
*
* @see {@link https://hono.dev/docs/api/context#set-get}
*
* @example
* ```ts
* app.use('*', async (c, next) => {
* c.set('message', 'Hono is hot!!')
* await next()
* })
* ```
*/
set = /* @__PURE__ */ __name((key, value) => {
this.#var ??= /* @__PURE__ */ new Map();
this.#var.set(key, value);
}, "set");
/**
* `.get()` can use the value specified by the key.
*
* @see {@link https://hono.dev/docs/api/context#set-get}
*
* @example
* ```ts
* app.get('/', (c) => {
* const message = c.get('message')
* return c.text(`The message is "${message}"`)
* })
* ```
*/
get = /* @__PURE__ */ __name((key) => {
return this.#var ? this.#var.get(key) : void 0;
}, "get");
/**
* `.var` can access the value of a variable.
*
* @see {@link https://hono.dev/docs/api/context#var}
*
* @example
* ```ts
* const result = c.var.client.oneMethod()
* ```
*/
// c.var.propName is a read-only
get var() {
if (!this.#var) {
return {};
}
return Object.fromEntries(this.#var);
}
#newResponse(data, arg, headers) {
const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
if (typeof arg === "object" && "headers" in arg) {
const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
for (const [key, value] of argHeaders) {
if (key.toLowerCase() === "set-cookie") {
responseHeaders.append(key, value);
} else {
responseHeaders.set(key, value);
}
}
}
if (headers) {
for (const [k, v] of Object.entries(headers)) {
if (typeof v === "string") {
responseHeaders.set(k, v);
} else {
responseHeaders.delete(k);
for (const v2 of v) {
responseHeaders.append(k, v2);
}
}
}
}
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
return createResponseInstance(data, { status, headers: responseHeaders });
}
newResponse = /* @__PURE__ */ __name((...args) => this.#newResponse(...args), "newResponse");
/**
* `.body()` can return the HTTP response.
* You can set headers with `.header()` and set HTTP status code with `.status`.
* This can also be set in `.text()`, `.json()` and so on.
*
* @see {@link https://hono.dev/docs/api/context#body}
*
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
* // Set HTTP status code
* c.status(201)
*
* // Return the response body
* return c.body('Thank you for coming')
* })
* ```
*/
body = /* @__PURE__ */ __name((data, arg, headers) => this.#newResponse(data, arg, headers), "body");
/**
* `.text()` can render text as `Content-Type:text/plain`.
*
* @see {@link https://hono.dev/docs/api/context#text}
*
* @example
* ```ts
* app.get('/say', (c) => {
* return c.text('Hello!')
* })
* ```
*/
text = /* @__PURE__ */ __name((text, arg, headers) => {
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
text,
arg,
setDefaultContentType(TEXT_PLAIN, headers)
);
}, "text");
/**
* `.json()` can render JSON as `Content-Type:application/json`.
*
* @see {@link https://hono.dev/docs/api/context#json}
*
* @example
* ```ts
* app.get('/api', (c) => {
* return c.json({ message: 'Hello!' })
* })
* ```
*/
json = /* @__PURE__ */ __name((object, arg, headers) => {
return this.#newResponse(
JSON.stringify(object),
arg,
setDefaultContentType("application/json", headers)
);
}, "json");
html = /* @__PURE__ */ __name((html, arg, headers) => {
const res = /* @__PURE__ */ __name((html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers)), "res");
return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
}, "html");
/**
* `.redirect()` can Redirect, default status code is 302.
*
* @see {@link https://hono.dev/docs/api/context#redirect}
*
* @example
* ```ts
* app.get('/redirect', (c) => {
* return c.redirect('/')
* })
* app.get('/redirect-permanently', (c) => {
* return c.redirect('/', 301)
* })
* ```
*/
redirect = /* @__PURE__ */ __name((location, status) => {
const locationString = String(location);
this.header(
"Location",
// Multibyes should be encoded
// eslint-disable-next-line no-control-regex
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
);
return this.newResponse(null, status ?? 302);
}, "redirect");
/**
* `.notFound()` can return the Not Found Response.
*
* @see {@link https://hono.dev/docs/api/context#notfound}
*
* @example
* ```ts
* app.get('/notfound', (c) => {
* return c.notFound()
* })
* ```
*/
notFound = /* @__PURE__ */ __name(() => {
this.#notFoundHandler ??= () => createResponseInstance();
return this.#notFoundHandler(this);
}, "notFound");
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router.js
var METHOD_NAME_ALL = "ALL";
var METHOD_NAME_ALL_LOWERCASE = "all";
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
var UnsupportedPathError = class extends Error {
static {
__name(this, "UnsupportedPathError");
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/utils/constants.js
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono-base.js
var notFoundHandler = /* @__PURE__ */ __name((c) => {
return c.text("404 Not Found", 404);
}, "notFoundHandler");
var errorHandler = /* @__PURE__ */ __name((err, c) => {
if ("getResponse" in err) {
const res = err.getResponse();
return c.newResponse(res.body, res);
}
console.error(err);
return c.text("Internal Server Error", 500);
}, "errorHandler");
var Hono = class _Hono {
static {
__name(this, "_Hono");
}
get;
post;
put;
delete;
options;
patch;
all;
on;
use;
/*
This class is like an abstract class and does not have a router.
To use it, inherit the class and implement router in the constructor.
*/
router;
getPath;
// Cannot use `#` because it requires visibility at JavaScript runtime.
_basePath = "/";
#path = "/";
routes = [];
constructor(options = {}) {
const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
allMethods.forEach((method) => {
this[method] = (args1, ...args) => {
if (typeof args1 === "string") {
this.#path = args1;
} else {
this.#addRoute(method, this.#path, args1);
}
args.forEach((handler) => {
this.#addRoute(method, this.#path, handler);
});
return this;
};
});
this.on = (method, path, ...handlers) => {
for (const p of [path].flat()) {
this.#path = p;
for (const m of [method].flat()) {
handlers.map((handler) => {
this.#addRoute(m.toUpperCase(), this.#path, handler);
});
}
}
return this;
};
this.use = (arg1, ...handlers) => {
if (typeof arg1 === "string") {
this.#path = arg1;
} else {
this.#path = "*";
handlers.unshift(arg1);
}
handlers.forEach((handler) => {
this.#addRoute(METHOD_NAME_ALL, this.#path, handler);
});
return this;
};
const { strict, ...optionsWithoutStrict } = options;
Object.assign(this, optionsWithoutStrict);
this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
}
#clone() {
const clone = new _Hono({
router: this.router,
getPath: this.getPath
});
clone.errorHandler = this.errorHandler;
clone.#notFoundHandler = this.#notFoundHandler;
clone.routes = this.routes;
return clone;
}
#notFoundHandler = notFoundHandler;
// Cannot use `#` because it requires visibility at JavaScript runtime.
errorHandler = errorHandler;
/**
* `.route()` allows grouping other Hono instance in routes.
*
* @see {@link https://hono.dev/docs/api/routing#grouping}
*
* @param {string} path - base Path
* @param {Hono} app - other Hono instance
* @returns {Hono} routed Hono instance
*
* @example
* ```ts
* const app = new Hono()
* const app2 = new Hono()
*
* app2.get("/user", (c) => c.text("user"))
* app.route("/api", app2) // GET /api/user
* ```
*/
route(path, app2) {
const subApp = this.basePath(path);
app2.routes.map((r) => {
let handler;
if (app2.errorHandler === errorHandler) {
handler = r.handler;
} else {
handler = /* @__PURE__ */ __name(async (c, next) => (await compose([], app2.errorHandler)(c, () => r.handler(c, next))).res, "handler");
handler[COMPOSED_HANDLER] = r.handler;
}
subApp.#addRoute(r.method, r.path, handler, r.basePath);
});
return this;
}
/**
* `.basePath()` allows base paths to be specified.
*
* @see {@link https://hono.dev/docs/api/routing#base-path}
*
* @param {string} path - base Path
* @returns {Hono} changed Hono instance
*
* @example
* ```ts
* const api = new Hono().basePath('/api')
* ```
*/
basePath(path) {
const subApp = this.#clone();
subApp._basePath = mergePath(this._basePath, path);
return subApp;
}
/**
* `.onError()` handles an error and returns a customized Response.
*
* @see {@link https://hono.dev/docs/api/hono#error-handling}
*
* @param {ErrorHandler} handler - request Handler for error
* @returns {Hono} changed Hono instance
*
* @example
* ```ts
* app.onError((err, c) => {
* console.error(`${err}`)
* return c.text('Custom Error Message', 500)
* })
* ```
*/
onError = /* @__PURE__ */ __name((handler) => {
this.errorHandler = handler;
return this;
}, "onError");
/**
* `.notFound()` allows you to customize a Not Found Response.
*
* @see {@link https://hono.dev/docs/api/hono#not-found}
*
* @param {NotFoundHandler} handler - request handler for not-found
* @returns {Hono} changed Hono instance
*
* @example
* ```ts
* app.notFound((c) => {
* return c.text('Custom 404 Message', 404)
* })
* ```
*/
notFound = /* @__PURE__ */ __name((handler) => {
this.#notFoundHandler = handler;
return this;
}, "notFound");
/**
* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
*
* @see {@link https://hono.dev/docs/api/hono#mount}
*
* @param {string} path - base Path
* @param {Function} applicationHandler - other Request Handler
* @param {MountOptions} [options] - options of `.mount()`
* @returns {Hono} mounted Hono instance
*
* @example
* ```ts
* import { Router as IttyRouter } from 'itty-router'
* import { Hono } from 'hono'
* // Create itty-router application
* const ittyRouter = IttyRouter()
* // GET /itty-router/hello
* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
*
* const app = new Hono()
* app.mount('/itty-router', ittyRouter.handle)
* ```
*
* @example
* ```ts
* const app = new Hono()
* // Send the request to another application without modification.
* app.mount('/app', anotherApp, {
* replaceRequest: (req) => req,
* })
* ```
*/
mount(path, applicationHandler, options) {
let replaceRequest;
let optionHandler;
if (options) {
if (typeof options === "function") {
optionHandler = options;
} else {
optionHandler = options.optionHandler;
if (options.replaceRequest === false) {
replaceRequest = /* @__PURE__ */ __name((request) => request, "replaceRequest");
} else {
replaceRequest = options.replaceRequest;
}
}
}
const getOptions = optionHandler ? (c) => {
const options2 = optionHandler(c);
return Array.isArray(options2) ? options2 : [options2];
} : (c) => {
let executionContext = void 0;
try {
executionContext = c.executionCtx;
} catch {
}
return [c.env, executionContext];
};
replaceRequest ||= (() => {
const mergedPath = mergePath(this._basePath, path);
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
return (request) => {
const url = new URL(request.url);
url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
return new Request(url, request);
};
})();
const handler = /* @__PURE__ */ __name(async (c, next) => {
const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
if (res) {
return res;
}
await next();
}, "handler");
this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler);
return this;
}
#addRoute(method, path, handler, baseRoutePath) {
method = method.toUpperCase();
path = mergePath(this._basePath, path);
const r = {
basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
path,
method,
handler
};
this.router.add(method, path, [handler, r]);
this.routes.push(r);
}
#handleError(err, c) {
if (err instanceof Error) {
return this.errorHandler(err, c);
}
throw err;
}
#dispatch(request, executionCtx, env2, method) {
if (method === "HEAD") {
return (async () => new Response(null, await this.#dispatch(request, executionCtx, env2, "GET")))();
}
const path = this.getPath(request, { env: env2 });
const matchResult = this.router.match(method, path);
const c = new Context(request, {
path,
matchResult,
env: env2,
executionCtx,
notFoundHandler: this.#notFoundHandler
});
if (matchResult[0].length === 1) {
let res;
try {
res = matchResult[0][0][0][0](c, async () => {
c.res = await this.#notFoundHandler(c);
});
} catch (err) {
return this.#handleError(err, c);
}
return res instanceof Promise ? res.then(
(resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
}
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
return (async () => {
try {
const context2 = await composed(c);
if (!context2.finalized) {
throw new Error(
"Context is not finalized. Did you forget to return a Response object or `await next()`?"
);
}
return context2.res;
} catch (err) {
return this.#handleError(err, c);
}
})();
}
/**
* `.fetch()` will be entry point of your app.
*
* @see {@link https://hono.dev/docs/api/hono#fetch}
*
* @param {Request} request - request Object of request
* @param {Env} Env - env Object
* @param {ExecutionContext} - context of execution
* @returns {Response | Promise<Response>} response of request
*
*/
fetch = /* @__PURE__ */ __name((request, ...rest) => {
return this.#dispatch(request, rest[1], rest[0], request.method);
}, "fetch");
/**
* `.request()` is a useful method for testing.
* You can pass a URL or pathname to send a GET request.
* app will return a Response object.
* ```ts
* test('GET /hello is ok', async () => {
* const res = await app.request('/hello')
* expect(res.status).toBe(200)
* })
* ```
* @see https://hono.dev/docs/api/hono#request
*/
request = /* @__PURE__ */ __name((input, requestInit, Env, executionCtx) => {
if (input instanceof Request) {
return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
}
input = input.toString();
return this.fetch(
new Request(
/^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`,
requestInit
),
Env,
executionCtx
);
}, "request");
/**
* `.fire()` automatically adds a global fetch event listener.
* This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
* @deprecated
* Use `fire` from `hono/service-worker` instead.
* ```ts
* import { Hono } from 'hono'
* import { fire } from 'hono/service-worker'
*
* const app = new Hono()
* // ...
* fire(app)
* ```
* @see https://hono.dev/docs/api/hono#fire
* @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
* @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
*/
fire = /* @__PURE__ */ __name(() => {
addEventListener("fetch", (event) => {
event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
});
}, "fire");
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/matcher.js
var emptyParam = [];
function match(method, path) {
const matchers = this.buildAllMatchers();
const match2 = /* @__PURE__ */ __name(((method2, path2) => {
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
const staticMatch = matcher[2][path2];
if (staticMatch) {
return staticMatch;
}
const match3 = path2.match(matcher[0]);
if (!match3) {
return [[], emptyParam];
}
const index = match3.indexOf("", 1);
return [matcher[1][index], match3];
}), "match2");
this.match = match2;
return match2(method, path);
}
__name(match, "match");
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/node.js
var LABEL_REG_EXP_STR = "[^/]+";
var ONLY_WILDCARD_REG_EXP_STR = ".*";
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
var PATH_ERROR = /* @__PURE__ */ Symbol();
var regExpMetaChars = new Set(".\\+*[^]$()");
function compareKey(a, b) {
if (a.length === 1) {
return b.length === 1 ? a < b ? -1 : 1 : -1;
}
if (b.length === 1) {
return 1;
}
if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
return 1;
} else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
return -1;
}
if (a === LABEL_REG_EXP_STR) {
return 1;
} else if (b === LABEL_REG_EXP_STR) {
return -1;
}
return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
}
__name(compareKey, "compareKey");
var Node = class _Node {
static {
__name(this, "_Node");
}
#index;
#varIndex;
#children = /* @__PURE__ */ Object.create(null);
insert(tokens, index, paramMap, context2, pathErrorCheckOnly) {
if (tokens.length === 0) {
if (this.#index !== void 0) {
throw PATH_ERROR;
}
if (pathErrorCheckOnly) {
return;
}
this.#index = index;
return;
}
const [token, ...restTokens] = tokens;
const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
let node;
if (pattern) {
const name = pattern[1];
let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
if (name && pattern[2]) {
if (regexpStr === ".*") {
throw PATH_ERROR;
}
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
if (/\((?!\?:)/.test(regexpStr)) {
throw PATH_ERROR;
}
}
node = this.#children[regexpStr];
if (!node) {
if (Object.keys(this.#children).some(
(k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
)) {
throw PATH_ERROR;
}
if (pathErrorCheckOnly) {
return;
}
node = this.#children[regexpStr] = new _Node();
if (name !== "") {
node.#varIndex = context2.varIndex++;
}
}
if (!pathErrorCheckOnly && name !== "") {
paramMap.push([name, node.#varIndex]);
}
} else {
node = this.#children[token];
if (!node) {
if (Object.keys(this.#children).some(
(k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
)) {
throw PATH_ERROR;
}
if (pathErrorCheckOnly) {
return;
}
node = this.#children[token] = new _Node();
}
}
node.insert(restTokens, index, paramMap, context2, pathErrorCheckOnly);
}
buildRegExpStr() {
const childKeys = Object.keys(this.#children).sort(compareKey);
const strList = childKeys.map((k) => {
const c = this.#children[k];
return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
});
if (typeof this.#index === "number") {
strList.unshift(`#${this.#index}`);
}
if (strList.length === 0) {
return "";
}
if (strList.length === 1) {
return strList[0];
}
return "(?:" + strList.join("|") + ")";
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/trie.js
var Trie = class {
static {
__name(this, "Trie");
}
#context = { varIndex: 0 };
#root = new Node();
insert(path, index, pathErrorCheckOnly) {
const paramAssoc = [];
const groups = [];
for (let i = 0; ; ) {
let replaced = false;
path = path.replace(/\{[^}]+\}/g, (m) => {
const mark = `@\\${i}`;
groups[i] = [mark, m];
i++;
replaced = true;
return mark;
});
if (!replaced) {
break;
}
}
const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
for (let i = groups.length - 1; i >= 0; i--) {
const [mark] = groups[i];
for (let j = tokens.length - 1; j >= 0; j--) {
if (tokens[j].indexOf(mark) !== -1) {
tokens[j] = tokens[j].replace(mark, groups[i][1]);
break;
}
}
}
this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
return paramAssoc;
}
buildRegExp() {
let regexp = this.#root.buildRegExpStr();
if (regexp === "") {
return [/^$/, [], []];
}
let captureIndex = 0;
const indexReplacementMap = [];
const paramReplacementMap = [];
regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
if (handlerIndex !== void 0) {
indexReplacementMap[++captureIndex] = Number(handlerIndex);
return "$()";
}
if (paramIndex !== void 0) {
paramReplacementMap[Number(paramIndex)] = ++captureIndex;
return "";
}
return "";
});
return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/reg-exp-router/router.js
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
function buildWildcardRegExp(path) {
return wildcardRegExpCache[path] ??= new RegExp(
path === "*" ? "" : `^${path.replace(
/\/\*$|([.\\+*[^\]$()])/g,
(_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
)}$`
);
}
__name(buildWildcardRegExp, "buildWildcardRegExp");
function clearWildcardRegExpCache() {
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
}
__name(clearWildcardRegExpCache, "clearWildcardRegExpCache");
function buildMatcherFromPreprocessedRoutes(routes) {
const trie = new Trie();
const handlerData = [];
if (routes.length === 0) {
return nullMatcher;
}
const routesWithStaticPathFlag = routes.map(
(route) => [!/\*|\/:/.test(route[0]), ...route]
).sort(
([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
);
const staticMap = /* @__PURE__ */ Object.create(null);
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
if (pathErrorCheckOnly) {
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
} else {
j++;
}
let paramAssoc;
try {
paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
} catch (e) {
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
}
if (pathErrorCheckOnly) {
continue;
}
handlerData[j] = handlers.map(([h, paramCount]) => {
const paramIndexMap = /* @__PURE__ */ Object.create(null);
paramCount -= 1;
for (; paramCount >= 0; paramCount--) {
const [key, value] = paramAssoc[paramCount];
paramIndexMap[key] = value;
}
return [h, paramIndexMap];
});
}
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
for (let i = 0, len = handlerData.length; i < len; i++) {
for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
const map = handlerData[i][j]?.[1];
if (!map) {
continue;
}
const keys = Object.keys(map);
for (let k = 0, len3 = keys.length; k < len3; k++) {
map[keys[k]] = paramReplacementMap[map[keys[k]]];
}
}
}
const handlerMap = [];
for (const i in indexReplacementMap) {
handlerMap[i] = handlerData[indexReplacementMap[i]];
}
return [regexp, handlerMap, staticMap];
}
__name(buildMatcherFromPreprocessedRoutes, "buildMatcherFromPreprocessedRoutes");
function findMiddleware(middleware, path) {
if (!middleware) {
return void 0;
}
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
if (buildWildcardRegExp(k).test(path)) {
return [...middleware[k]];
}
}
return void 0;
}
__name(findMiddleware, "findMiddleware");
var RegExpRouter = class {
static {
__name(this, "RegExpRouter");
}
name = "RegExpRouter";
#middleware;
#routes;
constructor() {
this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
}
add(method, path, handler) {
const middleware = this.#middleware;
const routes = this.#routes;
if (!middleware || !routes) {
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
}
if (!middleware[method]) {
;
[middleware, routes].forEach((handlerMap) => {
handlerMap[method] = /* @__PURE__ */ Object.create(null);
Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
});
});
}
if (path === "/*") {
path = "*";
}
const paramCount = (path.match(/\/:/g) || []).length;
if (/\*$/.test(path)) {
const re = buildWildcardRegExp(path);
if (method === METHOD_NAME_ALL) {
Object.keys(middleware).forEach((m) => {
middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
});
} else {
middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
}
Object.keys(middleware).forEach((m) => {
if (method === METHOD_NAME_ALL || method === m) {
Object.keys(middleware[m]).forEach((p) => {
re.test(p) && middleware[m][p].push([handler, paramCount]);
});
}
});
Object.keys(routes).forEach((m) => {
if (method === METHOD_NAME_ALL || method === m) {
Object.keys(routes[m]).forEach(
(p) => re.test(p) && routes[m][p].push([handler, paramCount])
);
}
});
return;
}
const paths = checkOptionalParameter(path) || [path];
for (let i = 0, len = paths.length; i < len; i++) {
const path2 = paths[i];
Object.keys(routes).forEach((m) => {
if (method === METHOD_NAME_ALL || method === m) {
routes[m][path2] ||= [
...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
];
routes[m][path2].push([handler, paramCount - len + i + 1]);
}
});
}
}
match = match;
buildAllMatchers() {
const matchers = /* @__PURE__ */ Object.create(null);
Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
matchers[method] ||= this.#buildMatcher(method);
});
this.#middleware = this.#routes = void 0;
clearWildcardRegExpCache();
return matchers;
}
#buildMatcher(method) {
const routes = [];
let hasOwnRoute = method === METHOD_NAME_ALL;
[this.#middleware, this.#routes].forEach((r) => {
const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];
if (ownRoute.length !== 0) {
hasOwnRoute ||= true;
routes.push(...ownRoute);
} else if (method !== METHOD_NAME_ALL) {
routes.push(
...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])
);
}
});
if (!hasOwnRoute) {
return null;
} else {
return buildMatcherFromPreprocessedRoutes(routes);
}
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/smart-router/router.js
var SmartRouter = class {
static {
__name(this, "SmartRouter");
}
name = "SmartRouter";
#routers = [];
#routes = [];
constructor(init) {
this.#routers = init.routers;
}
add(method, path, handler) {
if (!this.#routes) {
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
}
this.#routes.push([method, path, handler]);
}
match(method, path) {
if (!this.#routes) {
throw new Error("Fatal error");
}
const routers = this.#routers;
const routes = this.#routes;
const len = routers.length;
let i = 0;
let res;
for (; i < len; i++) {
const router = routers[i];
try {
for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
router.add(...routes[i2]);
}
res = router.match(method, path);
} catch (e) {
if (e instanceof UnsupportedPathError) {
continue;
}
throw e;
}
this.match = router.match.bind(router);
this.#routers = [router];
this.#routes = void 0;
break;
}
if (i === len) {
throw new Error("Fatal error");
}
this.name = `SmartRouter + ${this.activeRouter.name}`;
return res;
}
get activeRouter() {
if (this.#routes || this.#routers.length !== 1) {
throw new Error("No active router has been determined yet.");
}
return this.#routers[0];
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/node.js
var emptyParams = /* @__PURE__ */ Object.create(null);
var hasChildren = /* @__PURE__ */ __name((children) => {
for (const _ in children) {
return true;
}
return false;
}, "hasChildren");
var Node2 = class _Node2 {
static {
__name(this, "_Node");
}
#methods;
#children;
#patterns;
#order = 0;
#params = emptyParams;
constructor(method, handler, children) {
this.#children = children || /* @__PURE__ */ Object.create(null);
this.#methods = [];
if (method && handler) {
const m = /* @__PURE__ */ Object.create(null);
m[method] = { handler, possibleKeys: [], score: 0 };
this.#methods = [m];
}
this.#patterns = [];
}
insert(method, path, handler) {
this.#order = ++this.#order;
let curNode = this;
const parts = splitRoutingPath(path);
const possibleKeys = [];
for (let i = 0, len = parts.length; i < len; i++) {
const p = parts[i];
const nextP = parts[i + 1];
const pattern = getPattern(p, nextP);
const key = Array.isArray(pattern) ? pattern[0] : p;
if (key in curNode.#children) {
curNode = curNode.#children[key];
if (pattern) {
possibleKeys.push(pattern[1]);
}
continue;
}
curNode.#children[key] = new _Node2();
if (pattern) {
curNode.#patterns.push(pattern);
possibleKeys.push(pattern[1]);
}
curNode = curNode.#children[key];
}
curNode.#methods.push({
[method]: {
handler,
possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
score: this.#order
}
});
return curNode;
}
#pushHandlerSets(handlerSets, node, method, nodeParams, params) {
for (let i = 0, len = node.#methods.length; i < len; i++) {
const m = node.#methods[i];
const handlerSet = m[method] || m[METHOD_NAME_ALL];
const processedSet = {};
if (handlerSet !== void 0) {
handlerSet.params = /* @__PURE__ */ Object.create(null);
handlerSets.push(handlerSet);
if (nodeParams !== emptyParams || params && params !== emptyParams) {
for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
const key = handlerSet.possibleKeys[i2];
const processed = processedSet[handlerSet.score];
handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
processedSet[handlerSet.score] = true;
}
}
}
}
}
search(method, path) {
const handlerSets = [];
this.#params = emptyParams;
const curNode = this;
let curNodes = [curNode];
const parts = splitPath(path);
const curNodesQueue = [];
const len = parts.length;
let partOffsets = null;
for (let i = 0; i < len; i++) {
const part = parts[i];
const isLast = i === len - 1;
const tempNodes = [];
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
const node = curNodes[j];
const nextNode = node.#children[part];
if (nextNode) {
nextNode.#params = node.#params;
if (isLast) {
if (nextNode.#children["*"]) {
this.#pushHandlerSets(handlerSets, nextNode.#children["*"], method, node.#params);
}
this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);
} else {
tempNodes.push(nextNode);
}
}
for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {
const pattern = node.#patterns[k];
const params = node.#params === emptyParams ? {} : { ...node.#params };
if (pattern === "*") {
const astNode = node.#children["*"];
if (astNode) {
this.#pushHandlerSets(handlerSets, astNode, method, node.#params);
astNode.#params = params;
tempNodes.push(astNode);
}
continue;
}
const [key, name, matcher] = pattern;
if (!part && !(matcher instanceof RegExp)) {
continue;
}
const child = node.#children[key];
if (matcher instanceof RegExp) {
if (partOffsets === null) {
partOffsets = new Array(len);
let offset = path[0] === "/" ? 1 : 0;
for (let p = 0; p < len; p++) {
partOffsets[p] = offset;
offset += parts[p].length + 1;
}
}
const restPathString = path.substring(partOffsets[i]);
const m = matcher.exec(restPathString);
if (m) {
params[name] = m[0];
this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
if (hasChildren(child.#children)) {
child.#params = params;
const componentCount = m[0].match(/\//)?.length ?? 0;
const targetCurNodes = curNodesQueue[componentCount] ||= [];
targetCurNodes.push(child);
}
continue;
}
}
if (matcher === true || matcher.test(part)) {
params[name] = part;
if (isLast) {
this.#pushHandlerSets(handlerSets, child, method, params, node.#params);
if (child.#children["*"]) {
this.#pushHandlerSets(
handlerSets,
child.#children["*"],
method,
params,
node.#params
);
}
} else {
child.#params = params;
tempNodes.push(child);
}
}
}
}
const shifted = curNodesQueue.shift();
curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
}
if (handlerSets.length > 1) {
handlerSets.sort((a, b) => {
return a.score - b.score;
});
}
return [handlerSets.map(({ handler, params }) => [handler, params])];
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/router/trie-router/router.js
var TrieRouter = class {
static {
__name(this, "TrieRouter");
}
name = "TrieRouter";
#node;
constructor() {
this.#node = new Node2();
}
add(method, path, handler) {
const results = checkOptionalParameter(path);
if (results) {
for (let i = 0, len = results.length; i < len; i++) {
this.#node.insert(method, results[i], handler);
}
return;
}
this.#node.insert(method, path, handler);
}
match(method, path) {
return this.#node.search(method, path);
}
};
// node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/hono.js
var Hono2 = class extends Hono {
static {
__name(this, "Hono");
}
/**
* Creates an instance of the Hono class.
*
* @param options - Optional configuration options for the Hono instance.
*/
constructor(options = {}) {
super(options);
this.router = options.router ?? new SmartRouter({
routers: [new RegExpRouter(), new TrieRouter()]
});
}
};
// src/actions/entry-crud.ts
function uid(prefix) {
return `${prefix}_${crypto.randomUUID()}`;
}
__name(uid, "uid");
async function createEntry(db, input) {
const id = input.id ?? uid("e");
await db.prepare(
`INSERT INTO entries (id, content, entry_type, owner_id, parent_id, page_name, refs_json, tags_json, task_status, confidence, metadata_json)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).bind(
id,
input.content ?? null,
input.entry_type,
input.owner_id ?? null,
input.parent_id ?? null,
input.page_name ?? null,
input.refs_json ?? "[]",
input.tags_json ?? "[]",
input.task_status ?? null,
input.confidence ?? null,
input.metadata_json ?? null
).run();
const row = await getEntry(db, id);
if (!row) throw new Error("createEntry: insert succeeded but row not found");
return row;
}
__name(createEntry, "createEntry");
async function getEntry(db, id) {
const row = await db.prepare("SELECT * FROM entries WHERE id = ?").bind(id).first();
return row ?? null;
}
__name(getEntry, "getEntry");
async function listEntries(db, f = {}) {
const conds = [];
const params = [];
if (f.entry_type) {
conds.push("entry_type = ?");
params.push(f.entry_type);
}
if (f.owner_id) {
conds.push("owner_id = ?");
params.push(f.owner_id);
}
if (f.parent_id) {
conds.push("parent_id = ?");
params.push(f.parent_id);
}
if (f.page_name) {
conds.push("page_name = ?");
params.push(f.page_name);
}
if (f.source) {
conds.push("json_extract(metadata_json, '$.source') = ?");
params.push(f.source);
}
if (f.library && f.library.length > 0) {
conds.push(libraryPredicate(f.library));
params.push(...f.library);
}
if (f.q) {
conds.push("content LIKE ?");
params.push(`%${f.q}%`);
}
const where = conds.length ? `WHERE ${conds.join(" AND ")}` : "";
const limit = Math.min(f.limit ?? 100, 1e3);
const offset = f.offset ?? 0;
const [rowsRes, countRow] = await Promise.all([
db.prepare(`SELECT * FROM entries ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`).bind(...params, limit, offset).all(),
db.prepare(`SELECT COUNT(*) as total FROM entries ${where}`).bind(...params).first()
]);
return { entries: rowsRes.results ?? [], total: countRow?.total ?? 0 };
}
__name(listEntries, "listEntries");
async function updateEntry(db, id, patch) {
const cols = [];
const params = [];
const map = patch;
for (const k of ["content", "parent_id", "page_name", "refs_json", "tags_json", "task_status", "confidence", "metadata_json"]) {
if (k in map && map[k] !== void 0) {
cols.push(`${k} = ?`);
params.push(map[k]);
}
}
if (cols.length === 0) return getEntry(db, id);
cols.push("updated_at = unixepoch()");
await db.prepare(`UPDATE entries SET ${cols.join(", ")} WHERE id = ?`).bind(...params, id).run();
return getEntry(db, id);
}
__name(updateEntry, "updateEntry");
async function deleteEntry(db, id) {
await db.prepare("DELETE FROM entries WHERE id = ?").bind(id).run();
}
__name(deleteEntry, "deleteEntry");
function libraryPredicate(libraries) {
const placeholders = libraries.map(() => "?").join(",");
return `COALESCE(json_extract(metadata_json, '$.library'), 'general') IN (${placeholders})`;
}
__name(libraryPredicate, "libraryPredicate");
var NOT_DEPRECATED_PREDICATE = "(json_extract(metadata_json, '$.status') IS NULL OR json_extract(metadata_json, '$.status') != 'deprecated')";
function isDeprecatedEntry(entry) {
if (!entry.metadata_json) return false;
try {
const meta = JSON.parse(entry.metadata_json);
return !!meta && meta.status === "deprecated";
} catch {
return false;
}
}
__name(isDeprecatedEntry, "isDeprecatedEntry");
async function searchEntries(db, q, owner_id, entry_type, limit = 50, library, source, includeDeprecated = false) {
const conds = ["content LIKE ?"];
const params = [`%${q}%`];
if (owner_id) {
conds.push("owner_id = ?");
params.push(owner_id);
}
if (entry_type) {
conds.push("entry_type = ?");
params.push(entry_type);
}
if (source) {
conds.push("json_extract(metadata_json, '$.source') = ?");
params.push(source);
}
if (library && library.length > 0) {
conds.push(libraryPredicate(library));
params.push(...library);
}
if (!includeDeprecated) {
conds.push(NOT_DEPRECATED_PREDICATE);
}
const res = await db.prepare(`SELECT * FROM entries WHERE ${conds.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`).bind(...params, Math.min(limit, 200)).all();
return res.results ?? [];
}
__name(searchEntries, "searchEntries");
// src/embed.ts
var EMBED_MODEL = "@cf/baai/bge-base-en-v1.5";
function embedEnabled(env2) {
return !!(env2.VECTORIZE && env2.AI);
}
__name(embedEnabled, "embedEnabled");
async function embedText(env2, text) {
const t = (text ?? "").trim();
if (!t || !env2.AI) return null;
const res = await env2.AI.run(EMBED_MODEL, { text: [t] });
return res?.data?.[0] ?? null;
}
__name(embedText, "embedText");
async function embedOnWrite(env2, entry) {
if (!embedEnabled(env2)) return false;
if (!isEmbeddable(entry)) return false;
const vec = await embedText(env2, entry.content ?? "");
if (!vec) return false;
await env2.VECTORIZE.upsert([
{
id: entry.id,
values: vec,
// metadata 走 indexed 範圍:owner_id(租戶隔離)、entry_type、source#5.1 過濾與語義共用)、
// libraryportal-auth P1「庫」filter)。library 在寫入端正規化:未標記='general'design §3.2
// 「未蓋章的舊資料視同 general」——D1 側用查詢端 COALESCE fallbackVectorize filter 做不了
// COALESCE,故在 upsert 時蓋 'general',查詢端單純 $in 即可)。
metadata: {
owner_id: entry.owner_id ?? "",
entry_type: entry.entry_type,
source: readSource(entry) ?? "",
library: readLibrary(entry) ?? "general"
}
}
]);
await env2.DB.prepare("UPDATE entries SET is_embedded = 1 WHERE id = ?").bind(entry.id).run();
return true;
}
__name(embedOnWrite, "embedOnWrite");
function isEmbeddable(entry) {
const meta = parseMeta(entry.metadata_json);
return meta?.embed === true;
}
__name(isEmbeddable, "isEmbeddable");
function readSource(entry) {
const meta = parseMeta(entry.metadata_json);
const s = meta?.source;
return typeof s === "string" ? s : null;
}
__name(readSource, "readSource");
function readLibrary(entry) {
const meta = parseMeta(entry.metadata_json);
const l = meta?.library;
return typeof l === "string" && l.trim() !== "" ? l : null;
}
__name(readLibrary, "readLibrary");
function parseMeta(json) {
if (!json) return null;
try {
const p = JSON.parse(json);
return p && typeof p === "object" ? p : null;
} catch {
return null;
}
}
__name(parseMeta, "parseMeta");
var BACKFILL_PREDICATE = "is_embedded = 0 AND content IS NOT NULL AND content <> '' AND json_extract(metadata_json, '$.embed') = 1";
async function backfillEmbeddings(env2, opts = {}) {
if (!embedEnabled(env2)) return { enabled: false, processed: 0, skipped: 0, remaining: 0, scanned: 0 };
const limit = Math.min(Math.max(opts.limit ?? 25, 1), 100);
const offset = Math.max(opts.offset ?? 0, 0);
const basePredicate = opts.reindex ? "content IS NOT NULL AND content <> '' AND json_extract(metadata_json, '$.embed') = 1" : BACKFILL_PREDICATE;
const conds = [basePredicate];
const params = [];
if (opts.owner_id) {
conds.push("owner_id = ?");
params.push(opts.owner_id);
}
if (opts.source) {
conds.push("json_extract(metadata_json, '$.source') = ?");
params.push(opts.source);
}
const where = conds.join(" AND ");
const res = await env2.DB.prepare(`SELECT * FROM entries WHERE ${where} ORDER BY created_at ASC LIMIT ? OFFSET ?`).bind(...params, limit, offset).all();
const rows = res.results ?? [];
const scanned = rows.length;
let processed = 0;
const embeddable = rows.filter((e) => (e.content ?? "").trim().length > 0);
if (embeddable.length > 0 && env2.AI && env2.VECTORIZE) {
const texts = embeddable.map((e) => (e.content ?? "").trim());
const out = await env2.AI.run(EMBED_MODEL, { text: texts });
const data = out?.data ?? [];
const vectors = embeddable.map((e, i) => ({ e, vec: data[i] })).filter((x) => Array.isArray(x.vec) && x.vec.length > 0).map((x) => ({
id: x.e.id,
values: x.vec,
metadata: {
owner_id: x.e.owner_id ?? "",
entry_type: x.e.entry_type,
source: readSource(x.e) ?? "",
library: readLibrary(x.e) ?? "general"
// 同 embedOnWrite:寫入端正規化(P1
}
}));
if (vectors.length > 0) {
await env2.VECTORIZE.upsert(vectors);
const ids = vectors.map((v) => v.id);
const placeholders = ids.map(() => "?").join(",");
await env2.DB.prepare(`UPDATE entries SET is_embedded = 1 WHERE id IN (${placeholders})`).bind(...ids).run();
processed = vectors.length;
}
}
const remRow = await env2.DB.prepare(`SELECT COUNT(*) as c FROM entries WHERE ${where}`).bind(...params).first();
const totalMatching = remRow?.c ?? 0;
const remaining = opts.reindex ? Math.max(0, totalMatching - (offset + scanned)) : totalMatching;
return { enabled: true, processed, skipped: scanned - processed, remaining, scanned };
}
__name(backfillEmbeddings, "backfillEmbeddings");
async function backfillStatus(env2, opts = {}) {
const conds = [];
const params = [];
if (opts.owner_id) {
conds.push("owner_id = ?");
params.push(opts.owner_id);
}
if (opts.source) {
conds.push("json_extract(metadata_json, '$.source') = ?");
params.push(opts.source);
}
const extra = conds.length ? ` AND ${conds.join(" AND ")}` : "";
const pendingRow = await env2.DB.prepare(`SELECT COUNT(*) as c FROM entries WHERE ${BACKFILL_PREDICATE}${extra}`).bind(...params).first();
const embeddedRow = await env2.DB.prepare(`SELECT COUNT(*) as c FROM entries WHERE is_embedded = 1 AND json_extract(metadata_json, '$.embed') = 1${extra}`).bind(...params).first();
return { enabled: embedEnabled(env2), pending: pendingRow?.c ?? 0, embedded: embeddedRow?.c ?? 0 };
}
__name(backfillStatus, "backfillStatus");
async function semanticSearch(env2, q, opts = {}) {
if (!embedEnabled(env2)) return null;
const vec = await embedText(env2, q);
if (!vec) return [];
const filter = {};
if (opts.owner_id) filter.owner_id = opts.owner_id;
if (opts.source) filter.source = opts.source;
if (opts.entry_type) filter.entry_type = opts.entry_type;
if (opts.library && opts.library.length > 0) filter.library = { $in: opts.library };
const res = await env2.VECTORIZE.query(vec, {
topK: Math.min(opts.topK ?? 20, 100),
returnMetadata: "indexed",
...Object.keys(filter).length ? { filter } : {}
});
const minScore = opts.min_score ?? 0;
return (res.matches ?? []).filter((m) => m.score >= minScore).map((m) => ({
id: m.id,
score: m.score,
owner_id: m.metadata?.owner_id,
entry_type: m.metadata?.entry_type,
source: m.metadata?.source,
library: m.metadata?.library
}));
}
__name(semanticSearch, "semanticSearch");
// src/routes/entries.ts
var entryRoutes = new Hono2();
function parseLibraryParam(raw2) {
if (!raw2) return void 0;
const libs = raw2.split(",").map((s) => s.trim()).filter(Boolean);
return libs.length > 0 ? libs : void 0;
}
__name(parseLibraryParam, "parseLibraryParam");
entryRoutes.post("/", async (c) => {
const body = await c.req.json().catch(() => null);
if (!body || !body.entry_type) return c.json({ success: false, error: "entry_type required" }, 400);
const entry = await createEntry(c.env.DB, body);
if (embedEnabled(c.env)) c.executionCtx.waitUntil(embedOnWrite(c.env, entry).catch(() => {
}));
return c.json({ success: true, entry });
});
entryRoutes.get("/", async (c) => {
const { entries, total } = await listEntries(c.env.DB, {
entry_type: c.req.query("entry_type") || void 0,
owner_id: c.req.query("owner_id") || void 0,
parent_id: c.req.query("parent_id") || void 0,
page_name: c.req.query("page_name") || void 0,
source: c.req.query("source") || void 0,
library: parseLibraryParam(c.req.query("library")),
q: c.req.query("q") || c.req.query("search") || void 0,
limit: c.req.query("limit") ? Number(c.req.query("limit")) : void 0,
offset: c.req.query("offset") ? Number(c.req.query("offset")) : void 0
});
return c.json({ success: true, entries, count: entries.length, total });
});
entryRoutes.get("/search", async (c) => {
const q = c.req.query("q");
if (!q) return c.json({ success: false, error: "q required" }, 400);
const owner_id = c.req.query("owner_id") || void 0;
const source = c.req.query("source") || void 0;
const entry_type = c.req.query("entry_type") || void 0;
const library = parseLibraryParam(c.req.query("library"));
const mode = c.req.query("mode") === "semantic" ? "semantic" : "keyword";
const include_deprecated = c.req.query("include_deprecated") === "true";
const topKNum = Number(c.req.query("top_k"));
const top_k = Number.isFinite(topKNum) && topKNum > 0 ? Math.floor(topKNum) : void 0;
const minScoreNum = Number(c.req.query("min_score"));
const min_score = Number.isFinite(minScoreNum) && minScoreNum > 0 ? minScoreNum : void 0;
if (mode === "semantic") {
const requestedTopK = top_k ?? 20;
const fetchTopK = include_deprecated ? requestedTopK : Math.min(requestedTopK * 3, 100);
const hits = await semanticSearch(c.env, q, {
owner_id,
source,
entry_type,
library,
topK: fetchTopK,
min_score
});
if (hits === null) {
const entries3 = await searchEntries(c.env.DB, q, owner_id, entry_type, void 0, library, source, include_deprecated);
return c.json({
success: true,
entries: entries3,
count: entries3.length,
mode: "keyword",
requested_mode: "semantic",
capability_hint: "\u8A9E\u7FA9\u67E5\u8A62\u9700\u5148\u958B vectorize\uFF08embed \u6A21\u7D44\uFF09\u3002\u53EB CC\u300C\u5E6B\u6211\u958B\u8A9E\u7FA9\u67E5\u8A62\u300D\u5373\u53EF\uFF08\u8A2D kbdb_embed:true + redeploy\uFF09\u3002\u672C\u6B21\u5DF2\u964D\u7D1A\u95DC\u9375\u5B57\u641C\u5C0B\u3002"
});
}
let entries2 = (await Promise.all(
hits.map(async (h) => {
const e = await getEntry(c.env.DB, h.id);
return e ? { ...e, score: h.score } : null;
})
)).filter((e) => e !== null);
if (!include_deprecated) {
entries2 = entries2.filter((e) => !isDeprecatedEntry(e));
}
entries2 = entries2.slice(0, requestedTopK);
return c.json({ success: true, entries: entries2, count: entries2.length, mode: "semantic" });
}
const entries = await searchEntries(c.env.DB, q, owner_id, entry_type, void 0, library, source, include_deprecated);
return c.json({ success: true, entries, count: entries.length, mode: "keyword" });
});
entryRoutes.get("/:id", async (c) => {
const entry = await getEntry(c.env.DB, c.req.param("id"));
if (!entry) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, entry });
});
entryRoutes.patch("/:id", async (c) => {
const body = await c.req.json().catch(() => ({}));
const entry = await updateEntry(c.env.DB, c.req.param("id"), body);
if (!entry) return c.json({ success: false, error: "not found" }, 404);
if (embedEnabled(c.env) && body.content !== void 0) {
c.executionCtx.waitUntil(embedOnWrite(c.env, entry).catch(() => {
}));
}
return c.json({ success: true, entry });
});
entryRoutes.delete("/:id", async (c) => {
if (embedEnabled(c.env)) {
c.executionCtx.waitUntil(c.env.VECTORIZE.deleteByIds([c.req.param("id")]).then(() => {
}).catch(() => {
}));
}
await deleteEntry(c.env.DB, c.req.param("id"));
return c.json({ success: true });
});
// src/actions/record-crud.ts
function uid2(prefix) {
return `${prefix}_${crypto.randomUUID()}`;
}
__name(uid2, "uid");
async function createTemplate(db, input) {
const id = input.id ?? uid2("tpl");
await db.prepare(`INSERT INTO templates (id, name, description, slots_json, created_by) VALUES (?, ?, ?, ?, ?)`).bind(id, input.name, input.description ?? null, JSON.stringify(input.slots), input.created_by ?? null).run();
const row = await getTemplate(db, id);
if (!row) throw new Error("createTemplate: row not found after insert");
return row;
}
__name(createTemplate, "createTemplate");
async function getTemplate(db, idOrName) {
const row = await db.prepare("SELECT * FROM templates WHERE id = ? OR name = ? LIMIT 1").bind(idOrName, idOrName).first();
return row ?? null;
}
__name(getTemplate, "getTemplate");
async function listTemplates(db) {
const res = await db.prepare("SELECT * FROM templates ORDER BY created_at DESC").all();
return res.results ?? [];
}
__name(listTemplates, "listTemplates");
async function updateTemplate(db, id, patch) {
const cols = [];
const params = [];
if (patch.description !== void 0) {
cols.push("description = ?");
params.push(patch.description);
}
if (patch.slots !== void 0) {
cols.push("slots_json = ?");
params.push(JSON.stringify(patch.slots));
}
if (cols.length === 0) return getTemplate(db, id);
cols.push("updated_at = unixepoch()");
await db.prepare(`UPDATE templates SET ${cols.join(", ")} WHERE id = ?`).bind(...params, id).run();
return getTemplate(db, id);
}
__name(updateTemplate, "updateTemplate");
async function createRecord(db, input) {
const tpl = await getTemplate(db, input.template);
if (!tpl) throw new Error(`template not found: ${input.template}`);
const slots = JSON.parse(tpl.slots_json);
const recordId = input.record_id ?? uid2("rec");
for (const slot of slots) {
if (!(slot in input.values)) continue;
const entry = await createEntry(db, {
content: input.values[slot],
entry_type: "value",
owner_id: input.owner_id ?? null
});
await db.prepare(`INSERT INTO entry_values (id, record_id, template_id, slot_name, entry_id) VALUES (?, ?, ?, ?, ?)`).bind(uid2("ev"), recordId, tpl.id, slot, entry.id).run();
}
return { record_id: recordId, template_id: tpl.id, values: input.values };
}
__name(createRecord, "createRecord");
async function updateRecord(db, recordId, values) {
const evRes = await db.prepare(
`SELECT ev.slot_name AS slot_name, ev.entry_id AS entry_id, ev.template_id AS template_id, e.owner_id AS owner_id
FROM entry_values ev JOIN entries e ON ev.entry_id = e.id
WHERE ev.record_id = ?`
).bind(recordId).all();
const evRows = evRes.results ?? [];
if (evRows.length === 0) return null;
const templateId = evRows[0].template_id;
const recordOwnerId = evRows.find((r) => r.owner_id != null)?.owner_id ?? null;
const slotToEntry = new Map(evRows.map((r) => [r.slot_name, r.entry_id]));
const tpl = await getTemplate(db, templateId);
const allowed = tpl ? JSON.parse(tpl.slots_json) : [...slotToEntry.keys()];
for (const [slot, content] of Object.entries(values)) {
if (!allowed.includes(slot)) {
throw new Error(`slot not in template: ${slot}`);
}
const entryId = slotToEntry.get(slot);
if (entryId) {
await db.prepare(`UPDATE entries SET content = ?, updated_at = unixepoch() WHERE id = ?`).bind(content, entryId).run();
} else {
const entry = await createEntry(db, { content, entry_type: "value", owner_id: recordOwnerId });
await db.prepare(`INSERT INTO entry_values (id, record_id, template_id, slot_name, entry_id) VALUES (?, ?, ?, ?, ?)`).bind(uid2("ev"), recordId, templateId, slot, entry.id).run();
}
}
return getRecord(db, recordId);
}
__name(updateRecord, "updateRecord");
async function getRecord(db, recordId) {
const res = await db.prepare(
`SELECT ev.slot_name as slot, e.content as content, ev.template_id as template_id
FROM entry_values ev JOIN entries e ON ev.entry_id = e.id
WHERE ev.record_id = ?`
).bind(recordId).all();
const rows = res.results ?? [];
if (rows.length === 0) return null;
const values = {};
for (const r of rows) values[r.slot] = r.content;
return { record_id: recordId, template_id: rows[0].template_id, values };
}
__name(getRecord, "getRecord");
async function searchByTemplate(db, template, owner_id, limit = 100) {
const tpl = await getTemplate(db, template);
if (!tpl) return [];
const cap = Math.min(limit, 500);
const res = owner_id ? await db.prepare(
`SELECT DISTINCT ev.record_id as record_id FROM entry_values ev
JOIN entries e ON ev.entry_id = e.id
WHERE ev.template_id = ? AND e.owner_id = ?
ORDER BY ev.created_at DESC LIMIT ?`
).bind(tpl.id, owner_id, cap).all() : await db.prepare(`SELECT DISTINCT record_id FROM entry_values WHERE template_id = ? ORDER BY created_at DESC LIMIT ?`).bind(tpl.id, cap).all();
const ids = (res.results ?? []).map((r) => r.record_id);
if (ids.length === 0) return [];
const byId = /* @__PURE__ */ new Map();
for (let i = 0; i < ids.length; i += 90) {
const chunk = ids.slice(i, i + 90);
const placeholders = chunk.map(() => "?").join(",");
const evRes = await db.prepare(
`SELECT ev.record_id as record_id, ev.slot_name as slot, e.content as content, ev.template_id as template_id
FROM entry_values ev JOIN entries e ON ev.entry_id = e.id
WHERE ev.record_id IN (${placeholders})`
).bind(...chunk).all();
for (const r of evRes.results ?? []) {
let rec = byId.get(r.record_id);
if (!rec) {
rec = { record_id: r.record_id, template_id: r.template_id, values: {} };
byId.set(r.record_id, rec);
}
rec.values[r.slot] = r.content;
}
}
return ids.map((id) => byId.get(id)).filter((r) => !!r);
}
__name(searchByTemplate, "searchByTemplate");
// src/routes/templates.ts
var templateRoutes = new Hono2();
templateRoutes.post("/", async (c) => {
const body = await c.req.json().catch(() => null);
if (!body || !body.name || !Array.isArray(body.slots)) {
return c.json({ success: false, error: "name and slots[] required" }, 400);
}
const tpl = await createTemplate(c.env.DB, body);
return c.json({ success: true, template: tpl });
});
templateRoutes.get("/", async (c) => {
const templates = await listTemplates(c.env.DB);
return c.json({ success: true, templates, count: templates.length });
});
templateRoutes.get("/:idOrName", async (c) => {
const tpl = await getTemplate(c.env.DB, c.req.param("idOrName"));
if (!tpl) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, template: tpl });
});
templateRoutes.patch("/:id", async (c) => {
const body = await c.req.json().catch(() => ({}));
const tpl = await updateTemplate(c.env.DB, c.req.param("id"), body);
if (!tpl) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, template: tpl });
});
// src/routes/records.ts
var recordRoutes = new Hono2();
recordRoutes.post("/", async (c) => {
const body = await c.req.json().catch(() => null);
if (!body || !body.template || !body.values) {
return c.json({ success: false, error: "template and values required" }, 400);
}
try {
const rec = await createRecord(c.env.DB, body);
return c.json({ success: true, record: rec });
} catch (e) {
return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 400);
}
});
recordRoutes.get("/by-template/:template", async (c) => {
const records = await searchByTemplate(c.env.DB, c.req.param("template"), c.req.query("owner_id") || void 0);
return c.json({ success: true, records, count: records.length });
});
recordRoutes.get("/:recordId", async (c) => {
const rec = await getRecord(c.env.DB, c.req.param("recordId"));
if (!rec) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, record: rec });
});
recordRoutes.patch("/:recordId", async (c) => {
const body = await c.req.json().catch(() => null);
if (!body || !body.values || typeof body.values !== "object") {
return c.json({ success: false, error: "values required" }, 400);
}
try {
const rec = await updateRecord(c.env.DB, c.req.param("recordId"), body.values);
if (!rec) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, record: rec });
} catch (e) {
return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 400);
}
});
// src/actions/recipe-stat.ts
function statId(canonicalId) {
return `recipestat:${canonicalId}`;
}
__name(statId, "statId");
async function recordRecipeResult(db, canonicalId, ok, nowMs) {
const id = statId(canonicalId);
const existing = await db.prepare("SELECT metadata_json FROM entries WHERE id = ?").bind(id).first();
let stat;
if (existing) {
const prev = existing.metadata_json ? JSON.parse(existing.metadata_json) : emptyStat(canonicalId);
stat = {
canonical_id: canonicalId,
success_count: prev.success_count + (ok ? 1 : 0),
failure_count: prev.failure_count + (ok ? 0 : 1),
last_status: ok ? "success" : "failure",
last_at: nowMs
};
await db.prepare("UPDATE entries SET metadata_json = ?, updated_at = unixepoch() WHERE id = ?").bind(JSON.stringify(stat), id).run();
} else {
stat = {
canonical_id: canonicalId,
success_count: ok ? 1 : 0,
failure_count: ok ? 0 : 1,
last_status: ok ? "success" : "failure",
last_at: nowMs
};
await db.prepare("INSERT INTO entries (id, content, entry_type, metadata_json) VALUES (?, ?, ?, ?)").bind(id, canonicalId, "recipe_stat", JSON.stringify(stat)).run();
}
return stat;
}
__name(recordRecipeResult, "recordRecipeResult");
async function getRecipeStat(db, canonicalId) {
const row = await db.prepare("SELECT metadata_json FROM entries WHERE id = ?").bind(statId(canonicalId)).first();
if (!row || !row.metadata_json) return emptyStat(canonicalId);
return JSON.parse(row.metadata_json);
}
__name(getRecipeStat, "getRecipeStat");
function emptyStat(canonicalId) {
return { canonical_id: canonicalId, success_count: 0, failure_count: 0, last_status: null, last_at: null };
}
__name(emptyStat, "emptyStat");
// src/routes/recipe-stats.ts
var recipeStatRoutes = new Hono2();
recipeStatRoutes.post("/record", async (c) => {
const body = await c.req.json().catch(() => null);
if (!body || !body.canonical_id || typeof body.ok !== "boolean") {
return c.json({ success: false, error: "canonical_id and ok(boolean) required" }, 400);
}
const at = typeof body.at === "number" ? body.at : 0;
const stat = await recordRecipeResult(c.env.DB, body.canonical_id, body.ok, at);
return c.json({ success: true, stat });
});
recipeStatRoutes.get("/:canonical_id", async (c) => {
const stat = await getRecipeStat(c.env.DB, c.req.param("canonical_id"));
return c.json({ success: true, stat });
});
// src/routes/embed.ts
var embedRoutes = new Hono2();
var OFF_HINT = "\u8A9E\u7FA9\u88DC\u5D4C\u9700\u5148\u958B embed \u6A21\u7D44\uFF08Vectorize+AI binding\uFF09\u3002\u53EB CC\u300C\u5E6B\u6211\u958B\u8A9E\u7FA9\u67E5\u8A62\u300D\uFF08\u8A2D kbdb_embed:true + redeploy \u6CE8\u5165 binding\uFF09\u5F8C\u518D\u547C\u53EB\u672C\u7AEF\u9EDE\u3002";
embedRoutes.post("/backfill", async (c) => {
if (!embedEnabled(c.env)) {
return c.json(
{ success: false, error: "embed module not enabled (need VECTORIZE + AI bindings)", capability_hint: OFF_HINT },
409
);
}
const body = await c.req.json().catch(() => ({}));
const result = await backfillEmbeddings(c.env, {
limit: body.limit !== void 0 ? Number(body.limit) : void 0,
owner_id: body.owner_id || void 0,
source: body.source || void 0,
// reindexArcrun#11):重推既有向量讓事後建立的 Vectorize metadata index 收錄(見 embed.ts)。
reindex: body.reindex === true,
offset: body.offset !== void 0 ? Number(body.offset) : void 0
});
return c.json({ success: true, ...result });
});
embedRoutes.get("/backfill/status", async (c) => {
const status = await backfillStatus(c.env, {
owner_id: c.req.query("owner_id") || void 0,
source: c.req.query("source") || void 0
});
return c.json({ success: true, ...status });
});
// src/actions/library-map.ts
var LIBRARY_MAP_TEMPLATE_ID = "tpl-library-map";
var LIBRARY_MAP_TEMPLATE_NAME = "library_map";
var LIBRARY_MAP_SLOTS = [
"library",
"narrative",
"top_entities",
"relation_profile",
"bridges",
"triplet_count",
"commit_hash",
"status"
];
var DEFAULT_TRIPLET_TEMPLATE = "triplet";
async function ensureLibraryMapTemplate(db) {
const existing = await getTemplate(db, LIBRARY_MAP_TEMPLATE_NAME);
if (existing) return;
try {
await createTemplate(db, {
id: LIBRARY_MAP_TEMPLATE_ID,
name: LIBRARY_MAP_TEMPLATE_NAME,
description: "per-library map block\uFF08\u85CF\u66F8\u5730\u5716\uFF1Agraph \u6A5F\u68B0\u5C0E\u51FA\uFF0C\u96F6 LLM \u751F\u6210\uFF1BArcrun#39\uFF09",
slots: LIBRARY_MAP_SLOTS,
created_by: "system"
});
} catch {
if (!await getTemplate(db, LIBRARY_MAP_TEMPLATE_NAME)) throw new Error("ensureLibraryMapTemplate failed");
}
}
__name(ensureLibraryMapTemplate, "ensureLibraryMapTemplate");
async function ensureTripletLibrarySlot(db, tripletTemplate) {
const tpl = await getTemplate(db, tripletTemplate);
if (!tpl) throw new Error(`triplet template not found: ${tripletTemplate}`);
const slots = JSON.parse(tpl.slots_json);
if (slots.includes("library")) return false;
await updateTemplate(db, tpl.id, { slots: [...slots, "library"] });
return true;
}
__name(ensureTripletLibrarySlot, "ensureTripletLibrarySlot");
function tripletPivotSql(ownerFiltered) {
return `SELECT ev.record_id AS rid,
MAX(CASE WHEN ev.slot_name = 'subject' THEN e.content END) AS subject,
MAX(CASE WHEN ev.slot_name = 'object' THEN e.content END) AS object,
MAX(CASE WHEN ev.slot_name = 'predicate' THEN e.content END) AS predicate,
MAX(CASE WHEN ev.slot_name = 'status' THEN e.content END) AS status,
MAX(CASE WHEN ev.slot_name = 'library' THEN e.content END) AS library,
MAX(CASE WHEN ev.slot_name = 'source_uri' THEN e.content END) AS source_uri
FROM entry_values ev JOIN entries e ON ev.entry_id = e.id
WHERE ev.template_id = ?${ownerFiltered ? " AND e.owner_id = ?" : ""}
GROUP BY ev.record_id`;
}
__name(tripletPivotSql, "tripletPivotSql");
function mapPivotSql(ownerFiltered) {
return `SELECT ev.record_id AS rid,
MAX(CASE WHEN ev.slot_name = 'library' THEN e.content END) AS library,
MAX(CASE WHEN ev.slot_name = 'narrative' THEN e.content END) AS narrative,
MAX(CASE WHEN ev.slot_name = 'top_entities' THEN e.content END) AS top_entities,
MAX(CASE WHEN ev.slot_name = 'relation_profile' THEN e.content END) AS relation_profile,
MAX(CASE WHEN ev.slot_name = 'bridges' THEN e.content END) AS bridges,
MAX(CASE WHEN ev.slot_name = 'triplet_count' THEN e.content END) AS triplet_count,
MAX(CASE WHEN ev.slot_name = 'commit_hash' THEN e.content END) AS commit_hash,
MAX(CASE WHEN ev.slot_name = 'status' THEN e.content END) AS status,
MAX(ev.created_at) AS ts
FROM entry_values ev JOIN entries e ON ev.entry_id = e.id
WHERE ev.template_id = ?${ownerFiltered ? " AND e.owner_id = ?" : ""}
GROUP BY ev.record_id`;
}
__name(mapPivotSql, "mapPivotSql");
function parseJsonArray(raw2) {
if (!raw2) return [];
try {
const v = JSON.parse(raw2);
return Array.isArray(v) ? v : [];
} catch {
return [];
}
}
__name(parseJsonArray, "parseJsonArray");
async function recomputeLibraryMap(db, input) {
const library = input.library.trim();
if (!library) throw new Error("library required");
const tripletTemplateName = input.triplet_template ?? DEFAULT_TRIPLET_TEMPLATE;
const topN = Math.min(Math.max(Math.floor(input.top_n ?? 10), 1), 50);
await ensureLibraryMapTemplate(db);
const librarySlotAdded = await ensureTripletLibrarySlot(db, tripletTemplateName);
const tripletTpl = await getTemplate(db, tripletTemplateName);
if (!tripletTpl) throw new Error(`triplet template not found: ${tripletTemplateName}`);
const owner = input.owner_id || void 0;
const pivot = tripletPivotSql(!!owner);
const pivotParams = owner ? [tripletTpl.id, owner] : [tripletTpl.id];
const libCond = input.source_prefix ? `(t.library = ? OR (t.library IS NULL AND t.source_uri LIKE ? || '%'))` : `t.library = ?`;
const libParams = input.source_prefix ? [library, input.source_prefix] : [library];
const withLib = `WITH t AS (${pivot}), lib AS (
SELECT * FROM t WHERE COALESCE(t.status, 'active') = 'active' AND ${libCond})`;
const baseParams = [...pivotParams, ...libParams];
const [countRow, topRes, relRes, bridgeRes] = await Promise.all([
db.prepare(`${withLib} SELECT COUNT(*) AS n FROM lib`).bind(...baseParams).first(),
// degreeentity 在該庫 active triplet 的出現次數(subject+object 兩側都算;同名並列取名字序穩定輸出)
db.prepare(
`${withLib} SELECT name, COUNT(*) AS degree FROM (
SELECT subject AS name FROM lib UNION ALL SELECT object AS name FROM lib)
WHERE name IS NOT NULL GROUP BY name ORDER BY degree DESC, name ASC LIMIT ?`
).bind(...baseParams, topN).all(),
// predicate 分布=庫的「性格」(spec §3 relation_profile
db.prepare(
`${withLib} SELECT predicate, COUNT(*) AS n FROM lib
WHERE predicate IS NOT NULL GROUP BY predicate ORDER BY n DESC, predicate ASC LIMIT 100`
).bind(...baseParams).all(),
// bridges=本庫 entity 同時出現在其他庫(跨庫 join)。對面那側只能靠 library slot 標記值
//source_prefix 只描述本庫的前綴,無法反推他庫)→ M3 backfill 前 bridges 會偏稀疏,誠實現況。
db.prepare(
`${withLib}, labeled AS (
SELECT DISTINCT name, library FROM (
SELECT subject AS name, library FROM t WHERE COALESCE(status,'active') = 'active'
UNION SELECT object AS name, library FROM t WHERE COALESCE(status,'active') = 'active')
WHERE name IS NOT NULL AND library IS NOT NULL AND library != ?),
mine AS (
SELECT DISTINCT subject AS name FROM lib WHERE subject IS NOT NULL
UNION SELECT DISTINCT object AS name FROM lib WHERE object IS NOT NULL)
SELECT l.name AS entity, l.library AS library FROM labeled l
JOIN mine m ON m.name = l.name ORDER BY l.name ASC, l.library ASC`
).bind(...baseParams, library).all()
]);
const tripletCount = countRow?.n ?? 0;
const topEntities = (topRes.results ?? []).map((r) => ({ name: r.name, degree: r.degree }));
const relationProfile = (relRes.results ?? []).map((r) => ({ predicate: r.predicate, count: r.n }));
const bridgeMap = /* @__PURE__ */ new Map();
for (const r of bridgeRes.results ?? []) {
if (!bridgeMap.has(r.entity) && bridgeMap.size >= 50) continue;
const libs = bridgeMap.get(r.entity) ?? [];
if (!libs.includes(r.library)) libs.push(r.library);
bridgeMap.set(r.entity, libs);
}
const bridges = [...bridgeMap.entries()].map(([entity, libraries]) => ({ entity, libraries }));
const narrative = input.narrative?.trim() || "";
const coreNames = topEntities.slice(0, 3).map((t) => t.name);
const content = `${library}\uFF1A${narrative || "\uFF08narrative \u5F85 ingest \u88DC\u5BEB\uFF09"}\u3002\u6838\u5FC3\uFF1A${coreNames.length ? coreNames.join("\u3001") : "\uFF08\u5C1A\u7121 entities\uFF09"}`;
const blockEntry = await createEntry(db, {
content,
entry_type: "block",
owner_id: owner ?? null,
page_name: `library-map:${library}`,
metadata_json: JSON.stringify({ kind: "library_map", library })
});
const values = {
library,
narrative,
top_entities: JSON.stringify(topEntities),
relation_profile: JSON.stringify(relationProfile),
bridges: JSON.stringify(bridges),
triplet_count: String(tripletCount),
status: "active"
};
if (input.commit_hash) values.commit_hash = input.commit_hash;
await createRecord(db, {
template: LIBRARY_MAP_TEMPLATE_NAME,
record_id: blockEntry.id,
values,
owner_id: owner ?? null
});
const mapTpl = await getTemplate(db, LIBRARY_MAP_TEMPLATE_NAME);
const oldParams = owner ? [mapTpl.id, owner, library, blockEntry.id] : [mapTpl.id, library, blockEntry.id];
const oldRes = await db.prepare(
`WITH m AS (${mapPivotSql(!!owner)})
SELECT rid FROM m WHERE m.library = ? AND COALESCE(m.status, 'active') = 'active' AND m.rid != ?`
).bind(...oldParams).all();
const superseded = [];
for (const row of oldRes.results ?? []) {
await updateRecord(db, row.rid, { status: "superseded" });
superseded.push(row.rid);
}
return {
map: {
record_id: blockEntry.id,
library,
narrative: narrative || null,
content,
top_entities: topEntities,
relation_profile: relationProfile,
bridges,
triplet_count: tripletCount,
commit_hash: input.commit_hash ?? null,
status: "active",
updated_at: blockEntry.created_at
},
superseded,
triplet_template: tripletTemplateName,
triplet_library_slot_added: librarySlotAdded
};
}
__name(recomputeLibraryMap, "recomputeLibraryMap");
async function listLibraryMaps(db, owner_id) {
const tpl = await getTemplate(db, LIBRARY_MAP_TEMPLATE_NAME);
if (!tpl) return [];
const params = owner_id ? [tpl.id, owner_id] : [tpl.id];
const res = await db.prepare(
`WITH m AS (${mapPivotSql(!!owner_id)})
SELECT * FROM m WHERE COALESCE(m.status, 'active') = 'active' AND m.library IS NOT NULL
ORDER BY m.ts DESC`
).bind(...params).all();
const byLib = /* @__PURE__ */ new Map();
for (const r of res.results ?? []) {
if (!r.library || byLib.has(r.library)) continue;
byLib.set(r.library, {
library: r.library,
narrative: r.narrative || null,
top_entities: parseJsonArray(r.top_entities).slice(0, 3).map((t) => t.name),
triplet_count: Number(r.triplet_count ?? 0) || 0,
updated_at: r.ts
});
}
return [...byLib.values()].sort((a, b) => a.library.localeCompare(b.library));
}
__name(listLibraryMaps, "listLibraryMaps");
async function getLibraryMapDetail(db, library, owner_id) {
const tpl = await getTemplate(db, LIBRARY_MAP_TEMPLATE_NAME);
if (!tpl) return null;
const params = owner_id ? [tpl.id, owner_id, library] : [tpl.id, library];
const row = await db.prepare(
`WITH m AS (${mapPivotSql(!!owner_id)})
SELECT * FROM m WHERE m.library = ? AND COALESCE(m.status, 'active') = 'active'
ORDER BY m.ts DESC LIMIT 1`
).bind(...params).first();
if (!row) return null;
const blockEntry = await getEntry(db, row.rid);
return {
record_id: row.rid,
library,
narrative: row.narrative || null,
content: blockEntry?.content ?? null,
top_entities: parseJsonArray(row.top_entities),
relation_profile: parseJsonArray(row.relation_profile),
bridges: parseJsonArray(row.bridges),
triplet_count: Number(row.triplet_count ?? 0) || 0,
commit_hash: row.commit_hash || null,
status: row.status ?? "active",
updated_at: row.ts
};
}
__name(getLibraryMapDetail, "getLibraryMapDetail");
// src/routes/map.ts
var mapRoutes = new Hono2();
mapRoutes.post("/recompute", async (c) => {
const body = await c.req.json().catch(() => ({}));
const library = c.req.query("library") || (typeof body.library === "string" ? body.library : "");
if (!library || !library.trim()) return c.json({ success: false, error: "library required" }, 400);
try {
const result = await recomputeLibraryMap(c.env.DB, {
library,
narrative: typeof body.narrative === "string" ? body.narrative : void 0,
commit_hash: typeof body.commit_hash === "string" ? body.commit_hash : void 0,
owner_id: typeof body.owner_id === "string" ? body.owner_id : c.req.query("owner_id") || void 0,
source_prefix: typeof body.source_prefix === "string" ? body.source_prefix : void 0,
triplet_template: typeof body.triplet_template === "string" ? body.triplet_template : void 0,
top_n: typeof body.top_n === "number" ? body.top_n : void 0
});
return c.json({ success: true, ...result });
} catch (e) {
return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 400);
}
});
mapRoutes.get("/", async (c) => {
const libraries = await listLibraryMaps(c.env.DB, c.req.query("owner_id") || void 0);
return c.json({ success: true, libraries, count: libraries.length });
});
mapRoutes.get("/:library", async (c) => {
const map = await getLibraryMapDetail(c.env.DB, c.req.param("library"), c.req.query("owner_id") || void 0);
if (!map) return c.json({ success: false, error: "not found" }, 404);
return c.json({ success: true, map });
});
// src/index.ts
var app = new Hono2();
app.get("/", (c) => c.json({ service: "arcrun-kbdb", tier: "base", status: "ok" }));
app.get("/health", (c) => c.json({ ok: true }));
app.route("/entries", entryRoutes);
app.route("/templates", templateRoutes);
app.route("/records", recordRoutes);
app.route("/recipe-stats", recipeStatRoutes);
app.route("/embed", embedRoutes);
app.route("/map", mapRoutes);
var index_default = app;
export {
index_default as default
};
//# sourceMappingURL=index.js.map