@metabase/custom-viz 0.0.1-alpha.3 → 0.0.1-alpha.5

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/dist/cli.js CHANGED
@@ -2,53 +2,99 @@
2
2
  import { existsSync as e, readFileSync as t } from "node:fs";
3
3
  import { mkdir as n, writeFile as r } from "node:fs/promises";
4
4
  import { dirname as i, join as a } from "node:path";
5
- import { Command as o } from "commander";
6
- import { fileURLToPath as s } from "node:url";
5
+ import { createInterface as o } from "node:readline";
6
+ import { Command as s } from "commander";
7
+ import { fileURLToPath as c } from "node:url";
7
8
  //#region package.json
8
- var c = "0.0.1-alpha.3", l = "node_modules/\n.DS_Store\n# dist must be committed\n", u = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\"/>\n</svg>\n", d = "import type {\n CreateCustomVisualization,\n CustomStaticVisualizationProps,\n CustomVisualizationProps,\n} from \"@metabase/custom-viz\";\n\ntype Settings = {\n threshold?: number;\n};\n\nconst createVisualization: CreateCustomVisualization<Settings> = ({\n getAssetUrl,\n}) => {\n return {\n id: \"__CUSTOM_VIZ_NAME__\",\n getName: () => \"__CUSTOM_VIZ_NAME__\",\n minSize: { width: 1, height: 1 },\n defaultSize: { width: 2, height: 2 },\n isSensible({ cols, rows }) {\n return cols.length === 1 && rows.length === 1 && typeof rows[0][0] === \"number\";\n },\n checkRenderable(series, settings) {\n if (series.length !== 1) {\n throw new Error(\"Only 1 series is supported\");\n }\n\n const [\n {\n data: { cols, rows },\n },\n ] = series;\n\n if (cols.length !== 1) {\n throw new Error(\"Query results should only have 1 column\");\n }\n\n if (rows.length !== 1) {\n throw new Error(\"Query results should only have 1 row\");\n }\n\n if (typeof rows[0][0] !== \"number\") {\n throw new Error(\"Result is not a number\");\n }\n\n if (typeof settings.threshold !== \"number\") {\n throw new Error(\"Threshold setting is not set\");\n }\n },\n settings: {\n threshold: {\n id: \"1\",\n title: \"Threshold\",\n widget: \"number\",\n getDefault() {\n return 0;\n },\n getProps() {\n return {\n options: {\n isInteger: false,\n isNonNegative: false,\n },\n placeholder: \"Set threshold\",\n };\n },\n },\n },\n VisualizationComponent: makeVisualizationComponent(getAssetUrl),\n StaticVisualizationComponent: makeStaticVisualizationComponent(getAssetUrl),\n };\n};\n\nconst makeVisualizationComponent = (getAssetUrl: (path: string) => string) => (props: CustomVisualizationProps<Settings>) => {\n const { height, series, settings, width } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji = value >= threshold ? \"👍\" : \"👎\";\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nconst makeStaticVisualizationComponent = (getAssetUrl: (path: string) => string) => (\n props: CustomStaticVisualizationProps<Settings>,\n) => {\n const width = 540;\n const height = 360;\n const { series, settings } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji =\n value >= threshold ? (\n <img src={getAssetUrl(\"thumbs-up.png\")} />\n ) : (\n <img src={getAssetUrl(\"thumbs-down.png\")} />\n );\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nexport default createVisualization;\n", f = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"icon\": \"icon.svg\",\n \"assets\": [\"icon.svg\", \"thumbs-up.png\", \"thumbs-down.png\"],\n \"metabase\": {\n \"version\": \">=59\"\n }\n}\n", p = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"vite build\",\n \"dev\": \"vite build --watch & vite preview\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@metabase/custom-viz\": \"__CUSTOM_VIZ_VERSION__\",\n \"@types/react\": \"^19.2.14\",\n \"react\": \"^19.1.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.0\"\n }\n}\n", m = "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"jsx\": \"react-jsx\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"outDir\": \"dist\",\n \"declaration\": true\n },\n \"include\": [\"src\"]\n}\n", h = "import { resolve } from \"path\";\nimport { createServer } from \"http\";\nimport { watch, cpSync } from \"fs\";\nimport { defineConfig } from \"vite\";\n\n/**\n * Vite plugin that replaces `react` and `react/jsx-runtime` imports with\n * virtual modules that read from Metabase's `window.__METABASE_VIZ_API__`.\n *\n * This is necessary because the ES module output format cannot use\n * `output.globals`, and bare `import 'react'` would fail in the browser.\n */\nfunction metabaseVizExternals() {\n const VIRTUAL_REACT = \"\\0virtual:react\";\n const VIRTUAL_JSX_RUNTIME = \"\\0virtual:react/jsx-runtime\";\n const VIRTUAL_CUSTOM_VIZ = \"\\0virtual:@metabase/custom-viz\";\n\n return {\n name: \"metabase-viz-externals\",\n enforce: \"pre\" as const,\n\n resolveId(source) {\n if (source === \"react\") {\n return VIRTUAL_REACT;\n }\n if (source === \"react/jsx-runtime\") {\n return VIRTUAL_JSX_RUNTIME;\n }\n if (source === \"@metabase/custom-viz\") {\n return VIRTUAL_CUSTOM_VIZ;\n }\n return null;\n },\n\n load(id) {\n if (id === VIRTUAL_REACT) {\n return [\n \"const React = window.__METABASE_VIZ_API__.React;\",\n \"export default React;\",\n \"export const { useState, useEffect, useRef, useCallback, useMemo, useReducer, useContext, createElement, Fragment } = React;\",\n ].join(\"\\n\");\n }\n if (id === VIRTUAL_JSX_RUNTIME) {\n return [\n \"const jsxRuntime = window.__METABASE_VIZ_API__.jsxRuntime;\",\n \"export const { jsx, jsxs, Fragment } = jsxRuntime;\",\n ].join(\"\\n\");\n }\n if (id === VIRTUAL_CUSTOM_VIZ) {\n return [\n \"const ct = window.__METABASE_VIZ_API__.columnTypes;\",\n \"export const { isDate, isNumeric, isInteger, isBoolean, isString, isStringLike, isSummable, isNumericBaseType, isDateWithoutTime, isNumber, isFloat, isTime, isFK, isPK, isEntityName, isTitle, isProduct, isSource, isAddress, isScore, isQuantity, isCategory, isAny, isState, isCountry, isCoordinate, isLatitude, isLongitude, isCurrency, isPercentage, isID, isURL, isEmail, isAvatarURL, isImageURL, hasLatitudeAndLongitudeColumns } = ct;\",\n \"export const formatValue = window.__METABASE_VIZ_API__.formatValue;\",\n ].join(\"\\n\");\n }\n return null;\n },\n };\n}\n\nconst NOTIFY_PORT = 5175;\n\n/**\n * Vite plugin that starts a tiny SSE server and sends a \"reload\" event\n * to all connected clients after each rebuild completes.\n * Metabase's frontend connects to this to live-reload the custom viz.\n */\nfunction metabaseNotifyReload() {\n const clients = new Set<import(\"http\").ServerResponse>();\n let server: ReturnType<typeof createServer> | null = null;\n\n return {\n name: \"metabase-notify-reload\",\n\n buildStart() {\n if (server) {\n return;\n }\n server = createServer((req, res) => {\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n clients.add(res);\n req.on(\"close\", () => clients.delete(res));\n });\n server.listen(NOTIFY_PORT, () => {\n console.log(\n `[metabase-notify] SSE server listening on http://localhost:${NOTIFY_PORT}`,\n );\n });\n\n // Watch public/assets/ for changes — copy to dist/assets/ and notify\n const assetsDir = resolve(__dirname, \"public/assets\");\n watch(assetsDir, { recursive: true }, (_event, filename) => {\n if (!filename) {\n return;\n }\n cpSync(resolve(assetsDir, filename), resolve(__dirname, \"dist/assets\", filename));\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(`[metabase-notify] Asset changed: ${filename}, notified ${clients.size} client(s)`);\n });\n },\n\n closeBundle() {\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(\n `[metabase-notify] Build complete, notified ${clients.size} client(s)`,\n );\n },\n };\n}\n\nconst isWatch = process.argv.includes(\"--watch\");\n\nexport default defineConfig({\n plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseNotifyReload()] : [])],\n publicDir: \"public\",\n build: {\n outDir: \"dist\",\n lib: {\n entry: resolve(__dirname, \"src/index.tsx\"),\n formats: [\"iife\"],\n fileName: () => \"index.js\",\n name: \"__customVizPlugin__\",\n },\n },\n preview: {\n port: 5174,\n host: true,\n cors: true,\n },\n});\n", g = "__CUSTOM_VIZ_NAME__", _ = "__CUSTOM_VIZ_VERSION__";
9
- function v(e, t) {
10
- return e.split(g).join(t);
9
+ var l = "0.0.1-alpha.5", u = "node_modules/\n.DS_Store\n# dist must be committed\n", d = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.79978 6.86661C1.65041 7.01583 1.53192 7.19302 1.45107 7.38806C1.37023 7.58309 1.32861 7.79215 1.32861 8.00328C1.32861 8.21441 1.37023 8.42347 1.45107 8.61851C1.53192 8.81354 1.65041 8.99073 1.79978 9.13995L6.85978 14.1999C7.00899 14.3493 7.18618 14.4678 7.38122 14.5487C7.57626 14.6295 7.78531 14.6711 7.99644 14.6711C8.20757 14.6711 8.41663 14.6295 8.61167 14.5487C8.80671 14.4678 8.9839 14.3493 9.13311 14.1999L14.1931 9.13995C14.3425 8.99073 14.461 8.81354 14.5418 8.61851C14.6227 8.42347 14.6643 8.21441 14.6643 8.00328C14.6643 7.79215 14.6227 7.58309 14.5418 7.38806C14.461 7.19302 14.3425 7.01583 14.1931 6.86661L9.13311 1.80661C8.9839 1.65725 8.80671 1.53875 8.61167 1.45791C8.41663 1.37706 8.20757 1.33545 7.99644 1.33545C7.78531 1.33545 7.57626 1.37706 7.38122 1.45791C7.18618 1.53875 7.00899 1.65725 6.85978 1.80661L1.79978 6.86661Z\" stroke=\"white\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n", f = "import type {\n CreateCustomVisualization,\n CustomStaticVisualizationProps,\n CustomVisualizationProps,\n} from \"@metabase/custom-viz\";\n\ntype Settings = {\n threshold?: number;\n};\n\nconst createVisualization: CreateCustomVisualization<Settings> = ({\n getAssetUrl,\n}) => {\n return {\n id: \"__CUSTOM_VIZ_NAME__\",\n getName: () => \"__CUSTOM_VIZ_NAME__\",\n minSize: { width: 1, height: 1 },\n defaultSize: { width: 2, height: 2 },\n isSensible({ cols, rows }) {\n return cols.length === 1 && rows.length === 1 && typeof rows[0][0] === \"number\";\n },\n checkRenderable(series, settings) {\n if (series.length !== 1) {\n throw new Error(\"Only 1 series is supported\");\n }\n\n const [\n {\n data: { cols, rows },\n },\n ] = series;\n\n if (cols.length !== 1) {\n throw new Error(\"Query results should only have 1 column\");\n }\n\n if (rows.length !== 1) {\n throw new Error(\"Query results should only have 1 row\");\n }\n\n if (typeof rows[0][0] !== \"number\") {\n throw new Error(\"Result is not a number\");\n }\n\n if (typeof settings.threshold !== \"number\") {\n throw new Error(\"Threshold setting is not set\");\n }\n },\n settings: {\n threshold: {\n id: \"1\",\n title: \"Threshold\",\n widget: \"number\",\n getDefault() {\n return 0;\n },\n getProps() {\n return {\n options: {\n isInteger: false,\n isNonNegative: false,\n },\n placeholder: \"Set threshold\",\n };\n },\n },\n },\n VisualizationComponent: makeVisualizationComponent(getAssetUrl),\n StaticVisualizationComponent: makeStaticVisualizationComponent(getAssetUrl),\n };\n};\n\nconst makeVisualizationComponent = (getAssetUrl: (path: string) => string) => (props: CustomVisualizationProps<Settings>) => {\n const { height, series, settings, width } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji = value >= threshold ? \"👍\" : \"👎\";\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nconst makeStaticVisualizationComponent = (getAssetUrl: (path: string) => string) => (\n props: CustomStaticVisualizationProps<Settings>,\n) => {\n const width = 540;\n const height = 360;\n const { series, settings } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji =\n value >= threshold ? (\n <img src={getAssetUrl(\"thumbs-up.png\")} />\n ) : (\n <img src={getAssetUrl(\"thumbs-down.png\")} />\n );\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nexport default createVisualization;\n", p = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"icon\": \"icon.svg\",\n \"assets\": [\"icon.svg\", \"thumbs-up.png\", \"thumbs-down.png\"],\n \"metabase\": {\n \"version\": \">=59\"\n }\n}\n", m = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"vite build\",\n \"dev\": \"vite build --watch\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@metabase/custom-viz\": \"__CUSTOM_VIZ_VERSION__\",\n \"@types/react\": \"^19.2.14\",\n \"react\": \"^19.1.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.0\"\n }\n}\n", h = "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"jsx\": \"react-jsx\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"outDir\": \"dist\",\n \"declaration\": true\n },\n \"include\": [\"src\"]\n}\n", g = "import { resolve } from \"path\";\nimport { createServer } from \"http\";\nimport { watch, cpSync } from \"fs\";\nimport { defineConfig } from \"vite\";\n\n/**\n * Vite plugin that replaces `react` and `react/jsx-runtime` imports with\n * virtual modules that read from Metabase's `window.__METABASE_VIZ_API__`.\n *\n * This is necessary because the ES module output format cannot use\n * `output.globals`, and bare `import 'react'` would fail in the browser.\n */\nfunction metabaseVizExternals() {\n const VIRTUAL_REACT = \"\\0virtual:react\";\n const VIRTUAL_JSX_RUNTIME = \"\\0virtual:react/jsx-runtime\";\n return {\n name: \"metabase-viz-externals\",\n enforce: \"pre\" as const,\n\n resolveId(source) {\n if (source === \"react\") {\n return VIRTUAL_REACT;\n }\n if (source === \"react/jsx-runtime\") {\n return VIRTUAL_JSX_RUNTIME;\n }\n return null;\n },\n\n load(id) {\n if (id === VIRTUAL_REACT) {\n return [\n \"const React = window.__METABASE_VIZ_API__.React;\",\n \"export default React;\",\n \"export const { useState, useEffect, useRef, useCallback, useMemo, useReducer, useContext, createElement, Fragment } = React;\",\n ].join(\"\\n\");\n }\n if (id === VIRTUAL_JSX_RUNTIME) {\n return [\n \"const jsxRuntime = window.__METABASE_VIZ_API__.jsxRuntime;\",\n \"export const { jsx, jsxs, Fragment } = jsxRuntime;\",\n ].join(\"\\n\");\n }\n return null;\n },\n };\n}\n\nconst DEV_PORT = 5174;\n\n/**\n * Vite plugin that starts a dev server serving both static files from dist/\n * and an SSE endpoint at /__sse for hot-reload notifications.\n * Metabase's frontend connects to /__sse on the same origin as dev_bundle_url.\n */\nfunction metabaseDevServer() {\n const clients = new Set<import(\"http\").ServerResponse>();\n let server: ReturnType<typeof createServer> | null = null;\n\n return {\n name: \"metabase-dev-server\",\n\n buildStart() {\n if (server) {\n return;\n }\n\n const distDir = resolve(__dirname, \"dist\");\n\n server = createServer((req, res) => {\n const url = req.url ?? \"/\";\n\n // SSE endpoint for hot-reload\n if (url === \"/__sse\") {\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n clients.add(res);\n req.on(\"close\", () => clients.delete(res));\n return;\n }\n\n // CORS headers for all static responses\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\n // Serve static files from dist/\n const { readFile, stat } = require(\"fs\");\n const { join, extname } = require(\"path\");\n\n const filePath = url === \"/\" ? join(distDir, \"index.html\") : join(distDir, url);\n\n // Prevent directory traversal\n if (!filePath.startsWith(distDir)) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n stat(filePath, (err: NodeJS.ErrnoException | null) => {\n if (err) {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const mimeTypes: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n };\n const contentType = mimeTypes[extname(filePath)] ?? \"application/octet-stream\";\n\n readFile(filePath, (readErr: NodeJS.ErrnoException | null, data: Buffer) => {\n if (readErr) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(data);\n });\n });\n });\n\n server.listen(DEV_PORT, () => {\n console.log(\n `[custom-viz] Dev server listening on http://localhost:${DEV_PORT}`,\n );\n });\n\n // Watch public/assets/ for changes — copy to dist/assets/ and notify\n const assetsDir = resolve(__dirname, \"public/assets\");\n watch(assetsDir, { recursive: true }, (_event, filename) => {\n if (!filename) {\n return;\n }\n cpSync(resolve(assetsDir, filename), resolve(__dirname, \"dist/assets\", filename));\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);\n });\n },\n\n closeBundle() {\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(\n `[custom-viz] Build complete, notified ${clients.size} client(s)`,\n );\n },\n };\n}\n\nconst isWatch = process.argv.includes(\"--watch\");\n\nexport default defineConfig({\n plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseDevServer()] : [])],\n publicDir: \"public\",\n build: {\n outDir: \"dist\",\n lib: {\n entry: resolve(__dirname, \"src/index.tsx\"),\n formats: [\"iife\"],\n fileName: () => \"index.js\",\n name: \"__customVizPlugin__\",\n },\n },\n});\n", _ = "__CUSTOM_VIZ_NAME__", v = "__CUSTOM_VIZ_VERSION__";
10
+ function y(e, t) {
11
+ return e.split(_).join(t);
11
12
  }
12
- function y(e) {
13
- return v(p, e).split(_).join(c);
14
- }
15
- function b() {
16
- return h;
13
+ function b(e) {
14
+ return y(m, e).split(v).join(l);
17
15
  }
18
16
  function x() {
19
- return m;
17
+ return g;
20
18
  }
21
- function S(e) {
22
- return v(d, e);
19
+ function S() {
20
+ return h;
23
21
  }
24
22
  function C(e) {
25
- return v(f, e);
23
+ return y(f, e);
26
24
  }
27
- function w() {
28
- return u;
25
+ function w(e) {
26
+ return y(p, e);
29
27
  }
30
- var T = a(i(s(import.meta.url)), "templates");
31
- function E(e) {
32
- return t(a(T, e));
28
+ function T() {
29
+ return d;
33
30
  }
34
- function D() {
35
- return l;
31
+ var E = a(i(c(import.meta.url)), "templates");
32
+ function D(e) {
33
+ return t(a(E, e));
34
+ }
35
+ function O() {
36
+ return u;
37
+ }
38
+ function k(e) {
39
+ let t = JSON.parse(e), n = JSON.parse(m.split(_).join("__placeholder__").split(v).join(l));
40
+ return t.devDependencies = {
41
+ ...t.devDependencies,
42
+ ...n.devDependencies
43
+ }, t.scripts = {
44
+ ...t.scripts,
45
+ ...n.scripts
46
+ }, JSON.stringify(t, null, 2) + "\n";
36
47
  }
37
48
  //#endregion
38
49
  //#region src/cli.ts
39
- var O = new o();
40
- O.name("metabase-custom-viz").description("CLI for creating custom visualizations for Metabase").version("0.0.1"), O.command("init").description("Scaffold a new custom visualization").argument("<name>", "Name of the custom visualization").action(async (t) => {
50
+ var A = new s();
51
+ A.name("metabase-custom-viz").description("CLI for creating custom visualizations for Metabase").version(l), A.command("init").description("Scaffold a new custom visualization").argument("<name>", "Name of the custom visualization").action(async (t) => {
41
52
  let i = t.trim().replace(/\s+/g, "-").toLowerCase();
42
53
  (!i || !/^[a-z0-9@][a-z0-9._\-/]*$/.test(i)) && (console.error(`Error: "${t}" is not a valid project name. Use letters, numbers, hyphens, and dots.`), process.exit(1)), e(i) && (console.error(`Error: Directory "${i}" already exists.`), process.exit(1)), console.log(`Scaffolding custom visualization: ${i}\n`), await Promise.all([n(a(i, "src"), { recursive: !0 }), n(a(i, "public", "assets"), { recursive: !0 })]), await Promise.all([
43
- r(a(i, "package.json"), y(i)),
44
- r(a(i, "vite.config.ts"), b()),
45
- r(a(i, "tsconfig.json"), x()),
46
- r(a(i, "src", "index.tsx"), S(i)),
47
- r(a(i, "metabase-plugin.json"), C(i)),
48
- r(a(i, "public", "assets", "icon.svg"), w()),
49
- r(a(i, "public", "assets", "thumbs-up.png"), E("thumbs-up.png")),
50
- r(a(i, "public", "assets", "thumbs-down.png"), E("thumbs-down.png")),
51
- r(a(i, ".gitignore"), D())
54
+ r(a(i, "package.json"), b(i)),
55
+ r(a(i, "vite.config.ts"), x()),
56
+ r(a(i, "tsconfig.json"), S()),
57
+ r(a(i, "src", "index.tsx"), C(i)),
58
+ r(a(i, "metabase-plugin.json"), w(i)),
59
+ r(a(i, "public", "assets", "icon.svg"), T()),
60
+ r(a(i, "public", "assets", "thumbs-up.png"), D("thumbs-up.png")),
61
+ r(a(i, "public", "assets", "thumbs-down.png"), D("thumbs-down.png")),
62
+ r(a(i, ".gitignore"), O())
52
63
  ]), console.log("Created files:"), console.log(` ${i}/package.json`), console.log(` ${i}/vite.config.ts`), console.log(` ${i}/tsconfig.json`), console.log(` ${i}/src/index.tsx`), console.log(` ${i}/metabase-plugin.json`), console.log(` ${i}/public/assets/icon.svg`), console.log(` ${i}/public/assets/thumbs-up.png`), console.log(` ${i}/public/assets/thumbs-down.png`), console.log(` ${i}/.gitignore`), console.log(), console.log("Next steps:"), console.log(` cd ${i}`), console.log(" npm install"), console.log(" npm run dev # Watch mode"), console.log(" npm run build # Production build");
53
- }), O.parse();
64
+ }), A.command("upgrade").description("Upgrade an existing custom visualization to the latest template version").action(async () => {
65
+ let n = process.cwd(), i = a(n, "package.json");
66
+ e(i) || (console.error("Error: No package.json found. Run this command from the root of a custom visualization project."), process.exit(1));
67
+ let o;
68
+ try {
69
+ o = JSON.parse(t(i, "utf-8"));
70
+ } catch {
71
+ console.error("Error: Could not parse package.json."), process.exit(1);
72
+ }
73
+ let s = o.devDependencies?.["@metabase/custom-viz"];
74
+ if (s || (console.error("Error: @metabase/custom-viz not found in devDependencies. Is this a custom visualization project?"), process.exit(1)), s === "0.0.1-alpha.5") {
75
+ console.log(`Already up to date (v${l}). No changes needed.`);
76
+ return;
77
+ }
78
+ if (console.log(`Upgrading from @metabase/custom-viz ${s} → ${l}\n`), console.log("The following changes will be made:\n"), console.log(" vite.config.ts — Replace with the latest build configuration"), console.log(" tsconfig.json — Replace with the latest TypeScript configuration"), console.log(" .gitignore — Replace with the latest gitignore rules"), console.log(" package.json — Update devDependencies and scripts to latest versions"), console.log(), console.log("Your source code (src/), assets (public/), and metabase-plugin.json will NOT be modified.\n"), !await j("Proceed with upgrade?")) {
79
+ console.log("Upgrade cancelled.");
80
+ return;
81
+ }
82
+ console.log();
83
+ let c = [];
84
+ await r(a(n, "vite.config.ts"), x()), c.push("vite.config.ts"), await r(a(n, "tsconfig.json"), S()), c.push("tsconfig.json"), await r(a(n, ".gitignore"), O()), c.push(".gitignore"), await r(i, k(t(i, "utf-8"))), c.push("package.json"), console.log("Updated files:");
85
+ for (let e of c) console.log(` ${e}`);
86
+ console.log(), console.log("Next steps:"), console.log(" npm install # Install updated dependencies");
87
+ });
88
+ function j(e) {
89
+ let t = o({
90
+ input: process.stdin,
91
+ output: process.stdout
92
+ });
93
+ return new Promise((n) => {
94
+ t.question(`${e} (y/N) `, (e) => {
95
+ t.close(), n(e.trim().toLowerCase() === "y");
96
+ });
97
+ });
98
+ }
99
+ A.parse();
54
100
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"column-types.d.ts","sourceRoot":"","sources":["../src/column-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,eAAO,MAAM,MAAM,iBAAO,CAAC;AAC3B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,QAAQ,iBAAO,CAAC;AAC7B,eAAO,MAAM,YAAY,iBAAO,CAAC;AACjC,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,iBAAiB,iBAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,iBAAO,CAAC;AACtC,eAAO,MAAM,QAAQ,iBAAO,CAAC;AAC7B,eAAO,MAAM,OAAO,iBAAO,CAAC;AAC5B,eAAO,MAAM,MAAM,iBAAO,CAAC;AAC3B,eAAO,MAAM,IAAI,iBAAO,CAAC;AACzB,eAAO,MAAM,IAAI,iBAAO,CAAC;AACzB,eAAO,MAAM,YAAY,iBAAO,CAAC;AACjC,eAAO,MAAM,OAAO,iBAAO,CAAC;AAC5B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,QAAQ,iBAAO,CAAC;AAC7B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,OAAO,iBAAO,CAAC;AAC5B,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,KAAK,iBAAO,CAAC;AAC1B,eAAO,MAAM,OAAO,iBAAO,CAAC;AAC5B,eAAO,MAAM,SAAS,iBAAO,CAAC;AAC9B,eAAO,MAAM,YAAY,iBAAO,CAAC;AACjC,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,WAAW,iBAAO,CAAC;AAChC,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,YAAY,iBAAO,CAAC;AACjC,eAAO,MAAM,IAAI,iBAAO,CAAC;AACzB,eAAO,MAAM,KAAK,iBAAO,CAAC;AAC1B,eAAO,MAAM,OAAO,iBAAO,CAAC;AAC5B,eAAO,MAAM,WAAW,iBAAO,CAAC;AAChC,eAAO,MAAM,UAAU,iBAAO,CAAC;AAC/B,eAAO,MAAM,8BAA8B,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OACpD,CAAC;AAEd,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"column-types.d.ts","sourceRoot":"","sources":["../src/column-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAQ3C,eAAO,MAAM,MAAM,EAAE,eAA2C,CAAC;AACjE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,QAAQ,EAAE,eAA6C,CAAC;AACrE,eAAO,MAAM,YAAY,EAAE,eAAiD,CAAC;AAC7E,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,iBAAiB,EAAE,eAAsD,CAAC;AACvF,eAAO,MAAM,iBAAiB,EAAE,eAAsD,CAAC;AACvF,eAAO,MAAM,QAAQ,EAAE,eAA6C,CAAC;AACrE,eAAO,MAAM,OAAO,EAAE,eAA4C,CAAC;AACnE,eAAO,MAAM,MAAM,EAAE,eAA2C,CAAC;AACjE,eAAO,MAAM,IAAI,EAAE,eAAyC,CAAC;AAC7D,eAAO,MAAM,IAAI,EAAE,eAAyC,CAAC;AAC7D,eAAO,MAAM,YAAY,EAAE,eAAiD,CAAC;AAC7E,eAAO,MAAM,OAAO,EAAE,eAA4C,CAAC;AACnE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,QAAQ,EAAE,eAA6C,CAAC;AACrE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,OAAO,EAAE,eAA4C,CAAC;AACnE,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,KAAK,EAAE,eAA0C,CAAC;AAC/D,eAAO,MAAM,OAAO,EAAE,eAA4C,CAAC;AACnE,eAAO,MAAM,SAAS,EAAE,eAA8C,CAAC;AACvE,eAAO,MAAM,YAAY,EAAE,eAAiD,CAAC;AAC7E,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,WAAW,EAAE,eAAgD,CAAC;AAC3E,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,YAAY,EAAE,eAAiD,CAAC;AAC7E,eAAO,MAAM,IAAI,EAAE,eAAyC,CAAC;AAC7D,eAAO,MAAM,KAAK,EAAE,eAA0C,CAAC;AAC/D,eAAO,MAAM,OAAO,EAAE,eAA4C,CAAC;AACnE,eAAO,MAAM,WAAW,EAAE,eAAgD,CAAC;AAC3E,eAAO,MAAM,UAAU,EAAE,eAA+C,CAAC;AACzE,eAAO,MAAM,8BAA8B,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OACZ,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,eAAO,MAAM,WAAW,EAAE,WAAsB,CAAC;AAEjD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAItE,eAAO,MAAM,WAAW,EAAE,WACgC,CAAC;AAE3D,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
+ export * from './lib';
1
2
  export * from './types';
2
3
  export * from './column-types';
3
4
  export * from './format';
5
+ export * from './measure-text';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
+ //#region src/lib/defineSetting.ts
2
+ function e(e) {
3
+ return e;
4
+ }
5
+ //#endregion
1
6
  //#region src/types/date-time.ts
2
- var e = [
7
+ var t = [
3
8
  "minute",
4
9
  "hour",
5
10
  "day",
@@ -7,7 +12,7 @@ var e = [
7
12
  "month",
8
13
  "quarter",
9
14
  "year"
10
- ], t = [
15
+ ], n = [
11
16
  "minute-of-hour",
12
17
  "hour-of-day",
13
18
  "day-of-week",
@@ -16,6 +21,15 @@ var e = [
16
21
  "week-of-year",
17
22
  "month-of-year",
18
23
  "quarter-of-year"
19
- ], n = [...e, ...t], r = () => !1, i = r, a = r, o = r, s = r, c = r, l = r, u = r, d = r, f = r, p = r, m = r, h = r, g = r, _ = r, v = r, y = r, b = r, x = r, S = r, C = r, w = r, T = r, E = r, D = r, O = r, k = r, A = r, j = r, M = r, N = r, P = r, F = r, I = r, L = r, R = r, z = () => !1, B = () => "";
24
+ ], r = [...t, ...n];
25
+ //#endregion
26
+ //#region src/column-types.ts
27
+ function i() {
28
+ return window.__METABASE_VIZ_API__.columnTypes;
29
+ }
30
+ var a = (e) => i().isDate(e), o = (e) => i().isNumeric(e), s = (e) => i().isInteger(e), c = (e) => i().isBoolean(e), l = (e) => i().isString(e), u = (e) => i().isStringLike(e), d = (e) => i().isSummable(e), f = (e) => i().isNumericBaseType(e), p = (e) => i().isDateWithoutTime(e), m = (e) => i().isNumber(e), h = (e) => i().isFloat(e), g = (e) => i().isTime(e), _ = (e) => i().isFK(e), v = (e) => i().isPK(e), y = (e) => i().isEntityName(e), b = (e) => i().isTitle(e), x = (e) => i().isProduct(e), S = (e) => i().isSource(e), C = (e) => i().isAddress(e), w = (e) => i().isScore(e), T = (e) => i().isQuantity(e), E = (e) => i().isCategory(e), D = (e) => i().isAny(e), O = (e) => i().isState(e), k = (e) => i().isCountry(e), A = (e) => i().isCoordinate(e), j = (e) => i().isLatitude(e), M = (e) => i().isLongitude(e), N = (e) => i().isCurrency(e), P = (e) => i().isPercentage(e), F = (e) => i().isID(e), I = (e) => i().isURL(e), L = (e) => i().isEmail(e), R = (e) => i().isAvatarURL(e), z = (e) => i().isImageURL(e), B = (e) => i().hasLatitudeAndLongitudeColumns(e), V = (e, t) => window.__METABASE_VIZ_API__.formatValue(e, t), H = () => ({
31
+ width: 0,
32
+ height: 0
33
+ }), U = () => 0, W = () => 0;
20
34
  //#endregion
21
- export { e as dateTimeAbsoluteUnits, t as dateTimeRelativeUnits, n as dateTimeUnits, B as formatValue, z as hasLatitudeAndLongitudeColumns, S as isAddress, E as isAny, L as isAvatarURL, s as isBoolean, T as isCategory, k as isCoordinate, O as isCountry, M as isCurrency, i as isDate, f as isDateWithoutTime, I as isEmail, v as isEntityName, g as isFK, m as isFloat, P as isID, R as isImageURL, o as isInteger, A as isLatitude, j as isLongitude, p as isNumber, a as isNumeric, d as isNumericBaseType, _ as isPK, N as isPercentage, b as isProduct, w as isQuantity, C as isScore, x as isSource, D as isState, c as isString, l as isStringLike, u as isSummable, h as isTime, y as isTitle, F as isURL };
35
+ export { t as dateTimeAbsoluteUnits, n as dateTimeRelativeUnits, r as dateTimeUnits, e as defineSetting, V as formatValue, B as hasLatitudeAndLongitudeColumns, C as isAddress, D as isAny, R as isAvatarURL, c as isBoolean, E as isCategory, A as isCoordinate, k as isCountry, N as isCurrency, a as isDate, p as isDateWithoutTime, L as isEmail, y as isEntityName, _ as isFK, h as isFloat, F as isID, z as isImageURL, s as isInteger, j as isLatitude, M as isLongitude, m as isNumber, o as isNumeric, f as isNumericBaseType, v as isPK, P as isPercentage, x as isProduct, T as isQuantity, w as isScore, S as isSource, O as isState, l as isString, u as isStringLike, d as isSummable, g as isTime, b as isTitle, I as isURL, H as measureText, W as measureTextHeight, U as measureTextWidth };
@@ -0,0 +1,22 @@
1
+ import { CustomVisualizationSettingDefinition, Series, WidgetName, Widgets } from '../types';
2
+ type PropsFromWidget<W> = W extends WidgetName ? Widgets[W] : W extends (props: infer P) => any ? P : never;
3
+ export declare function defineSetting<CustomVisualizationSettings extends Record<string, unknown>, TValue, W extends WidgetName | ((props: any) => any)>(settingDefinition: {
4
+ id: string;
5
+ section?: string;
6
+ title?: string;
7
+ group?: string;
8
+ index?: number;
9
+ inline?: boolean;
10
+ persistDefault?: boolean;
11
+ set?: boolean;
12
+ readDependencies?: string[];
13
+ writeDependencies?: string[];
14
+ eraseDependencies?: string[];
15
+ widget: W;
16
+ isValid?: (series: Series, settings: CustomVisualizationSettings) => boolean;
17
+ getDefault?: (series: Series, settings: CustomVisualizationSettings) => TValue;
18
+ getProps(object: Series, vizSettings: CustomVisualizationSettings): PropsFromWidget<W>;
19
+ getValue?: (series: Series, settings: CustomVisualizationSettings) => TValue;
20
+ }): CustomVisualizationSettingDefinition<CustomVisualizationSettings>;
21
+ export {};
22
+ //# sourceMappingURL=defineSetting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineSetting.d.ts","sourceRoot":"","sources":["../../src/lib/defineSetting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oCAAoC,EACpC,MAAM,EACN,UAAU,EACV,OAAO,EACR,MAAM,UAAU,CAAC;AAElB,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,GAC1C,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,GAC/B,CAAC,GACD,KAAK,CAAC;AAEZ,wBAAgB,aAAa,CAC3B,2BAA2B,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EACN,CAAC,SAAS,UAAU,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,EAC5C,iBAAiB,EAAE;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,OAAO,CAAC;IAEd,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B,MAAM,EAAE,CAAC,CAAC;IAEV,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,2BAA2B,KAAK,OAAO,CAAC;IAC7E,UAAU,CAAC,EAAE,CACX,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,2BAA2B,KAClC,MAAM,CAAC;IACZ,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,2BAA2B,GACvC,eAAe,CAAC,CAAC,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,2BAA2B,KAAK,MAAM,CAAC;CAC9E,GAAG,oCAAoC,CAAC,2BAA2B,CAAC,CAEpE"}
@@ -0,0 +1,2 @@
1
+ export * from './defineSetting';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { TextHeightMeasurer, TextMeasurer, TextWidthMeasurer } from './types/measure-text';
2
+ export declare const measureText: TextMeasurer;
3
+ export declare const measureTextWidth: TextWidthMeasurer;
4
+ export declare const measureTextHeight: TextHeightMeasurer;
5
+ //# sourceMappingURL=measure-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure-text.d.ts","sourceRoot":"","sources":["../src/measure-text.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAE9B,eAAO,MAAM,WAAW,EAAE,YAA8C,CAAC;AACzE,eAAO,MAAM,gBAAgB,EAAE,iBAA2B,CAAC;AAC3D,eAAO,MAAM,iBAAiB,EAAE,kBAA4B,CAAC"}
@@ -1,5 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
- <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
3
- <line x1="3" y1="9" x2="21" y2="9"/>
4
- <line x1="9" y1="21" x2="9" y2="9"/>
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.79978 6.86661C1.65041 7.01583 1.53192 7.19302 1.45107 7.38806C1.37023 7.58309 1.32861 7.79215 1.32861 8.00328C1.32861 8.21441 1.37023 8.42347 1.45107 8.61851C1.53192 8.81354 1.65041 8.99073 1.79978 9.13995L6.85978 14.1999C7.00899 14.3493 7.18618 14.4678 7.38122 14.5487C7.57626 14.6295 7.78531 14.6711 7.99644 14.6711C8.20757 14.6711 8.41663 14.6295 8.61167 14.5487C8.80671 14.4678 8.9839 14.3493 9.13311 14.1999L14.1931 9.13995C14.3425 8.99073 14.461 8.81354 14.5418 8.61851C14.6227 8.42347 14.6643 8.21441 14.6643 8.00328C14.6643 7.79215 14.6227 7.58309 14.5418 7.38806C14.461 7.19302 14.3425 7.01583 14.1931 6.86661L9.13311 1.80661C8.9839 1.65725 8.80671 1.53875 8.61167 1.45791C8.41663 1.37706 8.20757 1.33545 7.99644 1.33545C7.78531 1.33545 7.57626 1.37706 7.38122 1.45791C7.18618 1.53875 7.00899 1.65725 6.85978 1.80661L1.79978 6.86661Z" stroke="white" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
5
3
  </svg>
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "vite build",
8
- "dev": "vite build --watch & vite preview",
8
+ "dev": "vite build --watch",
9
9
  "type-check": "tsc --noEmit"
10
10
  },
11
11
  "devDependencies": {
@@ -13,8 +13,6 @@ import { defineConfig } from "vite";
13
13
  function metabaseVizExternals() {
14
14
  const VIRTUAL_REACT = "\0virtual:react";
15
15
  const VIRTUAL_JSX_RUNTIME = "\0virtual:react/jsx-runtime";
16
- const VIRTUAL_CUSTOM_VIZ = "\0virtual:@metabase/custom-viz";
17
-
18
16
  return {
19
17
  name: "metabase-viz-externals",
20
18
  enforce: "pre" as const,
@@ -26,9 +24,6 @@ function metabaseVizExternals() {
26
24
  if (source === "react/jsx-runtime") {
27
25
  return VIRTUAL_JSX_RUNTIME;
28
26
  }
29
- if (source === "@metabase/custom-viz") {
30
- return VIRTUAL_CUSTOM_VIZ;
31
- }
32
27
  return null;
33
28
  },
34
29
 
@@ -46,49 +41,98 @@ function metabaseVizExternals() {
46
41
  "export const { jsx, jsxs, Fragment } = jsxRuntime;",
47
42
  ].join("\n");
48
43
  }
49
- if (id === VIRTUAL_CUSTOM_VIZ) {
50
- return [
51
- "const ct = window.__METABASE_VIZ_API__.columnTypes;",
52
- "export const { isDate, isNumeric, isInteger, isBoolean, isString, isStringLike, isSummable, isNumericBaseType, isDateWithoutTime, isNumber, isFloat, isTime, isFK, isPK, isEntityName, isTitle, isProduct, isSource, isAddress, isScore, isQuantity, isCategory, isAny, isState, isCountry, isCoordinate, isLatitude, isLongitude, isCurrency, isPercentage, isID, isURL, isEmail, isAvatarURL, isImageURL, hasLatitudeAndLongitudeColumns } = ct;",
53
- "export const formatValue = window.__METABASE_VIZ_API__.formatValue;",
54
- ].join("\n");
55
- }
56
44
  return null;
57
45
  },
58
46
  };
59
47
  }
60
48
 
61
- const NOTIFY_PORT = 5175;
49
+ const DEV_PORT = 5174;
62
50
 
63
51
  /**
64
- * Vite plugin that starts a tiny SSE server and sends a "reload" event
65
- * to all connected clients after each rebuild completes.
66
- * Metabase's frontend connects to this to live-reload the custom viz.
52
+ * Vite plugin that starts a dev server serving both static files from dist/
53
+ * and an SSE endpoint at /__sse for hot-reload notifications.
54
+ * Metabase's frontend connects to /__sse on the same origin as dev_bundle_url.
67
55
  */
68
- function metabaseNotifyReload() {
56
+ function metabaseDevServer() {
69
57
  const clients = new Set<import("http").ServerResponse>();
70
58
  let server: ReturnType<typeof createServer> | null = null;
71
59
 
72
60
  return {
73
- name: "metabase-notify-reload",
61
+ name: "metabase-dev-server",
74
62
 
75
63
  buildStart() {
76
64
  if (server) {
77
65
  return;
78
66
  }
67
+
68
+ const distDir = resolve(__dirname, "dist");
69
+
79
70
  server = createServer((req, res) => {
80
- res.writeHead(200, {
81
- "Content-Type": "text/event-stream",
82
- "Cache-Control": "no-cache",
83
- Connection: "keep-alive",
84
- "Access-Control-Allow-Origin": "*",
71
+ const url = req.url ?? "/";
72
+
73
+ // SSE endpoint for hot-reload
74
+ if (url === "/__sse") {
75
+ res.writeHead(200, {
76
+ "Content-Type": "text/event-stream",
77
+ "Cache-Control": "no-cache",
78
+ Connection: "keep-alive",
79
+ "Access-Control-Allow-Origin": "*",
80
+ });
81
+ clients.add(res);
82
+ req.on("close", () => clients.delete(res));
83
+ return;
84
+ }
85
+
86
+ // CORS headers for all static responses
87
+ res.setHeader("Access-Control-Allow-Origin", "*");
88
+
89
+ // Serve static files from dist/
90
+ const { readFile, stat } = require("fs");
91
+ const { join, extname } = require("path");
92
+
93
+ const filePath = url === "/" ? join(distDir, "index.html") : join(distDir, url);
94
+
95
+ // Prevent directory traversal
96
+ if (!filePath.startsWith(distDir)) {
97
+ res.writeHead(403);
98
+ res.end("Forbidden");
99
+ return;
100
+ }
101
+
102
+ stat(filePath, (err: NodeJS.ErrnoException | null) => {
103
+ if (err) {
104
+ res.writeHead(404);
105
+ res.end("Not found");
106
+ return;
107
+ }
108
+
109
+ const mimeTypes: Record<string, string> = {
110
+ ".html": "text/html",
111
+ ".js": "application/javascript",
112
+ ".css": "text/css",
113
+ ".json": "application/json",
114
+ ".png": "image/png",
115
+ ".jpg": "image/jpeg",
116
+ ".svg": "image/svg+xml",
117
+ ".ico": "image/x-icon",
118
+ };
119
+ const contentType = mimeTypes[extname(filePath)] ?? "application/octet-stream";
120
+
121
+ readFile(filePath, (readErr: NodeJS.ErrnoException | null, data: Buffer) => {
122
+ if (readErr) {
123
+ res.writeHead(500);
124
+ res.end("Internal server error");
125
+ return;
126
+ }
127
+ res.writeHead(200, { "Content-Type": contentType });
128
+ res.end(data);
129
+ });
85
130
  });
86
- clients.add(res);
87
- req.on("close", () => clients.delete(res));
88
131
  });
89
- server.listen(NOTIFY_PORT, () => {
132
+
133
+ server.listen(DEV_PORT, () => {
90
134
  console.log(
91
- `[metabase-notify] SSE server listening on http://localhost:${NOTIFY_PORT}`,
135
+ `[custom-viz] Dev server listening on http://localhost:${DEV_PORT}`,
92
136
  );
93
137
  });
94
138
 
@@ -102,7 +146,7 @@ function metabaseNotifyReload() {
102
146
  for (const client of clients) {
103
147
  client.write("data: reload\n\n");
104
148
  }
105
- console.log(`[metabase-notify] Asset changed: ${filename}, notified ${clients.size} client(s)`);
149
+ console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);
106
150
  });
107
151
  },
108
152
 
@@ -111,7 +155,7 @@ function metabaseNotifyReload() {
111
155
  client.write("data: reload\n\n");
112
156
  }
113
157
  console.log(
114
- `[metabase-notify] Build complete, notified ${clients.size} client(s)`,
158
+ `[custom-viz] Build complete, notified ${clients.size} client(s)`,
115
159
  );
116
160
  },
117
161
  };
@@ -120,7 +164,7 @@ function metabaseNotifyReload() {
120
164
  const isWatch = process.argv.includes("--watch");
121
165
 
122
166
  export default defineConfig({
123
- plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseNotifyReload()] : [])],
167
+ plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseDevServer()] : [])],
124
168
  publicDir: "public",
125
169
  build: {
126
170
  outDir: "dist",
@@ -131,9 +175,4 @@ export default defineConfig({
131
175
  name: "__customVizPlugin__",
132
176
  },
133
177
  },
134
- preview: {
135
- port: 5174,
136
- host: true,
137
- cors: true,
138
- },
139
178
  });
@@ -1,12 +1,15 @@
1
1
  import { ComponentType } from 'react';
2
2
  import { Column, DatasetData, RowValue, Series } from './data';
3
- import { TextHeightMeasurer, TextMeasurer, TextWidthMeasurer } from './measure-text';
4
- import { WidgetName, Widgets } from './viz-settings';
3
+ import { TextHeightMeasurer, TextWidthMeasurer } from './measure-text';
5
4
  /**
6
5
  * Export this function to define a custom visualization.
7
6
  */
8
7
  export type CreateCustomVisualization<CustomVisualizationSettings> = (props: CreateCustomVisualizationProps) => CustomVisualization<CustomVisualizationSettings>;
9
8
  export type CreateCustomVisualizationProps = {
9
+ /**
10
+ * Current user's locale (e.g., "de", "ja", "en").
11
+ */
12
+ locale: string;
10
13
  /**
11
14
  * Translates text using ttag function used in Metabase.
12
15
  */
@@ -17,18 +20,10 @@ export type CreateCustomVisualizationProps = {
17
20
  * @example getAssetUrl("icon.svg")
18
21
  */
19
22
  getAssetUrl: (assetPath: string) => string;
20
- /**
21
- * Measures text dimensions (width and height) for given text and font style.
22
- */
23
- measureText: TextMeasurer;
24
- /**
25
- * Measures text width for given text and font style.
26
- */
27
- measureTextWidth: TextWidthMeasurer;
28
- /**
29
- * Measures text height for given text and font style.
30
- */
31
- measureTextHeight: TextHeightMeasurer;
23
+ };
24
+ declare const SettingDefinitionSymbol: unique symbol;
25
+ export type CustomVisualizationSettingDefinition<_CustomVisualizationSettings> = {
26
+ readonly [SettingDefinitionSymbol]: never;
32
27
  };
33
28
  export type CustomVisualization<CustomVisualizationSettings> = {
34
29
  /**
@@ -58,7 +53,7 @@ export type CustomVisualization<CustomVisualizationSettings> = {
58
53
  /**
59
54
  * Visualization settings definitions.
60
55
  */
61
- settings?: CustomVisualizationSettingsDefinitions<CustomVisualizationSettings>;
56
+ settings?: Record<keyof CustomVisualizationSettings, CustomVisualizationSettingDefinition<CustomVisualizationSettings>>;
62
57
  /**
63
58
  * This function should return true if the data shape makes sense for this visualization.
64
59
  * TODO: should it get series: Series instead?
@@ -77,48 +72,12 @@ export type CustomVisualization<CustomVisualizationSettings> = {
77
72
  */
78
73
  StaticVisualizationComponent?: ComponentType<CustomStaticVisualizationProps<CustomVisualizationSettings>>;
79
74
  };
80
- export type CustomVisualizationSettingsDefinitions<CustomVisualizationSettings, K extends keyof CustomVisualizationSettings = keyof CustomVisualizationSettings> = {
81
- [Key in K]-?: VisualizationSettingDefinition<CustomVisualizationSettings[Key], Record<string, unknown>, CustomVisualizationSettings>;
82
- };
83
75
  export type BaseWidgetProps<TValue, CustomVisualizationSettings> = {
84
76
  id: string;
85
77
  value: TValue | undefined;
86
78
  onChange: (value?: TValue | null) => void;
87
79
  onChangeSettings: (settings: Partial<CustomVisualizationSettings>) => void;
88
80
  };
89
- type VisualizationSettingDefinitionBase<TValue, CustomVisualizationSettings> = {
90
- id: string;
91
- section?: string;
92
- title?: string;
93
- group?: string;
94
- index?: number;
95
- inline?: boolean;
96
- default?: TValue;
97
- persistDefault?: boolean;
98
- set?: boolean;
99
- value?: TValue;
100
- readDependencies?: string[];
101
- writeDependencies?: string[];
102
- eraseDependencies?: string[];
103
- isValid?: (series: Series, settings: CustomVisualizationSettings) => boolean;
104
- getDefault?: (series: Series, settings: CustomVisualizationSettings) => TValue;
105
- getValue?: (series: Series, settings: CustomVisualizationSettings) => TValue;
106
- };
107
- type VisualizationSettingDefinitionWithBuiltInWidget<TValue, CustomVisualizationSettings> = {
108
- [Key in WidgetName]: VisualizationSettingDefinitionBase<TValue, CustomVisualizationSettings> & {
109
- widget: Key;
110
- getProps?: (object: Series, vizSettings: CustomVisualizationSettings) => Widgets[Key];
111
- };
112
- }[WidgetName];
113
- type VisualizationSettingDefinitionWithCustomWidget<TValue, TProps, CustomVisualizationSettings> = VisualizationSettingDefinitionBase<TValue, CustomVisualizationSettings> & {
114
- widget: ComponentType<TProps & BaseWidgetProps<TValue, CustomVisualizationSettings>>;
115
- getProps?: (object: Series, vizSettings: CustomVisualizationSettings) => TProps;
116
- };
117
- type VisualizationSettingDefinitionWithoutWidget<TValue, CustomVisualizationSettings> = VisualizationSettingDefinitionBase<TValue, CustomVisualizationSettings> & {
118
- widget?: never;
119
- getProps?: never;
120
- };
121
- export type VisualizationSettingDefinition<TValue, TProps, CustomVisualizationSettings> = VisualizationSettingDefinitionWithBuiltInWidget<TValue, CustomVisualizationSettings> | VisualizationSettingDefinitionWithCustomWidget<TValue, TProps, CustomVisualizationSettings> | VisualizationSettingDefinitionWithoutWidget<TValue, CustomVisualizationSettings>;
122
81
  export type VisualizationGridSize = {
123
82
  /**
124
83
  * Number of grid columns in a Metabase dashboard.
@@ -134,7 +93,8 @@ export type CustomVisualizationProps<CustomVisualizationSettings> = {
134
93
  height: number;
135
94
  series: Series;
136
95
  settings: CustomVisualizationSettings;
137
- onClick: (clickObject: ClickObject<CustomVisualizationSettings> | null) => void;
96
+ onVisualizationClick: (clickObject: ClickObject<CustomVisualizationSettings> | null) => void;
97
+ onHoverChange: (hoverObject?: HoveredObject | null) => void;
138
98
  };
139
99
  export type ColorGetter = (colorName: string) => string;
140
100
  export interface RenderingContext {
@@ -150,7 +110,6 @@ export type CustomStaticVisualizationProps<CustomVisualizationSettings> = {
150
110
  settings: CustomVisualizationSettings;
151
111
  hasDevWatermark?: boolean;
152
112
  };
153
- export type CustomVisualizationSettingsProps = {};
154
113
  export type ClickObject<CustomVisualizationSettings> = {
155
114
  value?: RowValue;
156
115
  column?: Column;
@@ -167,5 +126,24 @@ export interface ClickObjectDimension {
167
126
  value: RowValue;
168
127
  column: Column;
169
128
  }
129
+ export type HoveredDataPoint = {
130
+ key: string;
131
+ value: RowValue;
132
+ col: Column;
133
+ };
134
+ export type HoveredDimension = {
135
+ value: RowValue;
136
+ column: Column;
137
+ };
138
+ export type HoveredObject = {
139
+ index?: number;
140
+ seriesIndex?: number;
141
+ value?: unknown;
142
+ column?: Column;
143
+ data?: HoveredDataPoint[];
144
+ dimensions?: HoveredDimension[];
145
+ element?: Element;
146
+ event?: MouseEvent;
147
+ };
170
148
  export {};
171
149
  //# sourceMappingURL=viz.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"viz.d.ts","sourceRoot":"","sources":["../../src/types/viz.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"viz.d.ts","sourceRoot":"","sources":["../../src/types/viz.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metabase/custom-viz",
3
- "version": "0.0.1-alpha.3",
3
+ "version": "0.0.1-alpha.5",
4
4
  "description": "Creating custom visualizations for Metabase",
5
5
  "type": "module",
6
6
  "bin": {