diff --git a/.gitignore b/.gitignore index d8c07774..53ad46b7 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ __pycache__/ .dev.vars* .reports +.emulate/ .claude/settings.local.json .claude/worktrees AGENTS.override.md diff --git a/.oxlintrc.jsonc b/.oxlintrc.jsonc index 9c9b7f12..1b4ea31a 100644 --- a/.oxlintrc.jsonc +++ b/.oxlintrc.jsonc @@ -37,6 +37,7 @@ "no-console": "off", "no-ternary": "off", "no-undefined": "off", + "no-underscore-dangle": "off", "max-lines": "off", "id-length": "off", "func-style": [ @@ -170,6 +171,7 @@ "react/jsx-props-no-spreading": "off", "react/jsx-max-depth": "off", "react/no-multi-comp": "off", + "react/forbid-component-props": "off", "react_perf/jsx-no-jsx-as-prop": "off", "react_perf/jsx-no-new-object-as-prop": "off", @@ -177,6 +179,7 @@ "react_perf/jsx-no-new-function-as-prop": "off", // Not a blanket perf win with React Compiler; prefer targeted stabilization at memo/effect boundaries. "jsx-a11y/no-autofocus": "off", + "jsx-a11y/prefer-tag-over-role": "off", "sort-keys": "off", "no-inline-comments": "off", @@ -217,6 +220,7 @@ "no-script-url": "off", // TEMP ~1 "no-redeclare": "off", // TEMP ~1 "no-new": "off", // TEMP ~1 + "require-unicode-regexp": "off", // TEMP ~100 — add unicode flags to existing regex literals }, "ignorePatterns": [ "**/node_modules", diff --git a/apps/cli/bin/onequery.js b/apps/cli/bin/onequery.js index 7fa2940e..52ca20e6 100755 --- a/apps/cli/bin/onequery.js +++ b/apps/cli/bin/onequery.js @@ -15,8 +15,8 @@ import { resolveTargetTripleCandidates, } from "./package-constants.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const launcherFilePath = fileURLToPath(import.meta.url); +const launcherDir = path.dirname(launcherFilePath); const require = createRequire(import.meta.url); const runtimeBundleSpec = readRuntimeBundleSpec(resolveRuntimeBundleSpecPath()); @@ -27,7 +27,7 @@ const binaryName = binaryNameForPlatform(platform, CLI_BINARY_NAME); // CONTEXT: platform packages are installed through npm alias names so the // launcher resolves the alias folder, not the underlying published package id. -const localVendorRoot = path.join(__dirname, "..", "vendor"); +const localVendorRoot = path.join(launcherDir, "..", "vendor"); const resolvedVendor = resolveVendorPayload({ binaryName, localVendorRoot, @@ -112,7 +112,7 @@ if (childResult.type === "signal") { function detectPackageManager() { const userAgent = process.env.npm_config_user_agent ?? ""; - if (/\bbun\//.test(userAgent)) { + if (/\bbun\//u.test(userAgent)) { return "bun"; } @@ -122,8 +122,8 @@ function detectPackageManager() { } if ( - __dirname.includes(".bun/install/global") || - __dirname.includes(".bun\\install\\global") + launcherDir.includes(".bun/install/global") || + launcherDir.includes(".bun\\install\\global") ) { return "bun"; } @@ -196,7 +196,7 @@ function resolveBundlePaths({ binaryName, bundleRoot, runtimeBundleSpec }) { } function resolveRuntimeBundleSpecPath() { - const packagedSpecPath = path.join(__dirname, "..", "runtime-bundle.json"); + const packagedSpecPath = path.join(launcherDir, "..", "runtime-bundle.json"); if (existsSync(packagedSpecPath)) { return packagedSpecPath; } @@ -204,7 +204,7 @@ function resolveRuntimeBundleSpecPath() { // Comment: local workspace execution reads the canonical bundle spec from the // repo; published npm packages ship the same file at the package root. return path.join( - __dirname, + launcherDir, "..", "..", "..", diff --git a/apps/cli/package.json b/apps/cli/package.json index 107d5a75..aeb55aaf 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -3,6 +3,10 @@ "version": "0.0.0-dev", "private": false, "description": "OneQuery CLI", + "homepage": "https://onequery.dev", + "bugs": { + "url": "https://github.com/wordbricks/onequery/issues" + }, "license": "Apache-2.0", "repository": { "type": "git", diff --git a/apps/cli/scripts/build-npm-package.d.ts b/apps/cli/scripts/build-npm-package.d.ts index c98e0ac7..b92414ab 100644 --- a/apps/cli/scripts/build-npm-package.d.ts +++ b/apps/cli/scripts/build-npm-package.d.ts @@ -7,7 +7,7 @@ export function tarballNameForPackage( version: string ): string; -export const __internal: { +export const buildNpmPackageInternals: { indexWorkspacePackageManifestPaths( workspacePackageManifests: Array<{ name: string; diff --git a/apps/cli/scripts/build-npm-package.js b/apps/cli/scripts/build-npm-package.js index 0fa53ca1..8a69a250 100755 --- a/apps/cli/scripts/build-npm-package.js +++ b/apps/cli/scripts/build-npm-package.js @@ -40,10 +40,10 @@ import { binaryNameForTargetTriple, } from "../bin/package-constants.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const scriptFilePath = fileURLToPath(import.meta.url); +const scriptDir = path.dirname(scriptFilePath); -const CLI_ROOT = path.resolve(__dirname, ".."); +const CLI_ROOT = path.resolve(scriptDir, ".."); const WORKSPACE_ROOT = path.resolve(CLI_ROOT, "..", ".."); const WORKSPACE_MANIFEST_PATH = path.join(WORKSPACE_ROOT, "package.json"); const workspacePackageRequireCache = new Map(); @@ -331,8 +331,10 @@ function createReleasePlatformPackageManifest( ) { const stagedPlatformPackage = { cpu: [platformPackage.cpu], + bugs: packageJson.bugs, description: packageJson.description, files: ["vendor", "README.md"], + homepage: packageJson.homepage, license: packageJson.license, name: CLI_PACKAGE_NAME, os: [platformPackage.os], @@ -663,8 +665,9 @@ function indexWorkspacePackageManifestPaths(workspacePackageManifests) { return workspacePackageManifestPathIndex; } -export const __internal = { +export const buildNpmPackageInternals = { INSTALL_BUNDLE_PACKAGES, + createReleasePlatformPackageManifest, indexWorkspacePackageManifestPaths, readCliPackageJson, restorePackagedExecutableModes, diff --git a/apps/cli/scripts/build-npm-package.test.ts b/apps/cli/scripts/build-npm-package.test.ts index 109d9957..1ab2e831 100644 --- a/apps/cli/scripts/build-npm-package.test.ts +++ b/apps/cli/scripts/build-npm-package.test.ts @@ -7,11 +7,14 @@ import { tmpdir } from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import { __internal, tarballNameForPackage } from "./build-npm-package.js"; +import { + buildNpmPackageInternals, + tarballNameForPackage, +} from "./build-npm-package.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const WORKSPACE_ROOT = path.resolve(__dirname, "..", "..", ".."); +const testFilePath = fileURLToPath(import.meta.url); +const testDir = path.dirname(testFilePath); +const WORKSPACE_ROOT = path.resolve(testDir, "..", "..", ".."); const SERVER_PACKAGE_MANIFEST_PATH = path.join( WORKSPACE_ROOT, "packages", @@ -28,7 +31,9 @@ describe("build-npm-package runtime asset resolution", () => { it("anchors polyglotSql assets to the declared owner package manifest", async () => { const sourcePaths = - await __internal.resolveRuntimeAssetSourcePaths("polyglotSql"); + await buildNpmPackageInternals.resolveRuntimeAssetSourcePaths( + "polyglotSql" + ); const serverRequire = createRequire(SERVER_PACKAGE_MANIFEST_PATH); expect(sourcePaths).toEqual([ @@ -44,7 +49,7 @@ describe("build-npm-package runtime asset resolution", () => { it("fails clearly when a workspace package is missing", async () => { try { - await __internal.resolveWorkspacePackageRequire( + await buildNpmPackageInternals.resolveWorkspacePackageRequire( "@onequery/not-a-package" ); throw new Error("expected missing workspace package lookup to fail"); @@ -61,7 +66,7 @@ describe("build-npm-package runtime asset resolution", () => { it("rejects duplicate workspace package names when indexing manifests", () => { expect(() => - __internal.indexWorkspacePackageManifestPaths([ + buildNpmPackageInternals.indexWorkspacePackageManifestPaths([ { name: "@onequery/server", packageJsonPath: "/tmp/workspace-a/package.json", @@ -95,7 +100,7 @@ describe("build-npm-package runtime asset resolution", () => { }) ); - await __internal.restorePackagedExecutableModes({ + await buildNpmPackageInternals.restorePackagedExecutableModes({ targetRoot, targetTriple: "x86_64-unknown-linux-musl", }); diff --git a/apps/cli/scripts/build-server-bundle.js b/apps/cli/scripts/build-server-bundle.js index 1467abd8..7945eb03 100644 --- a/apps/cli/scripts/build-server-bundle.js +++ b/apps/cli/scripts/build-server-bundle.js @@ -9,11 +9,11 @@ import { build } from "rolldown"; import { serverBundleFilenameForTargetTriple } from "../bin/package-constants.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const scriptFilePath = fileURLToPath(import.meta.url); +const scriptDir = path.dirname(scriptFilePath); const require = createRequire(import.meta.url); -const CLI_ROOT = path.resolve(__dirname, ".."); +const CLI_ROOT = path.resolve(scriptDir, ".."); const WORKSPACE_ROOT = path.resolve(CLI_ROOT, "..", ".."); // Comment: resolve the packaged server entry through the runtime package's // declared export surface so CLI packaging does not depend on package-private diff --git a/apps/cli/scripts/generate-homebrew-formula.js b/apps/cli/scripts/generate-homebrew-formula.js index b9cf960d..703eceac 100644 --- a/apps/cli/scripts/generate-homebrew-formula.js +++ b/apps/cli/scripts/generate-homebrew-formula.js @@ -4,7 +4,7 @@ import { mkdir, writeFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; -const SHA256_PATTERN = /^[a-f0-9]{64}$/i; +const SHA256_PATTERN = /^[a-f0-9]{64}$/iu; const GENERATE_HOMEBREW_FORMULA_OPTIONS = new Set([ "--version", "--repo-owner", @@ -47,7 +47,7 @@ const PLATFORM_RELEASES = [ ]; function versionedReleaseAssetName(assetName, version) { - return assetName.replace(/\.tgz$/, `-${version}.tgz`); + return assetName.replace(/\.tgz$/u, `-${version}.tgz`); } function readOptionValue(argv, index, optionName) { @@ -266,7 +266,7 @@ export function buildFormula({ "", "class Onequery < Formula", ' desc "CLI for querying and self-hosting OneQuery"', - ` homepage "https://github.com/${repoOwner}/${repoName}"`, + ' homepage "https://onequery.dev"', ' license "Apache-2.0"', ` version "${version}"`, "", @@ -326,9 +326,9 @@ export async function writeFormula({ outputPath, formulaText }) { await writeFile(outputPath, formulaText, "utf8"); } -const __filename = fileURLToPath(import.meta.url); +const currentFilePath = fileURLToPath(import.meta.url); -if (process.argv[1] && path.resolve(process.argv[1]) === __filename) { +if (process.argv[1] && path.resolve(process.argv[1]) === currentFilePath) { const args = parseArgs(process.argv.slice(2)); const formulaText = buildFormula(args); await writeFormula({ diff --git a/apps/cli/scripts/self-host-runtime.js b/apps/cli/scripts/self-host-runtime.js index d8f4d156..d3967bee 100644 --- a/apps/cli/scripts/self-host-runtime.js +++ b/apps/cli/scripts/self-host-runtime.js @@ -19,10 +19,10 @@ import { } from "../bin/package-constants.js"; import { stagePackagedRuntime } from "./build-npm-package.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const scriptFilePath = fileURLToPath(import.meta.url); +const scriptDir = dirname(scriptFilePath); -export const cliRootDir = resolve(__dirname, ".."); +export const cliRootDir = resolve(scriptDir, ".."); const workspaceRootDir = resolve(cliRootDir, "..", ".."); const cliManifestPath = join(cliRootDir, "Cargo.toml"); const cliBinaryName = binaryNameForPlatform(process.platform, "onequery"); diff --git a/apps/landing/astro.config.ts b/apps/landing/astro.config.ts index a982e16c..53a75724 100644 --- a/apps/landing/astro.config.ts +++ b/apps/landing/astro.config.ts @@ -20,6 +20,7 @@ import { const BUNDLE_REPORT_TEMPLATES = ["markdown", "list", "raw-data"] as const; const BUNDLE_REPORT_TEMPLATE_SET = new Set(BUNDLE_REPORT_TEMPLATES); const REPOSITORY_ROOT = fileURLToPath(new URL("../../", import.meta.url)); +const SITE_URL = "https://onequery.dev"; type BundleReportTemplate = (typeof BUNDLE_REPORT_TEMPLATES)[number]; @@ -93,6 +94,12 @@ export default defineConfig({ }), }, }, + experimental: { + queuedRendering: { + enabled: true, + }, + rustCompiler: true, + }, integrations: [ partytown({ config: { @@ -162,7 +169,10 @@ export default defineConfig({ title: "OneQuery Docs", }), mdx(), - sitemap(), + sitemap({ + changefreq: "daily", + priority: 0.7, + }), agentMarkdown({ content: [ { @@ -179,7 +189,7 @@ export default defineConfig({ host: DEV_SERVER_HOST, port: DEFAULT_DEV_PORT, }, - site: "https://onequery.dev", + site: SITE_URL, // Cloudflare normalizes extensionless page URLs with trailing slashes in // production, so keep Astro's generated route shape aligned with the edge. trailingSlash: "always", diff --git a/apps/landing/docs/local-slack-emulator.md b/apps/landing/docs/local-slack-emulator.md new file mode 100644 index 00000000..59892e06 --- /dev/null +++ b/apps/landing/docs/local-slack-emulator.md @@ -0,0 +1,37 @@ +# Local Slack Emulator + +The landing app sends lead-capture notifications through +`LANDING_SLACK_WEBHOOK_URL`. `bun run dev` starts the Slack emulator when that +environment variable is unset, then injects the emulator webhook URL into Astro. + +Start local development with: + +```bash +rtk bun run dev +``` + +Submit the product updates form or the contact form in the local landing page, +then inspect the stored Slack messages at the URL printed by the dev server. +The default inspector URL is: + +```text +http://localhost:4003/ +``` + +If port 4003 is already in use, `bun run dev` picks another available port and +prints that inspector URL instead. + +The default emulator webhook posts to the emulator's `general` channel: + +```text +http://localhost:4003/services/T000000001/B000000001/X000000001 +``` + +If `LANDING_SLACK_WEBHOOK_URL` is already configured, `bun run dev` uses that +value and does not start the emulator. + +You can still run only the emulator with: + +```bash +rtk bun run slack:emulate +``` diff --git a/apps/landing/package.json b/apps/landing/package.json index 045154ac..6cb21d3d 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -4,22 +4,25 @@ "private": false, "type": "module", "scripts": { - "dev": "astro dev", - "preview": "astro preview", + "dev": "bun run cf-typegen && node scripts/dev-with-slack.ts", + "start": "bun run dev", + "build": "bun run cf-typegen && astro check && astro build", + "preview": "bun run cf-typegen && astro preview", "workspace:dev": "bun run dev", - "build": "astro build", "bundle:analyze": "ONEQUERY_BUNDLE_REPORT=1 astro build", "bundle:analyze:json": "ONEQUERY_BUNDLE_REPORT=1 ONEQUERY_BUNDLE_REPORT_TEMPLATE=raw-data astro build", "bundle:analyze:list": "ONEQUERY_BUNDLE_REPORT=1 ONEQUERY_BUNDLE_REPORT_TEMPLATE=list astro build", + "slack:emulate": "emulate start --service slack --port 4003", "deploy": "bun run --cwd ../.. landing:build && bunx wrangler deploy", "deploy:preview": "bun run --cwd ../.. landing:build && bunx wrangler versions upload", - "cf-typegen": "bunx wrangler types worker-configuration.d.ts --env-interface CloudflareEnv", + "cf-typegen": "bunx wrangler types worker-configuration.d.ts --env-interface CloudflareEnv && oxfmt worker-configuration.d.ts", "test": "vitest run", "test:watch": "vitest", "typecheck": "astro check && tsgo --noEmit -p tsconfig.json" }, "dependencies": { "@astrojs/cloudflare": "catalog:", + "@astrojs/compiler-rs": "catalog:", "@astrojs/mdx": "catalog:", "@astrojs/partytown": "catalog:", "@astrojs/react": "catalog:", @@ -31,21 +34,22 @@ "@onequery/db": "workspace:*", "@onequery/ui": "workspace:*", "astro": "catalog:", - "better-result": "catalog:", "mdast-util-to-string": "4.0.0", "nanostores": "catalog:", - "react": "19.3.0-canary-d5736f09-20260507", - "react-dom": "19.3.0-canary-d5736f09-20260507", + "react": "catalog:", + "react-dom": "catalog:", "reading-time": "1.5.0", - "simple-icons": "catalog:", - "zod": "catalog:" + "simple-icons": "catalog:" }, "devDependencies": { "@astrojs/check": "catalog:tooling", "@cloudflare/workers-types": "catalog:tooling", + "@emulators/core": "0.6.0", + "@emulators/slack": "0.6.0", "@onequery/installer": "workspace:*", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "emulate": "0.6.0", "rollup-plugin-visualizer": "catalog:tooling", "typescript": "catalog:tooling", "vitest": "catalog:testing", diff --git a/apps/landing/scripts/dev-with-slack.ts b/apps/landing/scripts/dev-with-slack.ts new file mode 100644 index 00000000..d7894d87 --- /dev/null +++ b/apps/landing/scripts/dev-with-slack.ts @@ -0,0 +1,412 @@ +import { createServer as createTcpServer } from "node:net"; + +import { + createServer as createEmulatorServer, + filePersistence, + serve, +} from "@emulators/core"; +import type { StoreSnapshot } from "@emulators/core"; +import { getSlackStore, slackPlugin } from "@emulators/slack"; +import type { SlackMessage } from "@emulators/slack"; +import { dev } from "astro"; + +const DEFAULT_SLACK_EMULATOR_PORT = 4003; +const DEFAULT_SLACK_EMULATOR_STATE_PATH = ".emulate/landing-slack.json"; +const SLACK_EMULATOR_WEBHOOK_PATH = + "/services/T000000001/B000000001/X000000001"; +const SLACK_EMULATOR_TOKEN = "xoxb-local-test"; +const MUTATING_METHODS = new Set(["DELETE", "PATCH", "POST", "PUT"]); + +type SlackDevEmulator = { + close: () => Promise; +}; + +type DevArgs = { + host?: boolean | string; + open?: boolean | string; + port?: number; +}; + +let shuttingDown = false; + +async function main() { + let server: Awaited> | undefined; + let slackEmulator: SlackDevEmulator | undefined; + + const configuredWebhookUrl = process.env.LANDING_SLACK_WEBHOOK_URL?.trim(); + const slackEmulatorConfig = configuredWebhookUrl + ? undefined + : await createSlackEmulatorConfig(); + const slackWebhookUrl = + configuredWebhookUrl ?? createSlackEmulatorWebhookUrl(slackEmulatorConfig); + + try { + slackEmulator = slackEmulatorConfig + ? await createSlackEmulator(slackEmulatorConfig) + : undefined; + + applyLandingSlackWebhookUrl(slackWebhookUrl); + logSlackDevState({ + configuredWebhookUrl, + slackBaseUrl: slackEmulatorConfig?.baseUrl, + slackWebhookUrl, + }); + + const shutdownSignal = createShutdownSignal(); + server = await dev({ + root: process.cwd(), + server: readDevServerConfig(process.argv.slice(2)), + }); + + await shutdownSignal; + } finally { + shuttingDown = true; + await server?.stop(); + await slackEmulator?.close(); + } +} + +async function createSlackEmulatorConfig() { + const port = await findPreferredAvailablePort(DEFAULT_SLACK_EMULATOR_PORT); + + return { + baseUrl: readSlackBaseUrl(port), + port, + }; +} + +function createSlackEmulatorWebhookUrl( + config: { baseUrl: string; port: number } | undefined +) { + if (!config) { + throw new Error("Slack emulator config was not created"); + } + + return `${config.baseUrl}${SLACK_EMULATOR_WEBHOOK_PATH}`; +} + +async function createSlackEmulator(input: { baseUrl: string; port: number }) { + try { + return await createPersistentSlackEmulator({ + baseUrl: input.baseUrl, + port: input.port, + statePath: DEFAULT_SLACK_EMULATOR_STATE_PATH, + }); + } catch (cause) { + throw new Error( + `Failed to start Slack emulator on port ${input.port}. Stop the process using that port and rerun bun run dev.`, + { cause } + ); + } +} + +function applyLandingSlackWebhookUrl(slackWebhookUrl: string | undefined) { + if (slackWebhookUrl) { + process.env.LANDING_SLACK_WEBHOOK_URL = slackWebhookUrl; + return; + } + + delete process.env.LANDING_SLACK_WEBHOOK_URL; +} + +function logSlackDevState(input: { + configuredWebhookUrl: string | undefined; + slackBaseUrl: string | undefined; + slackWebhookUrl: string | undefined; +}) { + if (input.configuredWebhookUrl) { + console.info("[dev] Using configured LANDING_SLACK_WEBHOOK_URL"); + return; + } + + if (input.slackBaseUrl) { + console.info(`[dev] Slack emulator inspector: ${input.slackBaseUrl}/`); + console.info(`[dev] Slack webhook: ${input.slackWebhookUrl}`); + } +} + +async function createPersistentSlackEmulator(input: { + baseUrl: string; + port: number; + statePath: string; +}): Promise { + const persistence = filePersistence(input.statePath); + const { app, store } = createEmulatorServer(slackPlugin, { + baseUrl: input.baseUrl, + fallbackUser: { + id: 1, + login: "U000000001", + scopes: [], + }, + port: input.port, + tokens: { + [SLACK_EMULATOR_TOKEN]: { + id: 1, + login: "U000000001", + scopes: [], + }, + test_token_admin: { + id: 1, + login: "U000000001", + scopes: [], + }, + }, + }); + + const restored = await restoreSlackState({ + persistence, + statePath: input.statePath, + store, + }); + if (!restored) { + slackPlugin.seed?.(store, input.baseUrl); + await persistence.save(JSON.stringify(store.snapshot())); + } + + const seenMessageTimestamps = new Set( + readSlackMessages(store).map((message) => message.ts) + ); + let pendingSave = Promise.resolve(); + + function enqueueSave() { + pendingSave = pendingSave + .catch(() => undefined) + .then(() => persistence.save(JSON.stringify(store.snapshot()))) + .catch((error: unknown) => { + console.warn( + `[dev] Failed to persist Slack emulator state: ${toErrorMessage( + error + )}` + ); + }); + } + + function logNewMessages() { + for (const message of readSlackMessages(store)) { + if (seenMessageTimestamps.has(message.ts)) { + continue; + } + + seenMessageTimestamps.add(message.ts); + console.info(`[dev] Slack message received: ${message.text}`); + } + } + + const httpServer = serve({ + fetch: async (request) => { + const response = await app.fetch(request); + + if (MUTATING_METHODS.has(request.method)) { + logNewMessages(); + enqueueSave(); + } + + return response; + }, + port: input.port, + }); + + console.info(`[dev] Slack emulator state: ${input.statePath}`); + + return { + async close() { + await pendingSave; + await new Promise((resolve, reject) => { + httpServer.close((error) => { + if (error) { + reject(error); + return; + } + + resolve(); + }); + }); + }, + }; +} + +async function restoreSlackState(input: { + persistence: ReturnType; + statePath: string; + store: { + restore: (snapshot: StoreSnapshot) => void; + }; +}) { + const raw = await input.persistence.load(); + if (!raw) { + return false; + } + + try { + input.store.restore(JSON.parse(raw) as StoreSnapshot); + return true; + } catch (error) { + console.warn( + `[dev] Ignoring unreadable Slack emulator state at ${ + input.statePath + }: ${toErrorMessage(error)}` + ); + return false; + } +} + +function readSlackMessages(store: Parameters[0]) { + return getSlackStore(store) + .messages.all() + .filter((message): message is SlackMessage => message.type === "message") + .sort((left, right) => left.ts.localeCompare(right.ts)); +} + +function toErrorMessage(error: unknown) { + return error instanceof Error ? error.message : String(error); +} + +function readDevServerConfig(args: string[]) { + const devArgs = readDevArgs(args); + + return { + ...(devArgs.host === undefined ? {} : { host: devArgs.host }), + ...(devArgs.open === undefined ? {} : { open: devArgs.open }), + ...(devArgs.port === undefined ? {} : { port: devArgs.port }), + }; +} + +function readDevArgs(args: string[]): DevArgs { + const devArgs: DevArgs = {}; + + for (let index = 0; index < args.length; index++) { + const arg = args[index]; + if (arg === "--host") { + const next = args[index + 1]; + if (next && !next.startsWith("-")) { + devArgs.host = next; + index++; + } else { + devArgs.host = true; + } + continue; + } + + if (arg?.startsWith("--host=")) { + devArgs.host = arg.slice("--host=".length); + continue; + } + + if (arg === "--open") { + const next = args[index + 1]; + if (next && !next.startsWith("-")) { + devArgs.open = next; + index++; + } else { + devArgs.open = true; + } + continue; + } + + if (arg?.startsWith("--open=")) { + devArgs.open = arg.slice("--open=".length); + continue; + } + + if (arg === "--port" || arg === "-p") { + devArgs.port = readPortArg(args[index + 1], arg); + index++; + continue; + } + + if (arg?.startsWith("--port=")) { + devArgs.port = readPortArg(arg.slice("--port=".length), "--port"); + continue; + } + + if (arg?.startsWith("-p") && arg.length > 2) { + devArgs.port = readPortArg(arg.slice(2), "-p"); + } + } + + return devArgs; +} + +function readPortArg(port: string | undefined, flag: string) { + if (!port) { + throw new Error(`Missing value for ${flag}`); + } + + return readPortNumber(port); +} + +function readSlackBaseUrl(port: number) { + return `http://localhost:${port}`; +} + +function readPortNumber(port: string) { + const value = Number.parseInt(port, 10); + if (!Number.isInteger(value) || value < 1 || value > 65_535) { + throw new Error(`Invalid port: ${port}`); + } + + return value; +} + +async function findPreferredAvailablePort(preferredPort: number) { + if (await isPortAvailable(preferredPort)) { + return preferredPort; + } + + return findAvailablePort(); +} + +async function isPortAvailable(port: number) { + return new Promise((resolve) => { + const server = createTcpServer(); + server.once("error", () => { + resolve(false); + }); + server.listen(port, "127.0.0.1", () => { + server.close(() => { + resolve(true); + }); + }); + }); +} + +async function findAvailablePort() { + return new Promise((resolve, reject) => { + const server = createTcpServer(); + server.once("error", reject); + server.listen(0, "127.0.0.1", () => { + const address = server.address(); + if (typeof address !== "object" || address === null) { + server.close(); + reject(new Error("Failed to allocate a local Slack emulator port")); + return; + } + + server.close(() => { + resolve(address.port); + }); + }); + }); +} + +function createShutdownSignal(): Promise { + return new Promise((resolve) => { + function handleShutdown() { + if (shuttingDown) { + return; + } + + shuttingDown = true; + resolve(); + } + + for (const signal of ["SIGINT", "SIGTERM"] as const) { + process.once(signal, handleShutdown); + } + }); +} + +main().catch((error: unknown) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/apps/landing/src/actions/index.ts b/apps/landing/src/actions/index.ts index 2a818ccf..618b3097 100644 --- a/apps/landing/src/actions/index.ts +++ b/apps/landing/src/actions/index.ts @@ -1,45 +1,106 @@ +import { z } from "astro/zod"; import { ActionError, defineAction } from "astro:actions"; import { LANDING_SLACK_WEBHOOK_URL } from "astro:env/server"; -import { submitContactLead } from "@/server/api"; -import { NotificationConfigurationError } from "@/server/notifications"; -import type { NotificationError } from "@/server/notifications"; -import { ContactRequestSchema } from "@/server/schemas"; +import { + createContactNotification, + createProductUpdatesNotification, + deliverSlackNotification, +} from "@/server/notifications"; +import type { + NotificationType, + SlackNotificationPayload, +} from "@/server/notifications"; -type ContactActionState = { - status: "sent"; -}; +const EmailSchema = z.preprocess( + (value) => (typeof value === "string" ? value.trim() : value), + z.email({ pattern: z.regexes.html5Email }) +); -const SENT_CONTACT_ACTION_STATE = { - status: "sent", -} satisfies ContactActionState; +const ProductUpdatesInputSchema = z.object({ + email: EmailSchema, +}); -function createActionError(error: NotificationError) { - const message = NotificationConfigurationError.is(error) - ? error.message - : "Failed to deliver notification"; +const ContactInputSchema = z.object({ + email: EmailSchema, + message: z.string().trim().min(1, "message is required").max(4000), + name: z.string().trim().min(1, "name is required").max(200), +}); +const SENT_CONTACT = { + status: "sent", +} as const; + +function createServiceUnavailableActionError(message: string) { return new ActionError({ code: "SERVICE_UNAVAILABLE", message, }); } +function readWebhookUrl() { + const webhookUrl = LANDING_SLACK_WEBHOOK_URL?.trim(); + if (webhookUrl) { + return webhookUrl; + } + + console.error( + { + event: "landing.notification.delivery_unconfigured", + }, + "landing notification delivery is unconfigured" + ); + throw createServiceUnavailableActionError("Landing ingest is not configured"); +} + +async function sendNotification(input: { + notificationType: NotificationType; + payload: SlackNotificationPayload; +}) { + const webhookUrl = readWebhookUrl(); + + try { + await deliverSlackNotification({ + notificationType: input.notificationType, + payload: input.payload, + webhookUrl, + }); + } catch (error) { + console.error( + { + error, + event: "landing.notification.action_failed", + notificationType: input.notificationType, + }, + "landing notification action failed" + ); + throw createServiceUnavailableActionError("Failed to deliver notification"); + } +} + export const server = { - contact: defineAction({ + productUpdates: defineAction({ accept: "form", - input: ContactRequestSchema, - handler: async (input, { request }): Promise => { - const result = await submitContactLead(input, { - request, - slackWebhookUrl: LANDING_SLACK_WEBHOOK_URL, + input: ProductUpdatesInputSchema, + handler: async ({ email }) => { + await sendNotification({ + notificationType: "product_updates", + payload: createProductUpdatesNotification(email), }); - if (result.isErr()) { - throw createActionError(result.error); - } + return { email }; + }, + }), + contact: defineAction({ + accept: "form", + input: ContactInputSchema, + handler: async (input) => { + await sendNotification({ + notificationType: "contact", + payload: createContactNotification(input), + }); - return SENT_CONTACT_ACTION_STATE; + return SENT_CONTACT; }, }), }; diff --git a/apps/landing/src/features/compare/data.ts b/apps/landing/src/features/compare/data.ts index c2303e66..3be22e29 100644 --- a/apps/landing/src/features/compare/data.ts +++ b/apps/landing/src/features/compare/data.ts @@ -4,6 +4,7 @@ import { getCollection } from "astro:content"; import { ONEQUERY } from "@/shared/seo/constants"; import type { ComparisonPage } from "./types"; + export type { ComparisonCriterion, ComparisonFaq, diff --git a/apps/landing/src/features/home/components/ControlPlaneDiagram.astro b/apps/landing/src/features/home/components/ControlPlaneDiagram.astro index cfa63881..8ec94880 100644 --- a/apps/landing/src/features/home/components/ControlPlaneDiagram.astro +++ b/apps/landing/src/features/home/components/ControlPlaneDiagram.astro @@ -215,3 +215,417 @@ const controlPlanePolicies = [ } + + diff --git a/apps/landing/src/features/home/components/DownloadCommand.astro b/apps/landing/src/features/home/components/DownloadCommand.astro index c9a16679..61a47a60 100644 --- a/apps/landing/src/features/home/components/DownloadCommand.astro +++ b/apps/landing/src/features/home/components/DownloadCommand.astro @@ -1,4 +1,6 @@ --- +import { Code } from "astro:components"; + import { COPY_FEEDBACK_RESET_DELAY_MS, INSTALL_COMMANDS, @@ -61,7 +63,14 @@ function getInstallTabId(index: number) { data-install-method-index={index} hidden={method !== defaultMethod} > - {method.command} + )) } @@ -79,6 +88,228 @@ function getInstallTabId(index: number) { + + diff --git a/apps/landing/src/shared/components/FooterContactButton.test.ts b/apps/landing/src/shared/components/FooterContactButton.test.ts deleted file mode 100644 index 7d662a82..00000000 --- a/apps/landing/src/shared/components/FooterContactButton.test.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { readFileSync } from "node:fs"; -import vm from "node:vm"; - -import { describe, expect, it, vi } from "vitest"; - -type Listener = (event: Record) => unknown; - -class FakeClassList { - private readonly classNames = new Set(); - - add(...classNames: string[]) { - for (const className of classNames) { - this.classNames.add(className); - } - } - - contains(className: string) { - return this.classNames.has(className); - } - - remove(...classNames: string[]) { - for (const className of classNames) { - this.classNames.delete(className); - } - } -} - -class FakeHTMLElement { - readonly attributes = new Map(); - readonly classList = new FakeClassList(); - disabled = false; - hidden = false; - readonly listeners = new Map(); - readonly style: Record = {}; - textContent = ""; - - addEventListener(type: string, listener: Listener) { - const listeners = this.listeners.get(type) ?? []; - listeners.push(listener); - this.listeners.set(type, listeners); - } - - dispatch(type: string, event: Record = {}) { - return Promise.all( - (this.listeners.get(type) ?? []).map((listener) => listener(event)) - ); - } - - focus() { - fakeDocument.activeElement = this; - } - - setAttribute(name: string, value: string) { - this.attributes.set(name, value); - } -} - -class FakeHTMLButtonElement extends FakeHTMLElement {} - -class FakeHTMLFormElement extends FakeHTMLElement { - action = "https://onequery.test/api/contact/"; - readonly elements = { - namedItem: (name: string) => - name === "name" ? fakeElements.nameField : null, - }; - readonly reportValidity = vi.fn(() => true); - readonly reset = vi.fn(); - - querySelector(selector: string) { - return selector === ".contact-modal-submit" - ? fakeElements.submitButton - : null; - } - - querySelectorAll(selector: string) { - return selector === ".t-input" ? fakeElements.fields : []; - } -} - -const fakeElements = { - backdrop: new FakeHTMLElement(), - closeButton: new FakeHTMLButtonElement(), - errorMessage: new FakeHTMLElement(), - fields: [] as FakeHTMLElement[], - form: new FakeHTMLFormElement(), - modal: new FakeHTMLElement(), - nameField: new FakeHTMLElement(), - openButton: new FakeHTMLButtonElement(), - submitButton: new FakeHTMLButtonElement(), -}; - -const fakeDocument = { - activeElement: null as FakeHTMLElement | null, - body: { - style: {} as Record, - }, - documentElement: new FakeHTMLElement(), - querySelector(selector: string) { - switch (selector) { - case "[data-contact-open]": - return fakeElements.openButton; - case "[data-contact-backdrop]": - return fakeElements.backdrop; - case "[data-contact-modal]": - return fakeElements.modal; - case "[data-contact-form]": - return fakeElements.form; - case "[data-contact-close]": - return fakeElements.closeButton; - case "[data-contact-error]": - return fakeElements.errorMessage; - default: - return null; - } - }, -}; - -function readInlineScript() { - const source = readFileSync( - new URL("./FooterContactButton.astro", import.meta.url), - "utf8" - ); - const script = / diff --git a/apps/landing/src/shared/styles/base.css b/apps/landing/src/shared/styles/base.css index ebd7433a..89108119 100644 --- a/apps/landing/src/shared/styles/base.css +++ b/apps/landing/src/shared/styles/base.css @@ -56,12 +56,6 @@ --dropdown-pre-scale: 0.97; --dropdown-closing-scale: 0.99; --dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1); - /* Modal open / close */ - --modal-open-dur: 250ms; - --modal-close-dur: 150ms; - --modal-scale: 0.96; - --modal-scale-close: 0.96; - --modal-ease: cubic-bezier(0.22, 1, 0.36, 1); /* Panel reveal */ --panel-open-dur: 400ms; --panel-close-dur: 350ms; @@ -104,14 +98,6 @@ --avatar-falloff: 0.45; --avatar-ease-in: cubic-bezier(0.22, 1, 0.36, 1); --avatar-ease-out: cubic-bezier(0.34, 3.85, 0.64, 1); - /* Error state shake */ - --shake-distance: 6px; - --shake-overshoot: 4px; - --shake-dur-a: 80ms; - --shake-dur-b: 60ms; - --shake-ease: cubic-bezier(0.22, 1, 0.36, 1); - --revert-hold: 3000ms; - --revert-dur: 280ms; } /* React ViewTransition recipes from $vercel-react-view-transitions. */ @@ -528,8 +514,8 @@ code { color: #0f766e; } -.contact-modal-input, -.contact-modal-textarea { +.contact-input, +.contact-textarea { width: 100%; border: 1px solid rgba(15, 23, 42, 0.18); background: #ffffff; @@ -537,180 +523,44 @@ code { outline: none; } -.contact-modal-input:focus, -.contact-modal-textarea:focus { +.contact-input:focus, +.contact-textarea:focus { border-color: rgba(37, 99, 235, 0.45); box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12); } .contact-link-button { - padding: 0; + display: inline-flex; + align-items: center; + min-height: 32px; + padding: 0 2px; border: 0; background: transparent; color: var(--text-soft); font-size: 14px; line-height: 20px; cursor: pointer; + text-decoration: none; } .contact-link-button:hover { color: var(--ink); } -.contact-link-button-loading { - cursor: progress; -} - -.contact-modal-backdrop { - position: fixed; - inset: 0; - z-index: 40; +.contact-section { display: grid; - place-items: center; - padding: 24px; - background: rgba(10, 10, 10, 0.28); - opacity: 0; - pointer-events: none; - backdrop-filter: blur(0); - transition: - opacity var(--modal-open-dur) var(--modal-ease), - backdrop-filter var(--modal-open-dur) var(--modal-ease); -} - -.contact-modal-backdrop.is-open { - opacity: 1; - pointer-events: auto; - backdrop-filter: blur(12px); -} - -.contact-modal-backdrop.is-closing { - opacity: 0; - pointer-events: none; - backdrop-filter: blur(0); - transition: - opacity var(--modal-close-dur) var(--modal-ease), - backdrop-filter var(--modal-close-dur) var(--modal-ease); -} - -.t-modal { - transform-origin: center; - transform: scale(var(--modal-scale)); - opacity: 0; - pointer-events: none; - transition: - transform var(--modal-open-dur) var(--modal-ease), - opacity var(--modal-open-dur) var(--modal-ease); - will-change: transform, opacity; -} -.t-modal.is-open { - transform: scale(1); - opacity: 1; - pointer-events: auto; -} -.t-modal.is-closing { - transform: scale(var(--modal-scale-close)); - opacity: 0; - pointer-events: none; - transition: - transform var(--modal-close-dur) var(--modal-ease), - opacity var(--modal-close-dur) var(--modal-ease); -} - -@media (prefers-reduced-motion: reduce) { - .t-modal { - transition: none !important; - } -} - -/* Border-color tween. Define your input's default / focused - / error border-color in your own component CSS; this rule - only owns the interpolation. Use a constant border-width - across states so the tween never shifts inner content. */ -.t-input { - transition: border-color 150ms ease-out; - will-change: transform; -} -.t-input.is-error { - /* Error border auto-reverts on the hold timer, so the - fade-out uses the slower revert duration (matches the - message fade). */ - transition: border-color var(--revert-dur, 280ms) ease-out; -} - -/* Error message reveal. Visibility is delayed by --revert-dur - on hide so the message stays painted for the full opacity - fade-out. Entering .is-error drops the delay to 0 so the - message becomes visible immediately. */ -.t-error-msg { - opacity: 0; - visibility: hidden; - transition: - opacity var(--revert-dur, 280ms) ease-out, - visibility 0s linear var(--revert-dur, 280ms); -} -.t-input-wrap.is-error .t-error-msg { - opacity: 1; - visibility: visible; - transition: - opacity var(--revert-dur, 280ms) ease-out, - visibility 0s linear 0s; -} - -/* Multi-segment keyframe with per-stop easing so each leg - of the shake follows its own cubic-bezier independently. - %-stops are cumulative durations as a fraction of the - total (80, 60, 80, 60 = 280ms): 28.57%, 57.14%, 78.57%, - 100%. Recompute if any segment duration changes. */ -.t-input.is-shaking { - animation: t-input-shake calc(var(--shake-dur-a) * 2 + var(--shake-dur-b) * 2) - linear; -} -@keyframes t-input-shake { - 0% { - transform: translateX(0); - animation-timing-function: var(--shake-ease); - } - 28.57% { - transform: translateX(var(--shake-distance)); - animation-timing-function: var(--shake-ease); - } - 57.14% { - transform: translateX(calc(var(--shake-distance) * -1)); - animation-timing-function: var(--shake-ease); - } - 78.57% { - transform: translateX(var(--shake-overshoot)); - animation-timing-function: var(--shake-ease); - } - 100% { - transform: translateX(0); - } -} - -@media (prefers-reduced-motion: reduce) { - .t-input { - animation: none !important; - transform: none !important; - } -} - -.contact-modal { - position: relative; - width: min(100%, 640px); - padding: 32px; - border: 1px solid var(--line); - border-radius: 18px; - background: - linear-gradient(180deg, rgba(0, 0, 0, 0.015), rgba(0, 0, 0, 0.04)), - var(--surface); - box-shadow: var(--shadow), var(--shadow-ring); + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + gap: 36px; + margin-top: 72px; + padding-top: 32px; + border-top: 1px solid var(--line); } -.contact-modal-header { - max-width: 480px; +.contact-section-header { + max-width: 520px; } -.contact-modal h2 { +.contact-section h2 { margin: 0; color: var(--ink); font-size: clamp(2rem, 4vw, 3rem); @@ -719,31 +569,30 @@ code { line-height: 1.02; } -.contact-modal-copy { +.contact-section-copy { margin: 18px 0 0; color: var(--text-muted); font-size: 16px; line-height: 1.65; } -.contact-modal-form { +.contact-form { display: grid; gap: 18px; - margin-top: 28px; } -.contact-modal-field-grid { +.contact-field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; } -.contact-modal-field { +.contact-field { display: grid; gap: 8px; } -.contact-modal-label { +.contact-label { color: var(--ink); font-size: 12px; font-weight: 600; @@ -751,33 +600,25 @@ code { text-transform: uppercase; } -.contact-modal-input, -.contact-modal-textarea { +.contact-input, +.contact-textarea { min-height: 48px; padding: 0 14px; - border-radius: 12px; + border-radius: 8px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3); color: var(--ink); font-size: 15px; line-height: 1.5; } -.contact-modal-textarea { +.contact-textarea { min-height: 152px; padding-top: 14px; padding-bottom: 14px; resize: vertical; } -.contact-modal-input.t-input.is-error, -.contact-modal-textarea.t-input.is-error { - border-color: rgba(180, 35, 24, 0.52); - box-shadow: - 0 0 0 4px rgba(180, 35, 24, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.contact-modal-actions { +.contact-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; @@ -785,51 +626,16 @@ code { margin-top: 6px; } -.contact-modal-note { +.contact-feedback { margin: 0; - color: var(--text-soft); - font-size: 13px; - line-height: 1.6; -} - -.contact-modal-actions .marketing-form-feedback-error { - grid-column: 1 / -1; } -.contact-modal-submit { +.contact-submit { min-width: 152px; min-height: 44px; border-radius: 10px; } -.contact-modal-close { - position: absolute; - top: 16px; - right: 16px; - display: inline-flex; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - border: 1px solid var(--line); - border-radius: 12px; - background: rgba(0, 0, 0, 0.02); - color: var(--text-soft); - font-size: 22px; - line-height: 1; - cursor: pointer; - transition: - color 160ms ease, - background-color 160ms ease, - border-color 160ms ease; -} - -.contact-modal-close:hover { - color: var(--ink); - border-color: var(--line-strong); - background: rgba(0, 0, 0, 0.05); -} - .site-footer { display: flex; align-items: center; @@ -840,6 +646,10 @@ code { border-top: 1px solid var(--line); } +.contact-section + .site-footer { + margin-top: 32px; +} + .site-footer p { margin: 0; color: var(--text-soft); @@ -881,6 +691,12 @@ code { padding-inline: 24px; } + .contact-section { + grid-template-columns: 1fr; + gap: 24px; + margin-top: 56px; + } + .site-footer { flex-direction: column; align-items: flex-start; @@ -898,10 +714,6 @@ code { grid-row: 1; justify-self: end; } - - .contact-modal { - padding: 28px 22px 24px; - } } @media (max-width: 640px) { @@ -914,12 +726,12 @@ code { padding-bottom: 16px; } - .contact-modal-field-grid, - .contact-modal-actions { + .contact-field-grid, + .contact-actions { grid-template-columns: 1fr; } - .contact-modal-submit { + .contact-submit { width: 100%; } } @@ -938,8 +750,4 @@ code { .button { transition: none; } - - .contact-modal-backdrop { - transition: none; - } } diff --git a/apps/landing/tsconfig.json b/apps/landing/tsconfig.json index a29569d7..b1931444 100644 --- a/apps/landing/tsconfig.json +++ b/apps/landing/tsconfig.json @@ -8,6 +8,7 @@ "include": [ ".astro/types.d.ts", "src", + "scripts", "astro.config.ts", "vitest.config.ts", "worker-configuration.d.ts" diff --git a/apps/landing/worker-configuration.d.ts b/apps/landing/worker-configuration.d.ts index 649c39a3..66cdc0e8 100644 --- a/apps/landing/worker-configuration.d.ts +++ b/apps/landing/worker-configuration.d.ts @@ -1,15 +1,17 @@ /* eslint-disable */ -// Generated by Wrangler by running `wrangler types worker-configuration.d.ts --env-interface CloudflareEnv` (hash: fc837cf8a3290d03a894b1ac8d2b8ad9) -// Runtime types generated with workerd@1.20260415.1 2026-04-14 +// Generated by Wrangler by running `wrangler types worker-configuration.d.ts --env-interface CloudflareEnv` (hash: 66c8845f99e25b001cea81c4187bd68e) +// Runtime types generated with workerd@1.20260526.1 2026-04-14 nodejs_compat +interface __BaseEnv_CloudflareEnv { + SESSION: KVNamespace; + ASSETS: Fetcher; +} declare namespace Cloudflare { interface GlobalProps { mainModule: typeof import("./src/worker"); } - interface Env { - ASSETS: Fetcher; - } + interface Env extends __BaseEnv_CloudflareEnv {} } -interface CloudflareEnv extends Cloudflare.Env {} +interface CloudflareEnv extends __BaseEnv_CloudflareEnv {} // Begin runtime types /*! ***************************************************************************** @@ -494,6 +496,7 @@ interface ExecutionContext { readonly exports: Cloudflare.Exports; readonly props: Props; cache?: CacheContext; + tracing?: Tracing; } type ExportedHandlerFetchHandler< Env = unknown, @@ -566,6 +569,7 @@ declare abstract class Navigator { sendBeacon(url: string, body?: BodyInit): boolean; readonly userAgent: string; readonly hardwareConcurrency: number; + readonly platform: string; readonly language: string; readonly languages: string[]; } @@ -583,7 +587,6 @@ interface CachePurgeError { } interface CachePurgeResult { success: boolean; - zoneTag: string; errors: CachePurgeError[]; } interface CachePurgeOptions { @@ -1115,7 +1118,7 @@ interface CustomEventCustomEventInit { */ declare class Blob { constructor( - type?: ((ArrayBuffer | ArrayBufferView) | string | Blob)[], + bits?: ((ArrayBuffer | ArrayBufferView) | string | Blob)[], options?: BlobOptions ); /** @@ -2356,11 +2359,34 @@ interface KVNamespaceGetWithMetadataResult { } type QueueContentType = "text" | "bytes" | "json" | "v8"; interface Queue { - send(message: Body, options?: QueueSendOptions): Promise; + metrics(): Promise; + send(message: Body, options?: QueueSendOptions): Promise; sendBatch( messages: Iterable>, options?: QueueSendBatchOptions - ): Promise; + ): Promise; +} +interface QueueSendMetrics { + backlogCount: number; + backlogBytes: number; + oldestMessageTimestamp?: Date; +} +interface QueueSendMetadata { + metrics: QueueSendMetrics; +} +interface QueueSendResponse { + metadata: QueueSendMetadata; +} +interface QueueSendBatchMetrics { + backlogCount: number; + backlogBytes: number; + oldestMessageTimestamp?: Date; +} +interface QueueSendBatchMetadata { + metrics: QueueSendBatchMetrics; +} +interface QueueSendBatchResponse { + metadata: QueueSendBatchMetadata; } interface QueueSendOptions { contentType?: QueueContentType; @@ -2374,6 +2400,19 @@ interface MessageSendRequest { contentType?: QueueContentType; delaySeconds?: number; } +interface QueueMetrics { + backlogCount: number; + backlogBytes: number; + oldestMessageTimestamp?: Date; +} +interface MessageBatchMetrics { + backlogCount: number; + backlogBytes: number; + oldestMessageTimestamp?: Date; +} +interface MessageBatchMetadata { + metrics: MessageBatchMetrics; +} interface QueueRetryOptions { delaySeconds?: number; } @@ -2388,12 +2427,14 @@ interface Message { interface QueueEvent extends ExtendableEvent { readonly messages: readonly Message[]; readonly queue: string; + readonly metadata: MessageBatchMetadata; retryAll(options?: QueueRetryOptions): void; ackAll(): void; } interface MessageBatch { readonly messages: readonly Message[]; readonly queue: string; + readonly metadata: MessageBatchMetadata; retryAll(options?: QueueRetryOptions): void; ackAll(): void; } @@ -2412,7 +2453,7 @@ interface R2ListOptions { startAfter?: string; include?: ("httpMetadata" | "customMetadata")[]; } -declare abstract class R2Bucket { +interface R2Bucket { head(key: string): Promise; get( key: string, @@ -4029,76 +4070,160 @@ declare abstract class Performance { */ toJSON(): object; } +interface Tracing { + enterSpan( + name: string, + callback: (span: Span, ...args: A) => T, + ...args: A + ): T; + Span: typeof Span; +} +declare abstract class Span { + get isTraced(): boolean; + setAttribute(key: string, value?: boolean | number | string): void; +} // ============ AI Search Error Interfaces ============ interface AiSearchInternalError extends Error {} interface AiSearchNotFoundError extends Error {} -// ============ AI Search Request Types ============ -type AiSearchSearchRequest = { - messages: Array<{ - role: "system" | "developer" | "user" | "assistant" | "tool"; - content: string | null; - }>; - ai_search_options?: { - retrieval?: { - retrieval_type?: "vector" | "keyword" | "hybrid"; - /** Match threshold (0-1, default 0.4) */ - match_threshold?: number; - /** Maximum number of results (1-50, default 10) */ - max_num_results?: number; - filters?: VectorizeVectorMetadataFilter; - /** Context expansion (0-3, default 0) */ - context_expansion?: number; - [key: string]: unknown; - }; - query_rewrite?: { - enabled?: boolean; - model?: string; - rewrite_prompt?: string; - [key: string]: unknown; - }; - reranking?: { - enabled?: boolean; - model?: "@cf/baai/bge-reranker-base" | string; - /** Match threshold (0-1, default 0.4) */ - match_threshold?: number; - [key: string]: unknown; - }; +// ============ AI Search Common Types ============ +/** A single message in a conversation-style search or chat request. */ +type AiSearchMessage = { + role: "system" | "developer" | "user" | "assistant" | "tool"; + content: string | null; +}; +/** + * Common shape for `ai_search_options` used by both single-instance and multi-instance requests. + * Contains retrieval, query rewrite, reranking, and cache sub-options. + */ +type AiSearchOptions = { + retrieval?: { + /** Which retrieval backend to use. Defaults to the instance's configured index_method. */ + retrieval_type?: "vector" | "keyword" | "hybrid"; + /** Fusion method for combining vector + keyword results. */ + fusion_method?: "max" | "rrf"; + /** How keyword terms are combined: "and" = all terms must match, "or" = any term matches. */ + keyword_match_mode?: "and" | "or"; + /** Minimum similarity score (0-1) for a result to be included. Default 0.4. */ + match_threshold?: number; + /** Maximum number of results to return (1-50). Default 10. */ + max_num_results?: number; + /** Vectorize metadata filters applied to the search. */ + filters?: VectorizeVectorMetadataFilter; + /** Number of surrounding chunks to include for context (0-3). Default 0. */ + context_expansion?: number; + /** If true, return only item metadata without chunk text. */ + metadata_only?: boolean; + /** If true (default), return empty results on retrieval failure instead of throwing. */ + return_on_failure?: boolean; + /** Boost results by metadata field values. Max 3 entries. */ + boost_by?: Array<{ + field: string; + direction?: "asc" | "desc" | "exists" | "not_exists"; + }>; [key: string]: unknown; }; + query_rewrite?: { + enabled?: boolean; + model?: string; + rewrite_prompt?: string; + [key: string]: unknown; + }; + reranking?: { + enabled?: boolean; + model?: string; + /** Match threshold (0-1, default 0.4) */ + match_threshold?: number; + [key: string]: unknown; + }; + cache?: { + enabled?: boolean; + cache_threshold?: + | "super_strict_match" + | "close_enough" + | "flexible_friend" + | "anything_goes"; + }; + [key: string]: unknown; }; +// ============ AI Search Request Types ============ +/** + * Request body for single-instance search. + * Exactly one of `query` or `messages` must be provided. + */ +type AiSearchSearchRequest = + | { + /** Simple query string. */ + query: string; + messages?: never; + ai_search_options?: AiSearchOptions; + } + | { + query?: never; + /** Conversation-style input. At least one user message with non-empty content is required. */ + messages: AiSearchMessage[]; + ai_search_options?: AiSearchOptions; + }; type AiSearchChatCompletionsRequest = { - messages: Array<{ - role: "system" | "developer" | "user" | "assistant" | "tool"; - content: string | null; - [key: string]: unknown; - }>; + messages: AiSearchMessage[]; model?: string; stream?: boolean; - ai_search_options?: { - retrieval?: { - retrieval_type?: "vector" | "keyword" | "hybrid"; - match_threshold?: number; - max_num_results?: number; - filters?: VectorizeVectorMetadataFilter; - context_expansion?: number; - [key: string]: unknown; - }; - query_rewrite?: { - enabled?: boolean; - model?: string; - rewrite_prompt?: string; - [key: string]: unknown; - }; - reranking?: { - enabled?: boolean; - model?: "@cf/baai/bge-reranker-base" | string; - match_threshold?: number; - [key: string]: unknown; - }; - [key: string]: unknown; - }; + ai_search_options?: AiSearchOptions; [key: string]: unknown; }; +// ============ AI Search Multi-Instance Types (Namespace-Scoped) ============ +/** `ai_search_options` shape for multi-instance requests — requires `instance_ids`. */ +type AiSearchMultiSearchOptions = AiSearchOptions & { + /** Instance IDs to search across (1-10). */ + instance_ids: string[]; +}; +/** + * Request for searching across multiple instances within a namespace. + * `ai_search_options` is required and must include `instance_ids`. + * Exactly one of `query` or `messages` must be provided. + */ +type AiSearchMultiSearchRequest = + | { + /** Simple query string. */ + query: string; + messages?: never; + ai_search_options: AiSearchMultiSearchOptions; + } + | { + query?: never; + /** Conversation-style input. */ + messages: AiSearchMessage[]; + ai_search_options: AiSearchMultiSearchOptions; + }; +/** A search result chunk tagged with the instance it originated from. */ +type AiSearchMultiSearchChunk = AiSearchSearchResponse["chunks"][number] & { + instance_id: string; +}; +/** Describes a per-instance error during a multi-instance operation. */ +type AiSearchMultiSearchError = { + instance_id: string; + message: string; +}; +/** Response from a multi-instance search, with chunks tagged by instance and optional partial-failure errors. */ +type AiSearchMultiSearchResponse = { + search_query: string; + chunks: AiSearchMultiSearchChunk[]; + errors?: AiSearchMultiSearchError[]; +}; +/** Request for chat completions across multiple instances within a namespace. `ai_search_options` is required and must include `instance_ids`. */ +type AiSearchMultiChatCompletionsRequest = Omit< + AiSearchChatCompletionsRequest, + "ai_search_options" +> & { + ai_search_options: AiSearchMultiSearchOptions; +}; +/** Response from multi-instance chat completions, with chunks tagged by instance and optional partial-failure errors. */ +type AiSearchMultiChatCompletionsResponse = Omit< + AiSearchChatCompletionsResponse, + "chunks" +> & { + chunks: AiSearchMultiSearchChunk[]; + errors?: AiSearchMultiSearchError[]; +}; // ============ AI Search Response Types ============ type AiSearchSearchResponse = { search_query: string; @@ -4118,6 +4243,14 @@ type AiSearchSearchResponse = { keyword_score?: number; /** Vector similarity score (0-1) */ vector_score?: number; + /** Keyword rank position */ + keyword_rank?: number; + /** Vector rank position */ + vector_rank?: number; + /** Reranking model score */ + reranking_score?: number; + /** Fusion method used to combine results */ + fusion_method?: "rrf" | "max"; [key: string]: unknown; }; }>; @@ -4146,19 +4279,88 @@ type AiSearchStatsResponse = { skipped?: number; outdated?: number; last_activity?: string; + /** Storage engine statistics. */ + engine?: { + vectorize?: { + vectorsCount: number; + dimensions: number; + }; + r2?: { + payloadSizeBytes: number; + metadataSizeBytes: number; + objectCount: number; + }; + }; }; // ============ AI Search Instance Info Types ============ type AiSearchInstanceInfo = { id: string; type?: "r2" | "web-crawler" | string; source?: string; + source_params?: unknown; paused?: boolean; status?: string; namespace?: string; created_at?: string; modified_at?: string; + token_id?: string; + ai_gateway_id?: string; + rewrite_query?: boolean; + reranking?: boolean; + embedding_model?: string; + ai_search_model?: string; + rewrite_model?: string; + reranking_model?: string; + /** @deprecated Use index_method instead. */ + hybrid_search_enabled?: boolean; + /** Controls which storage backends are active. */ + index_method?: { + vector?: boolean; + keyword?: boolean; + }; + /** Fusion method for combining vector and keyword results. */ + fusion_method?: "max" | "rrf"; + indexing_options?: { + keyword_tokenizer?: "porter" | "trigram"; + } | null; + retrieval_options?: { + keyword_match_mode?: "and" | "or"; + boost_by?: Array<{ + field: string; + direction?: "asc" | "desc" | "exists" | "not_exists"; + }>; + } | null; + chunk?: boolean; + chunk_size?: number; + chunk_overlap?: number; + score_threshold?: number; + max_num_results?: number; + cache?: boolean; + cache_threshold?: + | "super_strict_match" + | "close_enough" + | "flexible_friend" + | "anything_goes"; + custom_metadata?: Array<{ + field_name: string; + data_type: "text" | "number" | "boolean" | "datetime"; + }>; + /** Sync interval in seconds. */ + sync_interval?: 3600 | 7200 | 14400 | 21600 | 43200 | 86400; + metadata?: Record; [key: string]: unknown; }; +/** Pagination, search, and ordering parameters for listing instances within a namespace. */ +type AiSearchListInstancesParams = { + page?: number; + per_page?: number; + /** Search instances by ID. */ + search?: string; + /** Field to sort by. */ + order_by?: "created_at"; + /** Sort direction. */ + order_by_direction?: "asc" | "desc"; +}; type AiSearchListResponse = { result: AiSearchInstanceInfo[]; result_info?: { @@ -4186,19 +4388,64 @@ type AiSearchConfig = { reranking?: boolean; embedding_model?: string; ai_search_model?: string; + rewrite_model?: string; + reranking_model?: string; + /** @deprecated Use index_method instead. */ + hybrid_search_enabled?: boolean; + /** Controls which storage backends are used during indexing. Defaults to vector-only. */ + index_method?: { + vector?: boolean; + keyword?: boolean; + }; + /** Fusion method for combining vector and keyword results. "rrf" = reciprocal rank fusion (default), "max" = maximum score. */ + fusion_method?: "max" | "rrf"; + indexing_options?: { + keyword_tokenizer?: "porter" | "trigram"; + } | null; + retrieval_options?: { + keyword_match_mode?: "and" | "or"; + boost_by?: Array<{ + field: string; + direction?: "asc" | "desc" | "exists" | "not_exists"; + }>; + } | null; + chunk?: boolean; + chunk_size?: number; + chunk_overlap?: number; + /** Minimum similarity score (0-1) for a result to be included. */ + score_threshold?: number; + max_num_results?: number; + cache?: boolean; + /** Similarity threshold for cache hits. Stricter = fewer cache hits but higher relevance. */ + cache_threshold?: + | "super_strict_match" + | "close_enough" + | "flexible_friend" + | "anything_goes"; + custom_metadata?: Array<{ + field_name: string; + data_type: "text" | "number" | "boolean" | "datetime"; + }>; + namespace?: string; + /** Sync interval in seconds. 3600=1h, 7200=2h, 14400=4h, 21600=6h, 43200=12h, 86400=24h. */ + sync_interval?: 3600 | 7200 | 14400 | 21600 | 43200 | 86400; + metadata?: Record; [key: string]: unknown; }; // ============ AI Search Item Types ============ type AiSearchItemInfo = { id: string; key: string; - status: - | "completed" - | "error" - | "skipped" - | "queued" - | "processing" - | "outdated"; + status: "completed" | "error" | "skipped" | "queued" | "running" | "outdated"; + next_action?: "INDEX" | "DELETE" | null; + error?: string; + checksum?: string; + namespace?: string; + chunks_count?: number | null; + file_size?: number | null; + source_id?: string | null; + last_seen_at?: string; + created_at?: string; metadata?: Record; [key: string]: unknown; }; @@ -4214,6 +4461,22 @@ type AiSearchUploadItemOptions = { type AiSearchListItemsParams = { page?: number; per_page?: number; + /** Search items by key name. */ + search?: string; + /** Sort order for results. */ + sort_by?: "status" | "modified_at"; + /** Filter items by processing status. */ + status?: + | "queued" + | "running" + | "completed" + | "error" + | "skipped" + | "outdated"; + /** Filter items by source (e.g. "builtin" or "web-crawler:https://example.com"). */ + source?: string; + /** JSON-encoded Vectorize filter for metadata filtering. */ + metadata_filter?: string; }; type AiSearchListItemsResponse = { result: AiSearchItemInfo[]; @@ -4224,6 +4487,61 @@ type AiSearchListItemsResponse = { total_count: number; }; }; +// ============ AI Search Item Logs Types ============ +type AiSearchItemLogsParams = { + /** Maximum number of log entries to return (1-100, default 50). */ + limit?: number; + /** Opaque cursor for pagination. Pass the `cursor` value from a previous response. */ + cursor?: string; +}; +type AiSearchItemLog = { + timestamp: string; + action: string; + message: string; + fileKey?: string; + chunkCount?: number; + processingTimeMs?: number; + errorType?: string; +}; +/** Paginated response for item processing logs (cursor-based). */ +type AiSearchItemLogsResponse = { + result: AiSearchItemLog[]; + result_info: { + count: number; + per_page: number; + cursor: string | null; + truncated: boolean; + }; +}; +// ============ AI Search Item Chunks Types ============ +type AiSearchItemChunksParams = { + /** Maximum number of chunks to return (1-100, default 20). */ + limit?: number; + /** Offset into the chunks list (default 0). */ + offset?: number; +}; +/** A single indexed chunk belonging to an item, including its text content and byte range. */ +type AiSearchItemChunk = { + id: string; + text: string; + start_byte: number; + end_byte: number; + item?: { + timestamp?: number; + key: string; + metadata?: Record; + }; +}; +/** Paginated response for item chunks (offset-based). */ +type AiSearchItemChunksResponse = { + result: AiSearchItemChunk[]; + result_info: { + count: number; + total: number; + limit: number; + offset: number; + }; +}; // ============ AI Search Job Types ============ type AiSearchJobInfo = { id: string; @@ -4272,7 +4590,7 @@ type AiSearchJobLogsResponse = { // ============ AI Search Sub-Service Classes ============ /** * Single item service for an AI Search instance. - * Provides info, delete, and download operations on a specific item. + * Provides info, download, sync, logs, and chunks operations on a specific item. */ declare abstract class AiSearchItem { /** Get metadata about this item. */ @@ -4282,6 +4600,25 @@ declare abstract class AiSearchItem { * @returns Object with body stream, content type, filename, and size. */ download(): Promise; + /** + * Trigger re-indexing of this item. + * @returns The updated item info. + */ + sync(): Promise; + /** + * Retrieve processing logs for this item (cursor-based pagination). + * @param params Optional pagination parameters (limit, cursor). + * @returns Paginated log entries for this item. + */ + logs(params?: AiSearchItemLogsParams): Promise; + /** + * List indexed chunks for this item (offset-based pagination). + * @param params Optional pagination parameters (limit, offset). + * @returns Paginated chunk entries for this item. + */ + chunks( + params?: AiSearchItemChunksParams + ): Promise; } /** * Items collection service for an AI Search instance. @@ -4291,49 +4628,64 @@ declare abstract class AiSearchItems { /** List items in this instance. */ list(params?: AiSearchListItemsParams): Promise; /** - * Upload a file as an item. + * Upload a file as an item. Behaves as an upsert: if an item with the same + * filename already exists, it is overwritten and re-indexed. * @param name Filename for the uploaded item. - * @param content File content as a ReadableStream, ArrayBuffer, or string. + * @param content File content as a ReadableStream, Blob, or string. * @param options Optional metadata to attach to the item. * @returns The created item info. */ upload( name: string, - content: ReadableStream | ArrayBuffer | string, + content: ReadableStream | Blob | string, options?: AiSearchUploadItemOptions ): Promise; /** * Upload a file and poll until processing completes. + * Behaves as an upsert: if an item with the same filename already exists, + * it is overwritten and re-indexed. * @param name Filename for the uploaded item. - * @param content File content as a ReadableStream, ArrayBuffer, or string. - * @param options Optional metadata to attach to the item. + * @param content File content as a ReadableStream, Blob, or string. + * @param options Optional metadata and polling configuration. * @returns The item info after processing completes (or timeout). */ uploadAndPoll( name: string, - content: ReadableStream | ArrayBuffer | string, - options?: AiSearchUploadItemOptions + content: ReadableStream | Blob | string, + options?: AiSearchUploadItemOptions & { + /** Polling interval in milliseconds (default 1000). */ + pollIntervalMs?: number; + /** Maximum time to wait in milliseconds (default 30000). */ + timeoutMs?: number; + } ): Promise; /** * Get an item by ID. * @param itemId The item identifier. - * @returns Item service for info, delete, and download operations. + * @returns Item service for info, download, sync, logs, and chunks operations. */ get(itemId: string): AiSearchItem; - /** Delete this item from the instance. + /** + * Delete an item from the instance. * @param itemId The item identifier. */ delete(itemId: string): Promise; } /** * Single job service for an AI Search instance. - * Provides info and logs for a specific job. + * Provides info, logs, and cancel operations for a specific job. */ declare abstract class AiSearchJob { /** Get metadata about this job. */ info(): Promise; /** Get logs for this job. */ logs(params?: AiSearchJobLogsParams): Promise; + /** + * Cancel a running job. + * @returns The updated job info. + * @throws AiSearchNotFoundError if the job does not exist. + */ + cancel(): Promise; } /** * Jobs collection service for an AI Search instance. @@ -4351,7 +4703,7 @@ declare abstract class AiSearchJobs { /** * Get a job by ID. * @param jobId The job identifier. - * @returns Job service for info and logs operations. + * @returns Job service for info, logs, and cancel operations. */ get(jobId: string): AiSearchJob; } @@ -4370,7 +4722,7 @@ declare abstract class AiSearchJobs { * // Via namespace binding * const instance = env.AI_SEARCH.get("blog"); * const results = await instance.search({ - * messages: [{ role: "user", content: "How does caching work?" }], + * query: "How does caching work?", * }); * * // Via single instance binding @@ -4382,7 +4734,7 @@ declare abstract class AiSearchJobs { declare abstract class AiSearchInstance { /** * Search the AI Search instance for relevant chunks. - * @param params Search request with messages and optional AI search options. + * @param params Search request with query or messages and optional AI search options. * @returns Search response with matching chunks and search query. */ search(params: AiSearchSearchRequest): Promise; @@ -4414,7 +4766,7 @@ declare abstract class AiSearchInstance { info(): Promise; /** * Get instance statistics (item count, indexing status, etc.). - * @returns Statistics with counts per status and last activity time. + * @returns Statistics with counts per status, last activity time, and engine details. */ stats(): Promise; /** Items collection — list, upload, and manage items in this instance. */ @@ -4426,27 +4778,30 @@ declare abstract class AiSearchInstance { * Namespace-level AI Search service. * * Used as the type of `env.AI_SEARCH` (namespace binding via `ai_search_namespaces`). - * Scoped to a single namespace. Provides dynamic instance access, creation, and deletion. + * Scoped to a single namespace. Provides dynamic instance access, creation, deletion, + * and multi-instance search/chat operations. * * @example * ```ts * // Access an instance within the namespace * const blog = env.AI_SEARCH.get("blog"); - * const results = await blog.search({ - * messages: [{ role: "user", content: "How does caching work?" }], - * }); + * const results = await blog.search({ query: "How does caching work?" }); * * // List all instances in the namespace * const instances = await env.AI_SEARCH.list(); * * // Create a new instance with built-in storage - * const tenant = await env.AI_SEARCH.create({ - * id: "tenant-123", - * }); + * const tenant = await env.AI_SEARCH.create({ id: "tenant-123" }); * * // Upload items into the instance * await tenant.items.upload("doc.pdf", fileContent); * + * // Search across multiple instances + * const multi = await env.AI_SEARCH.search({ + * query: "caching", + * ai_search_options: { instance_ids: ["blog", "docs"] }, + * }); + * * // Delete an instance * await env.AI_SEARCH.delete("tenant-123"); * ``` @@ -4459,10 +4814,11 @@ declare abstract class AiSearchNamespace { */ get(name: string): AiSearchInstance; /** - * List all instances in the bound namespace. - * @returns Array of instance metadata. + * List instances in the bound namespace. + * @param params Optional pagination, search, and ordering parameters. + * @returns Array of instance metadata with pagination info. */ - list(): Promise; + list(params?: AiSearchListInstancesParams): Promise; /** * Create a new instance within the bound namespace. * @param config Instance configuration. Only `id` is required — omit `type` and `source` to create with built-in storage. @@ -4487,6 +4843,35 @@ declare abstract class AiSearchNamespace { * @param name Instance name to delete. */ delete(name: string): Promise; + /** + * Search across multiple instances within the bound namespace. + * Fans out to the specified instance_ids and merges results. + * @param params Search request with required `ai_search_options.instance_ids`. + * @returns Search response with chunks tagged by instance_id and optional partial-failure errors. + */ + search( + params: AiSearchMultiSearchRequest + ): Promise; + /** + * Generate chat completions across multiple instances within the bound namespace (streaming). + * Fans out to the specified instance_ids, merges context, and generates a response. + * @param params Chat completions request with stream: true and required `ai_search_options.instance_ids`. + * @returns ReadableStream of server-sent events. + */ + chatCompletions( + params: AiSearchMultiChatCompletionsRequest & { + stream: true; + } + ): Promise; + /** + * Generate chat completions across multiple instances within the bound namespace. + * Fans out to the specified instance_ids, merges context, and generates a response. + * @param params Chat completions request with required `ai_search_options.instance_ids`. + * @returns Chat completion response with choices, chunks tagged by instance_id, and optional partial-failure errors. + */ + chatCompletions( + params: AiSearchMultiChatCompletionsRequest + ): Promise; } type AiImageClassificationInput = { image: number[]; @@ -5140,9 +5525,6 @@ type ChatCompletionChoice = { | "function_call"; logprobs: ChatCompletionLogprobs | null; }; -type ChatCompletionsPromptInput = { - prompt: string; -} & ChatCompletionsCommonOptions; type ChatCompletionsMessagesInput = { messages: Array; } & ChatCompletionsCommonOptions; @@ -9267,11 +9649,11 @@ declare abstract class Base_Ai_Cf_Pipecat_Ai_Smart_Turn_V2 { postProcessedOutputs: Ai_Cf_Pipecat_Ai_Smart_Turn_V2_Output; } declare abstract class Base_Ai_Cf_Openai_Gpt_Oss_120B { - inputs: XOR; + inputs: XOR; postProcessedOutputs: XOR; } declare abstract class Base_Ai_Cf_Openai_Gpt_Oss_20B { - inputs: XOR; + inputs: XOR; postProcessedOutputs: XOR; } interface Ai_Cf_Leonardo_Phoenix_1_0_Input { @@ -10365,6 +10747,10 @@ declare abstract class Base_Ai_Cf_Moonshotai_Kimi_K2_5 { inputs: ChatCompletionsInput; postProcessedOutputs: ChatCompletionsOutput; } +declare abstract class Base_Ai_Cf_Moonshotai_Kimi_K2_6 { + inputs: ChatCompletionsInput; + postProcessedOutputs: ChatCompletionsOutput; +} declare abstract class Base_Ai_Cf_Nvidia_Nemotron_3_120B_A12B { inputs: ChatCompletionsInput; postProcessedOutputs: ChatCompletionsOutput; @@ -10462,7 +10848,9 @@ interface AiModels { "@cf/black-forest-labs/flux-2-klein-9b": Base_Ai_Cf_Black_Forest_Labs_Flux_2_Klein_9B; "@cf/zai-org/glm-4.7-flash": Base_Ai_Cf_Zai_Org_Glm_4_7_Flash; "@cf/moonshotai/kimi-k2.5": Base_Ai_Cf_Moonshotai_Kimi_K2_5; + "@cf/moonshotai/kimi-k2.6": Base_Ai_Cf_Moonshotai_Kimi_K2_6; "@cf/nvidia/nemotron-3-120b-a12b": Base_Ai_Cf_Nvidia_Nemotron_3_120B_A12B; + "@cf/google/gemma-4-26b-a4b-it": Base_Ai_Cf_Google_Gemma_4_26B_A4B_IT; } type AiOptions = { /** @@ -10515,16 +10903,8 @@ type AiModelsSearchObject = { value: string; }[]; }; -type ChatCompletionsBase = XOR< - ChatCompletionsPromptInput, - ChatCompletionsMessagesInput ->; -type ChatCompletionsInput = XOR< - ChatCompletionsBase, - { - requests: ChatCompletionsBase[]; - } ->; +type ChatCompletionsBase = ChatCompletionsMessagesInput; +type ChatCompletionsInput = ChatCompletionsMessagesInput; interface InferenceUpstreamError extends Error {} interface AiInternalError extends Error {} type AiModelListType = Record; @@ -10587,9 +10967,16 @@ declare abstract class Ai { inputs: AiModelList[Name]["inputs"], options?: AiOptions ): Promise; - // Unknown model (gateway fallback) - run( - model: string & {}, + // Unknown model (fallback). + // + // The `Exclude<..., keyof AiModelList>` constraint forces TypeScript to + // route any model name that is a literal key of `AiModelList` to one of + // the known-model overloads above (so input/output mismatches surface as + // type errors rather than silently falling back to `Record`). + // Names that aren't in `AiModelList` — e.g. third-party gateway models + // like `"google/nano-banana"` — still hit this overload. + run( + model: Model extends keyof AiModelList ? never : Model, inputs: Record, options?: AiOptions ): Promise>; @@ -10726,6 +11113,246 @@ declare abstract class AiGateway { ): Promise; getUrl(provider?: AIGatewayProviders | string): Promise; // eslint-disable-line } +// Copyright (c) 2022-2025 Cloudflare, Inc. +// Licensed under the Apache 2.0 license found in the LICENSE file or at: +// https://opensource.org/licenses/Apache-2.0 +/** + * Artifacts — Git-compatible file storage on Cloudflare Workers. + * + * Provides programmatic access to create, manage, and fork repositories, + * and to issue and revoke scoped access tokens. + */ +/** Information about a repository. */ +interface ArtifactsRepoInfo { + /** Unique repository ID. */ + id: string; + /** Repository name. */ + name: string; + /** Repository description, or null if not set. */ + description: string | null; + /** Default branch name (e.g. "main"). */ + defaultBranch: string; + /** ISO 8601 creation timestamp. */ + createdAt: string; + /** ISO 8601 last-updated timestamp. */ + updatedAt: string; + /** ISO 8601 timestamp of the last push, or null if never pushed. */ + lastPushAt: string | null; + /** Fork source (e.g. "github:owner/repo", "artifacts:namespace/repo"), or null if not a fork. */ + source: string | null; + /** Whether the repository is read-only. */ + readOnly: boolean; + /** HTTPS git remote URL. */ + remote: string; +} +/** Result of creating a repository — includes the initial access token. */ +interface ArtifactsCreateRepoResult { + /** Unique repository ID. */ + id: string; + /** Repository name. */ + name: string; + /** Repository description, or null if not set. */ + description: string | null; + /** Default branch name. */ + defaultBranch: string; + /** HTTPS git remote URL. */ + remote: string; + /** Plaintext access token (only returned at creation time). */ + token: string; + /** ISO 8601 token expiry timestamp. */ + tokenExpiresAt: string; +} +/** Paginated list of repositories. */ +interface ArtifactsRepoListResult { + /** Repositories in this page (without the `remote` field). */ + repos: Omit[]; + /** Total number of repositories in the namespace. */ + total: number; + /** Cursor for the next page, if there are more results. */ + cursor?: string; +} +/** Result of creating an access token. */ +interface ArtifactsCreateTokenResult { + /** Unique token ID. */ + id: string; + /** Plaintext token (only returned at creation time). */ + plaintext: string; + /** Token scope: "read" or "write". */ + scope: "read" | "write"; + /** ISO 8601 token expiry timestamp. */ + expiresAt: string; +} +/** Token metadata (no plaintext). */ +interface ArtifactsTokenInfo { + /** Unique token ID. */ + id: string; + /** Token scope: "read" or "write". */ + scope: "read" | "write"; + /** Token state: "active", "expired", or "revoked". */ + state: "active" | "expired" | "revoked"; + /** ISO 8601 creation timestamp. */ + createdAt: string; + /** ISO 8601 expiry timestamp. */ + expiresAt: string; +} +/** Paginated list of tokens for a repository. */ +interface ArtifactsTokenListResult { + /** Tokens in this page. */ + tokens: ArtifactsTokenInfo[]; + /** Total number of tokens for the repository. */ + total: number; +} +/** + * Handle for a single repository. Returned by Artifacts.get(). + * + * Methods may throw `ArtifactsError` with code `INTERNAL_ERROR` if an unexpected service error occurs. + */ +interface ArtifactsRepo extends ArtifactsRepoInfo { + /** + * Create an access token for this repo. + * @param scope Token scope: "write" (default) or "read". + * @param ttl Time-to-live in seconds (default 86400, min 60, max 31536000). + * @throws {ArtifactsError} with code `INVALID_TTL` if ttl is out of range. + */ + createToken( + scope?: "write" | "read", + ttl?: number + ): Promise; + /** List tokens for this repo (metadata only, no plaintext). */ + listTokens(): Promise; + /** + * Revoke a token by plaintext or ID. + * @param tokenOrId Plaintext token or token ID. + * @returns true if revoked, false if not found. + * @throws {ArtifactsError} with code `INVALID_INPUT` if tokenOrId is empty. + */ + revokeToken(tokenOrId: string): Promise; + // ── Fork ── + /** + * Fork this repo to a new repo. + * @param name Target repository name. + * @param opts Optional: description, readOnly flag, defaultBranchOnly (default true). + * @throws {ArtifactsError} with code `INVALID_REPO_NAME` if name is invalid. + * @throws {ArtifactsError} with code `ALREADY_EXISTS` if the target repo already exists. + * @throws {ArtifactsError} with code `FORK_IN_PROGRESS` if a fork is already running. + */ + fork( + name: string, + opts?: { + description?: string; + readOnly?: boolean; + defaultBranchOnly?: boolean; + } + ): Promise; +} +// ── Error types ────────────────────────────────────────────────────────────── +/** + * Error codes returned by Artifacts binding operations. + * + * Each code maps to a numeric code available on `ArtifactsError.numericCode`. + */ +type ArtifactsErrorCode = + | "ALREADY_EXISTS" + | "NOT_FOUND" + | "IMPORT_IN_PROGRESS" + | "FORK_IN_PROGRESS" + | "INVALID_INPUT" + | "INVALID_REPO_NAME" + | "INVALID_TTL" + | "INVALID_URL" + | "REMOTE_AUTH_REQUIRED" + | "UPSTREAM_UNAVAILABLE" + | "MEMORY_LIMIT" + | "INTERNAL_ERROR"; +/** + * Error thrown by Artifacts binding operations. + * + * Uses a string `.code` discriminator following the Cloudflare platform + * convention (StreamError, ImagesError, etc.). The `.numericCode` matches + * the REST API `errors[].code` values. + */ +interface ArtifactsError extends Error { + readonly name: "ArtifactsError"; + /** String error code for programmatic matching. */ + readonly code: ArtifactsErrorCode; + /** Numeric error code matching the REST API. */ + readonly numericCode: number; +} +// ── Binding ────────────────────────────────────────────────────────────────── +/** + * Artifacts binding — namespace-level operations. + * + * Methods may throw `ArtifactsError` with code `INTERNAL_ERROR` if an unexpected service error occurs. + */ +interface Artifacts { + /** + * Create a new repository with an initial access token. + * @param name Repository name (alphanumeric, dots, hyphens, underscores). + * @param opts Optional: readOnly flag, description, default branch name. + * @returns Repo metadata with initial token. + * @throws {ArtifactsError} with code `INVALID_REPO_NAME` if name is invalid. + * @throws {ArtifactsError} with code `ALREADY_EXISTS` if the repo already exists. + */ + create( + name: string, + opts?: { + readOnly?: boolean; + description?: string; + setDefaultBranch?: string; + } + ): Promise; + /** + * Get a handle to an existing repository. + * @param name Repository name. + * @returns Repo handle. + * @throws {ArtifactsError} with code `NOT_FOUND` if the repo does not exist. + * @throws {ArtifactsError} with code `IMPORT_IN_PROGRESS` if the repo is still importing. + * @throws {ArtifactsError} with code `FORK_IN_PROGRESS` if the repo is still forking. + */ + get(name: string): Promise; + /** + * Import a repository from an external git remote. + * @param params Source URL and optional branch/depth, plus target name and options. + * @returns Repo metadata with initial token. + * @throws {ArtifactsError} with code `INVALID_REPO_NAME` if the target name is invalid. + * @throws {ArtifactsError} with code `INVALID_INPUT` if the source URL is not valid HTTPS. + * @throws {ArtifactsError} with code `INVALID_URL` if the source URL does not point to a git repository. + * @throws {ArtifactsError} with code `REMOTE_AUTH_REQUIRED` if the remote requires authentication. + * @throws {ArtifactsError} with code `NOT_FOUND` if the remote repository does not exist. + * @throws {ArtifactsError} with code `UPSTREAM_UNAVAILABLE` if the remote cannot be reached. + * @throws {ArtifactsError} with code `MEMORY_LIMIT` if the import exceeds service memory limits. + * @throws {ArtifactsError} with code `ALREADY_EXISTS` if the target repo already exists. + */ + import(params: { + source: { + url: string; + branch?: string; + depth?: number; + }; + target: { + name: string; + opts?: { + description?: string; + readOnly?: boolean; + }; + }; + }): Promise; + /** + * List repositories with cursor-based pagination. + * @param opts Optional: limit (1–200, default 50), cursor for next page. + */ + list(opts?: { + limit?: number; + cursor?: string; + }): Promise; + /** + * Delete a repository and all associated tokens. + * @param name Repository name. + * @returns true if deleted, false if not found. + * @throws {ArtifactsError} with code `INVALID_REPO_NAME` if name is invalid. + */ + delete(name: string): Promise; +} /** * @deprecated Use the standalone AI Search Workers binding instead. * See https://developers.cloudflare.com/ai-search/usage/workers-binding/ @@ -12108,11 +12735,11 @@ interface SendEmail { send(message: EmailMessage): Promise; send(builder: { from: string | EmailAddress; - to: string | string[]; + to: string | EmailAddress | (string | EmailAddress)[]; subject: string; replyTo?: string | EmailAddress; - cc?: string | string[]; - bcc?: string | string[]; + cc?: string | EmailAddress | (string | EmailAddress)[]; + bcc?: string | EmailAddress | (string | EmailAddress)[]; headers?: Record; text?: string; html?: string; @@ -12138,8 +12765,8 @@ declare module "cloudflare:email" { * Evaluation context for targeting rules. * Keys are attribute names (e.g. "userId", "country"), values are the attribute values. */ -type EvaluationContext = Record; -interface EvaluationDetails { +type FlagshipEvaluationContext = Record; +interface FlagshipEvaluationDetails { flagKey: string; value: T; variant?: string | undefined; @@ -12147,7 +12774,7 @@ interface EvaluationDetails { errorCode?: string | undefined; errorMessage?: string | undefined; } -interface FlagEvaluationError extends Error {} +interface FlagshipEvaluationError extends Error {} /** * Feature flags binding for evaluating feature flags from a Cloudflare Workers script. * @@ -12167,7 +12794,7 @@ interface FlagEvaluationError extends Error {} * console.log(details.variant, details.reason); * ``` */ -declare abstract class Flags { +declare abstract class Flagship { /** * Get a flag value without type checking. * @param flagKey The key of the flag to evaluate. @@ -12177,7 +12804,7 @@ declare abstract class Flags { get( flagKey: string, defaultValue?: unknown, - context?: EvaluationContext + context?: FlagshipEvaluationContext ): Promise; /** * Get a boolean flag value. @@ -12188,7 +12815,7 @@ declare abstract class Flags { getBooleanValue( flagKey: string, defaultValue: boolean, - context?: EvaluationContext + context?: FlagshipEvaluationContext ): Promise; /** * Get a string flag value. @@ -12199,7 +12826,7 @@ declare abstract class Flags { getStringValue( flagKey: string, defaultValue: string, - context?: EvaluationContext + context?: FlagshipEvaluationContext ): Promise; /** * Get a number flag value. @@ -12210,7 +12837,7 @@ declare abstract class Flags { getNumberValue( flagKey: string, defaultValue: number, - context?: EvaluationContext + context?: FlagshipEvaluationContext ): Promise; /** * Get an object flag value. @@ -12221,7 +12848,7 @@ declare abstract class Flags { getObjectValue( flagKey: string, defaultValue: T, - context?: EvaluationContext + context?: FlagshipEvaluationContext ): Promise; /** * Get a boolean flag value with full evaluation details. @@ -12232,8 +12859,8 @@ declare abstract class Flags { getBooleanDetails( flagKey: string, defaultValue: boolean, - context?: EvaluationContext - ): Promise>; + context?: FlagshipEvaluationContext + ): Promise>; /** * Get a string flag value with full evaluation details. * @param flagKey The key of the flag to evaluate. @@ -12243,8 +12870,8 @@ declare abstract class Flags { getStringDetails( flagKey: string, defaultValue: string, - context?: EvaluationContext - ): Promise>; + context?: FlagshipEvaluationContext + ): Promise>; /** * Get a number flag value with full evaluation details. * @param flagKey The key of the flag to evaluate. @@ -12254,8 +12881,8 @@ declare abstract class Flags { getNumberDetails( flagKey: string, defaultValue: number, - context?: EvaluationContext - ): Promise>; + context?: FlagshipEvaluationContext + ): Promise>; /** * Get an object flag value with full evaluation details. * @param flagKey The key of the flag to evaluate. @@ -12265,8 +12892,8 @@ declare abstract class Flags { getObjectDetails( flagKey: string, defaultValue: T, - context?: EvaluationContext - ): Promise>; + context?: FlagshipEvaluationContext + ): Promise>; } /** * Hello World binding to serve as an explanatory example. DO NOT USE @@ -13106,17 +13733,36 @@ declare namespace CloudflareWorkersModule { type: string; }; export type WorkflowStepContext = { + step: { + name: string; + count: number; + }; attempt: number; + config: WorkflowStepConfig; + }; + export type WorkflowRollbackContext = { + error: Error; + output: T | undefined; + stepName: string; + }; + export type WorkflowRollbackHandler = ( + ctx: WorkflowRollbackContext + ) => Promise; + export type WorkflowStepRollbackOptions = { + rollback?: WorkflowRollbackHandler; + rollbackConfig?: WorkflowStepConfig; }; export abstract class WorkflowStep { do>( name: string, - callback: (ctx: WorkflowStepContext) => Promise + callback: (ctx: WorkflowStepContext) => Promise, + rollbackOptions?: WorkflowStepRollbackOptions ): Promise; do>( name: string, config: WorkflowStepConfig, - callback: (ctx: WorkflowStepContext) => Promise + callback: (ctx: WorkflowStepContext) => Promise, + rollbackOptions?: WorkflowStepRollbackOptions ): Promise; sleep: (name: string, duration: WorkflowSleepDuration) => Promise; sleepUntil: (name: string, timestamp: Date | number) => Promise; @@ -13163,6 +13809,8 @@ declare namespace CloudflareWorkersModule { ): unknown; export const env: Cloudflare.Env; export const exports: Cloudflare.Exports; + export const cache: CacheContext; + export const tracing: Tracing; } declare module "cloudflare:workers" { export = CloudflareWorkersModule; @@ -14070,7 +14718,8 @@ declare namespace TailStream { | "exceededMemory" | "loadShed" | "responseStreamDisconnected" - | "scriptNotFound"; + | "scriptNotFound" + | "internalError"; interface ScriptVersion { readonly id: string; readonly tag?: string; @@ -14197,6 +14846,9 @@ declare namespace TailStream { // 1. This is an Onset event // 2. We are not inheriting any SpanContext. (e.g. this is a cross-account service binding or a new top-level invocation) readonly spanId?: string; + // W3C trace flags from an upstream traceparent. Absent when no upstream + // sampling decision was made. + readonly traceFlags?: number; } interface TailEvent { // invocation id of the currently invoked worker stage. @@ -14502,6 +15154,103 @@ type WorkerVersionMetadata = { /** The timestamp of when the Worker Version was uploaded */ timestamp: string; }; +// ============ Web Search Request Types ============ +/** + * Options for a Web Search query. + */ +type WebSearchSearchOptions = { + /** The search query. */ + query: string; + /** + * Maximum number of results to return. Defaults to 10, capped at 20. + * The actual count may be lower if fewer matches exist. + */ + limit?: number; +}; +// ============ Web Search Response Types ============ +/** + * A single Web Search result. + * + * Web Search is discovery-only -- results carry catalog metadata about a page + * but never the page body. To read a result's content the caller invokes the + * global `fetch()` API against the result's `url`, at which point the + * destination's own access controls apply (including Cloudflare Pay-per-Crawl). + */ +type WebSearchResult = { + /** Canonical URL. */ + url: string; + /** Page title. */ + title: string; + /** Page-level description. May be absent. */ + description?: string; + /** + * Last-modified date for the page, when known. Naive (no timezone) + * ISO-8601 datetime, e.g. `"2025-11-30T04:39:48"`. + */ + lastModifiedDate?: string; + /** + * Page meta image URL (typically the `og:image`). May be absent. + */ + imageUrl?: string; + /** Optional favicon URL for UI hints. */ + faviconUrl?: string; +}; +/** + * Per-response metadata for a Web Search query. Carries operational + * fields useful for support and debugging. + */ +type WebSearchResponseMetadata = { + /** The query that was executed. */ + query: string; + /** Opaque request identifier used for support and debugging. */ + requestId: string; + /** End-to-end latency for this search request, in milliseconds. */ + latencyMs: number; +}; +/** + * Response from a Web Search query. + */ +type WebSearchSearchResponse = { + items: WebSearchResult[]; + metadata: WebSearchResponseMetadata; +}; +// ============ Web Search Binding Class ============ +/** + * Cloudflare Web Search binding. + * + * Discovery-only primitive for agents and Workers. Returns URLs and catalog + * metadata for a query; never returns page content or excerpts. To read a + * result's body, fetch the URL with the global `fetch()` API. + * + * Declared in wrangler with a single object (there is exactly one corpus, the + * public web, so there is no name, namespace, or instance to specify): + * + * ```jsonc + * { "web_search": { "binding": "WEBSEARCH" } } + * ``` + * + * @example + * ```ts + * const { items, metadata } = await env.WEBSEARCH.search({ + * query: "Cloudflare Workers", + * }); + * + * const top = items[0]; + * console.log(top.url, top.title, metadata.latencyMs); + * + * // Read content yourself; pay-per-crawl and other publisher + * // controls apply at the fetch site, not at search time. + * const page = await fetch(top.url); + * ``` + */ +declare abstract class WebSearch { + /** + * Run a Web Search query. + * @param options Search options. Only `query` is required. + * @returns The matching results plus per-response metadata. + */ + search(options: WebSearchSearchOptions): Promise; +} interface DynamicDispatchLimits { /** * Limit CPU time in milliseconds. @@ -14625,6 +15374,27 @@ interface WorkflowError { code?: number; message: string; } +interface WorkflowInstanceRestartOptions { + /** + * Restart from a specific step. If omitted, the instance restarts from the beginning. + * The step must exist in the instance's execution history. + */ + from?: { + /** + * The step name as defined in your workflow code. + */ + name: string; + /** + * 1-indexed occurrence of this step name. Use when the same step name appears multiple times (e.g. in a loop). + * @default 1 + */ + count?: number; + /** + * Step type filter. Use when different step types share the same name. + */ + type?: "do" | "sleep" | "waitForEvent"; + }; +} declare abstract class WorkflowInstance { public id: string; /** @@ -14640,9 +15410,11 @@ declare abstract class WorkflowInstance { */ public terminate(): Promise; /** - * Restart the instance. + * Restart the instance. Optionally restart from a specific step, preserving + * cached results for all steps before it. + * @param options Options for the restart, including an optional step to restart from. */ - public restart(): Promise; + public restart(options?: WorkflowInstanceRestartOptions): Promise; /** * Returns the current status of the instance. */ diff --git a/apps/landing/wrangler.toml b/apps/landing/wrangler.toml index d1990571..2931afd5 100644 --- a/apps/landing/wrangler.toml +++ b/apps/landing/wrangler.toml @@ -5,6 +5,7 @@ name = "onequery-landing" main = "./src/worker.ts" compatibility_date = "2026-04-14" +# Starlight's Cloudflare SSR path depends on Node-compatible modules. compatibility_flags = ["nodejs_compat"] logpush = true preview_urls = true @@ -17,7 +18,9 @@ id = "4eae4e6551dc4042950bd2270b09f772" [assets] directory = "./dist/client" binding = "ASSETS" -run_worker_first = ["/", "/connectors/*", "/blog/*"] +# Routes with generated Markdown sidecars need Worker-first handling so +# Accept: text/markdown can be negotiated before static asset serving. +run_worker_first = ["/", "/connectors/*", "/blog/*", "/docs/*", "/compare/*"] [observability] enabled = true diff --git a/bun.lock b/bun.lock index b0d3df76..21160755 100644 --- a/bun.lock +++ b/bun.lock @@ -22,12 +22,12 @@ "eslint-plugin-turbo": "2.9.5", "happy-dom": "20.3.3", "knip": "6.0.5", - "lefthook": "2.1.6", + "lefthook": "2.1.9", "npm-check-updates": "19.3.1", "openclaw": "catalog:tooling", "oxfmt": "catalog:tooling", "oxlint": "catalog:tooling", - "oxlint-tsgolint": "0.22.0", + "oxlint-tsgolint": "0.23.0", "turbo": "2.9.5", "vitest": "catalog:testing", }, @@ -118,6 +118,7 @@ "version": "0.0.0", "dependencies": { "@astrojs/cloudflare": "catalog:", + "@astrojs/compiler-rs": "catalog:", "@astrojs/mdx": "catalog:", "@astrojs/partytown": "catalog:", "@astrojs/react": "catalog:", @@ -129,21 +130,22 @@ "@onequery/db": "workspace:*", "@onequery/ui": "workspace:*", "astro": "catalog:", - "better-result": "catalog:", "mdast-util-to-string": "4.0.0", "nanostores": "catalog:", - "react": "19.3.0-canary-d5736f09-20260507", - "react-dom": "19.3.0-canary-d5736f09-20260507", + "react": "catalog:", + "react-dom": "catalog:", "reading-time": "1.5.0", "simple-icons": "catalog:", - "zod": "catalog:", }, "devDependencies": { "@astrojs/check": "catalog:tooling", "@cloudflare/workers-types": "catalog:tooling", + "@emulators/core": "0.6.0", + "@emulators/slack": "0.6.0", "@onequery/installer": "workspace:*", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "emulate": "0.6.0", "rollup-plugin-visualizer": "catalog:tooling", "typescript": "catalog:tooling", "vitest": "catalog:testing", @@ -281,6 +283,9 @@ "packages/datetime": { "name": "@onequery/datetime", "version": "0.0.0", + "devDependencies": { + "vitest": "catalog:testing", + }, }, "packages/db": { "name": "@onequery/db", @@ -446,6 +451,7 @@ }, "catalog": { "@astrojs/cloudflare": "13.5.1", + "@astrojs/compiler-rs": "0.2.1", "@astrojs/mdx": "5.0.6", "@astrojs/partytown": "2.1.7", "@astrojs/react": "5.0.5", @@ -475,7 +481,7 @@ "antiox": "0.1.4", "astro": "6.3.7", "better-auth": "1.5.5", - "better-result": "2.9.0", + "better-result": "2.9.2", "hono": "4.12.16", "hono-problem-details": "0.6.1", "hono-rate-limiter": "0.5.3", @@ -518,15 +524,15 @@ "@vitejs/plugin-react": "6.0.1", "babel-plugin-react-compiler": "1.0.0", "openclaw": "2026.4.10", - "oxfmt": "0.46.0", - "oxlint": "1.61.0", + "oxfmt": "0.52.0", + "oxlint": "1.67.0", "postcss": "8.5.6", "rollup-plugin-visualizer": "7.0.1", "tailwindcss": "4.2.2", "typescript": "5.4.5", "vite": "8.0.2", "vite-tsconfig-paths": "6.1.1", - "wrangler": "4.83.0", + "wrangler": "4.95.0", }, }, "packages": { @@ -548,6 +554,28 @@ "@astrojs/compiler": ["@astrojs/compiler@4.0.0", "", {}, "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA=="], + "@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.2.1", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.2.1", "@astrojs/compiler-binding-darwin-x64": "0.2.1", "@astrojs/compiler-binding-linux-arm64-gnu": "0.2.1", "@astrojs/compiler-binding-linux-arm64-musl": "0.2.1", "@astrojs/compiler-binding-linux-x64-gnu": "0.2.1", "@astrojs/compiler-binding-linux-x64-musl": "0.2.1", "@astrojs/compiler-binding-wasm32-wasi": "0.2.1", "@astrojs/compiler-binding-win32-arm64-msvc": "0.2.1", "@astrojs/compiler-binding-win32-x64-msvc": "0.2.1" } }, "sha512-KkGifC48eylyWndrbTGkCoc9ojAFWrHQvV1YON06rtEDSroC6U2hWFu2vWGgkZuT0hJpWFKqeelLvpJZeUbCMQ=="], + + "@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Nr1mMFWMxKK7YQSQ+nGbtIoDj+qu/npb7GLfYpLMAgo+1gbYnbRCIRwnVsVBENP/PO2X+3mSfaYZo+pMcyxN3Q=="], + + "@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-sAEAl+hgqJ2z0Vfe/yOhho/gnBavjVNXuEQY2vKyqAgfWfZbSpgqySZKezwTJhg7IczzellDt1PX4wI3hhkbZg=="], + + "@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WGR/L4fenBN2J1J+C3s3oz8eGfzvZW1wLwo54xp8IgFXbvGfuZbvirWPArPt6KkmyQOuGcfj+/GqEPuwOSj3FA=="], + + "@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-OKPERWCM/3oqz1MBKG6OfAUGzkBOqf1OQLFpUXEZrd4WuMra3dOyC+1ZA9x0c0Su8JFTRakVop1Z2b7uSajwkw=="], + + "@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-QtULbhtBKO2zL2X8cwcIawP6rjAe4a5C4xXzLk3+Nk5OZQBof1uQIJucPKj+WmfdfXaic+kzmRhPzMOpBo2xbg=="], + + "@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-wOvgpg3RcjaKhTP5UUi2E2Kj8rL4I5R3IZC7qyCmmEur1q+rZpDKBwfeijVYz5GU/8e4rbGoZNqkrUCPI4g5Dg=="], + + "@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.2.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-sDi0S6Kypd38ykhHjnbovwhfHSQ0OYqkMfYBGFIJ/Wkj2Ptwk6hU0K0/2H28uHzGqRfbL8suRPeypcijBUoA0g=="], + + "@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-Y0CtraoAikHLMOV1mESibU66FfbsWa06jT8I978bIpVNlZfjDMPlma0QCvTXsY9uTBfHRFllGqiYzspcCXY0Rw=="], + + "@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-RKBJSfLwwnreQMonelV9lOwU86qdkIV+o6czbXK8moht16jp4mvhINtRqQWacEyXlCkSRAeM2CNtEu82jcu6Og=="], + + "@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.2.1", "", { "dependencies": { "@astrojs/compiler-binding": "0.2.1" } }, "sha512-Yb9c/IkOxwKT/FOIsd/cUv/3jhqwJZAQ5Lcjxyu84erV9rWK1Yq2k2NpqVtJYNGjoBCdS15PkYei/3CvPSWjMg=="], + "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.9.1", "", { "dependencies": { "picomatch": "^4.0.4" } }, "sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ=="], "@astrojs/language-server": ["@astrojs/language-server@2.16.8", "", { "dependencies": { "@astrojs/compiler": "^2.13.1", "@astrojs/yaml2ts": "^0.2.3", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.28", "@volar/language-core": "~2.4.28", "@volar/language-server": "~2.4.28", "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", "tinyglobby": "^0.2.16", "volar-service-css": "0.0.70", "volar-service-emmet": "0.0.70", "volar-service-html": "0.0.70", "volar-service-prettier": "0.0.70", "volar-service-typescript": "0.0.70", "volar-service-typescript-twoslash-queries": "0.0.70", "volar-service-yaml": "0.0.70", "vscode-html-languageservice": "^5.6.2", "vscode-uri": "^3.1.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "bin/nodeServer.js" } }, "sha512-yg1pZF6hs9FaKr2fgXMOGbW7pDLgFexFjuhWilPAc8VybTU+WSnbfbhYaUL1exm6dAK4sM3aKXGcfVwss+HXbg=="], @@ -836,21 +864,21 @@ "@clack/prompts": ["@clack/prompts@1.2.0", "", { "dependencies": { "@clack/core": "1.2.0", "fast-string-width": "^1.1.0", "fast-wrap-ansi": "^0.1.3", "sisteransi": "^1.0.5" } }, "sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w=="], - "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], + "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.5.0", "", {}, "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg=="], - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg=="], + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], "@cloudflare/vite-plugin": ["@cloudflare/vite-plugin@1.32.3", "", { "dependencies": { "@cloudflare/unenv-preset": "2.16.0", "miniflare": "4.20260415.0", "unenv": "2.0.0-rc.24", "wrangler": "4.83.0", "ws": "8.18.0" }, "peerDependencies": { "vite": "^6.1.0 || ^7.0.0 || ^8.0.0" } }, "sha512-a8ZkCA/SOiJ36jT3LlBLkUb7ZzGInhYJoTY4BMRBGdk+nsh44HavbNvtu/RdaqS5VJEMLM4+LqVIJ+V0ahGeFg=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260415.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-dsxaKsQm3LnPGNPEdsRv09QN3Y4DqCw7kX5j6noKqbAtro2jTr95sVlYM1jUxZ5FkOl1f7SXgaKKB9t5H5Nkbg=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260526.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/pR3GH3gfv0PUp7DjI8v0aAIDOqFwibq4bg5xT7TZgcVdBV/cJQWckdXCMqiRtHiawLwogUX00EIOINkYJ1Zqg=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260415.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+JgSgVA49KyKteHRA1SnonE4Zn5Ei5zdAp5FQMxFmXI8qulZw4Hl7safXxRyK4i9sTO8gl7TFOKO5Q64VPvSDQ=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260526.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rcyu0iANYfaiezKh3Mcao1O4IIgVfQldxduiL5TZT1sP0NIeRY4YReSTrzPxNnXxSYaIqaqRHMcHbUM/ic4knA=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260415.1", "", { "os": "linux", "cpu": "x64" }, "sha512-tU+9pwsqCy8afOVlGtiWrWQc/fedQK4SRm4KPIAt+zOiQWDxWASm6YGBUJis5c648WN80yz47qnmdDi8DQNOcA=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260526.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5EZAEnlLwa9oGJRo8Nd3iY5Wcd9ROGNNG90xNIGp8MEjj8v2jTn42NC47fCZKFdnLj3+S+vWEhu1x0GVJnALjA=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260415.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-bR9uITnV19r5NQ14xnypi2xHXu2iQvfYV8cVgx0JouFUmWwTEEAwFVojDdssGq93VHX9hr/pi2IRUZeegbYBog=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260526.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-X/YBQXeXFeCN7QTStoWrATEBc9WKl7PIqkw/dQkjyJ72gh3rkLe0+Xkzp3wO7gtxTDQMa7NPGy1W4+sdMf8q1g=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260415.1", "", { "os": "win32", "cpu": "x64" }, "sha512-4NuMLlerI0Ijua3Ir8HXQ+qyNvCUDEG5gDco5Om+sAiK6rnWiz+aGoSlbB8W16yW9QAgzCstbmXLiVknUBflfQ=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260526.1", "", { "os": "win32", "cpu": "x64" }, "sha512-R+tqpFFdcfZIljx8fIW9rj9fRTtDgfoA2yonsfAGa6e8snrmr+38mdFHtkRC0D3UyZpn/hOtmXiUBfdX2gMR7Q=="], "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20260405.1", "", {}, "sha512-PokTmySa+D6MY01R1UfYH48korsN462NK/fl3aw47Hg7XuLuSo/RTpjT0vtWaJhJoFY5tHGOBBIbDcIc8wltLg=="], @@ -904,6 +932,10 @@ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@emulators/core": ["@emulators/core@0.6.0", "", { "dependencies": { "jose": "^6.2.2" } }, "sha512-HFGyF4yA3NoUCYq/5lg7YNXx5Cfaz8oMUz5gfJ/8X+tFdZbi2oKAmQoAzfXV9kiAUWvXlkiahZ1EZDpxeC36gA=="], + + "@emulators/slack": ["@emulators/slack@0.6.0", "", { "dependencies": { "@emulators/core": "0.6.0" } }, "sha512-zXrrYFdwFczRO4+BdZmmuWWtwJkI62B7BEy0+E7ddpXOTditaGKzM3Aso8xm/YbRsypkdLfZ/q48RjIfSkxf5Q=="], + "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="], "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], @@ -1434,93 +1466,93 @@ "@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.19.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw=="], - "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.46.0", "", { "os": "android", "cpu": "arm" }, "sha512-b1doV4WRcJU+BESSlCvCjV+5CEr/T6h0frArAdV26Nir+gGNFNaylvDiiMPfF1pxeV0txZEs38ojzJaxBYg+ng=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.52.0", "", { "os": "android", "cpu": "arm" }, "sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ=="], - "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.46.0", "", { "os": "android", "cpu": "arm64" }, "sha512-v6+HhjsoV3GO0u2u9jLSAZrvWfTraDxKofUIQ7/ktS7tzS+epVsxdHmeM+XxuNcAY/nWxxU1Sg4JcGTNRXraBA=="], + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.52.0", "", { "os": "android", "cpu": "arm64" }, "sha512-A2G1IdwGEW2lLJkIxcvuirRH1CzSl/e0NX11zTlW1gvxJThfwbI/BEoaKrTNpm7M2FchvIf6guvIQU7d5iz+OQ=="], - "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.46.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3eeooJGrqGIlI5MyryDZsAcKXSmKIgAD4yYtfRrRJzXZ0UTFZtiSveIur56YPrGMYZwT4XyVhHsMqrNwr1XeFA=="], + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.52.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-f9+bLvOYxy7NttCLFTvQ7afmqDOWY4wIP9xdvfj5trQ1qj6f2UFAGwZESlfsMjvJNTyRpXfIlOanCI9FOvoeQA=="], - "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.46.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-QG8BDM0CXWbu84k2SKmCqfEddPQPFiBicwtYnLqHRWZZl57HbtOLRMac/KTq2NO4AEc4ICCBpFxJIV9zcqYfkQ=="], + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.52.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-YSTB9sJ5nnQd/Q0ddHkgof0ZCHPAnWZT1IW2SJ8omz7CP7KluJhO1fNHrpqdxCtpztJwSs4hY1uAee35wKxxaw=="], - "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.46.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9DdCqS/n2ncu/Chazvt3cpgAjAmIGQDz7hFKSrNItMApyV/Ja9mz3hD4JakIE3nS8PW9smEbPWnb389QLBY4nw=="], + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.52.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-NIrRNTTPCs4UbmVs0bxLSCDlLCtIRMJIXklNKaXa5Oj2/K1UIMBvgE8+uPVo01Io3N9HF0+GAX+aAHjUgZS7vA=="], - "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.46.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Dgs7VeE2jT0LHMhw6tPEt0xQYe54kBqHEovmWsv4FVQlegCOvlIJNx0S8n4vj8WUtpT+Z6BD2HhKJPLglLxvZg=="], + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.52.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JXUCde8mn3GpgQouz2PXUokgy/uT1QrRJBL2s983VWcSQp62wTFYiNXgTKdeo1Jgbr0IgUnKKvzIk/YBlj/nVQ=="], - "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.46.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Zxn3adhTH13JKnU4xXJj8FeEfF680XjXh3gSShKl57HCMBRde2tUJTgogV/1MSHA80PJEVrDa7r66TLVq3Ia7Q=="], + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.52.0", "", { "os": "linux", "cpu": "arm" }, "sha512-psbUXaRZ+V8DaXz10Qf7LSHtdtdKAmC8fxXgeU608jjzrmWK4quamZMOpl6sf+dikoFHA85uE93Q0BqxrCdQrQ=="], - "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.46.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-+TWipjrgVM8D7aIdDD0tlr3teLTTvQTn7QTE5BpT10H1Fj82gfdn9X6nn2sDgx/MepuSCfSnzFNJq2paLL0OiA=="], + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.52.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Jw7MgWUU9lcLCcy82updISP3EthTlfvAwR6gWNxPzqly7+fLvOi2gHQE9xXQjpqaVLm/8P+gOzlv9ODuoVlaaw=="], - "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.46.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-aAUPBWJ1lGwwnxZUEDLJ94+Iy6MuwJwPxUgO4sCA5mEEyDk7b+cDQ+JpX1VR150Zoyd+D49gsrUzpUK5h587Eg=="], + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.52.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-wZg6bLjDvh2KibyI3QFUYo8GTXneIFsd0JvehtvJiUmQ8WRPERgxd/VM4ctWb86U5FT1FkqgS8/wZKVB+AZScg=="], - "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.46.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ufBCJukyFX/UDrokP/r6BGDoTInnsDs7bxyzKAgMiZlt2Qu8GPJSJ6Zm6whIiJzKk0naxA8ilwmbO1LMw6Htxw=="], + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.52.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-IngE8uxhNvxcMrLjZNDo9xNLY7rEK33AKnaMd2B46he1e/mz2CfcW6If/U1wUjdRZddm1QzQaciqZkuMkdh1FA=="], - "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.46.0", "", { "os": "linux", "cpu": "none" }, "sha512-eqtlC2YmPqjun76R1gVfGLuKWx7NuEnLEAudZ7n6ipSKbCZTqIKSs1b5Y8K/JHZsRpLkeSmAAjig5HOIg8fQzQ=="], + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.52.0", "", { "os": "linux", "cpu": "none" }, "sha512-H3+DdFMv/efN3Efmhsv18jDrpiWWqKG7wsfAlQBqAt6z/E2Bx+TwEj2Nowe51CPOWB8/mFBC2dAMSgVFLvvowA=="], - "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.46.0", "", { "os": "linux", "cpu": "none" }, "sha512-yccVOO2nMXkQLGgy0He3EQEwKD7NF0zEk+/OWmroznkqXyJdN6bfK0LtNnr6/14Bh3FjpYq7bP33l/VloCnxpA=="], + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.52.0", "", { "os": "linux", "cpu": "none" }, "sha512-zji+1kb7lJKohSDjzC1IsS+K/cKRs1hdVf0ZH0VbdbiakmtLvN9twBoXo/k8VdjFax7kfo+DyPxS7vv52br1aw=="], - "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.46.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-aAf7fG23OQCey6VRPj9IeCraoYtpgtx0ZyJ1CXkPyT1wjzBE7c3xtuxHe/AdHaJfVVb/SXpSk8Gl1LzyQupSqw=="], + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.52.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hcLBYedpCy7ToUvvBidWk7+11Yhg1oAZ4+6hKPic/mQI6NaqXJSXMps5nFlwUuX2ewhtLZZDPg63TI042qGKBg=="], - "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.46.0", "", { "os": "linux", "cpu": "x64" }, "sha512-q0JPsTMyJNjYrBvYFDz4WbVsafNZaPCZv4RnFypRotLqpKROtBZcEaXQW4eb9YmvLU3NckVemLJnzkSZSdmOxw=="], + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.52.0", "", { "os": "linux", "cpu": "x64" }, "sha512-IDO2loXK2OtTOhSPchU9MW25mWL2QCDGdJbjN8MXKZVS80qXe5gMTwQWu/gMJ3juoBHbkuUZNB2N1LHzNT7DoA=="], - "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.46.0", "", { "os": "linux", "cpu": "x64" }, "sha512-7LsLY9Cw57GPkhSR+duI3mt9baRczK/DtHYSldQ4BEU92da9igBQNl4z7Vq5U9NNPsh1FmpKvv1q9WDtiUQR1A=="], + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.52.0", "", { "os": "linux", "cpu": "x64" }, "sha512-mAV2Hjn0SatJ+KoAzKUC3eJhdJ8wv+3m1KyuS0dTsbF0c5weq+QrCt/DRZZM+uj/XiKzCDEUKYsBF30e2qkcyw=="], - "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.46.0", "", { "os": "none", "cpu": "arm64" }, "sha512-lHiBOz8Duaku7JtRNLlps3j++eOaICPZSd8FCVmTDM4DFOPT71Bjn7g6iar1z7StXlKRweUKxWUs4sA+zWGDXg=="], + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.52.0", "", { "os": "none", "cpu": "arm64" }, "sha512-vd4npaUIwChxp7XzkqmepBWTT9YMcSe/NBApVGPC30/lLyOVaV3dvma1SKo03t8O73BPRAG7EyJzGlN5cJM5hQ=="], - "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.46.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/5ktYUliP89RhgC37DBH1x20U5zPSZMy3cMEcO0j3793rbHP9MWsknBwQB6eozRzWmYrh0IFM/p20EbPvDlYlg=="], + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.52.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-k2sz6gWQdMfh5HPpIS+Bw/0UEV/kaK2xuqJRrWL233sEHx9WLlsmvlPFM4HUNThkYbSN0U0vPW7LVKZWDS8hPQ=="], - "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.46.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3WTnoiuIr8XvV0DIY7SN+1uJSwKf4sPpcbHfobcRT9JutGcLaef/miyBB87jxd3aqH+mS0+G5lsgHuXLUwjjpQ=="], + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.52.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-rhke69GTcArodLHpjMTfNnvjTEBryDeZcUCKK/VjXDMtfTULl6QRh0ymX5/hbCUv2WjYm9h/QbW++q2vE15gWQ=="], - "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.46.0", "", { "os": "win32", "cpu": "x64" }, "sha512-IXxiQpkYnOwNfP23vzwSfhdpxJzyiPTY7eTn6dn3DsriKddESzM8i6kfq9R7CD/PUJwCvQT22NgtygBeug3KoA=="], + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.52.0", "", { "os": "win32", "cpu": "x64" }, "sha512-q5xL7oeXkZdEtNZWBdvehJcmt+GRu9l2bK40yJs1jJXlqq+r0Hygb1rTjq+FM2o/2xyt4cufH6KRplHp3Jjsvw=="], - "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.22.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/exgXceakHbQrzaHTtKOe7MuDATaWMCCWpsCDQCZKeYhLGXzComipTrCYnHzAXrdnNBb5r5K+RRf5A6ormrhMA=="], + "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.23.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw=="], - "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.22.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xFGdIahlmUbK+/MpZ5y08D0ewMGLDbd2Vki5wxVFYg50lSrtgPAtdDl+kqKZLNaFu0zpMar8n9wv1le05sL/jw=="], + "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.23.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA=="], - "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.22.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-53RvC9f77eUo+V1dfQNwGVnsIfPJFMibRR0ee128EUpYNDOZe/ojmCfuXJeU7cY91V7r7fZSm42KPJocXUX8og=="], + "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.23.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw=="], - "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.22.0", "", { "os": "linux", "cpu": "x64" }, "sha512-evZcJAZ9hjNyuN69RnXwbt+U2pAOcYt+yvqukgugiCkRm4iBZ0R0CvpY1tgfG2XcGUhEPh8dljO+nPZTEVGpCQ=="], + "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.23.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA=="], - "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.22.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-7jTO+k1mr5BxRAI2fxc1NRcE3MAbHNZ0Vef9SD1yAR6d1E6qEv5D/D7yuHpQpw6AO3qoecSVo2Jzr+JirN61+w=="], + "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.23.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw=="], - "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.22.0", "", { "os": "win32", "cpu": "x64" }, "sha512-7lbl9XFcqO+scsynxMzTQdl0XUe6sBUCyY/oGWvCB+JmV4U+70vzSyZJdTEzzxtkZiNnUVFFh9RJLmoiQSne+w=="], + "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.23.0", "", { "os": "win32", "cpu": "x64" }, "sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ=="], - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.61.0", "", { "os": "android", "cpu": "arm" }, "sha512-6eZBPgiigK5txqoVgRqxbaxiom4lM8AP8CyKPPvpzKnQ3iFRFOIDc+0AapF+qsUSwjOzr5SGk4SxQDpQhkSJMQ=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.67.0", "", { "os": "android", "cpu": "arm" }, "sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw=="], - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.61.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CkwLR69MUnyv5wjzebvbbtTSUwqLxM35CXE79bHqDIK+NtKmPEUpStTcLQRZMCo4MP0qRT6TXIQVpK0ZVScnMA=="], + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.67.0", "", { "os": "android", "cpu": "arm64" }, "sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ=="], - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.61.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8JbefTkbmvqkqWjmQrHke+MdpgT2UghhD/ktM4FOQSpGeCgbMToJEKdl9zwhr/YWTl92i4QI1KiTwVExpcUN8A=="], + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.67.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg=="], - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.61.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-uWpoxDT47hTnDLcdEh5jVbso8rlTTu5o0zuqa9J8E0JAKmIWn7kGFEIB03Pycn2hd2vKxybPGLhjURy/9We5FQ=="], + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.67.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg=="], - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.61.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-K/o4hEyW7flfMel0iBVznmMBt7VIMHGdjADocHKpK1DUF9erpWnJ+BSSWd2W0c8K3mPtpph+CuHzRU6CI3l9jQ=="], + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.67.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg=="], - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-P6040ZkcyweJ0Po9yEFqJCdvZnf3VNCGs1SIHgXDf8AAQNC6ID/heXQs9iSgo2FH7gKaKq32VWc59XZwL34C5Q=="], + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.67.0", "", { "os": "linux", "cpu": "arm" }, "sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g=="], - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-bwxrGCzTZkuB+THv2TQ1aTkVEfv5oz8sl+0XZZCpoYzErJD8OhPQOTA0ENPd1zJz8QsVdSzSrS2umKtPq4/JXg=="], + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.67.0", "", { "os": "linux", "cpu": "arm" }, "sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw=="], - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vkhb9/wKguMkLlrm3FoJW/Xmdv31GgYAE+x8lxxQ+7HeOxXUySI0q36a3NTVIuQUdLzxCI1zzMGsk1o37FOe3w=="], + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.67.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg=="], - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-bl1dQh8LnVqsj6oOQAcxwbuOmNJkwc4p6o//HTBZhNTzJy21TLDwAviMqUFNUxDHkPGpmdKTSN4tWTjLryP8xg=="], + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.67.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w=="], - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.61.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-QoOX6KB2IiEpyOj/HKqaxi+NQHPnOgNgnr22n9N4ANJCzXkUlj1UmeAbFb4PpqdlHIzvGDM5xZ0OKtcLq9RhiQ=="], + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.67.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug=="], - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-1TGcTerjY6p152wCof3oKElccq3xHljS/Mucp04gV/4ATpP6nO7YNnp7opEg6SHkv2a57/b4b8Ndm9znJ1/qAw=="], + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.67.0", "", { "os": "linux", "cpu": "none" }, "sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ=="], - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-65wXEmZIrX2ADwC8i/qFL4EWLSbeuBpAm3suuX1vu4IQkKd+wLT/HU/BOl84kp91u2SxPkPDyQgu4yrqp8vwVA=="], + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.67.0", "", { "os": "linux", "cpu": "none" }, "sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA=="], - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.61.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-TVvhgMvor7Qa6COeXxCJ7ENOM+lcAOGsQ0iUdPSCv2hxb9qSHLQ4XF1h50S6RE1gBOJ0WV3rNukg4JJJP1LWRA=="], + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.67.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q=="], - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SjpS5uYuFoDnDdZPwZE59ndF95AsY47R5MliuneTWR1pDm2CxGJaYXbKULI71t5TVfLQUWmrHEGRL9xvuq6dnA=="], + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.67.0", "", { "os": "linux", "cpu": "x64" }, "sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA=="], - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-gGfAeGD4sNJGILZbc/yKcIimO9wQnPMoYp9swAaKeEtwsSQAbU+rsdQze5SBtIP6j0QDzeYd4XSSUCRCF+LIeQ=="], + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.67.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg=="], - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.61.0", "", { "os": "none", "cpu": "arm64" }, "sha512-OlVT0LrG/ct33EVtWRyR+B/othwmDWeRxfi13wUdPeb3lAT5TgTcFDcfLfarZtzB4W1nWF/zICMgYdkggX2WmQ=="], + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.67.0", "", { "os": "none", "cpu": "arm64" }, "sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g=="], - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.61.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vI//NZPJk6DToiovPtaiwD4iQ7kO1r5ReWQD0sOOyKRtP3E2f6jxin4uvwi3OvDzHA2EFfd7DcZl5dtkQh7g1w=="], + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.67.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA=="], - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.61.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-0ySj4/4zd2XjePs3XAQq7IigIstN4LPQZgCyigX5/ERMLjdWAJfnxcTsrtxZxuij8guJW8foXuHmhGxW0H4dDA=="], + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.67.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg=="], - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.61.0", "", { "os": "win32", "cpu": "x64" }, "sha512-0xgSiyeqDLDZxXoe9CVJrOx3TUVsfyoOY7cNi03JbItNcC9WCZqrSNdrAbHONxhSPaVh/lzfnDcON1RqSUMhHw=="], + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.67.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ=="], "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.5.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ=="], @@ -2374,7 +2406,7 @@ "better-call": ["better-call@1.3.2", "", { "dependencies": { "@better-auth/utils": "^0.3.1", "@better-fetch/fetch": "^1.1.21", "rou3": "^0.7.12", "set-cookie-parser": "^3.0.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw=="], - "better-result": ["better-result@2.9.0", "", {}, "sha512-NHwGDGVbRlWDOce3CwcfGIrcNR9zY37ut3SVwQVfv57DZdVhxjhA4mfaHN1n8QwWnRAR4iErpW1X/eaiaUaFYg=="], + "better-result": ["better-result@2.9.2", "", {}, "sha512-WIFoBPCdnTOdk9inkE1ZRvCZ4P0CpSkAiLlchC65N7n9DcjZ3NhqkBOlafzpOVnO8ixyi37kicmSJ3ENhPZl7Q=="], "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], @@ -2664,6 +2696,8 @@ "emojis-list": ["emojis-list@3.0.0", "", {}, "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="], + "emulate": ["emulate@0.6.0", "", { "dependencies": { "commander": "^14", "picocolors": "^1.1.1", "yaml": "^2" }, "bin": { "emulate": "dist/index.js" } }, "sha512-UcuKgskLUCD4TnqMw/EHJRUw8y3E11ks4lzx5MkAq0jJbfl3031aFgJeR3AArl4xB0aABC9Q9RZw00srZbcHgw=="], + "enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="], "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], @@ -3174,27 +3208,27 @@ "kysely": ["kysely@0.28.16", "", {}, "sha512-3i5pmOiZvMDj00qhrIVbH0AnioVTx22DMP7Vn5At4yJO46iy+FM8Y/g61ltenLVSo3fiO8h8Q3QOFgf/gQ72ww=="], - "lefthook": ["lefthook@2.1.6", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.6", "lefthook-darwin-x64": "2.1.6", "lefthook-freebsd-arm64": "2.1.6", "lefthook-freebsd-x64": "2.1.6", "lefthook-linux-arm64": "2.1.6", "lefthook-linux-x64": "2.1.6", "lefthook-openbsd-arm64": "2.1.6", "lefthook-openbsd-x64": "2.1.6", "lefthook-windows-arm64": "2.1.6", "lefthook-windows-x64": "2.1.6" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-w9sBoR0mdN+kJc3SB85VzpiAAl451/rxdCRcZlwW71QLjkeH3EBQFgc4VMj5apePychYDHAlqEWTB8J8JK/j1Q=="], + "lefthook": ["lefthook@2.1.9", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.9", "lefthook-darwin-x64": "2.1.9", "lefthook-freebsd-arm64": "2.1.9", "lefthook-freebsd-x64": "2.1.9", "lefthook-linux-arm64": "2.1.9", "lefthook-linux-x64": "2.1.9", "lefthook-openbsd-arm64": "2.1.9", "lefthook-openbsd-x64": "2.1.9", "lefthook-windows-arm64": "2.1.9", "lefthook-windows-x64": "2.1.9" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-bwDaIOViTktE8kJLf9jP0p+H2/RDTlFFlc43Am2YgUsX22hI6Sq4RbzsrecwzY5y+MHTipOH7WsmWSEniePHWQ=="], - "lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hyB7eeiX78BS66f70byTJacDLC/xV1vgMv9n+idFUsrM7J3Udd/ag9Ag5NP3t0eN0EqQqAtrNnt35EH01lxnRQ=="], + "lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-119HryNcvr4nqn0wUIrNPgpMEPn9yMQzEcW/lezRsnb56PCJriJB92+MCySPVcWDxJnZef7o0T3jdnPNiSH7Qg=="], - "lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-5Ka6cFxiH83krt+OMRQtmS6zqoZR5SLXSudLjTbZA1c3ZqF0+dqkeb4XcB6plx6WR0GFizabuc6Bi3iXPIe1eQ=="], + "lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-dwo5Tke2XcQCM56DGHgFKBfRbJIL6xs2wZ0zG1TUVZgl4t4mQUt6LiZ4V/ZQfYHTZF9qywvXoIlR5N35qOaiVQ=="], - "lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.6", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-VswyOg5CVN3rMaOJ2HtnkltiMKgFHW/wouWxXsV8RxSa4tgWOKxM0EmSXi8qc2jX+LRga6B0uOY6toXS01zWxA=="], + "lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.9", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-+09PVap6nl6xsaHch5JLtq7WvIR++U1Q2MzA2ai0M4uB/VP3AqrvKqHw6+9hjyKnIH+HHL83uqi77EAY+LaxLA=="], - "lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.6", "", { "os": "freebsd", "cpu": "x64" }, "sha512-vXsCUFYuVwrVWwcypB7Zt2Hf+5pl1V1la7ZfvGYZaTRURu0zF/XUnMF/nOz/PebGv0f4x/iOWXWwP7E42xRWsg=="], + "lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-8XresjKIYpkE9ARgCtBEZgJZxAU3T4MIqzj4zNy15XRT59I1Us+QdqXTNm+pkZ41Yd2X/nxs2Pkvbq3NWWlIGw=="], - "lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-WDJiQhJdZOvKORZd+kF/ms2l6NSsXzdA9ahflyr65V90AC4jES223W8VtEMbGPUtHuGWMEZ/v/XvwlWv0Ioz9g=="], + "lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-1oNIQfwrPe6rgU2KcDM3aF6+hpZDCKx1TmawQKpXUY5gVsbZ7MqX0Sk/1lnnWxqPm+kQQ5f6J2dpFWd+4xH8jg=="], - "lefthook-linux-x64": ["lefthook-linux-x64@2.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-C18nCd7nTX1AVL4TcvwMmLAO1VI1OuGluIOTjiPkBQ746Ls1HhL5rl//jMPACmT28YmxIQJ2ZcLPNmhvEVBZvw=="], + "lefthook-linux-x64": ["lefthook-linux-x64@2.1.9", "", { "os": "linux", "cpu": "x64" }, "sha512-fT+7Q+BJyGp+CslFQkNXmdFRgyVXsPHPi9NAsDX0a6QOyNnoORByAsvx6zeAKuF5rL3BBgNfho1/v2RuGxGy9w=="], - "lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.6", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-mZOMxM8HiPxVFXDO3PtCUbH4GB8rkveXhsgXF27oAZTYVzQ3gO9vT6r/pxit6msqRXz3fvcwimLVJgb8eRsa8A=="], + "lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.9", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-4bVuafBk3dddVNo0+3hMbjcJs4mqYAstxpPMmX2ufkudSTYFNIhWoqwuGVQV/SS/xdcOKJAldW4qayAzed2ysw=="], - "lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.6", "", { "os": "openbsd", "cpu": "x64" }, "sha512-sG9ALLZSnnMOfXu+B7SmxFhJhuoAh4bqi5En5aaHJET48TqrLOcWWZuH+7ArFM6gr/U5KfSUvdmHFmY8WqCcIg=="], + "lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.9", "", { "os": "openbsd", "cpu": "x64" }, "sha512-PmPoMmLP/wQQWcQ9u2YH86bTZ3UCfBsxuEmVTEyPU2U8R1qSTp5r/Gs3G8cN5Mxo91XB9oBERtF1n+xD3W6aVA=="], - "lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-lD8yFWY4Csuljd0Rqs7EQaySC0VvDf7V3rN1FhRMUISTRDHutebIom1Loc8ckQPvKYGC6mftT9k0GvipsS+Brw=="], + "lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-KphfkBKmwBnmolyrdhIl3lrBaOyTcCgXBT2AB/9OHnEXhOLvv5uTCUkrD4YRAxXPtFKq6UvnapIeoL3GZq0bdA=="], - "lefthook-windows-x64": ["lefthook-windows-x64@2.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-q4z2n3xucLscoWiyMwFViEj3N8MDSkPulMwcJYuCYFHoPhP1h+icqNu7QRLGYj6AnVrCQweiUJY3Tb2X+GbD/A=="], + "lefthook-windows-x64": ["lefthook-windows-x64@2.1.9", "", { "os": "win32", "cpu": "x64" }, "sha512-2qlUtkJHZ3MyUxgV5XTEmcrIoNZA07iwaquoswAcqv/1MeBFXlD+O+koFRfrzWng2O5WYEbpJnd8tvaYnV8fTA=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], @@ -3440,7 +3474,7 @@ "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], - "miniflare": ["miniflare@4.20260415.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260415.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-JoExRWN4YBI2luA5BoSMFEgi8rQWXUGzo3mtE+58VXCLV3jj/Xnk5Yeqs/IXWz8Es5GJIaq6BtsixDvAxXSIng=="], + "miniflare": ["miniflare@4.20260526.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260526.1", "ws": "8.20.1", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA=="], "minimalistic-assert": ["minimalistic-assert@1.0.1", "", {}, "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="], @@ -3588,11 +3622,11 @@ "oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="], - "oxfmt": ["oxfmt@0.46.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.46.0", "@oxfmt/binding-android-arm64": "0.46.0", "@oxfmt/binding-darwin-arm64": "0.46.0", "@oxfmt/binding-darwin-x64": "0.46.0", "@oxfmt/binding-freebsd-x64": "0.46.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.46.0", "@oxfmt/binding-linux-arm-musleabihf": "0.46.0", "@oxfmt/binding-linux-arm64-gnu": "0.46.0", "@oxfmt/binding-linux-arm64-musl": "0.46.0", "@oxfmt/binding-linux-ppc64-gnu": "0.46.0", "@oxfmt/binding-linux-riscv64-gnu": "0.46.0", "@oxfmt/binding-linux-riscv64-musl": "0.46.0", "@oxfmt/binding-linux-s390x-gnu": "0.46.0", "@oxfmt/binding-linux-x64-gnu": "0.46.0", "@oxfmt/binding-linux-x64-musl": "0.46.0", "@oxfmt/binding-openharmony-arm64": "0.46.0", "@oxfmt/binding-win32-arm64-msvc": "0.46.0", "@oxfmt/binding-win32-ia32-msvc": "0.46.0", "@oxfmt/binding-win32-x64-msvc": "0.46.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-CopwJOwPAjZ9p76fCvz+mSOJTw9/NY3cSksZK3VO/bUQ8UoEcketNgUuYS0UB3p+R9XnXe7wGGXUmyFxc7QxJA=="], + "oxfmt": ["oxfmt@0.52.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.52.0", "@oxfmt/binding-android-arm64": "0.52.0", "@oxfmt/binding-darwin-arm64": "0.52.0", "@oxfmt/binding-darwin-x64": "0.52.0", "@oxfmt/binding-freebsd-x64": "0.52.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.52.0", "@oxfmt/binding-linux-arm-musleabihf": "0.52.0", "@oxfmt/binding-linux-arm64-gnu": "0.52.0", "@oxfmt/binding-linux-arm64-musl": "0.52.0", "@oxfmt/binding-linux-ppc64-gnu": "0.52.0", "@oxfmt/binding-linux-riscv64-gnu": "0.52.0", "@oxfmt/binding-linux-riscv64-musl": "0.52.0", "@oxfmt/binding-linux-s390x-gnu": "0.52.0", "@oxfmt/binding-linux-x64-gnu": "0.52.0", "@oxfmt/binding-linux-x64-musl": "0.52.0", "@oxfmt/binding-openharmony-arm64": "0.52.0", "@oxfmt/binding-win32-arm64-msvc": "0.52.0", "@oxfmt/binding-win32-ia32-msvc": "0.52.0", "@oxfmt/binding-win32-x64-msvc": "0.52.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-nJlYM35F64zTDMecCNhoHNkf+D/eHv7xcjj9XDSj+bFAVtN93m7v8DQMdHd6nDG6Akf/kEYYHmDUBs2Dz27Sug=="], - "oxlint": ["oxlint@1.61.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.61.0", "@oxlint/binding-android-arm64": "1.61.0", "@oxlint/binding-darwin-arm64": "1.61.0", "@oxlint/binding-darwin-x64": "1.61.0", "@oxlint/binding-freebsd-x64": "1.61.0", "@oxlint/binding-linux-arm-gnueabihf": "1.61.0", "@oxlint/binding-linux-arm-musleabihf": "1.61.0", "@oxlint/binding-linux-arm64-gnu": "1.61.0", "@oxlint/binding-linux-arm64-musl": "1.61.0", "@oxlint/binding-linux-ppc64-gnu": "1.61.0", "@oxlint/binding-linux-riscv64-gnu": "1.61.0", "@oxlint/binding-linux-riscv64-musl": "1.61.0", "@oxlint/binding-linux-s390x-gnu": "1.61.0", "@oxlint/binding-linux-x64-gnu": "1.61.0", "@oxlint/binding-linux-x64-musl": "1.61.0", "@oxlint/binding-openharmony-arm64": "1.61.0", "@oxlint/binding-win32-arm64-msvc": "1.61.0", "@oxlint/binding-win32-ia32-msvc": "1.61.0", "@oxlint/binding-win32-x64-msvc": "1.61.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-ZC0ALuhDZ6ivOFG+sy0D0pEDN49EvsId98zVlmYdkcXHsEM14m/qTNUEsUpiFiCVbpIxYtVBmmLE87nsbUHohQ=="], + "oxlint": ["oxlint@1.67.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.67.0", "@oxlint/binding-android-arm64": "1.67.0", "@oxlint/binding-darwin-arm64": "1.67.0", "@oxlint/binding-darwin-x64": "1.67.0", "@oxlint/binding-freebsd-x64": "1.67.0", "@oxlint/binding-linux-arm-gnueabihf": "1.67.0", "@oxlint/binding-linux-arm-musleabihf": "1.67.0", "@oxlint/binding-linux-arm64-gnu": "1.67.0", "@oxlint/binding-linux-arm64-musl": "1.67.0", "@oxlint/binding-linux-ppc64-gnu": "1.67.0", "@oxlint/binding-linux-riscv64-gnu": "1.67.0", "@oxlint/binding-linux-riscv64-musl": "1.67.0", "@oxlint/binding-linux-s390x-gnu": "1.67.0", "@oxlint/binding-linux-x64-gnu": "1.67.0", "@oxlint/binding-linux-x64-musl": "1.67.0", "@oxlint/binding-openharmony-arm64": "1.67.0", "@oxlint/binding-win32-arm64-msvc": "1.67.0", "@oxlint/binding-win32-ia32-msvc": "1.67.0", "@oxlint/binding-win32-x64-msvc": "1.67.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ=="], - "oxlint-tsgolint": ["oxlint-tsgolint@0.22.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.22.0", "@oxlint-tsgolint/darwin-x64": "0.22.0", "@oxlint-tsgolint/linux-arm64": "0.22.0", "@oxlint-tsgolint/linux-x64": "0.22.0", "@oxlint-tsgolint/win32-arm64": "0.22.0", "@oxlint-tsgolint/win32-x64": "0.22.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-ku4MecLmCQIj1ScCtzNAqTuyl0BJQ02B36fJT+c5XQihHpYSFak+FC3GYO5fPyYk4oDwi0w0S7hTvrpNzuZhig=="], + "oxlint-tsgolint": ["oxlint-tsgolint@0.23.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.23.0", "@oxlint-tsgolint/darwin-x64": "0.23.0", "@oxlint-tsgolint/linux-arm64": "0.23.0", "@oxlint-tsgolint/linux-x64": "0.23.0", "@oxlint-tsgolint/win32-arm64": "0.23.0", "@oxlint-tsgolint/win32-x64": "0.23.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA=="], "p-finally": ["p-finally@1.0.0", "", {}, "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="], @@ -3886,6 +3920,14 @@ "rollup-plugin-visualizer": ["rollup-plugin-visualizer@7.0.1", "", { "dependencies": { "open": "^11.0.0", "picomatch": "^4.0.2", "source-map": "^0.7.4", "yargs": "^18.0.0" }, "peerDependencies": { "rolldown": "1.x || ^1.0.0-beta || ^1.0.0-rc", "rollup": "2.x || 3.x || 4.x" }, "optionalPeers": ["rolldown", "rollup"], "bin": { "rollup-plugin-visualizer": "dist/bin/cli.js" } }, "sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg=="], + "rosie-skills": ["rosie-skills@0.6.4", "", { "optionalDependencies": { "rosie-skills-darwin-arm64": "0.6.4", "rosie-skills-freebsd-x64": "0.6.4", "rosie-skills-linux-x64": "0.6.4" }, "bin": { "rosie-skills": "dist/bin.js" } }, "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA=="], + + "rosie-skills-darwin-arm64": ["rosie-skills-darwin-arm64@0.6.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg=="], + + "rosie-skills-freebsd-x64": ["rosie-skills-freebsd-x64@0.6.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng=="], + + "rosie-skills-linux-x64": ["rosie-skills-linux-x64@0.6.4", "", { "os": "linux", "cpu": "x64" }, "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng=="], + "rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], @@ -4334,9 +4376,9 @@ "wordwrapjs": ["wordwrapjs@5.1.1", "", {}, "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg=="], - "workerd": ["workerd@1.20260415.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260415.1", "@cloudflare/workerd-darwin-arm64": "1.20260415.1", "@cloudflare/workerd-linux-64": "1.20260415.1", "@cloudflare/workerd-linux-arm64": "1.20260415.1", "@cloudflare/workerd-windows-64": "1.20260415.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-phyPjRnx+mQDfkhN9ENPioL1L0SdhYs4S0YmJK/xF9Oga+ykNfdSy1MHnsOj8yqnOV96zcVQMx32dJ0r3pq0jQ=="], + "workerd": ["workerd@1.20260526.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260526.1", "@cloudflare/workerd-darwin-arm64": "1.20260526.1", "@cloudflare/workerd-linux-64": "1.20260526.1", "@cloudflare/workerd-linux-arm64": "1.20260526.1", "@cloudflare/workerd-windows-64": "1.20260526.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-IHzymht98p10JH1zzwdCpbViAqw97HrwKl7+KfZeASFMsYSrIsAULWdPn0LRC5FTUzBpamLNyKCCKxbgXHgRHQ=="], - "wrangler": ["wrangler@4.83.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260415.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260415.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260415.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-gw5g3LCiuAqVWxaoKY6+quE0HzAUEFb/FV3oAlNkE1ttd4XP3FiV91XDkkzUCcdqxS4WjhQvPhIDBNdhEi8P0A=="], + "wrangler": ["wrangler@4.95.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260526.0", "path-to-regexp": "6.3.0", "rosie-skills": "^0.6.3", "unenv": "2.0.0-rc.24", "workerd": "1.20260526.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260526.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-vgXzFVSCdUbeCadgVXvu8fK5tzNm8T9W+7lriyGWZMx0B1+CAdr4d8JTlZszHfgjypRAHmAxb49etZGIRD9pgg=="], "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -4398,6 +4440,8 @@ "@astrojs/cloudflare/vite": ["vite@7.3.3", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA=="], + "@astrojs/compiler-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@astrojs/language-server/@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], "@astrojs/react/@vitejs/plugin-react": ["@vitejs/plugin-react@5.2.0", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw=="], @@ -4778,6 +4822,12 @@ "@buape/carbon/discord-api-types": ["discord-api-types@0.38.45", "", {}, "sha512-DiI01i00FPv6n+hXcFkFxK8Y/rFRpKs6U6aP32N4T73nTbj37Eua3H/95TBpLktLWB6xnLXhYDGvyLq6zzYY2w=="], + "@cloudflare/vite-plugin/@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg=="], + + "@cloudflare/vite-plugin/miniflare": ["miniflare@4.20260415.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.8", "workerd": "1.20260415.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-JoExRWN4YBI2luA5BoSMFEgi8rQWXUGzo3mtE+58VXCLV3jj/Xnk5Yeqs/IXWz8Es5GJIaq6BtsixDvAxXSIng=="], + + "@cloudflare/vite-plugin/wrangler": ["wrangler@4.83.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.16.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260415.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260415.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260415.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-gw5g3LCiuAqVWxaoKY6+quE0HzAUEFb/FV3oAlNkE1ttd4XP3FiV91XDkkzUCcdqxS4WjhQvPhIDBNdhEi8P0A=="], + "@cloudflare/vite-plugin/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], @@ -4798,6 +4848,8 @@ "@ecies/ciphers/@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="], + "@emulators/core/jose": ["jose@6.2.3", "", {}, "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw=="], + "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], "@expressive-code/core/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], @@ -4870,10 +4922,6 @@ "@noble/curves/@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], - "@onequery/landing/react": ["react@19.3.0-canary-d5736f09-20260507", "", {}, "sha512-EL3w0mHylqEtiySCjcj/nPOkK1j6KvKsaFkeavTqR6hbd6bQi7gyCcTSHXQ2XpTjv8hfKWFArSVF6he1sgQcEQ=="], - - "@onequery/landing/react-dom": ["react-dom@19.3.0-canary-d5736f09-20260507", "", { "dependencies": { "scheduler": "0.28.0-canary-d5736f09-20260507" }, "peerDependencies": { "react": "19.3.0-canary-d5736f09-20260507" } }, "sha512-PrjUaYOYc1dX65Td8StJSNJ3TFTeO2KBpAdXQJiOmW5kxDbKK+lvkJmSK/U+f7LcNnJxQKwHzKVf8WdJVjJohg=="], - "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], "@qwik.dev/partytown/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], @@ -5148,7 +5196,7 @@ "miniflare/undici": ["undici@7.24.8", "", {}, "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ=="], - "miniflare/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + "miniflare/ws": ["ws@8.20.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w=="], "node-edge-tts/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], @@ -5396,6 +5444,16 @@ "@buape/carbon/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@cloudflare/vite-plugin/miniflare/undici": ["undici@7.24.8", "", {}, "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ=="], + + "@cloudflare/vite-plugin/miniflare/workerd": ["workerd@1.20260415.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260415.1", "@cloudflare/workerd-darwin-arm64": "1.20260415.1", "@cloudflare/workerd-linux-64": "1.20260415.1", "@cloudflare/workerd-linux-arm64": "1.20260415.1", "@cloudflare/workerd-windows-64": "1.20260415.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-phyPjRnx+mQDfkhN9ENPioL1L0SdhYs4S0YmJK/xF9Oga+ykNfdSy1MHnsOj8yqnOV96zcVQMx32dJ0r3pq0jQ=="], + + "@cloudflare/vite-plugin/wrangler/@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], + + "@cloudflare/vite-plugin/wrangler/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + + "@cloudflare/vite-plugin/wrangler/workerd": ["workerd@1.20260415.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260415.1", "@cloudflare/workerd-darwin-arm64": "1.20260415.1", "@cloudflare/workerd-linux-64": "1.20260415.1", "@cloudflare/workerd-linux-arm64": "1.20260415.1", "@cloudflare/workerd-windows-64": "1.20260415.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-phyPjRnx+mQDfkhN9ENPioL1L0SdhYs4S0YmJK/xF9Oga+ykNfdSy1MHnsOj8yqnOV96zcVQMx32dJ0r3pq0jQ=="], + "@discordjs/node-pre-gyp/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "@discordjs/node-pre-gyp/make-dir/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -5486,8 +5544,6 @@ "@matrix-org/matrix-sdk-crypto-nodejs/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "@onequery/landing/react-dom/scheduler": ["scheduler@0.28.0-canary-d5736f09-20260507", "", {}, "sha512-HkpDsMMSty/+FrYjvNnBZRwfU5P+LhZs8xRaWKVwTnB0rffXMg+BOntOebDmvlwI8hhB6D8ONBGXeOlWTzwVdA=="], - "@remotion/bundler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ=="], "@remotion/bundler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.0", "", { "os": "android", "cpu": "arm" }, "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g=="], @@ -5936,6 +5992,78 @@ "@aws-sdk/middleware-sdk-s3/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.7.3", "", { "dependencies": { "@nodable/entities": "^2.1.0", "fast-xml-builder": "^1.1.7", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg=="], + "@cloudflare/vite-plugin/miniflare/workerd/@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260415.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-dsxaKsQm3LnPGNPEdsRv09QN3Y4DqCw7kX5j6noKqbAtro2jTr95sVlYM1jUxZ5FkOl1f7SXgaKKB9t5H5Nkbg=="], + + "@cloudflare/vite-plugin/miniflare/workerd/@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260415.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+JgSgVA49KyKteHRA1SnonE4Zn5Ei5zdAp5FQMxFmXI8qulZw4Hl7safXxRyK4i9sTO8gl7TFOKO5Q64VPvSDQ=="], + + "@cloudflare/vite-plugin/miniflare/workerd/@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260415.1", "", { "os": "linux", "cpu": "x64" }, "sha512-tU+9pwsqCy8afOVlGtiWrWQc/fedQK4SRm4KPIAt+zOiQWDxWASm6YGBUJis5c648WN80yz47qnmdDi8DQNOcA=="], + + "@cloudflare/vite-plugin/miniflare/workerd/@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260415.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-bR9uITnV19r5NQ14xnypi2xHXu2iQvfYV8cVgx0JouFUmWwTEEAwFVojDdssGq93VHX9hr/pi2IRUZeegbYBog=="], + + "@cloudflare/vite-plugin/miniflare/workerd/@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260415.1", "", { "os": "win32", "cpu": "x64" }, "sha512-4NuMLlerI0Ijua3Ir8HXQ+qyNvCUDEG5gDco5Om+sAiK6rnWiz+aGoSlbB8W16yW9QAgzCstbmXLiVknUBflfQ=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "@cloudflare/vite-plugin/wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "@cloudflare/vite-plugin/wrangler/workerd/@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260415.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-dsxaKsQm3LnPGNPEdsRv09QN3Y4DqCw7kX5j6noKqbAtro2jTr95sVlYM1jUxZ5FkOl1f7SXgaKKB9t5H5Nkbg=="], + + "@cloudflare/vite-plugin/wrangler/workerd/@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260415.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+JgSgVA49KyKteHRA1SnonE4Zn5Ei5zdAp5FQMxFmXI8qulZw4Hl7safXxRyK4i9sTO8gl7TFOKO5Q64VPvSDQ=="], + + "@cloudflare/vite-plugin/wrangler/workerd/@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260415.1", "", { "os": "linux", "cpu": "x64" }, "sha512-tU+9pwsqCy8afOVlGtiWrWQc/fedQK4SRm4KPIAt+zOiQWDxWASm6YGBUJis5c648WN80yz47qnmdDi8DQNOcA=="], + + "@cloudflare/vite-plugin/wrangler/workerd/@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260415.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-bR9uITnV19r5NQ14xnypi2xHXu2iQvfYV8cVgx0JouFUmWwTEEAwFVojDdssGq93VHX9hr/pi2IRUZeegbYBog=="], + + "@cloudflare/vite-plugin/wrangler/workerd/@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260415.1", "", { "os": "win32", "cpu": "x64" }, "sha512-4NuMLlerI0Ijua3Ir8HXQ+qyNvCUDEG5gDco5Om+sAiK6rnWiz+aGoSlbB8W16yW9QAgzCstbmXLiVknUBflfQ=="], + "@discordjs/node-pre-gyp/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "@discordjs/node-pre-gyp/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], diff --git a/lefthook.yml b/lefthook.yml index c3e3c936..a3047120 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -12,7 +12,7 @@ pre-commit: - "*.{html,gql,graphql,hbs}" stage_fixed: true format: - run: bunx oxfmt {staged_files} + run: bunx oxfmt --no-error-on-unmatched-pattern {staged_files} glob: - "*.{js,jsx,ts,tsx,mjs,cjs}" - "*.astro" diff --git a/package.json b/package.json index 71534c1e..b0d1299e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ ], "catalog": { "@astrojs/cloudflare": "13.5.1", + "@astrojs/compiler-rs": "0.2.1", "@astrojs/mdx": "5.0.6", "@astrojs/partytown": "2.1.7", "@astrojs/react": "5.0.5", @@ -37,7 +38,7 @@ "antiox": "0.1.4", "astro": "6.3.7", "better-auth": "1.5.5", - "better-result": "2.9.0", + "better-result": "2.9.2", "hono": "4.12.16", "hono-problem-details": "0.6.1", "hono-rate-limiter": "0.5.3", @@ -80,15 +81,15 @@ "@vitejs/plugin-react": "6.0.1", "babel-plugin-react-compiler": "1.0.0", "openclaw": "2026.4.10", - "oxfmt": "0.46.0", - "oxlint": "1.61.0", + "oxfmt": "0.52.0", + "oxlint": "1.67.0", "postcss": "8.5.6", "rollup-plugin-visualizer": "7.0.1", "tailwindcss": "4.2.2", "typescript": "5.4.5", "vite": "8.0.2", "vite-tsconfig-paths": "6.1.1", - "wrangler": "4.83.0" + "wrangler": "4.95.0" } } }, @@ -156,12 +157,12 @@ "eslint-plugin-turbo": "2.9.5", "happy-dom": "20.3.3", "knip": "6.0.5", - "lefthook": "2.1.6", + "lefthook": "2.1.9", "npm-check-updates": "19.3.1", "openclaw": "catalog:tooling", "oxfmt": "catalog:tooling", "oxlint": "catalog:tooling", - "oxlint-tsgolint": "0.22.0", + "oxlint-tsgolint": "0.23.0", "turbo": "2.9.5", "vitest": "catalog:testing" }, diff --git a/packages/config/src/server-launch.ts b/packages/config/src/server-launch.ts index 5154214c..ff7dcb58 100644 --- a/packages/config/src/server-launch.ts +++ b/packages/config/src/server-launch.ts @@ -18,10 +18,8 @@ import type { ServerLaunchMigrationsConfig, ServerLaunchRateLimitConfig, ServerLaunchRuntimePathsConfig, - ServerLaunchSmtpConfig, ServerLaunchStorageConfig, ServerLaunchSupervisorControlConfig, - ServerLaunchSupervisorControlTransportConfig, WorkspaceDevServerLaunchConfig, } from "@onequery/proto-runtime/runtime/v1/launch_pb"; diff --git a/packages/datetime/package.json b/packages/datetime/package.json index 4b6170d8..98448e05 100644 --- a/packages/datetime/package.json +++ b/packages/datetime/package.json @@ -14,5 +14,7 @@ "test": "vitest run", "test:watch": "vitest" }, - "devDependencies": {} + "devDependencies": { + "vitest": "catalog:testing" + } } diff --git a/packages/openclaw-plugin/package.json b/packages/openclaw-plugin/package.json index 89dac7fc..c82111cd 100644 --- a/packages/openclaw-plugin/package.json +++ b/packages/openclaw-plugin/package.json @@ -8,7 +8,7 @@ "openclaw", "plugin" ], - "homepage": "https://github.com/wordbricks/onequery/tree/main/packages/openclaw-plugin#readme", + "homepage": "https://onequery.dev", "bugs": { "url": "https://github.com/wordbricks/onequery/issues" }, diff --git a/packages/openclaw-plugin/skills/onequery-cli/SKILL.md b/packages/openclaw-plugin/skills/onequery-cli/SKILL.md index 97d23f73..245b2c19 100644 --- a/packages/openclaw-plugin/skills/onequery-cli/SKILL.md +++ b/packages/openclaw-plugin/skills/onequery-cli/SKILL.md @@ -1,7 +1,7 @@ --- name: onequery-openclaw description: Use OpenClaw's exec tool to inspect orgs, sources, and run bounded read-only SQL through the OneQuery CLI directly. -metadata: {"openclaw":{"requires":{"bins":["onequery"]},"homepage":"https://github.com/wordbricks/onequery"}} +metadata: {"openclaw":{"requires":{"bins":["onequery"]},"homepage":"https://onequery.dev"}} --- Use this skill when the user wants company or customer data that should be read diff --git a/packages/server/src/services/data-source-query/core/validation.ts b/packages/server/src/services/data-source-query/core/validation.ts index 1555ebc4..80a1d2a1 100644 --- a/packages/server/src/services/data-source-query/core/validation.ts +++ b/packages/server/src/services/data-source-query/core/validation.ts @@ -23,7 +23,7 @@ export async function validateReadOnlySql(input: { }); if (validation.isErr()) { - return validation; + return Result.err(validation.error); } if (validation.value.isErr()) { diff --git a/packages/server/src/services/data-source-query/providers/bigquery/driver.ts b/packages/server/src/services/data-source-query/providers/bigquery/driver.ts index 9e3ac1ee..7a871059 100644 --- a/packages/server/src/services/data-source-query/providers/bigquery/driver.ts +++ b/packages/server/src/services/data-source-query/providers/bigquery/driver.ts @@ -47,7 +47,7 @@ function buildBigQueryQueryOptions(input: { const location = normalizeBigQueryLocation(input.location); if (location.isErr()) { - return location; + return Result.err(location.error); } return Result.ok( diff --git a/packages/server/src/services/data-source-query/providers/laminar/driver.ts b/packages/server/src/services/data-source-query/providers/laminar/driver.ts index d3471e55..5eef0e86 100644 --- a/packages/server/src/services/data-source-query/providers/laminar/driver.ts +++ b/packages/server/src/services/data-source-query/providers/laminar/driver.ts @@ -121,7 +121,7 @@ function resolveLaminarQueryUrl( }), }); if (urlResult.isErr()) { - return urlResult; + return Result.err(urlResult.error); } const url = urlResult.value; diff --git a/turbo.json b/turbo.json index 187826ba..1cf96a72 100644 --- a/turbo.json +++ b/turbo.json @@ -23,6 +23,7 @@ "CONNECTOR_ABORT_ON_AUTH_FAILURE", "CONNECTOR_ABORT_ON_PREREQ_FAILURE", "DATABASE_URL", + "LANDING_SLACK_WEBHOOK_URL", "ONEQUERY_RUNTIME_ROOT" ] }, @@ -33,6 +34,7 @@ "CONNECTOR_ABORT_ON_AUTH_FAILURE", "CONNECTOR_ABORT_ON_PREREQ_FAILURE", "DATABASE_URL", + "LANDING_SLACK_WEBHOOK_URL", "ONEQUERY_RUNTIME_ROOT" ] },