@databrainhq/mcp-server 0.3.0-rc.13 → 0.3.0-rc.15
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.
- package/.mcp.json +6 -1
- package/dist/apps/server.d.ts +102 -389
- package/dist/apps/server.js +5 -5
- package/dist/apps/stdio.d.ts +1 -2
- package/dist/apps/stdio.js +6 -6
- package/dist/{bundle-TDQXWIPM.js → bundle-QJNCUMNY.js} +2 -2
- package/dist/{chunk-Q5EYDKSA.js → chunk-2F7V6RZR.js} +511 -107
- package/dist/chunk-2F7V6RZR.js.map +1 -0
- package/dist/chunk-3AH56XX7.js +28 -0
- package/dist/chunk-3AH56XX7.js.map +1 -0
- package/dist/{chunk-AEQTEE5C.js → chunk-4E57ZRZO.js} +302 -63
- package/dist/chunk-4E57ZRZO.js.map +1 -0
- package/dist/{chunk-PSJVYD4W.js → chunk-6MD7KOAU.js} +11723 -10560
- package/dist/chunk-6MD7KOAU.js.map +1 -0
- package/dist/{chunk-HCYZN7I3.js → chunk-FJLRZJ4A.js} +10 -7
- package/dist/chunk-FJLRZJ4A.js.map +1 -0
- package/dist/{chunk-X44C5GW2.js → chunk-MUZ3KEJX.js} +63 -40
- package/dist/chunk-MUZ3KEJX.js.map +1 -0
- package/dist/{chunk-DTFYHLYN.js → chunk-NXE2A4WV.js} +26 -11
- package/dist/chunk-NXE2A4WV.js.map +1 -0
- package/dist/{chunk-233VGFHY.js → chunk-QQ6KNULX.js} +317 -147
- package/dist/chunk-QQ6KNULX.js.map +1 -0
- package/dist/chunk-V5JINLOA.js +506 -0
- package/dist/chunk-V5JINLOA.js.map +1 -0
- package/dist/cli.d.ts +16 -15
- package/dist/cli.js +134 -36
- package/dist/cli.js.map +1 -1
- package/dist/custom-chart/custom-runtime.js +6 -6
- package/dist/custom-chart/template/chart.ts +116 -28
- package/dist/custom-chart/template/icon.svg +1 -1
- package/dist/custom-chart/template/manifest.json +66 -12
- package/dist/custom-chart/template/sample-data.json +21 -3
- package/dist/index.d.ts +1 -2
- package/dist/index.js +67 -13
- package/dist/index.js.map +1 -1
- package/dist/{main-VEKNKWL5.js → main-2FKQQLWX.js} +489 -174
- package/dist/main-2FKQQLWX.js.map +1 -0
- package/dist/{test-only-LJGOY2QA.js → test-only-VH3FF5ML.js} +15 -9
- package/dist/test-only-VH3FF5ML.js.map +1 -0
- package/package.json +20 -9
- package/dist/chunk-233VGFHY.js.map +0 -1
- package/dist/chunk-AEQTEE5C.js.map +0 -1
- package/dist/chunk-DTFYHLYN.js.map +0 -1
- package/dist/chunk-HCYZN7I3.js.map +0 -1
- package/dist/chunk-PSJVYD4W.js.map +0 -1
- package/dist/chunk-Q5EYDKSA.js.map +0 -1
- package/dist/chunk-X44C5GW2.js.map +0 -1
- package/dist/main-VEKNKWL5.js.map +0 -1
- package/dist/test-only-LJGOY2QA.js.map +0 -1
- /package/dist/{bundle-TDQXWIPM.js.map → bundle-QJNCUMNY.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/custom-chart/bundle.ts","../src/custom-chart/assets.ts","../src/custom-chart/sanitize-svg.ts","../src/custom-chart/types.ts","../src/custom-chart/icon.ts","../src/custom-chart/manifest.ts","../src/custom-chart/zip.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join, resolve, sep } from 'node:path';\nimport { build as esbuild, type Plugin } from 'esbuild';\nimport { readRuntimeShim } from './assets.js';\nimport { sanitizeIcon, validateIcon } from './icon.js';\nimport { sortKeys, validateManifest } from './manifest.js';\nimport {\n type CustomChartBundle,\n type CustomChartManifest,\n MAX_BUNDLE_CSS_BYTES,\n MAX_BUNDLE_JS_BYTES,\n type Problem,\n} from './types.js';\nimport { writeBundleZip } from './zip.js';\n\nconst utf8Bytes = (text: string): number => Buffer.byteLength(text, 'utf8');\n\n/**\n * Content hash exactly as the backend computes it (brief section 5 and\n * FINDINGS be-core 2): sha256 hex over\n * JSON.stringify({ manifest, bundleJs, bundleCss, iconSvg }) in that key\n * order, the manifest keys sorted recursively (arrays keep their order) and\n * bundleCss always present, as \"\" when there is none.\n */\nexport function contentHash(bundle: CustomChartBundle): string {\n const payload = JSON.stringify({\n manifest: sortKeys(bundle.manifest),\n bundleJs: bundle.bundleJs,\n bundleCss: bundle.bundleCss ?? '',\n iconSvg: bundle.iconSvg,\n });\n return createHash('sha256').update(payload, 'utf8').digest('hex');\n}\n\n/** Bytes the upload carries: the four artifacts as UTF-8. */\nexport function bundleSizeBytes(bundle: CustomChartBundle): number {\n return (\n utf8Bytes(JSON.stringify(bundle.manifest)) +\n utf8Bytes(bundle.bundleJs) +\n (bundle.bundleCss ? utf8Bytes(bundle.bundleCss) : 0) +\n utf8Bytes(bundle.iconSvg)\n );\n}\n\nexport interface ValidateBundleInput {\n manifest: unknown;\n bundleJs?: string;\n bundleCss?: string;\n iconSvg?: string;\n}\n\n/**\n * The client side of the upload validation (the server repeats it). Manifest\n * rules first, then the bundle sizes, then the icon.\n */\nexport function validateBundle(input: ValidateBundleInput): Problem[] {\n const problems = validateManifest(input.manifest);\n if (input.bundleJs !== undefined) {\n if (typeof input.bundleJs !== 'string') {\n problems.push({\n code: 'bundle.js.type',\n path: '/bundleJs',\n message: 'bundleJs must be a string.',\n });\n } else if (input.bundleJs.trim().length === 0) {\n problems.push({\n code: 'bundle.js.empty',\n path: '/bundleJs',\n message: 'bundleJs must contain JavaScript.',\n });\n } else if (utf8Bytes(input.bundleJs) > MAX_BUNDLE_JS_BYTES) {\n problems.push({\n code: 'bundle.js.size',\n path: '/bundleJs',\n message: `bundleJs must be at most ${MAX_BUNDLE_JS_BYTES} bytes (2 MiB) as UTF-8. Drop or shrink a dependency.`,\n });\n }\n }\n if (input.bundleCss !== undefined) {\n if (typeof input.bundleCss !== 'string') {\n problems.push({\n code: 'bundle.css.type',\n path: '/bundleCss',\n message: 'bundleCss must be a string when present.',\n });\n } else if (utf8Bytes(input.bundleCss) > MAX_BUNDLE_CSS_BYTES) {\n problems.push({\n code: 'bundle.css.size',\n path: '/bundleCss',\n message: `bundleCss must be at most ${MAX_BUNDLE_CSS_BYTES} bytes (256 KiB).`,\n });\n }\n }\n if (input.iconSvg !== undefined)\n problems.push(...validateIcon(input.iconSvg, '/iconSvg'));\n return problems;\n}\n\nexport interface ChartProject {\n dir: string;\n manifest: unknown;\n manifestText?: string;\n chartEntry?: string;\n css?: string;\n icon?: string;\n sampleData?: unknown;\n problems: Problem[];\n}\n\n/** Read a chart project folder. Missing or unparsable files become problems. */\nexport function readProject(dirInput: string): ChartProject {\n const dir = resolve(dirInput);\n const problems: Problem[] = [];\n const project: ChartProject = { dir, manifest: undefined, problems };\n\n const manifestPath = join(dir, 'manifest.json');\n if (!existsSync(manifestPath)) {\n problems.push({\n code: 'project.manifest.missing',\n path: '/manifest.json',\n message: `No manifest.json in ${dir}.`,\n });\n } else {\n project.manifestText = readFileSync(manifestPath, 'utf8');\n try {\n project.manifest = JSON.parse(project.manifestText);\n } catch (err) {\n problems.push({\n code: 'project.manifest.parse',\n path: '/manifest.json',\n message: `manifest.json is not valid JSON: ${(err as Error).message}`,\n });\n }\n }\n\n const entry = ['chart.ts', 'chart.js']\n .map((name) => join(dir, name))\n .find((path) => existsSync(path));\n if (!entry) {\n problems.push({\n code: 'project.chart.missing',\n path: '/chart.ts',\n message: `No chart.ts in ${dir}. It must export render(ctx).`,\n });\n } else {\n project.chartEntry = entry;\n }\n\n const cssPath = join(dir, 'chart.css');\n if (existsSync(cssPath)) project.css = readFileSync(cssPath, 'utf8');\n\n const iconPath = join(dir, 'icon.svg');\n if (!existsSync(iconPath)) {\n problems.push({\n code: 'bundle.icon.required',\n path: '/icon.svg',\n message: `No icon.svg in ${dir}.`,\n });\n } else {\n project.icon = readFileSync(iconPath, 'utf8');\n }\n\n const samplePath = join(dir, 'sample-data.json');\n if (existsSync(samplePath)) {\n try {\n project.sampleData = JSON.parse(readFileSync(samplePath, 'utf8'));\n } catch (err) {\n problems.push({\n code: 'project.sampleData.parse',\n path: '/sample-data.json',\n message: `sample-data.json is not valid JSON: ${(err as Error).message}`,\n });\n }\n }\n return project;\n}\n\n/** validate = read the folder, check the manifest and the icon. No esbuild. */\nexport function validateProject(dir: string): {\n ok: boolean;\n problems: Problem[];\n project: ChartProject;\n} {\n const project = readProject(dir);\n const problems = [...project.problems];\n if (project.manifest !== undefined)\n problems.push(...validateManifest(project.manifest));\n // The build strips the XML declaration and comments before upload, so check that form.\n if (project.icon !== undefined)\n problems.push(...validateIcon(sanitizeIcon(project.icon)));\n if (\n project.css !== undefined &&\n utf8Bytes(project.css) > MAX_BUNDLE_CSS_BYTES\n ) {\n problems.push({\n code: 'bundle.css.size',\n path: '/chart.css',\n message: `chart.css must be at most ${MAX_BUNDLE_CSS_BYTES} bytes.`,\n });\n }\n return { ok: problems.length === 0, problems, project };\n}\n\nexport interface BuildOutputs extends CustomChartBundle {\n manifest: CustomChartManifest;\n contentHash: string;\n sizeBytes: number;\n}\n\nexport interface BuildResult {\n ok: boolean;\n problems: Problem[];\n outputs?: BuildOutputs;\n /** Absolute paths written under dist/, in write order. Empty when write is false. */\n written: string[];\n}\n\nexport const DIST_FILES = [\n 'index.js',\n 'manifest.json',\n 'icon.svg',\n 'index.css',\n 'bundle.zip',\n] as const;\n\n/**\n * Every import must resolve to a file inside the chart project. A relative\n * path that climbs out (`../../.config/x.json`) would be inlined into the\n * bundle and uploaded with it; the build refuses it with a problem instead.\n */\nfunction insideProjectOnly(dir: string): Plugin {\n const root = dir.endsWith(sep) ? dir : `${dir}${sep}`;\n return {\n name: 'databrain-inside-project-only',\n setup(build) {\n build.onResolve({ filter: /.*/ }, async (args) => {\n if (args.kind === 'entry-point' || args.pluginData?.databrainChecked)\n return undefined;\n const resolved = await build.resolve(args.path, {\n kind: args.kind,\n resolveDir: args.resolveDir,\n importer: args.importer,\n pluginData: { databrainChecked: true },\n });\n if (resolved.errors.length > 0) return { errors: resolved.errors };\n if (resolved.external || resolved.path.startsWith(root))\n return resolved;\n return {\n errors: [\n {\n text: `\"${args.path}\" is outside the chart project. Only files inside ${dir} can be imported.`,\n },\n ],\n };\n });\n },\n };\n}\n\n/**\n * Compile chart.ts with esbuild to one IIFE, prepend the runtime shim and\n * the slot id list the shim reads, enforce the 2 MiB gate and write dist/.\n * See brief section 4 and contract/runtime-shim.js.\n */\nexport async function buildProject(\n dir: string,\n options: { write?: boolean } = {}\n): Promise<BuildResult> {\n const validated = validateProject(dir);\n const { project } = validated;\n const problems = [...validated.problems];\n if (\n !project.chartEntry ||\n project.manifest === undefined ||\n problems.length > 0\n ) {\n return { ok: false, problems, written: [] };\n }\n const manifest = project.manifest as CustomChartManifest;\n\n // Bundled for the browser with no externals: every import is resolved\n // inside the project or it is a build error (a node builtin like \"fs\" does\n // not resolve on the browser platform), so dist/index.js never carries a\n // dangling require. The entry must be an ES module that exports render():\n // the shim reads globalThis.__dbnCustomChart.render, and a CommonJS\n // module.exports or a missing export would only fail later, as a blank tile.\n const common = {\n plugins: [insideProjectOnly(project.dir)],\n entryPoints: [project.chartEntry],\n absWorkingDir: project.dir,\n bundle: true as const,\n target: 'es2020',\n platform: 'browser' as const,\n write: false as const,\n legalComments: 'none' as const,\n logLevel: 'silent' as const,\n charset: 'utf8' as const,\n };\n let moduleJs: string;\n try {\n const shape = await esbuild({ ...common, format: 'esm', metafile: true });\n const exported = Object.values(shape.metafile.outputs)[0]?.exports ?? [];\n if (!exported.includes('render')) {\n problems.push({\n code: 'bundle.build.noRender',\n path: '/chart.ts',\n message:\n 'chart.ts must be an ES module that exports a function named render: `export function render(ctx) { ... }`. module.exports and default exports are not read.',\n });\n return { ok: false, problems, written: [] };\n }\n const result = await esbuild({\n ...common,\n format: 'iife',\n globalName: '__dbnCustomChart',\n minify: true,\n });\n moduleJs = result.outputFiles.map((file) => file.text).join('\\n');\n } catch (err) {\n const errors = (\n err as {\n errors?: {\n text: string;\n location?: { file?: string; line?: number } | null;\n }[];\n }\n ).errors;\n if (Array.isArray(errors) && errors.length > 0) {\n for (const error of errors) {\n const where = error.location\n ? `${error.location.file ?? 'chart.ts'}:${error.location.line ?? 0}`\n : 'chart.ts';\n problems.push({\n code: 'bundle.build.failed',\n path: `/${where}`,\n message: error.text,\n });\n }\n } else {\n problems.push({\n code: 'bundle.build.failed',\n path: '/chart.ts',\n message: (err as Error).message,\n });\n }\n return { ok: false, problems, written: [] };\n }\n\n // Shim first (byte identical to contract/runtime-shim.js), then the slot ids\n // so every manifest slot is present on ctx.slots, then the chart module.\n // chart.css is NOT inlined: the host injects bundleCss into the frame\n // (brief section 6.5); dist/index.css carries it for provenance and upload.\n const shim = readRuntimeShim();\n const slotIds = manifest.slots.map((slot) => slot.id);\n const globals = `globalThis.__dbnCustomChartSlots=${JSON.stringify(slotIds)};\\n`;\n const bundleJs = `${shim.trimEnd()}\\n${globals}${moduleJs.trimEnd()}\\nglobalThis.__dbnCustomChart=__dbnCustomChart;\\n`;\n const iconSvg = sanitizeIcon(project.icon as string);\n const bundleCss = project.css;\n\n problems.push(...validateBundle({ manifest, bundleJs, bundleCss, iconSvg }));\n if (problems.length > 0) return { ok: false, problems, written: [] };\n\n const bundle: CustomChartBundle = { manifest, bundleJs, bundleCss, iconSvg };\n const outputs: BuildOutputs = {\n ...bundle,\n contentHash: contentHash(bundle),\n sizeBytes: bundleSizeBytes(bundle),\n };\n\n const written: string[] = [];\n if (options.write !== false) {\n const dist = join(project.dir, 'dist');\n mkdirSync(dist, { recursive: true });\n const manifestJson = `${JSON.stringify(manifest, null, 2)}\\n`;\n const write = (name: string, content: string | Uint8Array) => {\n const path = join(dist, name);\n writeFileSync(path, content);\n written.push(path);\n };\n write('index.js', bundleJs);\n write('manifest.json', manifestJson);\n write('icon.svg', iconSvg);\n if (bundleCss !== undefined) write('index.css', bundleCss);\n write(\n 'bundle.zip',\n writeBundleZip({\n 'index.js': bundleJs,\n 'manifest.json': manifestJson,\n 'icon.svg': iconSvg,\n ...(bundleCss !== undefined ? { 'index.css': bundleCss } : {}),\n })\n );\n }\n\n return { ok: true, problems: [], outputs, written };\n}\n\n/** Read a previous build from dist/ (for upload without rebuilding). */\nexport function readDist(dir: string): {\n bundle?: CustomChartBundle;\n problems: Problem[];\n} {\n const dist = join(resolve(dir), 'dist');\n const problems: Problem[] = [];\n const need = ['index.js', 'manifest.json', 'icon.svg'];\n for (const name of need) {\n if (!existsSync(join(dist, name))) {\n problems.push({\n code: 'project.dist.missing',\n path: `/dist/${name}`,\n message: `dist/${name} is missing. Run databrain custom-chart build first.`,\n });\n }\n }\n if (problems.length > 0) return { problems };\n let manifest: unknown;\n try {\n manifest = JSON.parse(readFileSync(join(dist, 'manifest.json'), 'utf8'));\n } catch (err) {\n return {\n problems: [\n {\n code: 'project.dist.parse',\n path: '/dist/manifest.json',\n message: (err as Error).message,\n },\n ],\n };\n }\n const manifestProblems = validateManifest(manifest);\n if (manifestProblems.length > 0) return { problems: manifestProblems };\n const cssPath = join(dist, 'index.css');\n return {\n problems,\n bundle: {\n manifest: manifest as CustomChartManifest,\n bundleJs: readFileSync(join(dist, 'index.js'), 'utf8'),\n bundleCss: existsSync(cssPath)\n ? readFileSync(cssPath, 'utf8')\n : undefined,\n iconSvg: readFileSync(join(dist, 'icon.svg'), 'utf8'),\n },\n };\n}\n\n/** Compile caller-supplied source in memory. No filesystem, package resolution or execution. */\nexport async function buildSource(input: {\n manifest: unknown;\n chartTs: string;\n bundleCss?: string;\n iconSvg: string;\n}): Promise<BuildResult> {\n const problems = validateManifest(input.manifest);\n if (problems.length) return { ok: false, problems, written: [] };\n const manifest = input.manifest as CustomChartManifest;\n try {\n const common = {\n stdin: {\n contents: input.chartTs,\n loader: 'ts' as const,\n sourcefile: 'chart.ts',\n },\n bundle: true,\n platform: 'browser' as const,\n target: 'es2020',\n write: false,\n legalComments: 'none' as const,\n logLevel: 'silent' as const,\n plugins: [\n {\n name: 'no-host-imports',\n setup(build: Parameters<Plugin['setup']>[0]) {\n build.onResolve({ filter: /.*/ }, (args) => ({\n errors: [\n {\n text: `Import \"${args.path}\" is unavailable in hosted chart source. Use browser APIs or pass a prebuilt bundle.`,\n },\n ],\n }));\n },\n },\n ],\n };\n let shape = await esbuild({ ...common, format: 'esm', metafile: true });\n if (!Object.values(shape.metafile.outputs)[0]?.exports.includes('render')) {\n common.stdin.contents += '\\nexport { render };';\n shape = await esbuild({ ...common, format: 'esm', metafile: true });\n }\n if (!Object.values(shape.metafile.outputs)[0]?.exports.includes('render')) {\n return {\n ok: false,\n problems: [\n {\n code: 'bundle.build.noRender',\n path: '/chart.ts',\n message: 'Export function render(ctx).',\n },\n ],\n written: [],\n };\n }\n const built = await esbuild({\n ...common,\n format: 'iife',\n globalName: '__dbnCustomChart',\n minify: true,\n });\n const bundle: CustomChartBundle = {\n manifest,\n bundleCss: input.bundleCss,\n iconSvg: sanitizeIcon(input.iconSvg),\n bundleJs: `${readRuntimeShim().trimEnd()}\\nglobalThis.__dbnCustomChartSlots=${JSON.stringify(manifest.slots.map((s) => s.id))};\\n${built.outputFiles!.map((f) => f.text).join('\\n')}\\nglobalThis.__dbnCustomChart=__dbnCustomChart;\\n`,\n };\n const errors = validateBundle(bundle);\n return errors.length\n ? { ok: false, problems: errors, written: [] }\n : {\n ok: true,\n problems: [],\n written: [],\n outputs: {\n ...bundle,\n contentHash: contentHash(bundle),\n sizeBytes: bundleSizeBytes(bundle),\n },\n };\n } catch (error) {\n return {\n ok: false,\n problems: [\n {\n code: 'bundle.build.failed',\n path: '/chart.ts',\n message: (error as Error).message,\n },\n ],\n written: [],\n };\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildSync } from 'esbuild';\n\n/**\n * The template project and the runtime shim are shipped as plain files, not\n * as strings baked into the bundle, so that they stay byte identical to the\n * copies other repos test against. In source they live in\n * src/custom-chart/; tsup copies them to dist/custom-chart/ after a build\n * (see tsup.config.ts onSuccess). This finds them from either place.\n */\nlet cachedDir: string | undefined;\n\nexport function customChartAssetDir(): string {\n if (cachedDir) return cachedDir;\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n here,\n join(here, 'custom-chart'),\n join(here, '..', 'custom-chart'),\n join(here, '..', '..', 'custom-chart'),\n join(here, '..', 'src', 'custom-chart'),\n ];\n for (const candidate of candidates) {\n if (\n existsSync(join(candidate, 'runtime-shim.js')) &&\n existsSync(join(candidate, 'template', 'manifest.json'))\n ) {\n cachedDir = resolve(candidate);\n return cachedDir;\n }\n }\n throw new Error(\n `Custom chart assets not found near ${here}. Expected runtime-shim.js and template/ (run npm run build).`\n );\n}\n\nexport function readRuntimeShim(): string {\n return readFileSync(join(customChartAssetDir(), 'runtime-shim.js'), 'utf8');\n}\n\nexport function templateDir(): string {\n return join(customChartAssetDir(), 'template');\n}\n\n/** Every file in the template folder, keyed by its file name. */\nexport function readTemplateFiles(): Record<string, string> {\n const dir = templateDir();\n const files: Record<string, string> = {};\n for (const name of readdirSync(dir).sort()) {\n const path = join(dir, name);\n if (statSync(path).isFile()) files[name] = readFileSync(path, 'utf8');\n }\n return files;\n}\n\nlet cachedBrowserRuntime: string | undefined;\n/** Packaged asset in dist; source mode compiles only this fixed trusted entrypoint. */\nexport function readCustomChartBrowserRuntime(): string {\n if (cachedBrowserRuntime) return cachedBrowserRuntime;\n const dir = customChartAssetDir();\n const packed = join(dir, 'custom-runtime.js');\n cachedBrowserRuntime = existsSync(packed)\n ? readFileSync(packed, 'utf8')\n : buildSync({\n entryPoints: [join(dir, '..', 'apps', 'custom-runtime', 'browser.ts')],\n bundle: true,\n write: false,\n platform: 'browser',\n target: 'es2020',\n minify: true,\n }).outputFiles[0].text;\n return cachedBrowserRuntime;\n}\n","/**\n * Allow-list SVG sanitiser for icon.svg. A verbatim copy of the backend's\n * `serverless/express/src/utils/helpers/sanitizeSvg.ts` (the one that gates\n * the upload), so the CLI and the validate tool refuse exactly what the\n * server refuses instead of guessing with regexes. Keep the two files in\n * step: a rule added on one side and not the other means \"validate says ok,\n * upload says no\".\n *\n * WHAT IT DOES\n * ------------\n * - Drops the DOCTYPE (entity expansion) and every processing instruction\n * except the XML declaration; drops CDATA and comments.\n * - Keeps only elements on ALLOWED_ELEMENTS. A disallowed element and\n * everything inside it is removed (`<script>`, `<foreignObject>`,\n * `<iframe>`, `<animate>` ... ).\n * - Keeps only attributes on ALLOWED_ATTRIBUTES (plus `data-*` and the\n * `xmlns*` declarations). Every `on*` attribute goes. Any attribute whose\n * value carries `javascript:`, `data:text/html`, or `vbscript:` after\n * entity decoding goes.\n * - `href` / `xlink:href` survive only as a same-document `#id` reference,\n * or, on `<image>` alone, as a `data:image/(png|jpeg|gif|webp);base64`\n * URI. An external `<image href>` is removed with the element.\n * - `<style>` and `style=\"\"` survive only when they contain no `url(`,\n * `@import`, `expression(` or `-moz-binding`. A style that reaches out\n * of the file is dropped entirely rather than partially rewritten.\n *\n * Returns the cleaned markup and a count of what was removed, so the caller\n * can refuse the icon rather than silently rewriting it.\n */\nconst ALLOWED_ELEMENTS: ReadonlySet<string> = new Set([\n 'svg',\n 'g',\n 'defs',\n 'symbol',\n 'use',\n 'title',\n 'desc',\n 'metadata',\n 'path',\n 'rect',\n 'circle',\n 'ellipse',\n 'line',\n 'polyline',\n 'polygon',\n 'text',\n 'tspan',\n 'textpath',\n 'image',\n 'lineargradient',\n 'radialgradient',\n 'stop',\n 'clippath',\n 'mask',\n 'pattern',\n 'marker',\n 'filter',\n 'fegaussianblur',\n 'feoffset',\n 'feblend',\n 'fecolormatrix',\n 'fecomposite',\n 'feflood',\n 'femerge',\n 'femergenode',\n 'fedropshadow',\n 'style',\n 'switch',\n]);\n\nconst ALLOWED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'style',\n 'href',\n 'xlink:href',\n 'xml:space',\n 'lang',\n 'xml:lang',\n 'version',\n 'baseprofile',\n 'viewbox',\n 'preserveaspectratio',\n 'width',\n 'height',\n 'x',\n 'y',\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'cx',\n 'cy',\n 'r',\n 'rx',\n 'ry',\n 'fx',\n 'fy',\n 'fr',\n 'd',\n 'points',\n 'transform',\n 'transform-origin',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'stroke',\n 'stroke-width',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-opacity',\n 'opacity',\n 'color',\n 'display',\n 'visibility',\n 'overflow',\n 'clip-path',\n 'clip-rule',\n 'clippathunits',\n 'mask',\n 'maskunits',\n 'maskcontentunits',\n 'filter',\n 'filterunits',\n 'primitiveunits',\n 'in',\n 'in2',\n 'result',\n 'mode',\n 'operator',\n 'values',\n 'type',\n 'stddeviation',\n 'dx',\n 'dy',\n 'flood-color',\n 'flood-opacity',\n 'offset',\n 'stop-color',\n 'stop-opacity',\n 'gradientunits',\n 'gradienttransform',\n 'spreadmethod',\n 'patternunits',\n 'patterncontentunits',\n 'patterntransform',\n 'markerunits',\n 'markerwidth',\n 'markerheight',\n 'refx',\n 'refy',\n 'orient',\n 'font-family',\n 'font-size',\n 'font-weight',\n 'font-style',\n 'letter-spacing',\n 'text-anchor',\n 'dominant-baseline',\n 'alignment-baseline',\n 'text-decoration',\n 'word-spacing',\n 'paint-order',\n 'vector-effect',\n 'shape-rendering',\n 'text-rendering',\n 'image-rendering',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'enable-background',\n 'startoffset',\n 'method',\n 'spacing',\n 'requiredfeatures',\n 'systemlanguage',\n 'role',\n 'aria-label',\n 'aria-labelledby',\n 'aria-hidden',\n 'focusable',\n 'tabindex',\n]);\n\n/** Pattern over a tag's raw text: name, then attributes, then optional `/`. */\nconst TAG_RE = /^<\\s*(\\/?)\\s*([A-Za-z_][\\w:.-]*)([\\s\\S]*?)(\\/?)\\s*>$/;\n\nconst ATTRIBUTE_RE =\n /([^\\s=/\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'>]+)))?/g;\n\nconst decodeEntities = (value: string): string =>\n value\n .replace(/&#x([0-9a-fA-F]+);?/g, (_m, hex: string) =>\n String.fromCodePoint(parseInt(hex, 16))\n )\n .replace(/&#(\\d+);?/g, (_m, dec: string) =>\n String.fromCodePoint(parseInt(dec, 10))\n )\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, '&');\n\n/** Entity-decode, drop control and whitespace characters, lower-case. Then a scheme cannot hide as `java\\tscript:`. */\nconst normaliseForSchemeCheck = (value: string): string =>\n decodeEntities(value)\n // biome-ignore lint/suspicious/noControlCharactersInRegex: Stripping control characters is the security check here.\n .replace(/[\\u0000-\\u0020\\u007f-\\u00a0\\u200b-\\u200f\\u2028\\u2029\\ufeff]/g, '')\n .toLowerCase();\n\nconst DANGEROUS_SCHEME_RE =\n /^(javascript|vbscript|livescript|mocha|data:text\\/html|data:application)/;\n\nconst isDangerousValue = (value: string): boolean => {\n const normalised = normaliseForSchemeCheck(value);\n return (\n DANGEROUS_SCHEME_RE.test(normalised) ||\n normalised.includes('javascript:') ||\n normalised.includes('vbscript:')\n );\n};\n\nconst SAFE_DATA_IMAGE_RE =\n /^data:image\\/(png|jpeg|jpg|gif|webp);base64,[a-z0-9+/=]+$/;\n\nconst isAcceptableHref = (value: string, element: string): boolean => {\n const normalised = normaliseForSchemeCheck(value);\n if (normalised.startsWith('#')) return true;\n return element === 'image' && SAFE_DATA_IMAGE_RE.test(normalised);\n};\n\n/**\n * A style that leaves the document is dropped whole. `url(#id)` is a same\n * document paint server reference (`fill: url(#gradient)`) and is the one\n * `url(` a logo legitimately uses, so it is blanked before the test.\n */\nconst LOCAL_URL_RE = /url\\s*\\(\\s*(['\"]?)#[^)'\"]*\\1\\s*\\)/gi;\nconst STYLE_ESCAPE_RE =\n /url\\s*\\(|@import|expression\\s*\\(|-moz-binding|behavior\\s*:/i;\n\nconst isSafeStyle = (value: string): boolean =>\n !STYLE_ESCAPE_RE.test(decodeEntities(value).replace(LOCAL_URL_RE, ''));\n\nexport type SanitizeSvgResult = {\n svg: string;\n /** Elements, attributes and declarations that were taken out. */\n removed: number;\n /** True when the input did not even look like an SVG document. */\n isSvg: boolean;\n};\n\ntype Token =\n | { kind: 'text'; raw: string }\n | { kind: 'tag'; raw: string }\n | { kind: 'special'; raw: string };\n\n/**\n * Split markup into text, tags, and the specials (comments, CDATA, DOCTYPE,\n * processing instructions) that need their own terminators.\n */\nconst tokenize = (input: string): Token[] => {\n const tokens: Token[] = [];\n let index = 0;\n const length = input.length;\n\n const pushSpecial = (end: number, terminator: string): void => {\n const close = input.indexOf(terminator, end);\n const stop = close === -1 ? length : close + terminator.length;\n tokens.push({ kind: 'special', raw: input.slice(index, stop) });\n index = stop;\n };\n\n while (index < length) {\n const open = input.indexOf('<', index);\n if (open === -1) {\n tokens.push({ kind: 'text', raw: input.slice(index) });\n break;\n }\n if (open > index) {\n tokens.push({ kind: 'text', raw: input.slice(index, open) });\n index = open;\n }\n if (input.startsWith('<!--', index)) {\n pushSpecial(index + 4, '-->');\n continue;\n }\n if (input.startsWith('<![CDATA[', index)) {\n pushSpecial(index + 9, ']]>');\n continue;\n }\n if (input.startsWith('<?', index)) {\n pushSpecial(index + 2, '?>');\n continue;\n }\n if (input.startsWith('<!', index)) {\n // DOCTYPE may carry an internal subset in [ ... ]; find the real end.\n const bracket = input.indexOf('[', index);\n const plainEnd = input.indexOf('>', index);\n if (bracket !== -1 && (plainEnd === -1 || bracket < plainEnd)) {\n const subsetEnd = input.indexOf(']', bracket);\n pushSpecial(subsetEnd === -1 ? index + 2 : subsetEnd, '>');\n } else {\n pushSpecial(index + 2, '>');\n }\n continue;\n }\n // Ordinary tag: ends at the first `>` outside a quoted attribute value.\n let cursor = index + 1;\n let quote: string | null = null;\n while (cursor < length) {\n const ch = input[cursor];\n if (quote) {\n if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n } else if (ch === '>') {\n break;\n }\n cursor += 1;\n }\n const stop = cursor >= length ? length : cursor + 1;\n tokens.push({ kind: 'tag', raw: input.slice(index, stop) });\n index = stop;\n }\n return tokens;\n};\n\nconst isXmlDeclaration = (raw: string): boolean => /^<\\?xml\\b/i.test(raw);\n\n/**\n * Filter a tag's attributes. Returns the rebuilt attribute string (or `null`\n * when the element itself must go because its only href was hostile) and the\n * number of attributes dropped.\n */\nconst cleanAttributes = (\n element: string,\n rawAttributes: string\n): { attributes: string; removed: number; dropElement: boolean } => {\n let removed = 0;\n let dropElement = false;\n const kept: string[] = [];\n ATTRIBUTE_RE.lastIndex = 0;\n let match = ATTRIBUTE_RE.exec(rawAttributes);\n while (match !== null) {\n const [whole, name, dq, sq, bare] = match;\n match = ATTRIBUTE_RE.exec(rawAttributes);\n if (!name || name === '/') continue;\n const lower = name.toLowerCase();\n const value = dq ?? sq ?? bare ?? '';\n\n if (lower.startsWith('on')) {\n removed += 1;\n continue;\n }\n const isNamespaceDeclaration =\n lower === 'xmlns' || lower.startsWith('xmlns:');\n const isData = lower.startsWith('data-');\n if (!isNamespaceDeclaration && !isData && !ALLOWED_ATTRIBUTES.has(lower)) {\n removed += 1;\n continue;\n }\n if (isDangerousValue(value)) {\n removed += 1;\n continue;\n }\n if (lower === 'href' || lower === 'xlink:href') {\n if (!isAcceptableHref(value, element)) {\n removed += 1;\n // An <image> or <use> whose only reason to exist is an external\n // reference is not a logo any more once that reference is gone.\n if (element === 'image' || element === 'use') dropElement = true;\n continue;\n }\n }\n if (lower === 'style' && !isSafeStyle(value)) {\n removed += 1;\n continue;\n }\n kept.push(whole.trim());\n }\n return {\n attributes: kept.length ? ` ${kept.join(' ')}` : '',\n removed,\n dropElement,\n };\n};\n\n/**\n * Sentinel pushed before a `<style>` open tag so the whole element can be\n * unwound if its content turns out to reach outside the file. NUL bytes cannot\n * occur in well formed XML text, so no real chunk can collide with it, and it\n * is filtered out before the chunks are joined.\n */\nconst STYLE_OPEN_MARKER = '\\u0000style-open\\u0000';\n\nexport const sanitizeSvg = (input: string): SanitizeSvgResult => {\n const tokens = tokenize(input);\n const out: string[] = [];\n let removed = 0;\n let isSvg = false;\n\n // Depth inside a dropped element: while > 0 every token is discarded. The\n // stack tracks which open tags were dropped so the matching close is too.\n let dropDepth = 0;\n const dropStack: string[] = [];\n // Inside <style>: content must be checked as CSS, not copied blind.\n let styleBuffer: string[] | null = null;\n\n for (const token of tokens) {\n if (token.kind === 'special') {\n if (isXmlDeclaration(token.raw) && dropDepth === 0) {\n out.push(token.raw);\n } else {\n removed += 1;\n }\n continue;\n }\n\n if (token.kind === 'text') {\n if (dropDepth > 0) continue;\n if (styleBuffer) {\n styleBuffer.push(token.raw);\n } else {\n out.push(token.raw);\n }\n continue;\n }\n\n const parsed = TAG_RE.exec(token.raw);\n if (!parsed) {\n // Unparseable tag text. Inside a drop it goes anyway; outside, it is\n // not markup we can vouch for, so it goes too.\n removed += 1;\n continue;\n }\n const [, closing, rawName, rawAttributes, selfClosingSlash] = parsed;\n const name = rawName.toLowerCase();\n const isClosing = closing === '/';\n const isSelfClosing = selfClosingSlash === '/';\n\n if (name === 'svg') isSvg = true;\n\n if (dropDepth > 0) {\n if (isClosing) {\n if (dropStack[dropStack.length - 1] === name) {\n dropStack.pop();\n dropDepth -= 1;\n }\n } else if (!isSelfClosing) {\n dropStack.push(name);\n dropDepth += 1;\n }\n continue;\n }\n\n if (isClosing) {\n if (name === 'style' && styleBuffer) {\n const css = styleBuffer.join('');\n styleBuffer = null;\n if (isSafeStyle(css)) {\n out.push(css, token.raw);\n } else {\n // Drop the <style> we already emitted the open tag for.\n const openIndex = out.lastIndexOf(STYLE_OPEN_MARKER);\n if (openIndex !== -1) out.splice(openIndex);\n removed += 1;\n }\n continue;\n }\n if (ALLOWED_ELEMENTS.has(name)) out.push(token.raw);\n continue;\n }\n\n if (!ALLOWED_ELEMENTS.has(name)) {\n removed += 1;\n if (!isSelfClosing) {\n dropStack.push(name);\n dropDepth += 1;\n }\n continue;\n }\n\n const cleaned = cleanAttributes(name, rawAttributes);\n removed += cleaned.removed;\n if (cleaned.dropElement) {\n removed += 1;\n if (!isSelfClosing) {\n dropStack.push(name);\n dropDepth += 1;\n }\n continue;\n }\n\n const rebuilt = `<${rawName}${cleaned.attributes}${\n isSelfClosing ? '/' : ''\n }>`;\n if (name === 'style' && !isSelfClosing) {\n out.push(STYLE_OPEN_MARKER, rebuilt);\n styleBuffer = [];\n continue;\n }\n out.push(rebuilt);\n }\n\n // An unterminated <style> at EOF: keep nothing of it.\n if (styleBuffer) {\n const openIndex = out.lastIndexOf(STYLE_OPEN_MARKER);\n if (openIndex !== -1) out.splice(openIndex);\n removed += 1;\n }\n\n return {\n svg: out.filter((chunk) => chunk !== STYLE_OPEN_MARKER).join(''),\n removed,\n isSvg,\n };\n};\n","/**\n * Shared shapes for the custom chart package pipeline (DAT-925).\n * Problem is the one error shape used by the manifest validator, the bundle\n * builder, the icon check and the backend API (section 5 of the brief).\n */\nexport interface Problem {\n code: string;\n path: string;\n message: string;\n}\n\nexport type CustomChartFieldType = 'string' | 'number' | 'boolean';\n\nexport interface CustomChartSlot {\n id: string;\n label: string;\n role: 'dimension' | 'measure';\n types: CustomChartFieldType[];\n required: boolean;\n description?: string;\n}\n\nexport type CustomChartOption = {\n id: string;\n label: string;\n group?: string;\n} & (\n | { type: 'boolean'; default: boolean }\n | { type: 'number'; default: number; min: number; max: number; step?: number }\n | { type: 'string'; default: string; maxLength: number }\n | {\n type: 'select';\n default: string;\n choices: { value: string; label: string }[];\n }\n | { type: 'color'; default: string }\n);\n\nexport interface CustomChartTranslation {\n name?: string;\n description?: string;\n slots?: Record<string, { label?: string; description?: string }>;\n options?: Record<\n string,\n { label?: string; group?: string; choices?: Record<string, string> }\n >;\n}\n\nexport interface CustomChartManifest {\n schemaVersion: 1 | 2;\n id: string;\n name: string;\n version?: string;\n description?: string;\n slots: CustomChartSlot[];\n options: CustomChartOption[];\n translations?: Record<string, CustomChartTranslation>;\n}\n\n/** The four artifacts a build produces and an upload sends. */\nexport interface CustomChartBundle {\n manifest: CustomChartManifest;\n bundleJs: string;\n bundleCss?: string;\n iconSvg: string;\n}\n\nexport const MAX_MANIFEST_BYTES = 32 * 1024;\nexport const MAX_BUNDLE_JS_BYTES = 2 * 1024 * 1024;\nexport const MAX_BUNDLE_CSS_BYTES = 256 * 1024;\nexport const MAX_ICON_BYTES = 16 * 1024;\nexport const MAX_SLOTS = 16;\nexport const MAX_OPTIONS = 32;\n","import { sanitizeSvg } from './sanitize-svg.js';\nimport { MAX_ICON_BYTES, type Problem } from './types.js';\n\n/**\n * Strict SVG check for icon.svg (brief sections 4 and 5). Nothing is rewritten:\n * an icon either passes every rule or is refused with a problem that says what\n * to remove. The check is the backend's own allow-list sanitiser\n * (`sanitize-svg.ts`, a copy of the server file): the icon is refused when the\n * sanitiser would remove anything, when it carries an `<image>` element, or\n * when it is not one `<svg>` element. The backend runs the same sanitiser on\n * upload and refuses with the same codes: bundle.icon.required,\n * bundle.icon.size, bundle.icon.notSvg, bundle.icon.unsafe. The message names\n * the rule that tripped when one of the common ones did.\n */\nconst UNSAFE = 'bundle.icon.unsafe';\nconst RULES: { pattern: RegExp; message: string }[] = [\n {\n pattern: /<\\s*script\\b/i,\n message: 'Remove every <script> element from icon.svg.',\n },\n {\n pattern: /<\\s*foreignObject\\b/i,\n message: 'Remove every <foreignObject> element from icon.svg.',\n },\n {\n pattern: /<\\s*image\\b/i,\n message:\n 'Remove every <image> element from icon.svg. Draw with paths and shapes.',\n },\n {\n pattern: /[\\s/]on[a-z]+\\s*=/i,\n message: 'Remove every on*= event attribute from icon.svg.',\n },\n { pattern: /<!--/, message: 'Remove every <!-- comment --> from icon.svg.' },\n {\n pattern: /<!(?:ENTITY|DOCTYPE)\\b/i,\n message: 'Remove the DOCTYPE and entity declarations from icon.svg.',\n },\n {\n pattern: /<!\\[CDATA\\[/,\n message: 'Remove every CDATA section from icon.svg.',\n },\n {\n pattern: /(?:xlink:)?href\\s*=\\s*[\"']\\s*(?!#)/i,\n message:\n 'Every href in icon.svg must start with # (no external or data references).',\n },\n {\n pattern: /javascript\\s*:/i,\n message: 'Remove every javascript: reference from icon.svg.',\n },\n {\n pattern: /@import|expression\\s*\\(|-moz-binding/i,\n message:\n 'Remove @import, expression() and -moz-binding from icon.svg styles.',\n },\n {\n pattern: /url\\s*\\(\\s*['\"]?\\s*(?!#)/i,\n message: 'Every url() in icon.svg must point at a same-document #id.',\n },\n];\nconst GENERIC_UNSAFE =\n 'icon.svg must use only plain SVG drawing elements and attributes: no script, event handlers, foreignObject, image, animation, external hrefs, url() styles, comments, DOCTYPE or unknown attributes.';\n\nconst XML_DECLARATION = /^\\s*<\\?xml[^>]*\\?>\\s*/i;\n\n/** One `<svg ...>...</svg>` (or `<svg .../>`) and nothing else, after the XML declaration. */\nexport function isSingleSvgRoot(svg: string): boolean {\n const body = svg.replace(/^/, '').replace(XML_DECLARATION, '').trim();\n return (\n /^<svg[\\s>][\\s\\S]*<\\/svg>$/i.test(body) || /^<svg\\b[^>]*\\/>$/i.test(body)\n );\n}\n\nexport function validateIcon(svg: unknown, path = '/icon.svg'): Problem[] {\n if (typeof svg !== 'string' || svg.trim().length === 0) {\n return [\n {\n code: 'bundle.icon.required',\n path,\n message: 'icon.svg is required and must not be empty.',\n },\n ];\n }\n if (Buffer.byteLength(svg, 'utf8') > MAX_ICON_BYTES) {\n return [\n {\n code: 'bundle.icon.size',\n path,\n message: `icon.svg must be at most ${MAX_ICON_BYTES} bytes.`,\n },\n ];\n }\n const cleaned = sanitizeSvg(svg);\n if (!cleaned.isSvg || !isSingleSvgRoot(cleaned.svg)) {\n return [\n {\n code: 'bundle.icon.notSvg',\n path,\n message: 'icon.svg must be one <svg> element with nothing after it.',\n },\n ];\n }\n if (cleaned.removed > 0 || /<\\s*image\\b/i.test(svg)) {\n const rule = RULES.find((candidate) => candidate.pattern.test(svg));\n return [\n { code: UNSAFE, path, message: rule ? rule.message : GENERIC_UNSAFE },\n ];\n }\n return [];\n}\n\n/**\n * The form the CLI writes to dist/icon.svg and uploads: BOM, XML declaration\n * and comments removed, trimmed. The server refuses a comment rather than\n * stripping it, so the build strips them here; everything else is left as the\n * author wrote it and must already pass validateIcon.\n */\nexport function sanitizeIcon(svg: string): string {\n return svg\n .replace(/^/, '')\n .replace(XML_DECLARATION, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .trim();\n}\n","import { z } from 'zod';\nimport {\n type CustomChartManifest,\n MAX_MANIFEST_BYTES,\n MAX_OPTIONS,\n MAX_SLOTS,\n type Problem,\n} from './types.js';\n\n/**\n * Manifest v2 validator (brief section 3). It is a strict superset of the\n * plugin's sandbox manifest v1: every v1 manifest validates with\n * schemaVersion 1, and schemaVersion 2 unlocks version, description, the\n * color option type, the number step, the option group, slot descriptions and\n * translations. Unknown keys are refused at every level.\n *\n * The checks run in the plugin parser's order, step for step, and the backend\n * (`serverless/express/src/lib/customCharts/manifest.ts`) runs the same steps,\n * so the three validators produce the same problem list for the same\n * manifest. The cross-repo fixtures in tests/fixtures/custom-chart-manifests\n * pin the first code for every invalid case.\n *\n * 1. object, schemaVersion (stop on failure)\n * 2. top-level unknown and missing keys (stop on failure)\n * 3. id, name, version, description\n * 4. slots: shape and count, then each slot (unknown and missing keys\n * first, then the fields), then duplicate ids\n * 5. options: shape and count, then each option (reserved id, type,\n * unknown and missing keys, then the fields), then duplicate ids\n * 6. translations, only when everything above is clean\n * 7. size, only when everything above is clean\n */\n\nconst ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst FORBIDDEN_IDS = ['constructor', 'prototype', '__proto__'];\nconst LANGUAGE_PATTERN = /^[a-z]{2}(-[A-Z]{2})?$/;\nconst SEMVER_PATTERN =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[0-9A-Za-z.-]+)?(\\+[0-9A-Za-z.-]+)?$/;\nconst COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;\nconst FIELD_TYPES = ['string', 'number', 'boolean'];\nconst MAX_TEXT = 256;\nconst MAX_DESCRIPTION = 500;\nconst MAX_GROUP = 64;\nconst MAX_CHOICES = 32;\nconst MAX_STRING_OPTION_LENGTH = 1024;\n\nconst V1_TOP_KEYS = ['schemaVersion', 'id', 'name', 'slots', 'options'];\nconst V2_TOP_EXTRA_KEYS = ['version', 'description', 'translations'];\nconst V1_SLOT_KEYS = ['id', 'label', 'role', 'types', 'required'];\nconst V2_SLOT_EXTRA_KEYS = ['description'];\nconst OPTION_BASE_KEYS = ['id', 'label', 'type', 'default'];\nconst OPTION_TYPE_KEYS: Record<string, string[]> = {\n boolean: [],\n number: ['min', 'max'],\n string: ['maxLength'],\n select: ['choices'],\n color: [],\n};\nconst V2_OPTION_EXTRA_KEYS: Record<string, string[]> = {\n boolean: ['group'],\n number: ['group', 'step'],\n string: ['group'],\n select: ['group'],\n color: ['group'],\n};\nconst TRANSLATION_KEYS = ['name', 'description', 'slots', 'options'];\nconst SLOT_TRANSLATION_KEYS = ['label', 'description'];\nconst OPTION_TRANSLATION_KEYS = ['label', 'group', 'choices'];\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype;\n\nexport const isId = (value: unknown): value is string =>\n typeof value === 'string' &&\n ID_PATTERN.test(value) &&\n !FORBIDDEN_IDS.includes(value);\n\nconst isText = (value: unknown, max = MAX_TEXT): value is string =>\n typeof value === 'string' && value.length > 0 && value.length <= max;\n\n/** A translated string may be empty: the plugin renders it as given. */\nconst isTranslationText = (value: unknown): value is string =>\n typeof value === 'string' && value.length <= MAX_TEXT;\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nexport const jsonBytes = (value: unknown): number =>\n Buffer.byteLength(JSON.stringify(value), 'utf8');\n\nclass Collector {\n readonly problems: Problem[] = [];\n\n add(code: string, path: string, message: string): void {\n this.problems.push({ code, path, message });\n }\n\n /**\n * Unknown keys report `<scope>.unknownKey`, one per key; a missing required\n * key reports `missingCode(key)`. Returns false when anything was reported,\n * so the caller can stop looking at a shape it cannot trust.\n */\n checkKeys(\n value: Record<string, unknown>,\n path: string,\n scope: string,\n required: readonly string[],\n optional: readonly string[],\n missingCode: (key: string) => string = (key) => `${scope}.${key}`\n ): boolean {\n const allowed = new Set([...required, ...optional]);\n let ok = true;\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) {\n this.add(\n `${scope}.unknownKey`,\n `${path}/${key}`,\n `Remove \"${key}\". It is not a known key here.`\n );\n ok = false;\n }\n }\n for (const key of required) {\n if (!Object.hasOwn(value, key)) {\n this.add(\n missingCode(key),\n `${path}/${key}`,\n `Add the required key \"${key}\".`\n );\n ok = false;\n }\n }\n return ok;\n }\n}\n\nfunction validateSlot(\n c: Collector,\n value: unknown,\n path: string,\n v2: boolean\n): void {\n if (!isRecord(value)) {\n c.add('manifest.slot.invalid', path, 'A slot must be an object.');\n return;\n }\n if (\n !c.checkKeys(\n value,\n path,\n 'manifest.slot',\n V1_SLOT_KEYS,\n v2 ? V2_SLOT_EXTRA_KEYS : []\n )\n )\n return;\n if (!isId(value.id)) {\n c.add(\n 'manifest.slot.id',\n `${path}/id`,\n 'A slot id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters.'\n );\n }\n if (!isText(value.label)) {\n c.add(\n 'manifest.slot.label',\n `${path}/label`,\n `A slot label is 1 to ${MAX_TEXT} characters.`\n );\n }\n const role = value.role;\n if (role !== 'dimension' && role !== 'measure') {\n c.add(\n 'manifest.slot.role',\n `${path}/role`,\n 'A slot role is \"dimension\" or \"measure\".'\n );\n }\n if (typeof value.required !== 'boolean') {\n c.add(\n 'manifest.slot.required',\n `${path}/required`,\n 'required is true or false.'\n );\n }\n const types = value.types;\n const typesOk =\n Array.isArray(types) &&\n types.length > 0 &&\n types.length <= 3 &&\n new Set(types).size === types.length &&\n types.every((type) => FIELD_TYPES.includes(type as string));\n if (!typesOk) {\n c.add(\n 'manifest.slot.types',\n `${path}/types`,\n 'types is a list of 1 to 3 distinct values from \"string\", \"number\" and \"boolean\".'\n );\n } else if (\n role === 'measure' &&\n (types.length !== 1 || (types as string[])[0] !== 'number')\n ) {\n c.add(\n 'manifest.slot.types',\n `${path}/types`,\n 'A measure slot accepts only [\"number\"].'\n );\n }\n if (Object.hasOwn(value, 'description') && !isText(value.description)) {\n c.add(\n 'manifest.slot.description',\n `${path}/description`,\n `A slot description is 1 to ${MAX_TEXT} characters.`\n );\n }\n}\n\nfunction validateOption(\n c: Collector,\n value: unknown,\n path: string,\n v2: boolean\n): void {\n if (!isRecord(value)) {\n c.add('manifest.option.invalid', path, 'An option must be an object.');\n return;\n }\n // Reserved before anything else: the author needs to hear \"reserved\" first.\n const id = value.id;\n if (typeof id === 'string' && (id === 'theme' || id.startsWith('theme.'))) {\n c.add(\n 'manifest.option.reserved',\n `${path}/id`,\n 'The option id \"theme\" (and any id starting with \"theme.\") is reserved for the host theme.'\n );\n return;\n }\n const type = typeof value.type === 'string' ? value.type : '';\n const typeKeys = Object.hasOwn(OPTION_TYPE_KEYS, type)\n ? OPTION_TYPE_KEYS[type]\n : undefined;\n if (!typeKeys || (type === 'color' && !v2)) {\n c.add(\n 'manifest.option.type',\n `${path}/type`,\n v2\n ? 'An option type is one of \"boolean\", \"number\", \"string\", \"select\", \"color\".'\n : 'An option type is one of \"boolean\", \"number\", \"string\", \"select\" (color needs schemaVersion 2).'\n );\n return;\n }\n if (\n !c.checkKeys(\n value,\n path,\n 'manifest.option',\n [...OPTION_BASE_KEYS, ...typeKeys],\n v2 ? V2_OPTION_EXTRA_KEYS[type] : []\n )\n )\n return;\n if (!isId(id)) {\n c.add(\n 'manifest.option.id',\n `${path}/id`,\n 'An option id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters.'\n );\n }\n if (!isText(value.label)) {\n c.add(\n 'manifest.option.label',\n `${path}/label`,\n `An option label is 1 to ${MAX_TEXT} characters.`\n );\n }\n if (Object.hasOwn(value, 'group') && !isText(value.group, MAX_GROUP)) {\n c.add(\n 'manifest.option.group',\n `${path}/group`,\n `An option group is 1 to ${MAX_GROUP} characters.`\n );\n }\n switch (type) {\n case 'boolean':\n if (typeof value.default !== 'boolean') {\n c.add(\n 'manifest.option.default',\n `${path}/default`,\n 'A boolean default is true or false.'\n );\n }\n break;\n case 'number': {\n const rangeOk =\n isFiniteNumber(value.min) &&\n isFiniteNumber(value.max) &&\n value.min <= value.max;\n if (!rangeOk) {\n c.add(\n 'manifest.option.range',\n `${path}/min`,\n 'Set finite min and max with min <= max.'\n );\n break;\n }\n const min = value.min as number;\n const max = value.max as number;\n if (\n !isFiniteNumber(value.default) ||\n value.default < min ||\n value.default > max\n ) {\n c.add(\n 'manifest.option.default',\n `${path}/default`,\n 'A number default is a finite number between min and max.'\n );\n }\n if (\n Object.hasOwn(value, 'step') &&\n (!isFiniteNumber(value.step) ||\n value.step <= 0 ||\n value.step > max - min)\n ) {\n c.add(\n 'manifest.option.step',\n `${path}/step`,\n 'step is a positive number no larger than max - min.'\n );\n }\n break;\n }\n case 'string': {\n const maxLength = value.maxLength;\n if (\n !isFiniteNumber(maxLength) ||\n !Number.isInteger(maxLength) ||\n maxLength < 1 ||\n maxLength > MAX_STRING_OPTION_LENGTH\n ) {\n c.add(\n 'manifest.option.maxLength',\n `${path}/maxLength`,\n `A string option needs an integer \"maxLength\" from 1 to ${MAX_STRING_OPTION_LENGTH}.`\n );\n break;\n }\n if (\n typeof value.default !== 'string' ||\n value.default.length > maxLength\n ) {\n c.add(\n 'manifest.option.default',\n `${path}/default`,\n 'A string default is a string no longer than maxLength.'\n );\n }\n break;\n }\n case 'select': {\n const choices = value.choices;\n const choicesOk =\n Array.isArray(choices) &&\n choices.length > 0 &&\n choices.length <= MAX_CHOICES &&\n choices.every(\n (choice) =>\n isRecord(choice) &&\n Object.keys(choice).length === 2 &&\n isId(choice.value) &&\n isText(choice.label)\n ) &&\n new Set(choices.map((choice) => choice.value)).size === choices.length;\n if (!choicesOk) {\n c.add(\n 'manifest.option.choices',\n `${path}/choices`,\n `choices is a list of 1 to ${MAX_CHOICES} distinct { value, label } pairs; a value follows the id rule.`\n );\n break;\n }\n if (!choices.some((choice) => choice.value === value.default)) {\n c.add(\n 'manifest.option.default',\n `${path}/default`,\n 'A select default is the value of one of its choices.'\n );\n }\n break;\n }\n case 'color':\n if (\n typeof value.default !== 'string' ||\n !COLOR_PATTERN.test(value.default)\n ) {\n c.add(\n 'manifest.option.color',\n `${path}/default`,\n 'A color default is a 6 digit hex colour like \"#3366cc\".'\n );\n }\n break;\n default:\n break;\n }\n}\n\n/** Runs only on a manifest whose slots and options are already valid. */\nfunction validateTranslations(\n c: Collector,\n value: unknown,\n slots: { id: string }[],\n options: { id: string; type: string; choices?: { value: string }[] }[]\n): void {\n const path = '/translations';\n if (!isRecord(value)) {\n c.add(\n 'manifest.translations.invalid',\n path,\n 'translations is an object keyed by language code.'\n );\n return;\n }\n for (const [language, entry] of Object.entries(value)) {\n const langPath = `${path}/${language}`;\n if (!LANGUAGE_PATTERN.test(language)) {\n c.add(\n 'manifest.translations.language',\n langPath,\n `\"${language}\" is not a language code like \"fr\" or \"pt-BR\".`\n );\n continue;\n }\n if (!isRecord(entry)) {\n c.add(\n 'manifest.translations.invalid',\n langPath,\n 'A translation is an object with optional name, description, slots and options.'\n );\n continue;\n }\n if (\n !c.checkKeys(\n entry,\n langPath,\n 'manifest.translations',\n [],\n TRANSLATION_KEYS\n )\n )\n continue;\n for (const key of ['name', 'description'] as const) {\n if (Object.hasOwn(entry, key) && !isTranslationText(entry[key])) {\n c.add(\n 'manifest.translations.text',\n `${langPath}/${key}`,\n `A translated string is at most ${MAX_TEXT} characters.`\n );\n }\n }\n if (Object.hasOwn(entry, 'slots')) {\n const entrySlots = entry.slots;\n if (!isRecord(entrySlots)) {\n c.add(\n 'manifest.translations.invalid',\n `${langPath}/slots`,\n 'slots is an object keyed by slot id.'\n );\n } else {\n for (const [slotId, slotEntry] of Object.entries(entrySlots)) {\n const slotPath = `${langPath}/slots/${slotId}`;\n if (!slots.some((slot) => slot.id === slotId)) {\n c.add(\n 'manifest.translations.slot',\n slotPath,\n `\"${slotId}\" is not a slot id in this manifest.`\n );\n continue;\n }\n if (!isRecord(slotEntry)) {\n c.add(\n 'manifest.translations.invalid',\n slotPath,\n 'A slot translation is an object with optional label and description.'\n );\n continue;\n }\n if (\n !c.checkKeys(\n slotEntry,\n slotPath,\n 'manifest.translations',\n [],\n SLOT_TRANSLATION_KEYS\n )\n )\n continue;\n for (const key of ['label', 'description'] as const) {\n if (\n Object.hasOwn(slotEntry, key) &&\n !isTranslationText(slotEntry[key])\n ) {\n c.add(\n 'manifest.translations.text',\n `${slotPath}/${key}`,\n `A translated string is at most ${MAX_TEXT} characters.`\n );\n }\n }\n }\n }\n }\n if (Object.hasOwn(entry, 'options')) {\n const entryOptions = entry.options;\n if (!isRecord(entryOptions)) {\n c.add(\n 'manifest.translations.invalid',\n `${langPath}/options`,\n 'options is an object keyed by option id.'\n );\n } else {\n for (const [optionId, optionEntry] of Object.entries(entryOptions)) {\n const optionPath = `${langPath}/options/${optionId}`;\n const option = options.find((item) => item.id === optionId);\n if (!option) {\n c.add(\n 'manifest.translations.option',\n optionPath,\n `\"${optionId}\" is not an option id in this manifest.`\n );\n continue;\n }\n if (!isRecord(optionEntry)) {\n c.add(\n 'manifest.translations.invalid',\n optionPath,\n 'An option translation is an object with optional label, group and choices.'\n );\n continue;\n }\n if (\n !c.checkKeys(\n optionEntry,\n optionPath,\n 'manifest.translations',\n [],\n OPTION_TRANSLATION_KEYS\n )\n )\n continue;\n for (const key of ['label', 'group'] as const) {\n if (\n Object.hasOwn(optionEntry, key) &&\n !isTranslationText(optionEntry[key])\n ) {\n c.add(\n 'manifest.translations.text',\n `${optionPath}/${key}`,\n `A translated string is at most ${MAX_TEXT} characters.`\n );\n }\n }\n if (!Object.hasOwn(optionEntry, 'choices')) continue;\n const choices = optionEntry.choices;\n if (!isRecord(choices)) {\n c.add(\n 'manifest.translations.invalid',\n `${optionPath}/choices`,\n 'choices is an object keyed by choice value.'\n );\n continue;\n }\n for (const [choiceValue, label] of Object.entries(choices)) {\n const choicePath = `${optionPath}/choices/${choiceValue}`;\n if (\n option.type !== 'select' ||\n !(option.choices ?? []).some(\n (choice) => choice.value === choiceValue\n )\n ) {\n c.add(\n 'manifest.translations.choice',\n choicePath,\n `\"${choiceValue}\" is not a choice of option \"${optionId}\".`\n );\n } else if (!isTranslationText(label)) {\n c.add(\n 'manifest.translations.text',\n choicePath,\n `A translated string is at most ${MAX_TEXT} characters.`\n );\n }\n }\n }\n }\n }\n }\n}\n\n/**\n * Validate a manifest value. Returns every problem found, first problem first.\n * An empty array means the manifest is valid.\n */\nexport function validateManifest(value: unknown): Problem[] {\n const c = new Collector();\n if (!isRecord(value)) {\n c.add('manifest.invalid', '', 'manifest.json must be a JSON object.');\n return c.problems;\n }\n\n // 1. schemaVersion\n const schemaVersion = value.schemaVersion;\n if (schemaVersion !== 1 && schemaVersion !== 2) {\n c.add(\n 'manifest.schemaVersion.unsupported',\n '/schemaVersion',\n 'schemaVersion must be 1 or 2.'\n );\n return c.problems;\n }\n const v2 = schemaVersion === 2;\n\n // 2. unknown and missing top-level keys\n if (\n !c.checkKeys(\n value,\n '',\n 'manifest',\n V1_TOP_KEYS,\n v2 ? V2_TOP_EXTRA_KEYS : [],\n (key) => `manifest.${key}.required`\n )\n ) {\n return c.problems;\n }\n\n // 3. id, name and the v2 labels (on v1 the keys were already refused above)\n if (!isId(value.id)) {\n c.add(\n 'manifest.id.invalid',\n '/id',\n 'id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters. It becomes the chart type \"custom:<id>\".'\n );\n }\n if (!isText(value.name)) {\n c.add(\n 'manifest.name.invalid',\n '/name',\n `name is 1 to ${MAX_TEXT} characters.`\n );\n }\n if (\n Object.hasOwn(value, 'version') &&\n (typeof value.version !== 'string' || !SEMVER_PATTERN.test(value.version))\n ) {\n c.add(\n 'manifest.version.invalid',\n '/version',\n 'version is a semver string like \"1.2.0\".'\n );\n }\n if (\n Object.hasOwn(value, 'description') &&\n !isText(value.description, MAX_DESCRIPTION)\n ) {\n c.add(\n 'manifest.description.invalid',\n '/description',\n `description is 1 to ${MAX_DESCRIPTION} characters.`\n );\n }\n\n // 4. slots\n const slots = value.slots;\n if (!Array.isArray(slots)) {\n c.add('manifest.slots.invalid', '/slots', 'slots must be an array.');\n } else if (slots.length === 0) {\n c.add('manifest.slots.empty', '/slots', 'Declare at least one slot.');\n } else if (slots.length > MAX_SLOTS) {\n c.add(\n 'manifest.slots.tooMany',\n '/slots',\n `Declare at most ${MAX_SLOTS} slots.`\n );\n } else {\n for (const [index, slot] of slots.entries()) {\n validateSlot(c, slot, `/slots/${index}`, v2);\n }\n const seen = new Set<string>();\n slots.forEach((slot, index) => {\n if (!isRecord(slot) || typeof slot.id !== 'string') return;\n if (seen.has(slot.id)) {\n c.add(\n 'manifest.slot.duplicate',\n `/slots/${index}/id`,\n `Slot id \"${slot.id}\" is used more than once.`\n );\n }\n seen.add(slot.id);\n });\n }\n\n // 5. options\n const options = value.options;\n if (!Array.isArray(options)) {\n c.add(\n 'manifest.options.invalid',\n '/options',\n 'options must be an array (it may be empty).'\n );\n } else if (options.length > MAX_OPTIONS) {\n c.add(\n 'manifest.options.tooMany',\n '/options',\n `Declare at most ${MAX_OPTIONS} options.`\n );\n } else {\n for (const [index, option] of options.entries()) {\n validateOption(c, option, `/options/${index}`, v2);\n }\n const seen = new Set<string>();\n options.forEach((option, index) => {\n if (!isRecord(option) || typeof option.id !== 'string') return;\n if (seen.has(option.id)) {\n c.add(\n 'manifest.option.duplicate',\n `/options/${index}/id`,\n `Option id \"${option.id}\" is used more than once.`\n );\n }\n seen.add(option.id);\n });\n }\n\n // 6. translations, only on an otherwise clean manifest (v2 only; on v1 the key is unknown)\n if (c.problems.length === 0 && Object.hasOwn(value, 'translations')) {\n validateTranslations(\n c,\n value.translations,\n slots as { id: string }[],\n options as { id: string; type: string; choices?: { value: string }[] }[]\n );\n }\n\n // 7. size, only on an otherwise clean manifest\n if (c.problems.length === 0 && jsonBytes(value) > MAX_MANIFEST_BYTES) {\n c.add(\n 'manifest.size',\n '',\n `manifest.json must be at most ${MAX_MANIFEST_BYTES} bytes as JSON.`\n );\n }\n\n return c.problems;\n}\n\n/** Parse a manifest; returns null when validateManifest reports anything. */\nexport function parseManifest(value: unknown): CustomChartManifest | null {\n return validateManifest(value).length === 0\n ? (value as CustomChartManifest)\n : null;\n}\n\n/** Zod view of manifest v2 for tool input schemas. Shape only: validateManifest owns the rules. */\nconst slotSchema = z.object({\n id: z.string(),\n label: z.string(),\n role: z.enum(['dimension', 'measure']),\n types: z.array(z.enum(['string', 'number', 'boolean'])),\n required: z.boolean(),\n description: z.string().optional(),\n});\n\nconst optionSchema = z.object({\n id: z.string(),\n label: z.string(),\n type: z.enum(['boolean', 'number', 'string', 'select', 'color']),\n default: z.union([z.string(), z.number(), z.boolean()]),\n min: z.number().optional(),\n max: z.number().optional(),\n step: z.number().optional(),\n maxLength: z.number().optional(),\n choices: z\n .array(z.object({ value: z.string(), label: z.string() }))\n .optional(),\n group: z.string().optional(),\n});\n\nexport const manifestSchema = z.object({\n schemaVersion: z.union([z.literal(1), z.literal(2)]),\n id: z.string(),\n name: z.string(),\n version: z.string().optional(),\n description: z.string().optional(),\n slots: z.array(slotSchema),\n options: z.array(optionSchema),\n translations: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type ManifestSlotInput = z.infer<typeof slotSchema>;\nexport type ManifestOptionInput = z.infer<typeof optionSchema>;\nexport {\n optionSchema as manifestOptionSchema,\n slotSchema as manifestSlotSchema,\n};\n\n/** Deep key sort used by the content hash (brief section 5). Arrays keep their order. */\nexport function sortKeys<T>(value: T): T {\n if (Array.isArray(value)) return value.map((item) => sortKeys(item)) as T;\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort())\n out[key] = sortKeys(value[key]);\n return out as T;\n }\n return value;\n}\n","import { strFromU8, strToU8, unzipSync, zipSync } from 'fflate';\n\n/**\n * dist/bundle.zip is for humans (drag and drop upload in the app). The API\n * takes JSON. The zip holds exactly the four build outputs at its root.\n */\nexport const BUNDLE_ZIP_FILES = [\n 'index.js',\n 'manifest.json',\n 'icon.svg',\n 'index.css',\n] as const;\nexport type BundleZipFile = (typeof BUNDLE_ZIP_FILES)[number];\n\nexport type BundleZipInput = Partial<Record<BundleZipFile, string>> &\n Pick<\n Record<BundleZipFile, string>,\n 'index.js' | 'manifest.json' | 'icon.svg'\n >;\n\nexport function writeBundleZip(files: BundleZipInput): Uint8Array {\n const entries: Record<string, Uint8Array> = {};\n for (const name of BUNDLE_ZIP_FILES) {\n const content = files[name];\n if (typeof content === 'string') entries[name] = strToU8(content);\n }\n // Fixed mtime keeps the zip bytes stable for the same inputs.\n return zipSync(entries, {\n level: 6,\n mtime: new Date('2000-01-01T00:00:00Z'),\n });\n}\n\nexport function readBundleZip(\n bytes: Uint8Array\n): Partial<Record<BundleZipFile, string>> {\n const unzipped = unzipSync(bytes, {\n filter: (file) =>\n (BUNDLE_ZIP_FILES as readonly string[]).includes(file.name),\n });\n const files: Partial<Record<BundleZipFile, string>> = {};\n for (const name of BUNDLE_ZIP_FILES) {\n if (unzipped[name]) files[name] = strFromU8(unzipped[name]);\n }\n return files;\n}\n"],"mappings":"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","names":["existsSync","readFileSync","join","resolve","resolve","join","existsSync","readFileSync"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/hosted/types.ts
|
|
4
|
+
var HOSTED_SCOPES = [
|
|
5
|
+
"mcp:dashboards:read",
|
|
6
|
+
"mcp:dashboards:write",
|
|
7
|
+
"mcp:datamarts:read",
|
|
8
|
+
"mcp:datamarts:write",
|
|
9
|
+
"mcp:embeds:write",
|
|
10
|
+
"mcp:query",
|
|
11
|
+
"mcp:custom-charts:read",
|
|
12
|
+
"mcp:custom-charts:write"
|
|
13
|
+
];
|
|
14
|
+
var HostedAuthError = class extends Error {
|
|
15
|
+
constructor(status, code, detail, retryAfterMs) {
|
|
16
|
+
super(code);
|
|
17
|
+
this.status = status;
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.detail = detail;
|
|
20
|
+
this.retryAfterMs = retryAfterMs;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
HOSTED_SCOPES,
|
|
26
|
+
HostedAuthError
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=chunk-3AH56XX7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hosted/types.ts"],"sourcesContent":["import type { RequestOptions } from '../client/types.js';\n\nexport const HOSTED_SCOPES = [\n 'mcp:dashboards:read',\n 'mcp:dashboards:write',\n 'mcp:datamarts:read',\n 'mcp:datamarts:write',\n 'mcp:embeds:write',\n 'mcp:query',\n 'mcp:custom-charts:read',\n 'mcp:custom-charts:write',\n] as const;\nexport type HostedScope = (typeof HOSTED_SCOPES)[number];\n\n/** A workspace this sign-in may act in, as the issuer resolved it for this request. */\nexport interface GrantedWorkspace {\n id: string;\n name?: string;\n}\n\n/** What the user approved at consent: a list of workspaces, or every workspace they can access. */\nexport type GrantWorkspaces = { mode: 'all' } | { mode: 'list'; ids: string[] };\n\n/** Only the trusted auth adapter may produce this context. Never populate it from MCP input. */\nexport interface HostedPrincipal {\n actorKind: 'user';\n credentialType: 'oauth' | 'pat';\n userId: string;\n companyId: string;\n /** Set only when exactly one workspace is granted: the default for every call. */\n workspaceId?: string;\n workspaceName?: string;\n /** The grant as approved. Absent from issuers that grant one workspace only. */\n workspaces?: GrantWorkspaces;\n /**\n * Live: the granted workspaces the user can still access, read on every request.\n * Absent only on a principal built before multi-workspace grants (then `workspaceId`).\n */\n grantedWorkspaces?: GrantedWorkspace[];\n /** OAuth application ID, NOT the tenant identifier called clientId by legacy tools. */\n clientId: string;\n resource: string;\n scopes: HostedScope[];\n /** Required for stored PATs. OAuth may delegate expiry to fresh provider validation. */\n expiresAt?: number;\n /** Explicit tenant allow-list resolved by the backend; absent means no tenant access. */\n tenantIds?: string[];\n}\n\nexport interface PatRecord {\n hash: string;\n revokedAt: number | null;\n principal: HostedPrincipal;\n}\n\nexport interface PatStore {\n findByHash(hash: string): Promise<PatRecord | undefined>;\n}\n\n/**\n * Opaque per-request handle from `HostedAdapter.delegate`. It carries nothing a tool,\n * log or serializer can read; only the adapter that made it can act with it.\n */\nexport interface HostedDelegation {\n readonly kind: 'hosted-delegation';\n}\n\n/** Production integration must recheck membership, policy and revocation on every call. */\nexport interface HostedAdapter {\n verifyOAuth(token: string, resource: string): Promise<HostedPrincipal>;\n resolvePatGrant(principal: HostedPrincipal): Promise<HostedPrincipal>;\n /**\n * Optional. Bind this request's verified OAuth bearer to an opaque handle, so\n * executeRequest can act as this user at the configured issuer, which re-verifies\n * the token and enforces workspace, object and role checks on every call.\n */\n delegate?(token: string, principal: HostedPrincipal): HostedDelegation;\n /** Optional issuer discovery. Absent in older/test adapters; no extra API call occurs. */\n getBrynCatalogue?(\n principal: HostedPrincipal,\n delegation?: HostedDelegation\n ): Promise<unknown>;\n /**\n * Execute as this user/workspace with backend resource and tenant checks and auditing.\n * Receives NO incoming bearer or server service credential: only the opaque handle.\n * Do not impersonate a static service token.\n * Return the raw API result: the shared client performs its usual data unwrapping.\n * `workspace` is the granted workspace this tool call acts in, when one is known; the\n * adapter names it to the issuer and nowhere else.\n */\n executeRequest(\n options: RequestOptions,\n principal: HostedPrincipal,\n delegation?: HostedDelegation,\n workspace?: GrantedWorkspace\n ): Promise<unknown>;\n}\n\nexport interface HostedConfig {\n publicUrl: string;\n issuer: string;\n /** Where the issuer's API is reached, when not at the issuer origin itself. */\n apiUrl?: string;\n port: number;\n bind: string;\n testOnly: boolean;\n}\n\n/** The backend's own status, code and message for a 4xx that is not an auth denial. */\nexport interface HostedErrorDetail {\n status: number;\n code?: string;\n message?: string;\n}\n\nexport class HostedAuthError extends Error {\n constructor(\n public readonly status: 400 | 401 | 403 | 404 | 503,\n public readonly code: string,\n public readonly detail?: HostedErrorDetail,\n /** Set on a backend 429 that sent Retry-After. */\n public readonly retryAfterMs?: number\n ) {\n super(code);\n }\n}\n"],"mappings":";;;AAEO,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAwGO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACkB,QACA,MACA,QAEA,cAChB;AACA,UAAM,IAAI;AANM;AACA;AACA;AAEA;AAAA,EAGlB;AACF;","names":[]}
|