@palbase/web 7.3.5 → 7.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/gen/cli.ts","../../src/gen/generate.ts","../../src/gen/emitter.ts","../../src/gen/parser.ts"],"sourcesContent":["#!/usr/bin/env node\n// palbe-gen — SDK-owned typed-client codegen for @palbase/web.\n// Reads app-bound artifacts written by `palbase web link`, or fetches the spec\n// from an origin passed with --url, and writes the typed palbe.gen.ts module.\nimport process from 'node:process';\nimport { main } from './generate.js';\n\nmain(process.argv.slice(2)).then(\n (code) => process.exit(code),\n (err) => {\n process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n },\n);\n","// palbe-gen command logic: read the committed Palbase/ spec (or fetch it from\n// the origin passed with --url), run the parser+emitter, and write palbe.gen.ts.\n// Ports the CLI's Go semantics (internal/backend: pullTSTypes zero-op guard,\n// --soft policy, tswatch.go watch loop).\n\nimport { createHash } from 'node:crypto';\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { parseArgs } from 'node:util';\nimport { environmentRefFromPublishableApiKey } from '../api-key.js';\nimport { emitTypeScript, type GeneratedConfig, type OAuthConfig } from './emitter.js';\nimport { type Op, parseOpenAPI, readSpecDeploy } from './parser.js';\n\nexport type Writer = (line: string) => void;\n\nconst USAGE = `Usage: palbe-gen [--dir Palbase] [--out palbe.gen.ts] [--url <specOrigin>] [--soft] [--watch]\n\nGenerate the typed palbe.gen.ts web client for the @palbase/web SDK.\n\n --dir <dir> Directory holding the committed openapi.json and required\n palbase-config.json written by \\`palbase web link\\`\n (default: Palbase)\n --out <file> Output file (default: palbe.gen.ts)\n --url <origin> Fetch the spec from <origin>/openapi.json instead of --dir\n (e.g. a deployed Environment's origin)\n --soft Never fail: print a warning and exit 0 on any error\n (for predev/prebuild hooks)\n --watch Poll the --url origin every second and regenerate whenever\n the spec changes. Without --url, polls the linked\n checkout's own Environment (the base_url committed to\n {dir}/palbase-config.json by \\`palbase web link\\`)\n -h, --help Show this help`;\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\nexport class HttpStatusError extends Error {\n readonly status: number;\n constructor(status: number, url: string) {\n super(`GET ${url}: HTTP ${status}`);\n this.status = status;\n }\n}\n\nexport async function fetchSpec(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url, { signal: AbortSignal.timeout(3000) });\n } catch (e) {\n throw new Error(`GET ${url}: ${errMsg(e)}`);\n }\n if (!res.ok) throw new HttpStatusError(res.status, url);\n return res.text();\n}\n\n// readWebConfig reads the required canonical app-bound\n// {dir}/palbase-config.json shape.\nexport function readWebConfig(dir: string): GeneratedConfig {\n const path = join(dir, 'palbase-config.json');\n let text: string;\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n throw new Error(`${path} is required in dir mode — run \\`palbase web link\\``);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n throw new Error(`${path} is not valid JSON: ${errMsg(e)}`);\n }\n const obj = (raw ?? {}) as Record<string, unknown>;\n const str = (v: unknown) => (typeof v === 'string' ? v : '');\n const required = (field: 'app_id' | 'base_url' | 'api_key'): string => {\n const value = str(obj[field]);\n if (value.trim() === '') {\n throw new Error(`${path} is missing nonempty required field ${field}`);\n }\n return value.trim();\n };\n const cfg: GeneratedConfig = {\n url: required('base_url'),\n apiKey: required('api_key'),\n appId: required('app_id'),\n };\n // The project identity comes from the key and from nowhere else. This file\n // used to require an `environment_ref` field beside it and refuse when the two\n // disagreed — and on 2026-08-16 they did: `palbase link` wrote one value while\n // minting a key carrying another, so linking a web app to a project produced a\n // config this generator would not read. A copy that must equal its original is\n // not a second fact, it is a second chance to be wrong.\n const projectRef = environmentRefFromPublishableApiKey(cfg.apiKey);\n if (projectRef === '') {\n throw new Error(`${path} api_key does not contain a valid publishable project identity`);\n }\n let configURL: URL;\n try {\n configURL = new URL(cfg.url);\n } catch {\n throw new Error(`${path} base_url must be a valid HTTPS URL`);\n }\n if (configURL.protocol !== 'https:') {\n throw new Error(`${path} base_url must be a valid HTTPS URL`);\n }\n if (\n configURL.hostname.endsWith('.palbase.studio') &&\n configURL.hostname.split('.')[0] !== projectRef\n ) {\n throw new Error(`${path} base_url must match the project identity in api_key for palbase.studio`);\n }\n const oauthRaw = obj.oauth as Record<string, unknown> | undefined;\n if (oauthRaw && typeof oauthRaw === 'object') {\n const oauth: OAuthConfig = {};\n const apple = oauthRaw.apple as Record<string, unknown> | undefined;\n if (apple && typeof apple === 'object') {\n oauth.apple = { enabled: apple.enabled === true };\n }\n const google = oauthRaw.google as Record<string, unknown> | undefined;\n if (google && typeof google === 'object') {\n oauth.google = {\n enabled: google.enabled === true,\n clientId: str(google.client_id),\n redirectUri: str(google.redirect_uri),\n };\n }\n cfg.oauth = oauth;\n }\n return cfg;\n}\n\nfunction emitAndWrite(ops: Op[], cfg: GeneratedConfig, outFile: string): void {\n const dir = dirname(outFile);\n if (dir !== '.' && dir !== '') {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(outFile, emitTypeScript(ops, cfg));\n}\n\nfunction existingNonEmpty(outFile: string): boolean {\n try {\n return readFileSync(outFile).length > 0;\n } catch {\n return false;\n }\n}\n\n// writeGenerated applies the zero-op overwrite guard, then emits. A live spec\n// with 0 operations almost always means the backend's controller metadata\n// extraction broke (the \"zero endpoints collected\" failure class), not that\n// the app has no endpoints. Never clobber a previously good palbe.gen.ts with\n// an empty client; warn and exit 0 so a predev hook doesn't fail the build.\n// With nothing to protect, write the (empty) module anyway — a fresh project\n// still gets a compilable file — but warn loudly.\nexport function writeGenerated(\n ops: Op[],\n cfg: GeneratedConfig,\n outFile: string,\n out: Writer,\n specDeploy = '',\n): void {\n if (ops.length === 0) {\n if (existingNonEmpty(outFile)) {\n out(\n `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n );\n return;\n }\n out(\n `warning: live spec has 0 operations — ${outFile} registers no calls (fix your controllers and rerun)`,\n );\n }\n emitAndWrite(ops, cfg, outFile);\n out(`✓ wrote ${outFile} (${ops.length} operations${provenance(specDeploy)})`);\n}\n\n// provenance renders the deploy clause the success lines carry. Empty for a spec\n// with no identity — an artifact built before the stamp existed. Saying nothing\n// there is deliberate: a fabricated or guessed identity would read as verified.\nfunction provenance(specDeploy: string): string {\n return specDeploy === '' ? '' : `, deploy ${specDeploy}`;\n}\n\n// generateOnce is the single-shot generation path.\n// - default: read {dir}/openapi.json + required {dir}/palbase-config.json\n// - --url: fetch <origin>/openapi.json while retaining the canonical linked\n// Environment identity; only the runtime URL points at the origin.\nexport async function generateOnce(\n dir: string,\n outFile: string,\n url: string | undefined,\n out: Writer,\n): Promise<void> {\n let specText: string;\n let cfg: GeneratedConfig;\n if (url !== undefined) {\n const origin = url.replace(/\\/+$/, '');\n specText = await fetchSpec(`${origin}/openapi.json`);\n cfg = { ...readWebConfig(dir), url: origin };\n } else {\n cfg = readWebConfig(dir);\n const specPath = join(dir, 'openapi.json');\n try {\n specText = readFileSync(specPath, 'utf8');\n } catch {\n throw new Error(\n `no OpenAPI spec at ${specPath} — run \\`palbase web spec\\` first, or pass --url to fetch it from an origin`,\n );\n }\n }\n writeGenerated(parseOpenAPI(specText), cfg, outFile, out, readSpecDeploy(specText));\n}\n\n// --- Watch mode (tswatch.go port) --------------------------------------------\n\nexport type FetchFn = (url: string) => Promise<string>;\n\n// watchLoop polls specURL on each tick:\n// - Fetch fails: print a down message ONCE per transition — a waiting line\n// when nothing is listening, or the HTTP-error variant when the origin\n// answered with an error status.\n// - Fetch succeeds: SHA-256 the body. Same hash as the last EMIT → skip.\n// Same hash as the last WARNED-bad body → stay silent. Otherwise parse +\n// emit + write; a bad body (unparseable, or 0 ops with an existing file to\n// protect) warns once and records its hash. A successful emit resets the\n// bad-hash state.\n// Hash state starts EMPTY intentionally: the first successful fetch always\n// regenerates. Returns (printing \"watch stopped\") when the tick source ends.\nexport async function watchLoop(\n specURL: string,\n cfg: GeneratedConfig,\n outFile: string,\n fetchFn: FetchFn,\n ticks: AsyncIterable<void>,\n out: Writer,\n): Promise<void> {\n let lastEmittedHash = ''; // '' = nothing emitted yet\n let lastBadHash = ''; // '' = no standing bad-body warning\n let lastDownMsg = ''; // last printed down message; '' = the origin was up\n\n for await (const _ of ticks) {\n let specText: string;\n try {\n specText = await fetchFn(specURL);\n } catch (err) {\n let m = `waiting for ${specURL}…`;\n if (err instanceof HttpStatusError) {\n m = `${specURL} responded with an error (HTTP ${err.status})`;\n }\n if (m !== lastDownMsg) {\n out(m);\n lastDownMsg = m;\n }\n continue;\n }\n\n // The origin is (back) up.\n lastDownMsg = '';\n\n const h = createHash('sha256').update(specText).digest('hex');\n if (lastEmittedHash !== '' && h === lastEmittedHash) continue; // no change\n if (lastBadHash !== '' && h === lastBadHash) continue; // already warned\n\n let ops: Op[];\n try {\n ops = parseOpenAPI(specText);\n } catch (err) {\n out(`warning: failed to parse spec: ${errMsg(err)}`);\n lastBadHash = h;\n continue;\n }\n if (ops.length === 0 && existingNonEmpty(outFile)) {\n out(\n `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n );\n lastBadHash = h;\n continue;\n }\n\n try {\n emitAndWrite(ops, cfg, outFile);\n } catch (err) {\n // Environmental write failure (disk) — not spec-dependent, so do not\n // record a bad hash; the next tick retries.\n out(`warning: codegen error: ${errMsg(err)}`);\n continue;\n }\n\n lastEmittedHash = h;\n lastBadHash = ''; // a good emit resets the warn-dedup state\n out(`regenerated ${outFile} (${ops.length} operations${provenance(readSpecDeploy(specText))})`);\n }\n out('watch stopped');\n}\n\nfunction delay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) {\n resolve();\n return;\n }\n const onAbort = () => {\n clearTimeout(t);\n resolve();\n };\n const t = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nasync function* intervalTicks(ms: number, signal: AbortSignal): AsyncGenerator<void> {\n while (!signal.aborted) {\n await delay(ms, signal);\n if (signal.aborted) return;\n yield;\n }\n}\n\nasync function runWatch(\n dir: string,\n outFile: string,\n url: string | undefined,\n out: Writer,\n): Promise<void> {\n // readWebConfig throws a clear, actionable error when {dir} was never\n // linked — that's the same \"run `palbase web link`\" failure every other\n // dir-mode path already has, so an unlinked --watch fails loudly here, not\n // by silently retrying an address nothing answers.\n const linked = readWebConfig(dir);\n\n // No --url: watch the linked checkout's OWN Environment. `palbase serve`\n // (retired) used to expose the spec on http://localhost:4003; nothing\n // replaces that local server today, so defaulting to it just polled a dead\n // address forever with a misleading \"waiting for...\" message. base_url —\n // already read and validated above — is a real, currently-serving origin.\n const origin = (url ?? linked.url).replace(/\\/+$/, '');\n const specURL = `${origin}/openapi.json`;\n\n // The spec comes from the resolved origin, while identity remains bound to\n // the linked Environment. Initial fetch failure is soft because the loop\n // exists to wait for that origin to answer.\n const cfg: GeneratedConfig = { ...linked, url: origin };\n try {\n const initial = await fetchSpec(specURL);\n writeGenerated(parseOpenAPI(initial), cfg, outFile, out, readSpecDeploy(initial));\n } catch (err) {\n out(`warning: codegen skipped (${errMsg(err)})`);\n }\n\n // A real Ctrl-C aborts the tick source → clean \"watch stopped\" exit 0\n // instead of a hard kill that could truncate palbe.gen.ts mid-write.\n const ctrl = new AbortController();\n const stop = () => ctrl.abort();\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n try {\n await watchLoop(specURL, cfg, outFile, fetchSpec, intervalTicks(1000, ctrl.signal), out);\n } finally {\n process.removeListener('SIGINT', stop);\n process.removeListener('SIGTERM', stop);\n }\n}\n\n// --- Entry -------------------------------------------------------------------\n\nconst stdoutWriter: Writer = (line) => {\n process.stdout.write(`${line}\\n`);\n};\nconst stderrWriter: Writer = (line) => {\n process.stderr.write(`${line}\\n`);\n};\n\nfunction parseCliArgs(argv: string[]) {\n return parseArgs({\n args: argv,\n options: {\n dir: { type: 'string', default: 'Palbase' },\n out: { type: 'string', default: 'palbe.gen.ts' },\n url: { type: 'string' },\n soft: { type: 'boolean', default: false },\n watch: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n }).values;\n}\n\nexport async function main(\n argv: string[],\n out: Writer = stdoutWriter,\n errOut: Writer = stderrWriter,\n): Promise<number> {\n let values: ReturnType<typeof parseCliArgs>;\n try {\n values = parseCliArgs(argv);\n } catch (e) {\n errOut(`error: ${errMsg(e)}`);\n errOut(USAGE);\n return 1;\n }\n if (values.help) {\n out(USAGE);\n return 0;\n }\n try {\n if (values.watch) {\n await runWatch(values.dir, values.out, values.url, out);\n } else {\n await generateOnce(values.dir, values.out, values.url, out);\n }\n return 0;\n } catch (err) {\n // --soft turns ANY failure into a warning + exit 0, so a predev/prebuild\n // hook never blocks a machine without the spec or a running serve.\n if (values.soft) {\n out(`warning: codegen skipped (${errMsg(err)})`);\n return 0;\n }\n errOut(`error: ${errMsg(err)}`);\n return 1;\n }\n}\n","// palbe.gen.ts emitter — TypeScript port of the CLI's Go endpoint emitter.\n// The checked-in golden locks the complete app-bound runtime config and endpoint\n// output shape.\n\nimport type { ErrorDef, Op, Schema } from './parser.js';\n\n// GeneratedConfig carries the runtime config values the generated palbe.gen.ts\n// writes into __configure() (the web SDK seam — web embeds config in the\n// generated module, unlike iOS which reads the per-env plist).\nexport interface GeneratedConfig {\n url: string;\n apiKey: string;\n appId: string;\n oauth?: OAuthConfig;\n}\n\nexport interface OAuthConfig {\n apple?: { enabled: boolean };\n google?: { enabled: boolean; clientId: string; redirectUri?: string };\n}\n\n// --- Naming -----------------------------------------------------------------\n\nexport function opSegments(opId: string): string[] {\n return opId.split('.').filter((p) => p !== '');\n}\n\nfunction typeNameOf(s: string): string {\n return sanitize(s, true);\n}\n\n// typePrefix builds the PascalCase concatenation of all op-id segments, used\n// as the BASE for top-level <Prefix>Request / <Prefix>Response / <Prefix>Error\n// type names. Example: \"rooms.create\" → \"RoomsCreate\".\nfunction typePrefix(opId: string): string {\n return opSegments(opId).map(typeNameOf).join('');\n}\n\nfunction sanitize(s: string, firstUpper: boolean): string {\n const parts: string[] = [];\n let cur = '';\n for (const ch of s) {\n if (/^[A-Za-z0-9]$/.test(ch)) {\n cur += ch;\n } else if (cur.length > 0) {\n parts.push(cur);\n cur = '';\n }\n }\n if (cur.length > 0) parts.push(cur);\n if (parts.length === 0) return firstUpper ? 'Op' : 'op';\n let out = '';\n parts.forEach((p, i) => {\n out +=\n i === 0 && !firstUpper\n ? p.charAt(0).toLowerCase() + p.slice(1)\n : p.charAt(0).toUpperCase() + p.slice(1);\n });\n if (out.charAt(0) >= '0' && out.charAt(0) <= '9') out = `_${out}`;\n return out;\n}\n\n// --- Emit -------------------------------------------------------------------\n\n// emitTypeScript turns parsed operations into a palbe.gen.ts module.\n// The file structure:\n// header → imports → __configure → types section → typed-errors section →\n// namespaces section (skip comments + __registerNamespaces) → declare module\nexport function emitTypeScript(ops: Op[], cfg: GeneratedConfig): string {\n // Filter reserved top-level namespaces; collect skip comments.\n // Single-segment operationIds (the live wire shape — verb-prefixed ids like\n // `getHello`) pass the same filter and later register as ROOT-LEVEL\n // descriptor keys. Skip-comment dedup is case-insensitive (auth/Auth are the\n // same reserved surface); the first-seen casing is printed.\n const usable: Op[] = [];\n const skippedNS: string[] = [];\n const seenSkip = new Set<string>();\n for (const op of ops) {\n const [ns] = opSegments(op.operationId);\n if (ns === undefined) continue;\n if (tsReservedTopLevel(ns)) {\n const key = ns.toLowerCase();\n if (!seenSkip.has(key)) {\n seenSkip.add(key);\n skippedNS.push(ns);\n }\n continue;\n }\n usable.push(op);\n }\n skippedNS.sort();\n\n // Per-operation gates: nested-reserved / body+query / non-primitive-query /\n // kind-mismatch filtering happens BEFORE type emission, so skipped ops\n // neither emit dead types nor squat type-name prefixes against later ops.\n const [candidates, opSkips] = filterTSOps(usable);\n\n // Build all content sections FIRST (in-memory), so the import lines can be\n // derived from what is ACTUALLY emitted — an error-bearing op dropped by a\n // gate must not leave a stray `BackendError` import behind.\n const [typesOut, collisionSkips, typeCollisionOps] = emitTSTypes(candidates);\n\n // Type-collision ops have no usable types — they must not be callable-typed.\n const registerable = candidates.filter((op) => !typeCollisionOps.has(op.operationId));\n\n const [errorsOut, classCount] = emitTSTypedErrors(registerable);\n\n // --- Assemble ---\n let b = '';\n\n // Header.\n b += '// AUTO-GENERATED by `palbe-gen` — DO NOT EDIT.\\n';\n b += '// Regenerate: palbe-gen (or automatically via the predev/prebuild script)\\n';\n\n // Imports. `BackendError` is referenced only by emitted error classes;\n // `CallOptions` only by augmentation method signatures. When neither is\n // used, the whole `import type ...` line is omitted — the runtime import\n // from '@palbase/web/internal' always stays.\n const typeImports: string[] = [];\n if (classCount > 0) typeImports.push('BackendError');\n if (registerable.length > 0) typeImports.push('CallOptions');\n if (typeImports.length > 0) {\n b += `import type { ${typeImports.join(', ')} } from '@palbase/web';\\n`;\n }\n b += \"import { __configure, __registerNamespaces } from '@palbase/web/internal';\\n\\n\";\n\n b += emitTSConfigure(cfg);\n b += '\\n';\n\n // Types + typed errors (either may be empty).\n b += typesOut;\n b += errorsOut;\n\n // Namespaces section.\n b += '// ── Namespaces ─────────────────────────────────────────────────────\\n\\n';\n // Skip comments: reserved-namespace, then per-op gates, then type collisions.\n for (const ns of skippedNS) {\n b += `// codegen: skipped reserved namespace \"${ns}\"\\n`;\n }\n for (const l of opSkips) {\n b += `${l}\\n`;\n }\n for (const c of collisionSkips) {\n b += `${c}\\n`;\n }\n b += emitTSRegistration(registerable);\n\n // declare module augmentation — omitted entirely when nothing registers.\n if (registerable.length > 0) {\n b += '\\n';\n b += emitTSAugmentation(registerable);\n }\n\n return b;\n}\n\n// emitTSConfigure renders the __configure({…}) call.\nfunction emitTSConfigure(cfg: GeneratedConfig): string {\n let b = '__configure({\\n';\n b += ` url: ${tsStringLit(cfg.url)},\\n`;\n b += ` apiKey: ${tsStringLit(cfg.apiKey)},\\n`;\n b += ` appId: ${tsStringLit(cfg.appId)},\\n`;\n const oauth = renderTSOAuth(cfg.oauth);\n if (oauth !== '') {\n b += ' oauth: {\\n';\n b += oauth;\n b += ' },\\n';\n }\n b += '});\\n';\n return b;\n}\n\n// renderTSOAuth returns the indented inner lines of the oauth block, or '' to\n// omit the key entirely. Google is included only when enabled and clientId is\n// non-empty. Apple is included only when enabled.\nfunction renderTSOAuth(o: OAuthConfig | undefined): string {\n if (!o) return '';\n let b = '';\n if (o.apple?.enabled) {\n b += ' apple: { enabled: true },\\n';\n }\n if (o.google?.enabled && o.google.clientId !== '') {\n b += ` google: { enabled: true, clientId: ${tsStringLit(o.google.clientId)} },\\n`;\n }\n return b;\n}\n\n// --- Per-operation gates ------------------------------------------------\n\n// filterTSOps applies the per-op gates that decide whether an operation can\n// register at all: reserved nested segments, body+query conflict, query params\n// the runtime's serializeQuery cannot handle, and namespace/method kind\n// mismatches. Returns the surviving ops (input order preserved) plus loud\n// skip-comment lines.\nfunction filterTSOps(ops: Op[]): [Op[], string[]] {\n const out: Op[] = [];\n const skips: string[] = [];\n const root = new TSNode(); // shape-only trie for kind-mismatch detection\n\n for (const op of ops) {\n const segs = opSegments(op.operationId);\n const lastSeg = segs[segs.length - 1];\n if (lastSeg === undefined) continue;\n // Nested reserved check covers EVERY non-first segment — both the\n // intermediate namespace segments and the final method segment.\n let skip = false;\n for (const seg of segs.slice(1)) {\n if (tsReservedNested(seg)) {\n skips.push(`// codegen: skipped operation \"${op.operationId}\" (reserved segment \"${seg}\")`);\n skip = true;\n break;\n }\n }\n if (skip) continue;\n // A descriptor's `input` is single-valued: body (default) or query.\n if (op.input && op.query) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (both body and query declared — unsupported)`,\n );\n continue;\n }\n // Non-primitive query params would make the runtime's serializeQuery throw.\n if (op.query) {\n const bad = firstNonPrimitiveQueryProp(op.query);\n if (bad !== undefined) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (non-primitive query parameter \"${bad}\")`,\n );\n continue;\n }\n }\n // Kind-mismatch: a key claimed as both namespace and method.\n let node: TSNode | undefined = root;\n for (const seg of segs.slice(0, -1)) {\n node = node.childNode(seg);\n if (!node) break;\n }\n if (!node?.addMethod(lastSeg, op)) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (key collides with existing namespace/method)`,\n );\n continue;\n }\n out.push(op);\n }\n return [out, skips];\n}\n\n// firstNonPrimitiveQueryProp returns the name of the first query property whose\n// schema cannot be serialized into a query string, or undefined when all are\n// primitive.\nfunction firstNonPrimitiveQueryProp(q: Schema): string | undefined {\n for (const p of q.props) {\n switch (p.schema.kind) {\n case 'string':\n case 'number':\n case 'integer':\n case 'boolean':\n case 'enum':\n break; // primitive — serializeQuery handles it\n default:\n return p.name;\n }\n }\n return undefined;\n}\n\n// --- Types section ----------------------------------------------------------\n\n// emitTSTypes emits the `// ── Types ──` section: one named interface or type\n// alias per op schema (request, response, query, error-data). Returns the\n// rendered section (empty when no ops produce types), collision skip comment\n// lines, and the set of colliding op ids.\nfunction emitTSTypes(ops: Op[]): [string, string[], Set<string>] {\n const collisionOps = new Set<string>();\n // seenPrefix maps PascalCase typePrefix → first operationId that claimed it.\n const seenPrefix = new Map<string, string>();\n const collisionSkips: string[] = [];\n const lines: string[] = [];\n\n for (const op of ops) {\n const pfx = typePrefix(op.operationId);\n const first = seenPrefix.get(pfx);\n if (first !== undefined) {\n collisionSkips.push(`// codegen: skipped type \"${pfx}\" (collides with operation \"${first}\")`);\n collisionOps.add(op.operationId);\n continue;\n }\n seenPrefix.set(pfx, op.operationId);\n\n // Request type (input body).\n if (op.input) {\n lines.push(...tsNamedTypeLines(`${pfx}Request`, op.input));\n }\n // Query type (emitted before Response, per golden contract order).\n if (op.query) {\n lines.push(...tsNamedTypeLines(`${pfx}Query`, op.query));\n }\n // Response type (output).\n if (op.output) {\n lines.push(...tsResponseTypeLines(pfx, op.output));\n }\n // Error data interfaces (after response) — only for errors that actually\n // lift; filtered errors emit no class, so a Data interface would orphan.\n const [liftable] = tsLiftableErrors(op);\n for (const e of liftable) {\n if (!e.data) continue;\n const dataName = `${pfx}${typeNameOf(e.name)}Data`;\n lines.push(`/** ${e.code} (${e.status}): ${e.description} */`);\n lines.push(...tsNamedTypeLines(dataName, e.data));\n }\n }\n\n if (lines.length === 0) {\n return ['', collisionSkips, collisionOps];\n }\n\n let b = '// ── Types ──────────────────────────────────────────────────────────\\n\\n';\n for (const l of lines) {\n b += `${l}\\n`;\n }\n // Note: each type block ends with an empty-string entry that renders as a\n // blank separator line. No extra trailing newline needed here.\n return [b, collisionSkips, collisionOps];\n}\n\n// tsNamedTypeLines renders a named top-level type declaration: `export\n// interface` for object schemas, `export type` alias otherwise.\nfunction tsNamedTypeLines(name: string, s: Schema): string[] {\n if (s.kind === 'object') {\n return tsInterfaceLines(name, s);\n }\n return [`export type ${name} = ${tsTypeOf(s)};`, ''];\n}\n\n// tsResponseTypeLines handles the special case where a response is an array of\n// objects: emits `<Prefix>ResponseItem` interface + `<Prefix>Response` alias.\nfunction tsResponseTypeLines(pfx: string, s: Schema): string[] {\n if (s.kind === 'array' && s.elem && s.elem.kind === 'object') {\n return [\n ...tsInterfaceLines(`${pfx}ResponseItem`, s.elem),\n `export type ${pfx}Response = ${pfx}ResponseItem[];`,\n '',\n ];\n }\n return tsNamedTypeLines(`${pfx}Response`, s);\n}\n\n// tsInterfaceLines renders `export interface Name { ... }` with sorted props.\n// A property named __proto__ is skipped loudly: writing it in a JS object\n// literal sets the prototype, and JSON.stringify drops it — wire-dead anyway.\nfunction tsInterfaceLines(name: string, s: Schema): string[] {\n const lines: string[] = [`export interface ${name} {`];\n for (const p of s.props) {\n if (p.name === '__proto__') {\n lines.push(' // codegen: skipped property \"__proto__\"');\n continue;\n }\n const opt = p.required ? '' : '?';\n lines.push(` ${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)};`);\n }\n lines.push('}', '');\n return lines;\n}\n\n// tsTypeOf converts a Schema to its TypeScript type string. For NESTED object\n// schemas (appearing as property values) it emits an inline literal\n// `{ k: T; ... }` rather than a named interface.\nfunction tsTypeOf(s: Schema): string {\n switch (s.kind) {\n case 'string':\n return s.nullable ? 'string | null' : 'string';\n case 'number':\n case 'integer':\n return s.nullable ? 'number | null' : 'number';\n case 'boolean':\n return s.nullable ? 'boolean | null' : 'boolean';\n case 'enum': {\n const union = s.enumVals.map(tsStringLit).join(' | ');\n return s.nullable ? `(${union}) | null` : union;\n }\n case 'array': {\n if (!s.elem) {\n return s.nullable ? 'unknown[] | null' : 'unknown[]';\n }\n let elem = tsTypeOf(s.elem);\n // Parenthesise union element types (enum or nullable) so `T[]` parses.\n if (elem.includes(' | ') || elem.startsWith('(')) {\n elem = `(${elem})`;\n }\n const arr = `${elem}[]`;\n return s.nullable ? `${arr} | null` : arr;\n }\n case 'object': {\n const inline = tsInlineObject(s);\n return s.nullable ? `${inline} | null` : inline;\n }\n default: // 'any' or unknown\n return s.nullable ? 'unknown | null' : 'unknown';\n }\n}\n\n// tsInlineObject renders `{ k: T; k2?: U }` for a nested object schema.\n// __proto__ props are dropped here too (no comment slot inside a single-line\n// literal).\nfunction tsInlineObject(s: Schema): string {\n const parts: string[] = [];\n for (const p of s.props) {\n if (p.name === '__proto__') continue;\n const opt = p.required ? '' : '?';\n parts.push(`${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`);\n }\n if (parts.length === 0) return 'Record<string, unknown>';\n return `{ ${parts.join('; ')} }`;\n}\n\n// tsInfraReservedCodes is the set of error codes reserved by the palbe runtime\n// infrastructure. Emitting a class for these would shadow or collide with\n// palbe's own error-handling seams.\nconst tsInfraReservedCodes = new Set([\n 'not_configured',\n 'network_error',\n 'decode_error',\n 'validation_error',\n 'unauthorized',\n 'rate_limited',\n 'invalid_endpoint_name',\n 'unsupported_get_input',\n 'missing_path_param',\n 'unexpected_argument',\n 'invalid_query_value',\n 'reserved_namespace',\n 'invalid_namespace_tree',\n 'aborted',\n 'http_error',\n]);\n\n// tsLiftableErrors applies ALL per-op error filters in one place so the\n// typed-errors section, the Data-interface emission, and the descriptor's\n// errors map always agree on the surviving set:\n// - stable sort by wire code (ties keep parse order)\n// - `__proto__` codes dropped (object-literal prototype foot-gun)\n// - reserved infra codes dropped\n// - duplicate wire codes: first-wins\n// - duplicate CLASS names (roomLocked + room_locked both PascalCase to\n// RoomLocked → TS2300): first-wins\n// Returns the surviving defs plus the loud skip-comment lines, rendered at the\n// DESCRIPTOR site in the registration block.\nfunction tsLiftableErrors(op: Op): [ErrorDef[], string[]] {\n if (op.errors.length === 0) return [[], []];\n const sorted = [...op.errors].sort((a, b) => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));\n const seenCode = new Set<string>();\n const seenClass = new Map<string, string>(); // PascalCase class-name stem → first error name\n const liftable: ErrorDef[] = [];\n const comments: string[] = [];\n for (const e of sorted) {\n if (e.code === '__proto__') {\n comments.push('// codegen: skipped error code \"__proto__\"');\n continue;\n }\n if (tsInfraReservedCodes.has(e.code)) {\n comments.push(`// codegen: skipped error code \"${e.code}\" (reserved infra code)`);\n continue;\n }\n if (seenCode.has(e.code)) {\n comments.push(`// codegen: skipped duplicate error code \"${e.code}\"`);\n continue;\n }\n const stem = typeNameOf(e.name);\n const first = seenClass.get(stem);\n if (first !== undefined) {\n comments.push(`// codegen: skipped error \"${e.name}\" (class name collides with \"${first}\")`);\n continue;\n }\n seenCode.add(e.code);\n seenClass.set(stem, e.name);\n liftable.push(e);\n }\n return [liftable, comments];\n}\n\n// emitTSTypedErrors emits the `// ── Typed errors ──` section: one exported\n// class per liftable error definition across all registrable ops. Returns the\n// section text plus the emitted class COUNT (the import line includes\n// `BackendError` iff count ≥ 1). Filtered errors are skipped SILENTLY here —\n// their skip comments render at the descriptor site (see tsLiftableErrors).\nfunction emitTSTypedErrors(ops: Op[]): [string, number] {\n let count = 0;\n const lines: string[] = [];\n for (const op of ops) {\n const pfx = typePrefix(op.operationId);\n const [liftable] = tsLiftableErrors(op);\n for (const e of liftable) {\n const className = `${pfx}${typeNameOf(e.name)}Error`;\n const hasData = e.data !== undefined;\n lines.push(`export class ${className} extends Error {`);\n lines.push(` readonly name = '${className}';`);\n lines.push(` readonly code = '${e.code}';`);\n lines.push(` readonly status = ${e.status};`);\n if (hasData) {\n lines.push(` readonly data: ${pfx}${typeNameOf(e.name)}Data;`);\n }\n lines.push(' readonly cause: BackendError;');\n lines.push(' constructor(cause: BackendError) {');\n lines.push(' super(cause.message);');\n lines.push(' this.cause = cause;');\n if (hasData) {\n lines.push(` this.data = cause.data as ${pfx}${typeNameOf(e.name)}Data;`);\n }\n lines.push(' }');\n lines.push('}');\n lines.push('');\n count++;\n }\n }\n\n if (count === 0) return ['', 0];\n\n let b = '// ── Typed errors ───────────────────────────────────────────────────\\n\\n';\n for (const l of lines) {\n b += `${l}\\n`;\n }\n return [b, count];\n}\n\n// --- Registration tree --------------------------------------------------\n\n// TSNode is one level of the __registerNamespaces object literal. Entries keep\n// insertion order (ops arrive sorted by operationId, so rendered keys come out\n// alphabetically), each entry being either a nested namespace (child set) or a\n// method descriptor (op set).\ninterface TSEntry {\n key: string;\n child?: TSNode;\n op?: Op;\n}\n\nclass TSNode {\n entries: TSEntry[] = [];\n index = new Map<string, TSEntry>();\n\n // childNode returns (creating if needed) the nested namespace node for key.\n // Returns undefined if a METHOD entry already occupies the key (kind\n // mismatch).\n childNode(key: string): TSNode | undefined {\n const e = this.index.get(key);\n if (e) return e.child; // undefined when a method claims the key\n const child = new TSNode();\n const entry: TSEntry = { key, child };\n this.entries.push(entry);\n this.index.set(key, entry);\n return child;\n }\n\n // addMethod registers a method at key. Returns false if the key is already\n // occupied (either by another method or by a namespace node).\n addMethod(key: string, op: Op): boolean {\n if (this.index.has(key)) return false;\n const entry: TSEntry = { key, op };\n this.entries.push(entry);\n this.index.set(key, entry);\n return true;\n }\n}\n\n// buildTSTrie arranges PRE-FILTERED ops (filterTSOps survivors, possibly minus\n// type-collision ops) into the namespace trie. Kind mismatches are impossible\n// here — removing ops from a mismatch-free set never creates one.\nfunction buildTSTrie(ops: Op[]): TSNode {\n const root = new TSNode();\n for (const op of ops) {\n const segs = opSegments(op.operationId);\n const lastSeg = segs[segs.length - 1];\n if (lastSeg === undefined) continue;\n let node: TSNode | undefined = root;\n for (const seg of segs.slice(0, -1)) {\n node = node.childNode(seg);\n if (!node) break; // unreachable: pre-filtered by filterTSOps\n }\n if (node) {\n node.addMethod(lastSeg, op);\n }\n }\n return root;\n}\n\n// emitTSRegistration renders the __registerNamespaces({…}) call (no section\n// header or skip comments — those are written by emitTypeScript above). With\n// zero ops the call renders single-line.\nfunction emitTSRegistration(ops: Op[]): string {\n if (ops.length === 0) {\n return '__registerNamespaces({});\\n';\n }\n let b = '__registerNamespaces({\\n';\n b += renderTSNode(buildTSTrie(ops), 2);\n b += '});\\n';\n return b;\n}\n\n// renderTSNode renders one tree level at the given indent, recursing into\n// nested namespaces.\nfunction renderTSNode(node: TSNode, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n let b = '';\n for (const e of node.entries) {\n if (e.child) {\n b += `${ind}${tsPropKey(e.key)}: {\\n`;\n b += renderTSNode(e.child, indentSpaces + 2);\n b += `${ind}},\\n`;\n continue;\n }\n if (e.op) {\n b += renderTSDescriptor(e.op, e.key, indentSpaces);\n }\n }\n return b;\n}\n\n// renderTSDescriptor renders one method descriptor entry at the given indent\n// depth. Single-line when no errors survive filtering; multi-line when an\n// errors map is emitted.\n//\n// Descriptor field rules:\n// - `method` and `path` always present\n// - `pathParams` present when op.pathParams is non-empty\n// - `input: 'none'` when no body and no query\n// - `input: 'query'` when query declared (body+query handled upstream)\n// - no `input` key when a body is declared (body is the default)\n// - `errors` map when liftable errors exist → forces multi-line\nfunction renderTSDescriptor(op: Op, methodSeg: string, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n const key = tsPropKey(methodSeg);\n\n const [liftable, errComments] = tsLiftableErrors(op);\n const hasErrors = liftable.length > 0;\n\n const hasPathParams = op.pathParams.length > 0;\n const hasInput = op.input !== undefined;\n const hasQuery = op.query !== undefined;\n\n // Determine input field: '' = omit (body default).\n let inputVal = '';\n if (!hasInput && !hasQuery) {\n inputVal = 'none';\n } else if (hasQuery) {\n inputVal = 'query';\n }\n\n let b = '';\n if (!hasErrors) {\n // Single-line format: `key: { method: 'X', path: '...', [extras...] },`\n for (const c of errComments) {\n b += `${ind}${c}\\n`;\n }\n const parts = [`method: ${tsStringLit(op.method)}`, `path: ${tsStringLit(op.path)}`];\n if (hasPathParams) {\n parts.push(`pathParams: [${renderTSStringArray(op.pathParams)}]`);\n }\n if (inputVal !== '') {\n parts.push(`input: ${tsStringLit(inputVal)}`);\n }\n b += `${ind}${key}: { ${parts.join(', ')} },\\n`;\n return b;\n }\n\n // Multi-line format.\n const innerInd = ' '.repeat(indentSpaces + 2);\n b += `${ind}${key}: {\\n`;\n b += `${innerInd}method: ${tsStringLit(op.method)},\\n`;\n b += `${innerInd}path: ${tsStringLit(op.path)},\\n`;\n if (hasPathParams) {\n b += `${innerInd}pathParams: [${renderTSStringArray(op.pathParams)}],\\n`;\n }\n if (inputVal !== '') {\n b += `${innerInd}input: ${tsStringLit(inputVal)},\\n`;\n }\n for (const c of errComments) {\n b += `${innerInd}${c}\\n`;\n }\n b += `${innerInd}errors: { `;\n liftable.forEach((e, i) => {\n if (i > 0) b += ', ';\n const className = `${typePrefix(op.operationId)}${typeNameOf(e.name)}Error`;\n b += `${tsPropKey(e.code)}: (e) => new ${className}(e)`;\n });\n b += ' },\\n';\n b += `${ind}},\\n`;\n return b;\n}\n\n// renderTSStringArray renders string-array literal elements: `'a', 'b'` (no\n// surrounding brackets — caller adds them).\nfunction renderTSStringArray(ss: string[]): string {\n return ss.map(tsStringLit).join(', ');\n}\n\n// --- Augmentation (declare module '@palbase/web') ---------------------------\n\n// emitTSAugmentation renders the `declare module '@palbase/web' { interface PB\n// { ... } }` block, mirroring the registration trie shape with typed method\n// signatures. Ops arrive pre-filtered (same set as emitTSRegistration).\nfunction emitTSAugmentation(ops: Op[]): string {\n let b = \"declare module '@palbase/web' {\\n\";\n b += ' interface PB {\\n';\n b += renderTSAugNode(buildTSTrie(ops), 4);\n b += ' }\\n';\n b += '}\\n';\n return b;\n}\n\n// renderTSAugNode renders augmentation entries at the given indent.\nfunction renderTSAugNode(node: TSNode, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n let b = '';\n for (const e of node.entries) {\n if (e.child) {\n b += `${ind}${tsPropKey(e.key)}: {\\n`;\n b += renderTSAugNode(e.child, indentSpaces + 2);\n b += `${ind}};\\n`;\n continue;\n }\n if (e.op) {\n b += `${ind}${tsPropKey(e.key)}${renderTSMethodSignature(e.op)};\\n`;\n }\n }\n return b;\n}\n\n// renderTSMethodSignature builds the TypeScript method signature for one op.\n// Shape: (pathParam: string, ..., input?: T, options?: CallOptions): Promise<R>\nfunction renderTSMethodSignature(op: Op): string {\n const pfx = typePrefix(op.operationId);\n const args: string[] = [];\n\n // Leading path params. Wire names are sanitized into valid TS identifiers\n // (`{user-id}` → userId, reserved words escaped, repeats deduped) — names\n // are purely positional: the runtime substitutes via the descriptor's\n // pathParams, which keep the WIRE names, so renaming here is safe.\n const used = new Set<string>();\n for (const p of op.pathParams) {\n args.push(`${tsParamIdent(p, used)}: string`);\n }\n\n // Input arg. A zero-prop object body still takes a real `input` arg: `{}` is\n // a valid wire body and the descriptor defaults to body.\n if (op.input) {\n args.push(`input: ${pfx}Request`);\n } else if (op.query) {\n args.push(`query: ${pfx}Query`);\n }\n\n // Options arg: fold headers when present.\n args.push(buildOptionsArg(op.headers));\n\n const ret = op.output ? `Promise<${pfx}Response>` : 'Promise<void>';\n return `(${args.join(', ')}): ${ret}`;\n}\n\n// buildOptionsArg constructs the options parameter (with or without headers).\n// Required when any declared header is required; optional otherwise.\nfunction buildOptionsArg(headers: Schema | undefined): string {\n if (!headers || headers.props.length === 0) {\n return 'options?: CallOptions';\n }\n const anyRequired = headers.props.some((p) => p.required);\n\n const hParts = headers.props.map((p) => {\n const opt = p.required ? '' : '?';\n return `${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`;\n });\n const headersType = `{ ${hParts.join('; ')} }`;\n\n if (anyRequired) {\n return `options: CallOptions & { headers: ${headersType} }`;\n }\n return `options?: CallOptions & { headers?: ${headersType} }`;\n}\n\n// tsParamIdent converts a wire path-param name into a safe TS parameter\n// identifier: camelCase-sanitized (`user-id` → userId), reserved words and the\n// fixed signature arg names (input/query/options) escaped with a trailing\n// underscore, repeats deduped with a numeric suffix. Records the chosen name.\nfunction tsParamIdent(name: string, used: Set<string>): string {\n let id = sanitize(name, false);\n if (tsReservedWords.has(id) || id === 'input' || id === 'query' || id === 'options') {\n id += '_';\n }\n let candidate = id;\n for (let n = 2; used.has(candidate); n++) {\n candidate = id + n;\n }\n used.add(candidate);\n return candidate;\n}\n\n// tsReservedWords are ECMAScript keywords plus strict-mode reserved names that\n// cannot be used as parameter binding identifiers in a module.\nconst tsReservedWords = new Set([\n 'await',\n 'break',\n 'case',\n 'catch',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'else',\n 'enum',\n 'export',\n 'extends',\n 'false',\n 'finally',\n 'for',\n 'function',\n 'if',\n 'import',\n 'in',\n 'instanceof',\n 'new',\n 'null',\n 'return',\n 'super',\n 'switch',\n 'this',\n 'throw',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'while',\n 'with',\n 'yield',\n // strict-mode reserved / restricted binding names\n 'implements',\n 'interface',\n 'let',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'static',\n 'arguments',\n 'eval',\n]);\n\n// tsBareKeyRe matches identifiers that are valid bare TS object keys.\nconst tsBareKeyRe = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n// tsPropKey renders an object-literal property key: bare when it is a valid\n// identifier, single-quoted via tsStringLit otherwise (kebab-case segments,\n// codes with dots, …).\nfunction tsPropKey(name: string): string {\n return tsBareKeyRe.test(name) ? name : tsStringLit(name);\n}\n\n// tsStringLit returns a single-quoted TypeScript string literal, escaping\n// backslash and single quotes (and newlines/carriage returns defensively).\nfunction tsStringLit(s: string): string {\n return `'${s\n .replaceAll('\\\\', '\\\\\\\\')\n .replaceAll(\"'\", \"\\\\'\")\n .replaceAll('\\n', '\\\\n')\n .replaceAll('\\r', '\\\\r')}'`;\n}\n\n// tsReservedTopLevel reports whether the top-level namespace segment is\n// reserved. Case-insensitive for the iOS SDK set (auth/analytics/flags/\n// realtime) + case-sensitive for the web-only set (call, upload, then) and all\n// Object.prototype members.\nfunction tsReservedTopLevel(seg: string): boolean {\n switch (seg.toLowerCase()) {\n case 'auth':\n case 'analytics':\n case 'flags':\n case 'realtime':\n return true;\n default:\n return tsReservedWebOnly(seg);\n }\n}\n\n// tsReservedNested reports whether a non-first segment is reserved for nested\n// positions: the Object.prototype members + `then`, but NOT `call` or `upload`\n// (those are only reserved at the top level). Applied to every non-first\n// segment including the final method segment.\nfunction tsReservedNested(seg: string): boolean {\n if (seg === 'then') return true;\n return tsObjectPrototypeMember(seg);\n}\n\n// tsReservedWebOnly contains the web-only reserved set (call/upload/then) plus\n// Object.prototype members. Case-sensitive.\nfunction tsReservedWebOnly(seg: string): boolean {\n switch (seg) {\n case 'call':\n case 'upload':\n case 'then':\n return true;\n default:\n return tsObjectPrototypeMember(seg);\n }\n}\n\n// tsObjectPrototypeMember reports whether seg is an Object.prototype member.\nfunction tsObjectPrototypeMember(seg: string): boolean {\n switch (seg) {\n case 'constructor':\n case 'hasOwnProperty':\n case 'isPrototypeOf':\n case 'propertyIsEnumerable':\n case 'toLocaleString':\n case 'toString':\n case 'valueOf':\n case '__proto__':\n case '__defineGetter__':\n case '__defineSetter__':\n case '__lookupGetter__':\n case '__lookupSetter__':\n return true;\n default:\n return false;\n }\n}\n","// OpenAPI 3.1 → operation model parser for the palbe-gen typed-client codegen.\n// 1:1 TypeScript port of the CLI's Go parser (internal/backend/swiftgen.go —\n// dialect-neutral despite the historical \"swift\" name). Behavior parity with\n// the Go emitter is locked by the M1 cross-binding golden test.\n\n// --- Parsed model -----------------------------------------------------------\n\nexport type SchemaKind =\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'object'\n | 'array'\n | 'enum'\n | 'any';\n\nexport interface Schema {\n kind: SchemaKind;\n nullable: boolean;\n /** object */\n props: Prop[];\n /** array */\n elem?: Schema;\n /** enum */\n enumVals: string[];\n}\n\nexport interface Prop {\n name: string;\n schema: Schema;\n required: boolean;\n}\n\nexport interface Op {\n operationId: string;\n method: string;\n path: string;\n /** `{name}` path segments in path order → leading string method args */\n pathParams: string[];\n input?: Schema;\n output?: Schema;\n /** declared request headers (parameters[in:header]) */\n headers?: Schema;\n /** declared query params (parameters[in:query]) */\n query?: Schema;\n /** inferred errors via the `x-palbase-errors` extension */\n errors: ErrorDef[];\n}\n// ponytail: the Go parser also reads `x-palbase-upload` — the TS emitter never\n// consumes it (web has no generated upload surface), so it is not parsed here.\n\nexport interface ErrorDef {\n /** lowerCamel error name (e.g. \"todoLocked\") — class-name stem */\n name: string;\n /** wire `error` value (e.g. \"todo_locked\") — matched at decode time */\n code: string;\n /** HTTP status — kept for doc-comments */\n status: number;\n description: string;\n /** undefined when the error carries no payload */\n data?: Schema;\n}\n\ntype JsonObject = Record<string, unknown>;\n\nfunction asObject(v: unknown): JsonObject | undefined {\n if (typeof v === 'object' && v !== null && !Array.isArray(v)) return v as JsonObject;\n return undefined;\n}\n\nfunction asString(v: unknown): string {\n return typeof v === 'string' ? v : '';\n}\n\n/**\n * readSpecDeploy returns the document's `x-palbase-deploy` — the DEPLOY IDENTITY\n * the runtime stamps into every artifact it ships.\n *\n * Codegen prints it so \"generated successfully\" says WHICH contract it\n * generated from. The origin can legitimately serve the previous deploy for a\n * few seconds after a green one (a warm isolate re-reads its ACTIVE pointer on a\n * ~10s boundary), and a success line that hides that is how a client for 28\n * routes shipped after a deploy of 29 — caught only by counting operations by\n * hand.\n *\n * It is deliberately NOT `info.version`: OpenAPI requires that field, so it\n * always holds something and cannot express \"this runtime does not know\". The\n * extension is omitted instead, so absence is the answer and no placeholder\n * needs recognising.\n *\n * Returns '' when the document names no deploy, or is unreadable. It never\n * throws: parseOpenAPI owns the loud failure for a malformed document, and a\n * provenance note must not become a second, competing error path.\n */\nexport function readSpecDeploy(specText: string): string {\n try {\n return asString(asObject(JSON.parse(specText))?.['x-palbase-deploy']);\n } catch {\n return '';\n }\n}\n\n// --- Parse ------------------------------------------------------------------\n\nexport function parseOpenAPI(specText: string): Op[] {\n let root: JsonObject | undefined;\n try {\n root = asObject(JSON.parse(specText));\n } catch (e) {\n throw new Error(`openapi.json is not valid JSON: ${e instanceof Error ? e.message : e}`);\n }\n const paths = asObject(root?.paths);\n if (!paths) {\n throw new Error('openapi.json has no `paths`');\n }\n\n const ops: Op[] = [];\n for (const [path, item] of Object.entries(paths)) {\n const methods = asObject(item);\n if (!methods) continue;\n for (const [method, raw] of Object.entries(methods)) {\n const op = asObject(raw);\n if (!op) continue;\n const opId = asString(op.operationId);\n if (opId === '') continue;\n ops.push({\n operationId: opId,\n method: method.toUpperCase(),\n path,\n pathParams: pathParamNames(path),\n input: requestSchema(op),\n output: responseSchema(op),\n headers: parametersSchemaIn(op, 'header'),\n query: parametersSchemaIn(op, 'query'),\n errors: declaredErrors(op),\n });\n }\n }\n ops.sort((a, b) => (a.operationId < b.operationId ? -1 : a.operationId > b.operationId ? 1 : 0));\n return ops;\n}\n\n// declaredErrors reads the `x-palbase-errors` OpenAPI extension the backend\n// runtime stashes on each operation. Returns [] when no errors were inferred.\nfunction declaredErrors(op: JsonObject): ErrorDef[] {\n const extRaw = asObject(op['x-palbase-errors']);\n if (!extRaw) return [];\n const responses = asObject(op.responses);\n const out: ErrorDef[] = [];\n for (const [name, raw] of Object.entries(extRaw)) {\n const entry = asObject(raw);\n if (!entry) continue;\n const status = typeof entry.status === 'number' ? Math.trunc(entry.status) : 0;\n const code = asString(entry.code);\n const description = asString(entry.description);\n const hasData = entry.hasData === true;\n if (code === '' || status === 0) continue;\n const def: ErrorDef = { name, code, status, description };\n if (hasData) {\n def.data = errorDataSchema(responses, status, code);\n }\n out.push(def);\n }\n // Deterministic order: by error name.\n out.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n return out;\n}\n\n// errorDataSchema pulls the data-payload schema out of a declared error's\n// response shape. Single error on a status → the standalone schema; multiple\n// errors sharing a status → `oneOf`, pick the variant whose\n// `error: { const: <code> }` discriminator matches.\nfunction errorDataSchema(\n responses: JsonObject | undefined,\n status: number,\n code: string,\n): Schema | undefined {\n const resp = asObject(responses?.[String(status)]);\n const jsonCt = asObject(asObject(resp?.content)?.['application/json']);\n const schema = asObject(jsonCt?.schema);\n if (!schema) return undefined;\n\n const variants = schema.oneOf;\n if (Array.isArray(variants)) {\n for (const v of variants) {\n const vm = asObject(v);\n if (!vm) continue;\n const errProp = asObject(asObject(vm.properties)?.error);\n if (errProp && asString(errProp.const) === code) {\n return extractDataProperty(vm);\n }\n }\n return undefined;\n }\n return extractDataProperty(schema);\n}\n\nfunction extractDataProperty(schema: JsonObject): Schema | undefined {\n const dm = asObject(asObject(schema.properties)?.data);\n if (!dm) return undefined;\n return parseSchema(dm);\n}\n\nfunction requestSchema(op: JsonObject): Schema | undefined {\n const body = asObject(op.requestBody);\n if (!body) return undefined;\n return schemaFromContent(body.content);\n}\n\n// parametersSchemaIn collects the operation's `parameters[in:<where>]` entries\n// into a synthetic object Schema (one property per parameter), name-sorted for\n// deterministic output. Returns undefined when the op declares no parameter in\n// that location; path params are threaded separately (pathParamNames).\nfunction parametersSchemaIn(op: JsonObject, where: 'header' | 'query'): Schema | undefined {\n const paramsRaw = op.parameters;\n if (!Array.isArray(paramsRaw) || paramsRaw.length === 0) return undefined;\n const props: Prop[] = [];\n for (const p of paramsRaw) {\n const pm = asObject(p);\n if (!pm) continue;\n if (asString(pm.in) !== where) continue;\n const name = asString(pm.name);\n if (name === '') continue;\n const required = pm.required === true;\n const sm = asObject(pm.schema);\n const ps = sm ? parseSchema(sm) : emptySchema('string');\n props.push({ name, schema: ps, required });\n }\n if (props.length === 0) return undefined;\n props.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n return { ...emptySchema('object'), props };\n}\n\n// pathParamNames extracts the `{name}` template segments from an OpenAPI path,\n// in left-to-right path order. Empty `{}` is ignored.\nexport function pathParamNames(path: string): string[] {\n const out: string[] = [];\n let rest = path;\n for (;;) {\n const open = rest.indexOf('{');\n if (open < 0) break;\n const close = rest.indexOf('}', open);\n if (close < 0) break;\n const name = rest.slice(open + 1, close);\n if (name !== '') out.push(name);\n rest = rest.slice(close + 1);\n }\n return out;\n}\n\nfunction responseSchema(op: JsonObject): Schema | undefined {\n const responses = asObject(op.responses);\n if (!responses) return undefined;\n // Prefer 200, then 201, then any other 2xx (sorted).\n const others: string[] = [];\n for (const code of Object.keys(responses)) {\n if (code.startsWith('2') && code !== '200' && code !== '201') others.push(code);\n }\n others.sort();\n for (const code of ['200', '201', ...others]) {\n const resp = asObject(responses[code]);\n if (!resp) continue;\n const s = schemaFromContent(resp.content);\n if (s) return s;\n }\n return undefined;\n}\n\nfunction schemaFromContent(content: unknown): Schema | undefined {\n const jsonCt = asObject(asObject(content)?.['application/json']);\n const schema = asObject(jsonCt?.schema);\n if (!schema) return undefined;\n // Skip $ref'd shared components (error envelope etc.).\n if ('$ref' in schema) return undefined;\n return parseSchema(schema);\n}\n\nfunction emptySchema(kind: SchemaKind): Schema {\n return { kind, nullable: false, props: [], enumVals: [] };\n}\n\nexport function parseSchema(s: JsonObject): Schema {\n let nullable = s.nullable === true;\n\n const enumRaw = s.enum;\n if (Array.isArray(enumRaw)) {\n const cases: string[] = [];\n let allStrings = true;\n for (const v of enumRaw) {\n if (typeof v === 'string') {\n cases.push(v);\n } else {\n allStrings = false;\n break;\n }\n }\n if (allStrings && cases.length > 0) {\n return { ...emptySchema('enum'), nullable, enumVals: cases };\n }\n }\n\n // Draft 7 / OpenAPI 3.1 allow `type` as an array — `[\"string\",\"null\"]` is\n // what `zod-to-json-schema` emits for `z.string().nullable()`. Lower it to\n // the single non-null type + nullable=true.\n let typ = asString(s.type);\n if (typ === '' && Array.isArray(s.type)) {\n for (const v of s.type) {\n if (typeof v !== 'string') continue;\n if (v === 'null') {\n nullable = true;\n } else if (typ === '') {\n typ = v;\n }\n }\n }\n switch (typ) {\n case 'string':\n case 'number':\n case 'integer':\n case 'boolean':\n return { ...emptySchema(typ), nullable };\n case 'array': {\n const items = asObject(s.items);\n const elem = items ? parseSchema(items) : emptySchema('any');\n return { ...emptySchema('array'), nullable, elem };\n }\n case 'object':\n return parseObject(s, nullable);\n default:\n if ('properties' in s) return parseObject(s, nullable);\n return { ...emptySchema('any'), nullable };\n }\n}\n\nfunction parseObject(s: JsonObject, nullable: boolean): Schema {\n const propsRaw = asObject(s.properties) ?? {};\n const requiredSet = new Set<string>();\n if (Array.isArray(s.required)) {\n for (const r of s.required) {\n if (typeof r === 'string') requiredSet.add(r);\n }\n }\n const names = Object.keys(propsRaw).sort();\n const props: Prop[] = [];\n for (const name of names) {\n const pm = asObject(propsRaw[name]);\n const ps = pm ? parseSchema(pm) : emptySchema('any');\n props.push({ name, schema: ps, required: requiredSet.has(name) });\n }\n return { ...emptySchema('object'), nullable, props };\n}\n"],"mappings":"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","names":["process","process"]}
1
+ {"version":3,"sources":["../../src/gen/cli.ts","../../src/gen/generate.ts","../../src/gen/emitter.ts","../../src/gen/parser.ts"],"sourcesContent":["#!/usr/bin/env node\n// palbe-gen — SDK-owned typed-client codegen for @palbase/web.\n// Reads app-bound artifacts written by `palbase web link`, or fetches the spec\n// from an origin passed with --url, and writes the typed palbe.gen.ts module.\nimport process from 'node:process';\nimport { main } from './generate.js';\n\nmain(process.argv.slice(2)).then(\n (code) => process.exit(code),\n (err) => {\n process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n },\n);\n","// palbe-gen command logic: read the committed Palbase/ spec (or fetch it from\n// the origin passed with --url), run the parser+emitter, and write palbe.gen.ts.\n// Ports the CLI's Go semantics (internal/backend: pullTSTypes zero-op guard,\n// --soft policy, tswatch.go watch loop).\n\nimport { createHash } from 'node:crypto';\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport process from 'node:process';\nimport { parseArgs } from 'node:util';\nimport { environmentRefFromPublishableApiKey } from '../api-key.js';\nimport { emitTypeScript, type GeneratedConfig, type OAuthConfig } from './emitter.js';\nimport { type Op, parseOpenAPI, readSpecDeploy } from './parser.js';\n\nexport type Writer = (line: string) => void;\n\nconst USAGE = `Usage: palbe-gen [--dir Palbase] [--out palbe.gen.ts] [--url <specOrigin>] [--soft] [--watch]\n\nGenerate the typed palbe.gen.ts web client for the @palbase/web SDK.\n\n --dir <dir> Directory holding the committed openapi.json and required\n palbase-config.json written by \\`palbase web link\\`\n (default: Palbase)\n --out <file> Output file (default: palbe.gen.ts)\n --url <origin> Fetch the spec from <origin>/openapi.json instead of --dir\n (e.g. a deployed Environment's origin)\n --soft Never fail: print a warning and exit 0 on any error\n (for predev/prebuild hooks)\n --watch Poll the --url origin every second and regenerate whenever\n the spec changes. Without --url, polls the linked\n checkout's own Environment (the base_url committed to\n {dir}/palbase-config.json by \\`palbase web link\\`)\n -h, --help Show this help`;\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\nexport class HttpStatusError extends Error {\n readonly status: number;\n constructor(status: number, url: string) {\n super(`GET ${url}: HTTP ${status}`);\n this.status = status;\n }\n}\n\nexport async function fetchSpec(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url, { signal: AbortSignal.timeout(3000) });\n } catch (e) {\n throw new Error(`GET ${url}: ${errMsg(e)}`);\n }\n if (!res.ok) throw new HttpStatusError(res.status, url);\n return res.text();\n}\n\n// readWebConfig reads the required canonical app-bound\n// {dir}/palbase-config.json shape.\nexport function readWebConfig(dir: string): GeneratedConfig {\n const path = join(dir, 'palbase-config.json');\n let text: string;\n try {\n text = readFileSync(path, 'utf8');\n } catch {\n throw new Error(`${path} is required in dir mode — run \\`palbase web link\\``);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n throw new Error(`${path} is not valid JSON: ${errMsg(e)}`);\n }\n const obj = (raw ?? {}) as Record<string, unknown>;\n const str = (v: unknown) => (typeof v === 'string' ? v : '');\n const required = (field: 'app_id' | 'base_url' | 'api_key'): string => {\n const value = str(obj[field]);\n if (value.trim() === '') {\n throw new Error(`${path} is missing nonempty required field ${field}`);\n }\n return value.trim();\n };\n const cfg: GeneratedConfig = {\n url: required('base_url'),\n apiKey: required('api_key'),\n appId: required('app_id'),\n };\n // The project identity comes from the key and from nowhere else. This file\n // used to require an `environment_ref` field beside it and refuse when the two\n // disagreed — and on 2026-08-16 they did: `palbase link` wrote one value while\n // minting a key carrying another, so linking a web app to a project produced a\n // config this generator would not read. A copy that must equal its original is\n // not a second fact, it is a second chance to be wrong.\n const projectRef = environmentRefFromPublishableApiKey(cfg.apiKey);\n if (projectRef === '') {\n throw new Error(`${path} api_key does not contain a valid publishable project identity`);\n }\n let configURL: URL;\n try {\n configURL = new URL(cfg.url);\n } catch {\n throw new Error(`${path} base_url must be a valid HTTPS URL`);\n }\n if (configURL.protocol !== 'https:') {\n throw new Error(`${path} base_url must be a valid HTTPS URL`);\n }\n // THE HOST IS NOT DERIVABLE FROM THE KEY, and a check that pretends otherwise\n // refuses every correct config.\n //\n // This used to require the first label of a *.palbase.studio host to equal the\n // ref inside the key, on the premise that a publishable key names its own\n // address. That premise was v1's. On v2 a stack's identity is a COMPILE-TIME\n // constant — every tenant's key reads `pb_project_…` (v2-cloud\n // tenant-stack/main.go: bootStackRef, and palsvc panics at boot if a key\n // disagrees with it) — while the address is the tenant's own ref. So the two\n // never match, for any project, and the rule turned `palbe-gen` into something\n // that could not run against v2 at all.\n //\n // Nothing replaces it: there is no fact in the key to check the host against.\n // What DOES catch a config pointed at the wrong project is the generator's\n // next step — it fetches that host's contract with that key, and a mismatch\n // answers 401.\n const oauthRaw = obj.oauth as Record<string, unknown> | undefined;\n if (oauthRaw && typeof oauthRaw === 'object') {\n const oauth: OAuthConfig = {};\n const apple = oauthRaw.apple as Record<string, unknown> | undefined;\n if (apple && typeof apple === 'object') {\n oauth.apple = { enabled: apple.enabled === true };\n }\n const google = oauthRaw.google as Record<string, unknown> | undefined;\n if (google && typeof google === 'object') {\n oauth.google = {\n enabled: google.enabled === true,\n clientId: str(google.client_id),\n redirectUri: str(google.redirect_uri),\n };\n }\n cfg.oauth = oauth;\n }\n return cfg;\n}\n\nfunction emitAndWrite(ops: Op[], cfg: GeneratedConfig, outFile: string): void {\n const dir = dirname(outFile);\n if (dir !== '.' && dir !== '') {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(outFile, emitTypeScript(ops, cfg));\n}\n\nfunction existingNonEmpty(outFile: string): boolean {\n try {\n return readFileSync(outFile).length > 0;\n } catch {\n return false;\n }\n}\n\n// writeGenerated applies the zero-op overwrite guard, then emits. A live spec\n// with 0 operations almost always means the backend's controller metadata\n// extraction broke (the \"zero endpoints collected\" failure class), not that\n// the app has no endpoints. Never clobber a previously good palbe.gen.ts with\n// an empty client; warn and exit 0 so a predev hook doesn't fail the build.\n// With nothing to protect, write the (empty) module anyway — a fresh project\n// still gets a compilable file — but warn loudly.\nexport function writeGenerated(\n ops: Op[],\n cfg: GeneratedConfig,\n outFile: string,\n out: Writer,\n specDeploy = '',\n): void {\n if (ops.length === 0) {\n if (existingNonEmpty(outFile)) {\n out(\n `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n );\n return;\n }\n out(\n `warning: live spec has 0 operations — ${outFile} registers no calls (fix your controllers and rerun)`,\n );\n }\n emitAndWrite(ops, cfg, outFile);\n out(`✓ wrote ${outFile} (${ops.length} operations${provenance(specDeploy)})`);\n}\n\n// provenance renders the deploy clause the success lines carry. Empty for a spec\n// with no identity — an artifact built before the stamp existed. Saying nothing\n// there is deliberate: a fabricated or guessed identity would read as verified.\nfunction provenance(specDeploy: string): string {\n return specDeploy === '' ? '' : `, deploy ${specDeploy}`;\n}\n\n// generateOnce is the single-shot generation path.\n// - default: read {dir}/openapi.json + required {dir}/palbase-config.json\n// - --url: fetch <origin>/openapi.json while retaining the canonical linked\n// Environment identity; only the runtime URL points at the origin.\nexport async function generateOnce(\n dir: string,\n outFile: string,\n url: string | undefined,\n out: Writer,\n): Promise<void> {\n let specText: string;\n let cfg: GeneratedConfig;\n if (url !== undefined) {\n const origin = url.replace(/\\/+$/, '');\n specText = await fetchSpec(`${origin}/openapi.json`);\n cfg = { ...readWebConfig(dir), url: origin };\n } else {\n cfg = readWebConfig(dir);\n const specPath = join(dir, 'openapi.json');\n try {\n specText = readFileSync(specPath, 'utf8');\n } catch {\n throw new Error(\n `no OpenAPI spec at ${specPath} — run \\`palbase web spec\\` first, or pass --url to fetch it from an origin`,\n );\n }\n }\n writeGenerated(parseOpenAPI(specText), cfg, outFile, out, readSpecDeploy(specText));\n}\n\n// --- Watch mode (tswatch.go port) --------------------------------------------\n\nexport type FetchFn = (url: string) => Promise<string>;\n\n// watchLoop polls specURL on each tick:\n// - Fetch fails: print a down message ONCE per transition — a waiting line\n// when nothing is listening, or the HTTP-error variant when the origin\n// answered with an error status.\n// - Fetch succeeds: SHA-256 the body. Same hash as the last EMIT → skip.\n// Same hash as the last WARNED-bad body → stay silent. Otherwise parse +\n// emit + write; a bad body (unparseable, or 0 ops with an existing file to\n// protect) warns once and records its hash. A successful emit resets the\n// bad-hash state.\n// Hash state starts EMPTY intentionally: the first successful fetch always\n// regenerates. Returns (printing \"watch stopped\") when the tick source ends.\nexport async function watchLoop(\n specURL: string,\n cfg: GeneratedConfig,\n outFile: string,\n fetchFn: FetchFn,\n ticks: AsyncIterable<void>,\n out: Writer,\n): Promise<void> {\n let lastEmittedHash = ''; // '' = nothing emitted yet\n let lastBadHash = ''; // '' = no standing bad-body warning\n let lastDownMsg = ''; // last printed down message; '' = the origin was up\n\n for await (const _ of ticks) {\n let specText: string;\n try {\n specText = await fetchFn(specURL);\n } catch (err) {\n let m = `waiting for ${specURL}…`;\n if (err instanceof HttpStatusError) {\n m = `${specURL} responded with an error (HTTP ${err.status})`;\n }\n if (m !== lastDownMsg) {\n out(m);\n lastDownMsg = m;\n }\n continue;\n }\n\n // The origin is (back) up.\n lastDownMsg = '';\n\n const h = createHash('sha256').update(specText).digest('hex');\n if (lastEmittedHash !== '' && h === lastEmittedHash) continue; // no change\n if (lastBadHash !== '' && h === lastBadHash) continue; // already warned\n\n let ops: Op[];\n try {\n ops = parseOpenAPI(specText);\n } catch (err) {\n out(`warning: failed to parse spec: ${errMsg(err)}`);\n lastBadHash = h;\n continue;\n }\n if (ops.length === 0 && existingNonEmpty(outFile)) {\n out(\n `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n );\n lastBadHash = h;\n continue;\n }\n\n try {\n emitAndWrite(ops, cfg, outFile);\n } catch (err) {\n // Environmental write failure (disk) — not spec-dependent, so do not\n // record a bad hash; the next tick retries.\n out(`warning: codegen error: ${errMsg(err)}`);\n continue;\n }\n\n lastEmittedHash = h;\n lastBadHash = ''; // a good emit resets the warn-dedup state\n out(`regenerated ${outFile} (${ops.length} operations${provenance(readSpecDeploy(specText))})`);\n }\n out('watch stopped');\n}\n\nfunction delay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) {\n resolve();\n return;\n }\n const onAbort = () => {\n clearTimeout(t);\n resolve();\n };\n const t = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nasync function* intervalTicks(ms: number, signal: AbortSignal): AsyncGenerator<void> {\n while (!signal.aborted) {\n await delay(ms, signal);\n if (signal.aborted) return;\n yield;\n }\n}\n\nasync function runWatch(\n dir: string,\n outFile: string,\n url: string | undefined,\n out: Writer,\n): Promise<void> {\n // readWebConfig throws a clear, actionable error when {dir} was never\n // linked — that's the same \"run `palbase web link`\" failure every other\n // dir-mode path already has, so an unlinked --watch fails loudly here, not\n // by silently retrying an address nothing answers.\n const linked = readWebConfig(dir);\n\n // No --url: watch the linked checkout's OWN Environment. `palbase serve`\n // (retired) used to expose the spec on http://localhost:4003; nothing\n // replaces that local server today, so defaulting to it just polled a dead\n // address forever with a misleading \"waiting for...\" message. base_url —\n // already read and validated above — is a real, currently-serving origin.\n const origin = (url ?? linked.url).replace(/\\/+$/, '');\n const specURL = `${origin}/openapi.json`;\n\n // The spec comes from the resolved origin, while identity remains bound to\n // the linked Environment. Initial fetch failure is soft because the loop\n // exists to wait for that origin to answer.\n const cfg: GeneratedConfig = { ...linked, url: origin };\n try {\n const initial = await fetchSpec(specURL);\n writeGenerated(parseOpenAPI(initial), cfg, outFile, out, readSpecDeploy(initial));\n } catch (err) {\n out(`warning: codegen skipped (${errMsg(err)})`);\n }\n\n // A real Ctrl-C aborts the tick source → clean \"watch stopped\" exit 0\n // instead of a hard kill that could truncate palbe.gen.ts mid-write.\n const ctrl = new AbortController();\n const stop = () => ctrl.abort();\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n try {\n await watchLoop(specURL, cfg, outFile, fetchSpec, intervalTicks(1000, ctrl.signal), out);\n } finally {\n process.removeListener('SIGINT', stop);\n process.removeListener('SIGTERM', stop);\n }\n}\n\n// --- Entry -------------------------------------------------------------------\n\nconst stdoutWriter: Writer = (line) => {\n process.stdout.write(`${line}\\n`);\n};\nconst stderrWriter: Writer = (line) => {\n process.stderr.write(`${line}\\n`);\n};\n\nfunction parseCliArgs(argv: string[]) {\n return parseArgs({\n args: argv,\n options: {\n dir: { type: 'string', default: 'Palbase' },\n out: { type: 'string', default: 'palbe.gen.ts' },\n url: { type: 'string' },\n soft: { type: 'boolean', default: false },\n watch: { type: 'boolean', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n }).values;\n}\n\nexport async function main(\n argv: string[],\n out: Writer = stdoutWriter,\n errOut: Writer = stderrWriter,\n): Promise<number> {\n let values: ReturnType<typeof parseCliArgs>;\n try {\n values = parseCliArgs(argv);\n } catch (e) {\n errOut(`error: ${errMsg(e)}`);\n errOut(USAGE);\n return 1;\n }\n if (values.help) {\n out(USAGE);\n return 0;\n }\n try {\n if (values.watch) {\n await runWatch(values.dir, values.out, values.url, out);\n } else {\n await generateOnce(values.dir, values.out, values.url, out);\n }\n return 0;\n } catch (err) {\n // --soft turns ANY failure into a warning + exit 0, so a predev/prebuild\n // hook never blocks a machine without the spec or a running serve.\n if (values.soft) {\n out(`warning: codegen skipped (${errMsg(err)})`);\n return 0;\n }\n errOut(`error: ${errMsg(err)}`);\n return 1;\n }\n}\n","// palbe.gen.ts emitter — TypeScript port of the CLI's Go endpoint emitter.\n// The checked-in golden locks the complete app-bound runtime config and endpoint\n// output shape.\n\nimport type { ErrorDef, Op, Schema } from './parser.js';\n\n// GeneratedConfig carries the runtime config values the generated palbe.gen.ts\n// writes into __configure() (the web SDK seam — web embeds config in the\n// generated module, unlike iOS which reads the per-env plist).\nexport interface GeneratedConfig {\n url: string;\n apiKey: string;\n appId: string;\n oauth?: OAuthConfig;\n}\n\nexport interface OAuthConfig {\n apple?: { enabled: boolean };\n google?: { enabled: boolean; clientId: string; redirectUri?: string };\n}\n\n// --- Naming -----------------------------------------------------------------\n\nexport function opSegments(opId: string): string[] {\n return opId.split('.').filter((p) => p !== '');\n}\n\nfunction typeNameOf(s: string): string {\n return sanitize(s, true);\n}\n\n// typePrefix builds the PascalCase concatenation of all op-id segments, used\n// as the BASE for top-level <Prefix>Request / <Prefix>Response / <Prefix>Error\n// type names. Example: \"rooms.create\" → \"RoomsCreate\".\nfunction typePrefix(opId: string): string {\n return opSegments(opId).map(typeNameOf).join('');\n}\n\nfunction sanitize(s: string, firstUpper: boolean): string {\n const parts: string[] = [];\n let cur = '';\n for (const ch of s) {\n if (/^[A-Za-z0-9]$/.test(ch)) {\n cur += ch;\n } else if (cur.length > 0) {\n parts.push(cur);\n cur = '';\n }\n }\n if (cur.length > 0) parts.push(cur);\n if (parts.length === 0) return firstUpper ? 'Op' : 'op';\n let out = '';\n parts.forEach((p, i) => {\n out +=\n i === 0 && !firstUpper\n ? p.charAt(0).toLowerCase() + p.slice(1)\n : p.charAt(0).toUpperCase() + p.slice(1);\n });\n if (out.charAt(0) >= '0' && out.charAt(0) <= '9') out = `_${out}`;\n return out;\n}\n\n// --- Emit -------------------------------------------------------------------\n\n// emitTypeScript turns parsed operations into a palbe.gen.ts module.\n// The file structure:\n// header → imports → __configure → types section → typed-errors section →\n// namespaces section (skip comments + __registerNamespaces) → declare module\nexport function emitTypeScript(ops: Op[], cfg: GeneratedConfig): string {\n // Filter reserved top-level namespaces; collect skip comments.\n // Single-segment operationIds (the live wire shape — verb-prefixed ids like\n // `getHello`) pass the same filter and later register as ROOT-LEVEL\n // descriptor keys. Skip-comment dedup is case-insensitive (auth/Auth are the\n // same reserved surface); the first-seen casing is printed.\n const usable: Op[] = [];\n const skippedNS: string[] = [];\n const seenSkip = new Set<string>();\n for (const op of ops) {\n const [ns] = opSegments(op.operationId);\n if (ns === undefined) continue;\n if (tsReservedTopLevel(ns)) {\n const key = ns.toLowerCase();\n if (!seenSkip.has(key)) {\n seenSkip.add(key);\n skippedNS.push(ns);\n }\n continue;\n }\n usable.push(op);\n }\n skippedNS.sort();\n\n // Per-operation gates: nested-reserved / body+query / non-primitive-query /\n // kind-mismatch filtering happens BEFORE type emission, so skipped ops\n // neither emit dead types nor squat type-name prefixes against later ops.\n const [candidates, opSkips] = filterTSOps(usable);\n\n // Build all content sections FIRST (in-memory), so the import lines can be\n // derived from what is ACTUALLY emitted — an error-bearing op dropped by a\n // gate must not leave a stray `BackendError` import behind.\n const [typesOut, collisionSkips, typeCollisionOps] = emitTSTypes(candidates);\n\n // Type-collision ops have no usable types — they must not be callable-typed.\n const registerable = candidates.filter((op) => !typeCollisionOps.has(op.operationId));\n\n const [errorsOut, classCount] = emitTSTypedErrors(registerable);\n\n // --- Assemble ---\n let b = '';\n\n // Header.\n b += '// AUTO-GENERATED by `palbe-gen` — DO NOT EDIT.\\n';\n b += '// Regenerate: palbe-gen (or automatically via the predev/prebuild script)\\n';\n\n // Imports. `BackendError` is referenced only by emitted error classes;\n // `CallOptions` only by augmentation method signatures. When neither is\n // used, the whole `import type ...` line is omitted — the runtime import\n // from '@palbase/web/internal' always stays.\n const typeImports: string[] = [];\n if (classCount > 0) typeImports.push('BackendError');\n if (registerable.length > 0) typeImports.push('CallOptions');\n if (typeImports.length > 0) {\n b += `import type { ${typeImports.join(', ')} } from '@palbase/web';\\n`;\n }\n b += \"import { __configure, __registerNamespaces } from '@palbase/web/internal';\\n\\n\";\n\n b += emitTSConfigure(cfg);\n b += '\\n';\n\n // Types + typed errors (either may be empty).\n b += typesOut;\n b += errorsOut;\n\n // Namespaces section.\n b += '// ── Namespaces ─────────────────────────────────────────────────────\\n\\n';\n // Skip comments: reserved-namespace, then per-op gates, then type collisions.\n for (const ns of skippedNS) {\n b += `// codegen: skipped reserved namespace \"${ns}\"\\n`;\n }\n for (const l of opSkips) {\n b += `${l}\\n`;\n }\n for (const c of collisionSkips) {\n b += `${c}\\n`;\n }\n b += emitTSRegistration(registerable);\n\n // declare module augmentation — omitted entirely when nothing registers.\n if (registerable.length > 0) {\n b += '\\n';\n b += emitTSAugmentation(registerable);\n }\n\n return b;\n}\n\n// emitTSConfigure renders the __configure({…}) call.\nfunction emitTSConfigure(cfg: GeneratedConfig): string {\n let b = '__configure({\\n';\n b += ` url: ${tsStringLit(cfg.url)},\\n`;\n b += ` apiKey: ${tsStringLit(cfg.apiKey)},\\n`;\n b += ` appId: ${tsStringLit(cfg.appId)},\\n`;\n const oauth = renderTSOAuth(cfg.oauth);\n if (oauth !== '') {\n b += ' oauth: {\\n';\n b += oauth;\n b += ' },\\n';\n }\n b += '});\\n';\n return b;\n}\n\n// renderTSOAuth returns the indented inner lines of the oauth block, or '' to\n// omit the key entirely. Google is included only when enabled and clientId is\n// non-empty. Apple is included only when enabled.\nfunction renderTSOAuth(o: OAuthConfig | undefined): string {\n if (!o) return '';\n let b = '';\n if (o.apple?.enabled) {\n b += ' apple: { enabled: true },\\n';\n }\n if (o.google?.enabled && o.google.clientId !== '') {\n b += ` google: { enabled: true, clientId: ${tsStringLit(o.google.clientId)} },\\n`;\n }\n return b;\n}\n\n// --- Per-operation gates ------------------------------------------------\n\n// filterTSOps applies the per-op gates that decide whether an operation can\n// register at all: reserved nested segments, body+query conflict, query params\n// the runtime's serializeQuery cannot handle, and namespace/method kind\n// mismatches. Returns the surviving ops (input order preserved) plus loud\n// skip-comment lines.\nfunction filterTSOps(ops: Op[]): [Op[], string[]] {\n const out: Op[] = [];\n const skips: string[] = [];\n const root = new TSNode(); // shape-only trie for kind-mismatch detection\n\n for (const op of ops) {\n const segs = opSegments(op.operationId);\n const lastSeg = segs[segs.length - 1];\n if (lastSeg === undefined) continue;\n // Nested reserved check covers EVERY non-first segment — both the\n // intermediate namespace segments and the final method segment.\n let skip = false;\n for (const seg of segs.slice(1)) {\n if (tsReservedNested(seg)) {\n skips.push(`// codegen: skipped operation \"${op.operationId}\" (reserved segment \"${seg}\")`);\n skip = true;\n break;\n }\n }\n if (skip) continue;\n // A descriptor's `input` is single-valued: body (default) or query.\n if (op.input && op.query) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (both body and query declared — unsupported)`,\n );\n continue;\n }\n // Non-primitive query params would make the runtime's serializeQuery throw.\n if (op.query) {\n const bad = firstNonPrimitiveQueryProp(op.query);\n if (bad !== undefined) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (non-primitive query parameter \"${bad}\")`,\n );\n continue;\n }\n }\n // Kind-mismatch: a key claimed as both namespace and method.\n let node: TSNode | undefined = root;\n for (const seg of segs.slice(0, -1)) {\n node = node.childNode(seg);\n if (!node) break;\n }\n if (!node?.addMethod(lastSeg, op)) {\n skips.push(\n `// codegen: skipped operation \"${op.operationId}\" (key collides with existing namespace/method)`,\n );\n continue;\n }\n out.push(op);\n }\n return [out, skips];\n}\n\n// firstNonPrimitiveQueryProp returns the name of the first query property whose\n// schema cannot be serialized into a query string, or undefined when all are\n// primitive.\nfunction firstNonPrimitiveQueryProp(q: Schema): string | undefined {\n for (const p of q.props) {\n switch (p.schema.kind) {\n case 'string':\n case 'number':\n case 'integer':\n case 'boolean':\n case 'enum':\n break; // primitive — serializeQuery handles it\n default:\n return p.name;\n }\n }\n return undefined;\n}\n\n// --- Types section ----------------------------------------------------------\n\n// emitTSTypes emits the `// ── Types ──` section: one named interface or type\n// alias per op schema (request, response, query, error-data). Returns the\n// rendered section (empty when no ops produce types), collision skip comment\n// lines, and the set of colliding op ids.\nfunction emitTSTypes(ops: Op[]): [string, string[], Set<string>] {\n const collisionOps = new Set<string>();\n // seenPrefix maps PascalCase typePrefix → first operationId that claimed it.\n const seenPrefix = new Map<string, string>();\n const collisionSkips: string[] = [];\n const lines: string[] = [];\n\n for (const op of ops) {\n const pfx = typePrefix(op.operationId);\n const first = seenPrefix.get(pfx);\n if (first !== undefined) {\n collisionSkips.push(`// codegen: skipped type \"${pfx}\" (collides with operation \"${first}\")`);\n collisionOps.add(op.operationId);\n continue;\n }\n seenPrefix.set(pfx, op.operationId);\n\n // Request type (input body).\n if (op.input) {\n lines.push(...tsNamedTypeLines(`${pfx}Request`, op.input));\n }\n // Query type (emitted before Response, per golden contract order).\n if (op.query) {\n lines.push(...tsNamedTypeLines(`${pfx}Query`, op.query));\n }\n // Response type (output).\n if (op.output) {\n lines.push(...tsResponseTypeLines(pfx, op.output));\n }\n // Error data interfaces (after response) — only for errors that actually\n // lift; filtered errors emit no class, so a Data interface would orphan.\n const [liftable] = tsLiftableErrors(op);\n for (const e of liftable) {\n if (!e.data) continue;\n const dataName = `${pfx}${typeNameOf(e.name)}Data`;\n lines.push(`/** ${e.code} (${e.status}): ${e.description} */`);\n lines.push(...tsNamedTypeLines(dataName, e.data));\n }\n }\n\n if (lines.length === 0) {\n return ['', collisionSkips, collisionOps];\n }\n\n let b = '// ── Types ──────────────────────────────────────────────────────────\\n\\n';\n for (const l of lines) {\n b += `${l}\\n`;\n }\n // Note: each type block ends with an empty-string entry that renders as a\n // blank separator line. No extra trailing newline needed here.\n return [b, collisionSkips, collisionOps];\n}\n\n// tsNamedTypeLines renders a named top-level type declaration: `export\n// interface` for object schemas, `export type` alias otherwise.\nfunction tsNamedTypeLines(name: string, s: Schema): string[] {\n if (s.kind === 'object') {\n return tsInterfaceLines(name, s);\n }\n return [`export type ${name} = ${tsTypeOf(s)};`, ''];\n}\n\n// tsResponseTypeLines handles the special case where a response is an array of\n// objects: emits `<Prefix>ResponseItem` interface + `<Prefix>Response` alias.\nfunction tsResponseTypeLines(pfx: string, s: Schema): string[] {\n if (s.kind === 'array' && s.elem && s.elem.kind === 'object') {\n return [\n ...tsInterfaceLines(`${pfx}ResponseItem`, s.elem),\n `export type ${pfx}Response = ${pfx}ResponseItem[];`,\n '',\n ];\n }\n return tsNamedTypeLines(`${pfx}Response`, s);\n}\n\n// tsInterfaceLines renders `export interface Name { ... }` with sorted props.\n// A property named __proto__ is skipped loudly: writing it in a JS object\n// literal sets the prototype, and JSON.stringify drops it — wire-dead anyway.\nfunction tsInterfaceLines(name: string, s: Schema): string[] {\n const lines: string[] = [`export interface ${name} {`];\n for (const p of s.props) {\n if (p.name === '__proto__') {\n lines.push(' // codegen: skipped property \"__proto__\"');\n continue;\n }\n const opt = p.required ? '' : '?';\n lines.push(` ${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)};`);\n }\n lines.push('}', '');\n return lines;\n}\n\n// tsTypeOf converts a Schema to its TypeScript type string. For NESTED object\n// schemas (appearing as property values) it emits an inline literal\n// `{ k: T; ... }` rather than a named interface.\nfunction tsTypeOf(s: Schema): string {\n switch (s.kind) {\n case 'string':\n return s.nullable ? 'string | null' : 'string';\n case 'number':\n case 'integer':\n return s.nullable ? 'number | null' : 'number';\n case 'boolean':\n return s.nullable ? 'boolean | null' : 'boolean';\n case 'enum': {\n const union = s.enumVals.map(tsStringLit).join(' | ');\n return s.nullable ? `(${union}) | null` : union;\n }\n case 'array': {\n if (!s.elem) {\n return s.nullable ? 'unknown[] | null' : 'unknown[]';\n }\n let elem = tsTypeOf(s.elem);\n // Parenthesise union element types (enum or nullable) so `T[]` parses.\n if (elem.includes(' | ') || elem.startsWith('(')) {\n elem = `(${elem})`;\n }\n const arr = `${elem}[]`;\n return s.nullable ? `${arr} | null` : arr;\n }\n case 'object': {\n const inline = tsInlineObject(s);\n return s.nullable ? `${inline} | null` : inline;\n }\n default: // 'any' or unknown\n return s.nullable ? 'unknown | null' : 'unknown';\n }\n}\n\n// tsInlineObject renders `{ k: T; k2?: U }` for a nested object schema.\n// __proto__ props are dropped here too (no comment slot inside a single-line\n// literal).\nfunction tsInlineObject(s: Schema): string {\n const parts: string[] = [];\n for (const p of s.props) {\n if (p.name === '__proto__') continue;\n const opt = p.required ? '' : '?';\n parts.push(`${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`);\n }\n if (parts.length === 0) return 'Record<string, unknown>';\n return `{ ${parts.join('; ')} }`;\n}\n\n// tsInfraReservedCodes is the set of error codes reserved by the palbe runtime\n// infrastructure. Emitting a class for these would shadow or collide with\n// palbe's own error-handling seams.\nconst tsInfraReservedCodes = new Set([\n 'not_configured',\n 'network_error',\n 'decode_error',\n 'validation_error',\n 'unauthorized',\n 'rate_limited',\n 'invalid_endpoint_name',\n 'unsupported_get_input',\n 'missing_path_param',\n 'unexpected_argument',\n 'invalid_query_value',\n 'reserved_namespace',\n 'invalid_namespace_tree',\n 'aborted',\n 'http_error',\n]);\n\n// tsLiftableErrors applies ALL per-op error filters in one place so the\n// typed-errors section, the Data-interface emission, and the descriptor's\n// errors map always agree on the surviving set:\n// - stable sort by wire code (ties keep parse order)\n// - `__proto__` codes dropped (object-literal prototype foot-gun)\n// - reserved infra codes dropped\n// - duplicate wire codes: first-wins\n// - duplicate CLASS names (roomLocked + room_locked both PascalCase to\n// RoomLocked → TS2300): first-wins\n// Returns the surviving defs plus the loud skip-comment lines, rendered at the\n// DESCRIPTOR site in the registration block.\nfunction tsLiftableErrors(op: Op): [ErrorDef[], string[]] {\n if (op.errors.length === 0) return [[], []];\n const sorted = [...op.errors].sort((a, b) => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));\n const seenCode = new Set<string>();\n const seenClass = new Map<string, string>(); // PascalCase class-name stem → first error name\n const liftable: ErrorDef[] = [];\n const comments: string[] = [];\n for (const e of sorted) {\n if (e.code === '__proto__') {\n comments.push('// codegen: skipped error code \"__proto__\"');\n continue;\n }\n if (tsInfraReservedCodes.has(e.code)) {\n comments.push(`// codegen: skipped error code \"${e.code}\" (reserved infra code)`);\n continue;\n }\n if (seenCode.has(e.code)) {\n comments.push(`// codegen: skipped duplicate error code \"${e.code}\"`);\n continue;\n }\n const stem = typeNameOf(e.name);\n const first = seenClass.get(stem);\n if (first !== undefined) {\n comments.push(`// codegen: skipped error \"${e.name}\" (class name collides with \"${first}\")`);\n continue;\n }\n seenCode.add(e.code);\n seenClass.set(stem, e.name);\n liftable.push(e);\n }\n return [liftable, comments];\n}\n\n// emitTSTypedErrors emits the `// ── Typed errors ──` section: one exported\n// class per liftable error definition across all registrable ops. Returns the\n// section text plus the emitted class COUNT (the import line includes\n// `BackendError` iff count ≥ 1). Filtered errors are skipped SILENTLY here —\n// their skip comments render at the descriptor site (see tsLiftableErrors).\nfunction emitTSTypedErrors(ops: Op[]): [string, number] {\n let count = 0;\n const lines: string[] = [];\n for (const op of ops) {\n const pfx = typePrefix(op.operationId);\n const [liftable] = tsLiftableErrors(op);\n for (const e of liftable) {\n const className = `${pfx}${typeNameOf(e.name)}Error`;\n const hasData = e.data !== undefined;\n lines.push(`export class ${className} extends Error {`);\n lines.push(` readonly name = '${className}';`);\n lines.push(` readonly code = '${e.code}';`);\n lines.push(` readonly status = ${e.status};`);\n if (hasData) {\n lines.push(` readonly data: ${pfx}${typeNameOf(e.name)}Data;`);\n }\n lines.push(' readonly cause: BackendError;');\n lines.push(' constructor(cause: BackendError) {');\n lines.push(' super(cause.message);');\n lines.push(' this.cause = cause;');\n if (hasData) {\n lines.push(` this.data = cause.data as ${pfx}${typeNameOf(e.name)}Data;`);\n }\n lines.push(' }');\n lines.push('}');\n lines.push('');\n count++;\n }\n }\n\n if (count === 0) return ['', 0];\n\n let b = '// ── Typed errors ───────────────────────────────────────────────────\\n\\n';\n for (const l of lines) {\n b += `${l}\\n`;\n }\n return [b, count];\n}\n\n// --- Registration tree --------------------------------------------------\n\n// TSNode is one level of the __registerNamespaces object literal. Entries keep\n// insertion order (ops arrive sorted by operationId, so rendered keys come out\n// alphabetically), each entry being either a nested namespace (child set) or a\n// method descriptor (op set).\ninterface TSEntry {\n key: string;\n child?: TSNode;\n op?: Op;\n}\n\nclass TSNode {\n entries: TSEntry[] = [];\n index = new Map<string, TSEntry>();\n\n // childNode returns (creating if needed) the nested namespace node for key.\n // Returns undefined if a METHOD entry already occupies the key (kind\n // mismatch).\n childNode(key: string): TSNode | undefined {\n const e = this.index.get(key);\n if (e) return e.child; // undefined when a method claims the key\n const child = new TSNode();\n const entry: TSEntry = { key, child };\n this.entries.push(entry);\n this.index.set(key, entry);\n return child;\n }\n\n // addMethod registers a method at key. Returns false if the key is already\n // occupied (either by another method or by a namespace node).\n addMethod(key: string, op: Op): boolean {\n if (this.index.has(key)) return false;\n const entry: TSEntry = { key, op };\n this.entries.push(entry);\n this.index.set(key, entry);\n return true;\n }\n}\n\n// buildTSTrie arranges PRE-FILTERED ops (filterTSOps survivors, possibly minus\n// type-collision ops) into the namespace trie. Kind mismatches are impossible\n// here — removing ops from a mismatch-free set never creates one.\nfunction buildTSTrie(ops: Op[]): TSNode {\n const root = new TSNode();\n for (const op of ops) {\n const segs = opSegments(op.operationId);\n const lastSeg = segs[segs.length - 1];\n if (lastSeg === undefined) continue;\n let node: TSNode | undefined = root;\n for (const seg of segs.slice(0, -1)) {\n node = node.childNode(seg);\n if (!node) break; // unreachable: pre-filtered by filterTSOps\n }\n if (node) {\n node.addMethod(lastSeg, op);\n }\n }\n return root;\n}\n\n// emitTSRegistration renders the __registerNamespaces({…}) call (no section\n// header or skip comments — those are written by emitTypeScript above). With\n// zero ops the call renders single-line.\nfunction emitTSRegistration(ops: Op[]): string {\n if (ops.length === 0) {\n return '__registerNamespaces({});\\n';\n }\n let b = '__registerNamespaces({\\n';\n b += renderTSNode(buildTSTrie(ops), 2);\n b += '});\\n';\n return b;\n}\n\n// renderTSNode renders one tree level at the given indent, recursing into\n// nested namespaces.\nfunction renderTSNode(node: TSNode, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n let b = '';\n for (const e of node.entries) {\n if (e.child) {\n b += `${ind}${tsPropKey(e.key)}: {\\n`;\n b += renderTSNode(e.child, indentSpaces + 2);\n b += `${ind}},\\n`;\n continue;\n }\n if (e.op) {\n b += renderTSDescriptor(e.op, e.key, indentSpaces);\n }\n }\n return b;\n}\n\n// renderTSDescriptor renders one method descriptor entry at the given indent\n// depth. Single-line when no errors survive filtering; multi-line when an\n// errors map is emitted.\n//\n// Descriptor field rules:\n// - `method` and `path` always present\n// - `pathParams` present when op.pathParams is non-empty\n// - `input: 'none'` when no body and no query\n// - `input: 'query'` when query declared (body+query handled upstream)\n// - no `input` key when a body is declared (body is the default)\n// - `errors` map when liftable errors exist → forces multi-line\nfunction renderTSDescriptor(op: Op, methodSeg: string, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n const key = tsPropKey(methodSeg);\n\n const [liftable, errComments] = tsLiftableErrors(op);\n const hasErrors = liftable.length > 0;\n\n const hasPathParams = op.pathParams.length > 0;\n const hasInput = op.input !== undefined;\n const hasQuery = op.query !== undefined;\n\n // Determine input field: '' = omit (body default).\n let inputVal = '';\n if (!hasInput && !hasQuery) {\n inputVal = 'none';\n } else if (hasQuery) {\n inputVal = 'query';\n }\n\n let b = '';\n if (!hasErrors) {\n // Single-line format: `key: { method: 'X', path: '...', [extras...] },`\n for (const c of errComments) {\n b += `${ind}${c}\\n`;\n }\n const parts = [`method: ${tsStringLit(op.method)}`, `path: ${tsStringLit(op.path)}`];\n if (hasPathParams) {\n parts.push(`pathParams: [${renderTSStringArray(op.pathParams)}]`);\n }\n if (inputVal !== '') {\n parts.push(`input: ${tsStringLit(inputVal)}`);\n }\n b += `${ind}${key}: { ${parts.join(', ')} },\\n`;\n return b;\n }\n\n // Multi-line format.\n const innerInd = ' '.repeat(indentSpaces + 2);\n b += `${ind}${key}: {\\n`;\n b += `${innerInd}method: ${tsStringLit(op.method)},\\n`;\n b += `${innerInd}path: ${tsStringLit(op.path)},\\n`;\n if (hasPathParams) {\n b += `${innerInd}pathParams: [${renderTSStringArray(op.pathParams)}],\\n`;\n }\n if (inputVal !== '') {\n b += `${innerInd}input: ${tsStringLit(inputVal)},\\n`;\n }\n for (const c of errComments) {\n b += `${innerInd}${c}\\n`;\n }\n b += `${innerInd}errors: { `;\n liftable.forEach((e, i) => {\n if (i > 0) b += ', ';\n const className = `${typePrefix(op.operationId)}${typeNameOf(e.name)}Error`;\n b += `${tsPropKey(e.code)}: (e) => new ${className}(e)`;\n });\n b += ' },\\n';\n b += `${ind}},\\n`;\n return b;\n}\n\n// renderTSStringArray renders string-array literal elements: `'a', 'b'` (no\n// surrounding brackets — caller adds them).\nfunction renderTSStringArray(ss: string[]): string {\n return ss.map(tsStringLit).join(', ');\n}\n\n// --- Augmentation (declare module '@palbase/web') ---------------------------\n\n// emitTSAugmentation renders the `declare module '@palbase/web' { interface PB\n// { ... } }` block, mirroring the registration trie shape with typed method\n// signatures. Ops arrive pre-filtered (same set as emitTSRegistration).\nfunction emitTSAugmentation(ops: Op[]): string {\n let b = \"declare module '@palbase/web' {\\n\";\n b += ' interface PB {\\n';\n b += renderTSAugNode(buildTSTrie(ops), 4);\n b += ' }\\n';\n b += '}\\n';\n return b;\n}\n\n// renderTSAugNode renders augmentation entries at the given indent.\nfunction renderTSAugNode(node: TSNode, indentSpaces: number): string {\n const ind = ' '.repeat(indentSpaces);\n let b = '';\n for (const e of node.entries) {\n if (e.child) {\n b += `${ind}${tsPropKey(e.key)}: {\\n`;\n b += renderTSAugNode(e.child, indentSpaces + 2);\n b += `${ind}};\\n`;\n continue;\n }\n if (e.op) {\n b += `${ind}${tsPropKey(e.key)}${renderTSMethodSignature(e.op)};\\n`;\n }\n }\n return b;\n}\n\n// renderTSMethodSignature builds the TypeScript method signature for one op.\n// Shape: (pathParam: string, ..., input?: T, options?: CallOptions): Promise<R>\nfunction renderTSMethodSignature(op: Op): string {\n const pfx = typePrefix(op.operationId);\n const args: string[] = [];\n\n // Leading path params. Wire names are sanitized into valid TS identifiers\n // (`{user-id}` → userId, reserved words escaped, repeats deduped) — names\n // are purely positional: the runtime substitutes via the descriptor's\n // pathParams, which keep the WIRE names, so renaming here is safe.\n const used = new Set<string>();\n for (const p of op.pathParams) {\n args.push(`${tsParamIdent(p, used)}: string`);\n }\n\n // Input arg. A zero-prop object body still takes a real `input` arg: `{}` is\n // a valid wire body and the descriptor defaults to body.\n if (op.input) {\n args.push(`input: ${pfx}Request`);\n } else if (op.query) {\n args.push(`query: ${pfx}Query`);\n }\n\n // Options arg: fold headers when present.\n args.push(buildOptionsArg(op.headers));\n\n const ret = op.output ? `Promise<${pfx}Response>` : 'Promise<void>';\n return `(${args.join(', ')}): ${ret}`;\n}\n\n// buildOptionsArg constructs the options parameter (with or without headers).\n// Required when any declared header is required; optional otherwise.\nfunction buildOptionsArg(headers: Schema | undefined): string {\n if (!headers || headers.props.length === 0) {\n return 'options?: CallOptions';\n }\n const anyRequired = headers.props.some((p) => p.required);\n\n const hParts = headers.props.map((p) => {\n const opt = p.required ? '' : '?';\n return `${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`;\n });\n const headersType = `{ ${hParts.join('; ')} }`;\n\n if (anyRequired) {\n return `options: CallOptions & { headers: ${headersType} }`;\n }\n return `options?: CallOptions & { headers?: ${headersType} }`;\n}\n\n// tsParamIdent converts a wire path-param name into a safe TS parameter\n// identifier: camelCase-sanitized (`user-id` → userId), reserved words and the\n// fixed signature arg names (input/query/options) escaped with a trailing\n// underscore, repeats deduped with a numeric suffix. Records the chosen name.\nfunction tsParamIdent(name: string, used: Set<string>): string {\n let id = sanitize(name, false);\n if (tsReservedWords.has(id) || id === 'input' || id === 'query' || id === 'options') {\n id += '_';\n }\n let candidate = id;\n for (let n = 2; used.has(candidate); n++) {\n candidate = id + n;\n }\n used.add(candidate);\n return candidate;\n}\n\n// tsReservedWords are ECMAScript keywords plus strict-mode reserved names that\n// cannot be used as parameter binding identifiers in a module.\nconst tsReservedWords = new Set([\n 'await',\n 'break',\n 'case',\n 'catch',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'else',\n 'enum',\n 'export',\n 'extends',\n 'false',\n 'finally',\n 'for',\n 'function',\n 'if',\n 'import',\n 'in',\n 'instanceof',\n 'new',\n 'null',\n 'return',\n 'super',\n 'switch',\n 'this',\n 'throw',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'while',\n 'with',\n 'yield',\n // strict-mode reserved / restricted binding names\n 'implements',\n 'interface',\n 'let',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'static',\n 'arguments',\n 'eval',\n]);\n\n// tsBareKeyRe matches identifiers that are valid bare TS object keys.\nconst tsBareKeyRe = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n// tsPropKey renders an object-literal property key: bare when it is a valid\n// identifier, single-quoted via tsStringLit otherwise (kebab-case segments,\n// codes with dots, …).\nfunction tsPropKey(name: string): string {\n return tsBareKeyRe.test(name) ? name : tsStringLit(name);\n}\n\n// tsStringLit returns a single-quoted TypeScript string literal, escaping\n// backslash and single quotes (and newlines/carriage returns defensively).\nfunction tsStringLit(s: string): string {\n return `'${s\n .replaceAll('\\\\', '\\\\\\\\')\n .replaceAll(\"'\", \"\\\\'\")\n .replaceAll('\\n', '\\\\n')\n .replaceAll('\\r', '\\\\r')}'`;\n}\n\n// tsReservedTopLevel reports whether the top-level namespace segment is\n// reserved. Case-insensitive for the iOS SDK set (auth/analytics/flags/\n// realtime) + case-sensitive for the web-only set (call, upload, then) and all\n// Object.prototype members.\nfunction tsReservedTopLevel(seg: string): boolean {\n switch (seg.toLowerCase()) {\n case 'auth':\n case 'analytics':\n case 'flags':\n case 'realtime':\n return true;\n default:\n return tsReservedWebOnly(seg);\n }\n}\n\n// tsReservedNested reports whether a non-first segment is reserved for nested\n// positions: the Object.prototype members + `then`, but NOT `call` or `upload`\n// (those are only reserved at the top level). Applied to every non-first\n// segment including the final method segment.\nfunction tsReservedNested(seg: string): boolean {\n if (seg === 'then') return true;\n return tsObjectPrototypeMember(seg);\n}\n\n// tsReservedWebOnly contains the web-only reserved set (call/upload/then) plus\n// Object.prototype members. Case-sensitive.\nfunction tsReservedWebOnly(seg: string): boolean {\n switch (seg) {\n case 'call':\n case 'upload':\n case 'then':\n return true;\n default:\n return tsObjectPrototypeMember(seg);\n }\n}\n\n// tsObjectPrototypeMember reports whether seg is an Object.prototype member.\nfunction tsObjectPrototypeMember(seg: string): boolean {\n switch (seg) {\n case 'constructor':\n case 'hasOwnProperty':\n case 'isPrototypeOf':\n case 'propertyIsEnumerable':\n case 'toLocaleString':\n case 'toString':\n case 'valueOf':\n case '__proto__':\n case '__defineGetter__':\n case '__defineSetter__':\n case '__lookupGetter__':\n case '__lookupSetter__':\n return true;\n default:\n return false;\n }\n}\n","// OpenAPI 3.1 → operation model parser for the palbe-gen typed-client codegen.\n// 1:1 TypeScript port of the CLI's Go parser (internal/backend/swiftgen.go —\n// dialect-neutral despite the historical \"swift\" name). Behavior parity with\n// the Go emitter is locked by the M1 cross-binding golden test.\n\n// --- Parsed model -----------------------------------------------------------\n\nexport type SchemaKind =\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'object'\n | 'array'\n | 'enum'\n | 'any';\n\nexport interface Schema {\n kind: SchemaKind;\n nullable: boolean;\n /** object */\n props: Prop[];\n /** array */\n elem?: Schema;\n /** enum */\n enumVals: string[];\n}\n\nexport interface Prop {\n name: string;\n schema: Schema;\n required: boolean;\n}\n\nexport interface Op {\n operationId: string;\n method: string;\n path: string;\n /** `{name}` path segments in path order → leading string method args */\n pathParams: string[];\n input?: Schema;\n output?: Schema;\n /** declared request headers (parameters[in:header]) */\n headers?: Schema;\n /** declared query params (parameters[in:query]) */\n query?: Schema;\n /** inferred errors via the `x-palbase-errors` extension */\n errors: ErrorDef[];\n}\n// ponytail: the Go parser also reads `x-palbase-upload` — the TS emitter never\n// consumes it (web has no generated upload surface), so it is not parsed here.\n\nexport interface ErrorDef {\n /** lowerCamel error name (e.g. \"todoLocked\") — class-name stem */\n name: string;\n /** wire `error` value (e.g. \"todo_locked\") — matched at decode time */\n code: string;\n /** HTTP status — kept for doc-comments */\n status: number;\n description: string;\n /** undefined when the error carries no payload */\n data?: Schema;\n}\n\ntype JsonObject = Record<string, unknown>;\n\nfunction asObject(v: unknown): JsonObject | undefined {\n if (typeof v === 'object' && v !== null && !Array.isArray(v)) return v as JsonObject;\n return undefined;\n}\n\nfunction asString(v: unknown): string {\n return typeof v === 'string' ? v : '';\n}\n\n/**\n * readSpecDeploy returns the document's `x-palbase-deploy` — the DEPLOY IDENTITY\n * the runtime stamps into every artifact it ships.\n *\n * Codegen prints it so \"generated successfully\" says WHICH contract it\n * generated from. The origin can legitimately serve the previous deploy for a\n * few seconds after a green one (a warm isolate re-reads its ACTIVE pointer on a\n * ~10s boundary), and a success line that hides that is how a client for 28\n * routes shipped after a deploy of 29 — caught only by counting operations by\n * hand.\n *\n * It is deliberately NOT `info.version`: OpenAPI requires that field, so it\n * always holds something and cannot express \"this runtime does not know\". The\n * extension is omitted instead, so absence is the answer and no placeholder\n * needs recognising.\n *\n * Returns '' when the document names no deploy, or is unreadable. It never\n * throws: parseOpenAPI owns the loud failure for a malformed document, and a\n * provenance note must not become a second, competing error path.\n */\nexport function readSpecDeploy(specText: string): string {\n try {\n return asString(asObject(JSON.parse(specText))?.['x-palbase-deploy']);\n } catch {\n return '';\n }\n}\n\n// --- Parse ------------------------------------------------------------------\n\nexport function parseOpenAPI(specText: string): Op[] {\n let root: JsonObject | undefined;\n try {\n root = asObject(JSON.parse(specText));\n } catch (e) {\n throw new Error(`openapi.json is not valid JSON: ${e instanceof Error ? e.message : e}`);\n }\n const paths = asObject(root?.paths);\n if (!paths) {\n throw new Error('openapi.json has no `paths`');\n }\n\n const ops: Op[] = [];\n for (const [path, item] of Object.entries(paths)) {\n const methods = asObject(item);\n if (!methods) continue;\n for (const [method, raw] of Object.entries(methods)) {\n const op = asObject(raw);\n if (!op) continue;\n const opId = asString(op.operationId);\n if (opId === '') continue;\n ops.push({\n operationId: opId,\n method: method.toUpperCase(),\n path: normalizePathTemplate(path),\n pathParams: pathParamNames(path),\n input: requestSchema(op),\n output: responseSchema(op),\n headers: parametersSchemaIn(op, 'header'),\n query: parametersSchemaIn(op, 'query'),\n errors: declaredErrors(op),\n });\n }\n }\n ops.sort((a, b) => (a.operationId < b.operationId ? -1 : a.operationId > b.operationId ? 1 : 0));\n return ops;\n}\n\n// declaredErrors reads the `x-palbase-errors` OpenAPI extension the backend\n// runtime stashes on each operation. Returns [] when no errors were inferred.\nfunction declaredErrors(op: JsonObject): ErrorDef[] {\n const extRaw = asObject(op['x-palbase-errors']);\n if (!extRaw) return [];\n const responses = asObject(op.responses);\n const out: ErrorDef[] = [];\n for (const [name, raw] of Object.entries(extRaw)) {\n const entry = asObject(raw);\n if (!entry) continue;\n const status = typeof entry.status === 'number' ? Math.trunc(entry.status) : 0;\n const code = asString(entry.code);\n const description = asString(entry.description);\n const hasData = entry.hasData === true;\n if (code === '' || status === 0) continue;\n const def: ErrorDef = { name, code, status, description };\n if (hasData) {\n def.data = errorDataSchema(responses, status, code);\n }\n out.push(def);\n }\n // Deterministic order: by error name.\n out.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n return out;\n}\n\n// errorDataSchema pulls the data-payload schema out of a declared error's\n// response shape. Single error on a status → the standalone schema; multiple\n// errors sharing a status → `oneOf`, pick the variant whose\n// `error: { const: <code> }` discriminator matches.\nfunction errorDataSchema(\n responses: JsonObject | undefined,\n status: number,\n code: string,\n): Schema | undefined {\n const resp = asObject(responses?.[String(status)]);\n const jsonCt = asObject(asObject(resp?.content)?.['application/json']);\n const schema = asObject(jsonCt?.schema);\n if (!schema) return undefined;\n\n const variants = schema.oneOf;\n if (Array.isArray(variants)) {\n for (const v of variants) {\n const vm = asObject(v);\n if (!vm) continue;\n const errProp = asObject(asObject(vm.properties)?.error);\n if (errProp && asString(errProp.const) === code) {\n return extractDataProperty(vm);\n }\n }\n return undefined;\n }\n return extractDataProperty(schema);\n}\n\nfunction extractDataProperty(schema: JsonObject): Schema | undefined {\n const dm = asObject(asObject(schema.properties)?.data);\n if (!dm) return undefined;\n return parseSchema(dm);\n}\n\nfunction requestSchema(op: JsonObject): Schema | undefined {\n const body = asObject(op.requestBody);\n if (!body) return undefined;\n return schemaFromContent(body.content);\n}\n\n// parametersSchemaIn collects the operation's `parameters[in:<where>]` entries\n// into a synthetic object Schema (one property per parameter), name-sorted for\n// deterministic output. Returns undefined when the op declares no parameter in\n// that location; path params are threaded separately (pathParamNames).\nfunction parametersSchemaIn(op: JsonObject, where: 'header' | 'query'): Schema | undefined {\n const paramsRaw = op.parameters;\n if (!Array.isArray(paramsRaw) || paramsRaw.length === 0) return undefined;\n const props: Prop[] = [];\n for (const p of paramsRaw) {\n const pm = asObject(p);\n if (!pm) continue;\n if (asString(pm.in) !== where) continue;\n const name = asString(pm.name);\n if (name === '') continue;\n const required = pm.required === true;\n const sm = asObject(pm.schema);\n const ps = sm ? parseSchema(sm) : emptySchema('string');\n props.push({ name, schema: ps, required });\n }\n if (props.length === 0) return undefined;\n props.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n return { ...emptySchema('object'), props };\n}\n\n// pathParamNames extracts the `{name}` template segments from an OpenAPI path,\n// in left-to-right path order. Empty `{}` is ignored.\n/**\n * ACCEPTS BOTH SPELLINGS, because our own runtime writes the other one.\n *\n * OpenAPI templates a path parameter as `{name}`. The palbase backend runtime\n * stamps its contract with `:name` — Express's spelling — so every route with a\n * path parameter came through here with none found, and codegen emitted a\n * method that could not be given the value it needs. Measured against the live\n * control plane: `/v1/panel/projects/:projectId` produced\n * `projectById(options?)`.\n *\n * Normalising at the door is the narrow fix: everything downstream already\n * speaks `{name}`, so only this function has to know there are two spellings.\n */\nexport function normalizePathTemplate(path: string): string {\n return path.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, \"{$1}\");\n}\n\nexport function pathParamNames(rawPath: string): string[] {\n const path = normalizePathTemplate(rawPath);\n const out: string[] = [];\n let rest = path;\n for (;;) {\n const open = rest.indexOf('{');\n if (open < 0) break;\n const close = rest.indexOf('}', open);\n if (close < 0) break;\n const name = rest.slice(open + 1, close);\n if (name !== '') out.push(name);\n rest = rest.slice(close + 1);\n }\n return out;\n}\n\nfunction responseSchema(op: JsonObject): Schema | undefined {\n const responses = asObject(op.responses);\n if (!responses) return undefined;\n // Prefer 200, then 201, then any other 2xx (sorted).\n const others: string[] = [];\n for (const code of Object.keys(responses)) {\n if (code.startsWith('2') && code !== '200' && code !== '201') others.push(code);\n }\n others.sort();\n for (const code of ['200', '201', ...others]) {\n const resp = asObject(responses[code]);\n if (!resp) continue;\n const s = schemaFromContent(resp.content);\n if (s) return s;\n }\n return undefined;\n}\n\nfunction schemaFromContent(content: unknown): Schema | undefined {\n const jsonCt = asObject(asObject(content)?.['application/json']);\n const schema = asObject(jsonCt?.schema);\n if (!schema) return undefined;\n // Skip $ref'd shared components (error envelope etc.).\n if ('$ref' in schema) return undefined;\n return parseSchema(schema);\n}\n\nfunction emptySchema(kind: SchemaKind): Schema {\n return { kind, nullable: false, props: [], enumVals: [] };\n}\n\nexport function parseSchema(s: JsonObject): Schema {\n let nullable = s.nullable === true;\n\n const enumRaw = s.enum;\n if (Array.isArray(enumRaw)) {\n const cases: string[] = [];\n let allStrings = true;\n for (const v of enumRaw) {\n if (typeof v === 'string') {\n cases.push(v);\n } else {\n allStrings = false;\n break;\n }\n }\n if (allStrings && cases.length > 0) {\n return { ...emptySchema('enum'), nullable, enumVals: cases };\n }\n }\n\n // Draft 7 / OpenAPI 3.1 allow `type` as an array — `[\"string\",\"null\"]` is\n // what `zod-to-json-schema` emits for `z.string().nullable()`. Lower it to\n // the single non-null type + nullable=true.\n let typ = asString(s.type);\n if (typ === '' && Array.isArray(s.type)) {\n for (const v of s.type) {\n if (typeof v !== 'string') continue;\n if (v === 'null') {\n nullable = true;\n } else if (typ === '') {\n typ = v;\n }\n }\n }\n switch (typ) {\n case 'string':\n case 'number':\n case 'integer':\n case 'boolean':\n return { ...emptySchema(typ), nullable };\n case 'array': {\n const items = asObject(s.items);\n const elem = items ? parseSchema(items) : emptySchema('any');\n return { ...emptySchema('array'), nullable, elem };\n }\n case 'object':\n return parseObject(s, nullable);\n default:\n if ('properties' in s) return parseObject(s, nullable);\n return { ...emptySchema('any'), nullable };\n }\n}\n\nfunction parseObject(s: JsonObject, nullable: boolean): Schema {\n const propsRaw = asObject(s.properties) ?? {};\n const requiredSet = new Set<string>();\n if (Array.isArray(s.required)) {\n for (const r of s.required) {\n if (typeof r === 'string') requiredSet.add(r);\n }\n }\n const names = Object.keys(propsRaw).sort();\n const props: Prop[] = [];\n for (const name of names) {\n const pm = asObject(propsRaw[name]);\n const ps = pm ? parseSchema(pm) : emptySchema('any');\n props.push({ name, schema: ps, required: requiredSet.has(name) });\n }\n return { ...emptySchema('object'), nullable, props };\n}\n"],"mappings":"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","names":["process","process"]}
package/dist/index.cjs CHANGED
@@ -8020,7 +8020,7 @@ function localStorageSessionStorage(key = DEFAULT_KEY) {
8020
8020
  }
8021
8021
 
8022
8022
  // src/version.ts
8023
- var VERSION = "7.3.5";
8023
+ var VERSION = "7.3.7";
8024
8024
 
8025
8025
  // src/internal.ts
8026
8026
  function getRuntime() {