@databricks/appkit 0.69.0 → 0.69.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"static-server.js","names":["expressStatic","fs"],"sources":["../../../src/plugins/server/static-server.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type express from \"express\";\nimport expressStatic from \"express\";\n\nimport { BaseServer } from \"./base-server\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"./utils\";\n\n/**\n * Static server for the AppKit.\n *\n * Serves pre-built static files in production mode. Handles SPA routing\n * by serving index.html for non-API routes and injects runtime configuration.\n *\n * @example\n * ```ts\n * const staticServer = new StaticServer(app, staticPath, endpoints);\n * staticServer.setup();\n * ```\n */\nexport class StaticServer extends BaseServer {\n private staticPath: string;\n\n constructor(\n app: express.Application,\n staticPath: string,\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n ) {\n super(app, endpoints, pluginConfigs);\n this.staticPath = staticPath;\n }\n\n /** Setup the static server. */\n setup() {\n this.app.use(\n expressStatic.static(this.staticPath, {\n index: false,\n }),\n );\n\n this.app.get(\"*\", (req, res, next) => {\n if (req.path.startsWith(\"/api\") || req.path.startsWith(\"/query\")) {\n return next();\n }\n this.serveIndex(res);\n });\n }\n\n /** Serve the index.html file. */\n private serveIndex(res: express.Response) {\n const indexPath = path.join(this.staticPath, \"index.html\");\n\n if (!fs.existsSync(indexPath)) {\n res.status(404).send(\"index.html not found\");\n return;\n }\n\n let html = fs.readFileSync(indexPath, \"utf-8\");\n html = html.replace(\"<body>\", `<body>${this.getConfigScript()}`);\n res.send(html);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,IAAa,eAAb,cAAkC,WAAW;CAC3C,AAAQ;CAER,YACE,KACA,YACA,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EACvC;AACA,QAAM,KAAK,WAAW,cAAc;AACpC,OAAK,aAAa;;;CAIpB,QAAQ;AACN,OAAK,IAAI,IACPA,QAAc,OAAO,KAAK,YAAY,EACpC,OAAO,OACR,CAAC,CACH;AAED,OAAK,IAAI,IAAI,MAAM,KAAK,KAAK,SAAS;AACpC,OAAI,IAAI,KAAK,WAAW,OAAO,IAAI,IAAI,KAAK,WAAW,SAAS,CAC9D,QAAO,MAAM;AAEf,QAAK,WAAW,IAAI;IACpB;;;CAIJ,AAAQ,WAAW,KAAuB;EACxC,MAAM,YAAY,KAAK,KAAK,KAAK,YAAY,aAAa;AAE1D,MAAI,CAACC,OAAG,WAAW,UAAU,EAAE;AAC7B,OAAI,OAAO,IAAI,CAAC,KAAK,uBAAuB;AAC5C;;EAGF,IAAI,OAAOA,OAAG,aAAa,WAAW,QAAQ;AAC9C,SAAO,KAAK,QAAQ,UAAU,SAAS,KAAK,iBAAiB,GAAG;AAChE,MAAI,KAAK,KAAK"}
1
+ {"version":3,"file":"static-server.js","names":["expressStatic"],"sources":["../../../src/plugins/server/static-server.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type express from \"express\";\nimport expressStatic from \"express\";\n\nimport { BaseServer } from \"./base-server\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"./utils\";\n\n/**\n * Static server for the AppKit.\n *\n * Serves pre-built static files in production mode. Handles SPA routing\n * by serving index.html for non-API routes and injects runtime configuration.\n *\n * @example\n * ```ts\n * const staticServer = new StaticServer(app, staticPath, endpoints);\n * staticServer.setup();\n * ```\n */\nexport class StaticServer extends BaseServer {\n private staticPath: string;\n\n constructor(\n app: express.Application,\n staticPath: string,\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n ) {\n super(app, endpoints, pluginConfigs);\n this.staticPath = staticPath;\n }\n\n /** Setup the static server. */\n setup() {\n this.app.use(\n expressStatic.static(this.staticPath, {\n index: false,\n }),\n );\n\n this.app.get(\"*\", (req, res, next) => {\n if (req.path.startsWith(\"/api\") || req.path.startsWith(\"/query\")) {\n return next();\n }\n this.serveIndex(res);\n });\n }\n\n /** Serve the index.html file. */\n private serveIndex(res: express.Response) {\n const indexPath = path.join(this.staticPath, \"index.html\");\n\n if (!fs.existsSync(indexPath)) {\n res.status(404).send(\"index.html not found\");\n return;\n }\n\n let html = fs.readFileSync(indexPath, \"utf-8\");\n html = html.replace(\"<body>\", `<body>${this.getConfigScript()}`);\n res.send(html);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,IAAa,eAAb,cAAkC,WAAW;CAC3C,AAAQ;CAER,YACE,KACA,YACA,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EACvC;AACA,QAAM,KAAK,WAAW,cAAc;AACpC,OAAK,aAAa;;;CAIpB,QAAQ;AACN,OAAK,IAAI,IACPA,QAAc,OAAO,KAAK,YAAY,EACpC,OAAO,OACR,CAAC,CACH;AAED,OAAK,IAAI,IAAI,MAAM,KAAK,KAAK,SAAS;AACpC,OAAI,IAAI,KAAK,WAAW,OAAO,IAAI,IAAI,KAAK,WAAW,SAAS,CAC9D,QAAO,MAAM;AAEf,QAAK,WAAW,IAAI;IACpB;;;CAIJ,AAAQ,WAAW,KAAuB;EACxC,MAAM,YAAY,KAAK,KAAK,KAAK,YAAY,aAAa;AAE1D,MAAI,CAAC,GAAG,WAAW,UAAU,EAAE;AAC7B,OAAI,OAAO,IAAI,CAAC,KAAK,uBAAuB;AAC5C;;EAGF,IAAI,OAAO,GAAG,aAAa,WAAW,QAAQ;AAC9C,SAAO,KAAK,QAAQ,UAAU,SAAS,KAAK,iBAAiB,GAAG;AAChE,MAAI,KAAK,KAAK"}
@@ -1,7 +1,7 @@
1
1
  import crypto from "node:crypto";
2
2
  import pc from "picocolors";
3
3
  import path from "node:path";
4
- import fsSync from "node:fs";
4
+ import fs from "node:fs";
5
5
 
6
6
  //#region src/plugins/server/utils.ts
7
7
  function parseCookies(req) {
@@ -74,8 +74,8 @@ function printRoutes(routes) {
74
74
  }
75
75
  function getQueries(configFolder) {
76
76
  const queriesFolder = path.join(configFolder, "queries");
77
- if (!fsSync.existsSync(queriesFolder)) return {};
78
- return Object.fromEntries(fsSync.readdirSync(queriesFolder).filter((f) => path.extname(f) === ".sql").map((f) => [path.basename(f, ".sql"), path.basename(f, ".sql")]));
77
+ if (!fs.existsSync(queriesFolder)) return {};
78
+ return Object.fromEntries(fs.readdirSync(queriesFolder).filter((f) => path.extname(f) === ".sql").map((f) => [path.basename(f, ".sql"), path.basename(f, ".sql")]));
79
79
  }
80
80
  const APPKIT_CONFIG_SCRIPT_ID = "__appkit__";
81
81
  const EMPTY_RUNTIME_CONFIG_JSON = JSON.stringify({
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["fs"],"sources":["../../../src/plugins/server/utils.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport type http from \"node:http\";\nimport path from \"node:path\";\n\nimport pc from \"picocolors\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"shared\";\n\nexport function parseCookies(\n req: http.IncomingMessage,\n): Record<string, string> {\n const cookieHeader = req.headers.cookie;\n if (!cookieHeader) return {};\n\n // Fast path: if there's no semicolon, there's only one cookie\n const semicolonIndex = cookieHeader.indexOf(\";\");\n if (semicolonIndex === -1) {\n const eqIndex = cookieHeader.indexOf(\"=\");\n if (eqIndex === -1) return {};\n return {\n [cookieHeader.slice(0, eqIndex).trim()]: cookieHeader.slice(eqIndex + 1),\n };\n }\n\n // Multiple cookies: parse them all\n const cookies: Record<string, string> = {};\n const parts = cookieHeader.split(\";\");\n for (let i = 0; i < parts.length; i++) {\n const eqIndex = parts[i].indexOf(\"=\");\n if (eqIndex !== -1) {\n const key = parts[i].slice(0, eqIndex).trim();\n const value = parts[i].slice(eqIndex + 1);\n cookies[key] = value;\n }\n }\n return cookies;\n}\n\nexport function generateTunnelIdFromEmail(email?: string): string | undefined {\n if (!email) return undefined;\n\n const tunnelId = crypto\n .createHash(\"sha256\")\n .update(email)\n .digest(\"base64url\")\n .slice(0, 8);\n\n return tunnelId;\n}\n\nexport function getRoutes(stack: unknown[], basePath = \"\") {\n const routes: Array<{ path: string; methods: string[] }> = [];\n\n stack.forEach((layer: any) => {\n if (layer.route) {\n // normal route\n const path = basePath + layer.route.path;\n const methods = Object.keys(layer.route.methods).map((m) =>\n m.toUpperCase(),\n );\n routes.push({ path, methods });\n } else if (layer.name === \"router\" && layer.handle.stack) {\n // nested router\n const nestedBase =\n basePath +\n layer.regexp.source\n .replace(\"^\\\\\", \"\")\n .replace(\"\\\\/?(?=\\\\/|$)\", \"\")\n .replace(/\\\\\\//g, \"/\") // convert escaped slashes\n .replace(/\\$$/, \"\") || \"\";\n routes.push(...getRoutes(layer.handle.stack, nestedBase));\n }\n });\n\n return routes;\n}\n\nconst METHOD_COLORS: Record<string, (s: string) => string> = {\n GET: pc.green,\n POST: pc.blue,\n PUT: pc.yellow,\n PATCH: pc.yellow,\n DELETE: pc.red,\n HEAD: pc.magenta,\n OPTIONS: pc.magenta,\n};\n\nexport function printRoutes(\n routes: Array<{ path: string; methods: string[] }>,\n) {\n if (routes.length === 0) return;\n\n const rows = routes\n .flatMap((r) => r.methods.map((m) => ({ method: m, path: r.path })))\n .sort(\n (a, b) =>\n a.method.localeCompare(b.method) || a.path.localeCompare(b.path),\n );\n\n const maxMethodLen = Math.max(...rows.map((r) => r.method.length));\n const separator = pc.dim(\"─\".repeat(50));\n\n const colorizeParams = (p: string) =>\n p.replace(/(:[a-zA-Z_]\\w*)/g, (match) => pc.cyan(match));\n\n console.log(\"\");\n console.log(\n ` ${pc.bold(\"Registered Routes\")} ${pc.dim(`(${rows.length})`)}`,\n );\n console.log(` ${separator}`);\n\n for (const { method, path } of rows) {\n const colorize = METHOD_COLORS[method] || pc.white;\n const methodStr = colorize(pc.bold(method.padEnd(maxMethodLen)));\n console.log(` ${methodStr} ${colorizeParams(path)}`);\n }\n\n console.log(` ${separator}`);\n console.log(\"\");\n}\n\nexport function getQueries(configFolder: string) {\n const queriesFolder = path.join(configFolder, \"queries\");\n\n if (!fs.existsSync(queriesFolder)) {\n return {};\n }\n\n return Object.fromEntries(\n fs\n .readdirSync(queriesFolder)\n .filter((f) => path.extname(f) === \".sql\")\n .map((f) => [path.basename(f, \".sql\"), path.basename(f, \".sql\")]),\n );\n}\n\nexport type { PluginClientConfigs, PluginEndpoints };\n\ninterface RuntimeConfig {\n appName: string;\n queries: Record<string, string>;\n endpoints: PluginEndpoints;\n plugins: PluginClientConfigs;\n}\n\nconst APPKIT_CONFIG_SCRIPT_ID = \"__appkit__\";\nconst EMPTY_RUNTIME_CONFIG: RuntimeConfig = {\n appName: \"\",\n queries: {},\n endpoints: {},\n plugins: {},\n};\nconst EMPTY_RUNTIME_CONFIG_JSON = JSON.stringify(EMPTY_RUNTIME_CONFIG);\nconst JSON_SCRIPT_ESCAPE_MAP: Record<string, string> = {\n \"<\": \"\\\\u003c\",\n \">\": \"\\\\u003e\",\n \"&\": \"\\\\u0026\",\n \"\\u2028\": \"\\\\u2028\",\n \"\\u2029\": \"\\\\u2029\",\n};\n\nexport function getRuntimeConfig(\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n): RuntimeConfig {\n const configFolder = path.join(process.cwd(), \"config\");\n\n return {\n appName: process.env.DATABRICKS_APP_NAME || \"\",\n queries: getQueries(configFolder),\n endpoints,\n plugins: pluginConfigs,\n };\n}\n\nexport function getConfigScript(\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n): string {\n const config = getRuntimeConfig(endpoints, pluginConfigs);\n\n return `\n <script id=\"${APPKIT_CONFIG_SCRIPT_ID}\" type=\"application/json\">\n ${serializeRuntimeConfig(config)}\n </script>\n <script>\n window.__appkit__ = JSON.parse(\n document.getElementById(\"${APPKIT_CONFIG_SCRIPT_ID}\")?.textContent ||\n '${EMPTY_RUNTIME_CONFIG_JSON}',\n );\n </script>\n `;\n}\n\nfunction serializeRuntimeConfig(config: RuntimeConfig): string {\n return JSON.stringify(config).replace(\n /[<>&\\u2028\\u2029]/g,\n (char) => JSON_SCRIPT_ESCAPE_MAP[char] ?? char,\n );\n}\n"],"mappings":";;;;;;AAQA,SAAgB,aACd,KACwB;CACxB,MAAM,eAAe,IAAI,QAAQ;AACjC,KAAI,CAAC,aAAc,QAAO,EAAE;AAI5B,KADuB,aAAa,QAAQ,IAAI,KACzB,IAAI;EACzB,MAAM,UAAU,aAAa,QAAQ,IAAI;AACzC,MAAI,YAAY,GAAI,QAAO,EAAE;AAC7B,SAAO,GACJ,aAAa,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,aAAa,MAAM,UAAU,EAAE,EACzE;;CAIH,MAAM,UAAkC,EAAE;CAC1C,MAAM,QAAQ,aAAa,MAAM,IAAI;AACrC,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,UAAU,MAAM,GAAG,QAAQ,IAAI;AACrC,MAAI,YAAY,IAAI;GAClB,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM;AAE7C,WAAQ,OADM,MAAM,GAAG,MAAM,UAAU,EAAE;;;AAI7C,QAAO;;AAGT,SAAgB,0BAA0B,OAAoC;AAC5E,KAAI,CAAC,MAAO,QAAO;AAQnB,QANiB,OACd,WAAW,SAAS,CACpB,OAAO,MAAM,CACb,OAAO,YAAY,CACnB,MAAM,GAAG,EAAE;;AAKhB,SAAgB,UAAU,OAAkB,WAAW,IAAI;CACzD,MAAM,SAAqD,EAAE;AAE7D,OAAM,SAAS,UAAe;AAC5B,MAAI,MAAM,OAAO;GAEf,MAAM,OAAO,WAAW,MAAM,MAAM;GACpC,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC,KAAK,MACpD,EAAE,aAAa,CAChB;AACD,UAAO,KAAK;IAAE;IAAM;IAAS,CAAC;aACrB,MAAM,SAAS,YAAY,MAAM,OAAO,OAAO;GAExD,MAAM,aACJ,WACE,MAAM,OAAO,OACV,QAAQ,OAAO,GAAG,CAClB,QAAQ,iBAAiB,GAAG,CAC5B,QAAQ,SAAS,IAAI,CACrB,QAAQ,OAAO,GAAG,IAAI;AAC7B,UAAO,KAAK,GAAG,UAAU,MAAM,OAAO,OAAO,WAAW,CAAC;;GAE3D;AAEF,QAAO;;AAGT,MAAM,gBAAuD;CAC3D,KAAK,GAAG;CACR,MAAM,GAAG;CACT,KAAK,GAAG;CACR,OAAO,GAAG;CACV,QAAQ,GAAG;CACX,MAAM,GAAG;CACT,SAAS,GAAG;CACb;AAED,SAAgB,YACd,QACA;AACA,KAAI,OAAO,WAAW,EAAG;CAEzB,MAAM,OAAO,OACV,SAAS,MAAM,EAAE,QAAQ,KAAK,OAAO;EAAE,QAAQ;EAAG,MAAM,EAAE;EAAM,EAAE,CAAC,CACnE,MACE,GAAG,MACF,EAAE,OAAO,cAAc,EAAE,OAAO,IAAI,EAAE,KAAK,cAAc,EAAE,KAAK,CACnE;CAEH,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,EAAE,OAAO,OAAO,CAAC;CAClE,MAAM,YAAY,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC;CAExC,MAAM,kBAAkB,MACtB,EAAE,QAAQ,qBAAqB,UAAU,GAAG,KAAK,MAAM,CAAC;AAE1D,SAAQ,IAAI,GAAG;AACf,SAAQ,IACN,KAAK,GAAG,KAAK,oBAAoB,CAAC,GAAG,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,GAChE;AACD,SAAQ,IAAI,KAAK,YAAY;AAE7B,MAAK,MAAM,EAAE,QAAQ,UAAU,MAAM;EAEnC,MAAM,aADW,cAAc,WAAW,GAAG,OAClB,GAAG,KAAK,OAAO,OAAO,aAAa,CAAC,CAAC;AAChE,UAAQ,IAAI,KAAK,UAAU,IAAI,eAAe,KAAK,GAAG;;AAGxD,SAAQ,IAAI,KAAK,YAAY;AAC7B,SAAQ,IAAI,GAAG;;AAGjB,SAAgB,WAAW,cAAsB;CAC/C,MAAM,gBAAgB,KAAK,KAAK,cAAc,UAAU;AAExD,KAAI,CAACA,OAAG,WAAW,cAAc,CAC/B,QAAO,EAAE;AAGX,QAAO,OAAO,YACZA,OACG,YAAY,cAAc,CAC1B,QAAQ,MAAM,KAAK,QAAQ,EAAE,KAAK,OAAO,CACzC,KAAK,MAAM,CAAC,KAAK,SAAS,GAAG,OAAO,EAAE,KAAK,SAAS,GAAG,OAAO,CAAC,CAAC,CACpE;;AAYH,MAAM,0BAA0B;AAOhC,MAAM,4BAA4B,KAAK,UANK;CAC1C,SAAS;CACT,SAAS,EAAE;CACX,WAAW,EAAE;CACb,SAAS,EAAE;CACZ,CACqE;AACtE,MAAM,yBAAiD;CACrD,KAAK;CACL,KAAK;CACL,KAAK;CACL,UAAU;CACV,UAAU;CACX;AAED,SAAgB,iBACd,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EACxB;CACf,MAAM,eAAe,KAAK,KAAK,QAAQ,KAAK,EAAE,SAAS;AAEvD,QAAO;EACL,SAAS,QAAQ,IAAI,uBAAuB;EAC5C,SAAS,WAAW,aAAa;EACjC;EACA,SAAS;EACV;;AAGH,SAAgB,gBACd,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EAC/B;AAGR,QAAO;kBACS,wBAAwB;QAClC,uBAJS,iBAAiB,WAAW,cAAc,CAIrB,CAAC;;;;mCAIJ,wBAAwB;aAC9C,0BAA0B;;;;;AAMvC,SAAS,uBAAuB,QAA+B;AAC7D,QAAO,KAAK,UAAU,OAAO,CAAC,QAC5B,uBACC,SAAS,uBAAuB,SAAS,KAC3C"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/plugins/server/utils.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport type http from \"node:http\";\nimport path from \"node:path\";\n\nimport pc from \"picocolors\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"shared\";\n\nexport function parseCookies(\n req: http.IncomingMessage,\n): Record<string, string> {\n const cookieHeader = req.headers.cookie;\n if (!cookieHeader) return {};\n\n // Fast path: if there's no semicolon, there's only one cookie\n const semicolonIndex = cookieHeader.indexOf(\";\");\n if (semicolonIndex === -1) {\n const eqIndex = cookieHeader.indexOf(\"=\");\n if (eqIndex === -1) return {};\n return {\n [cookieHeader.slice(0, eqIndex).trim()]: cookieHeader.slice(eqIndex + 1),\n };\n }\n\n // Multiple cookies: parse them all\n const cookies: Record<string, string> = {};\n const parts = cookieHeader.split(\";\");\n for (let i = 0; i < parts.length; i++) {\n const eqIndex = parts[i].indexOf(\"=\");\n if (eqIndex !== -1) {\n const key = parts[i].slice(0, eqIndex).trim();\n const value = parts[i].slice(eqIndex + 1);\n cookies[key] = value;\n }\n }\n return cookies;\n}\n\nexport function generateTunnelIdFromEmail(email?: string): string | undefined {\n if (!email) return undefined;\n\n const tunnelId = crypto\n .createHash(\"sha256\")\n .update(email)\n .digest(\"base64url\")\n .slice(0, 8);\n\n return tunnelId;\n}\n\nexport function getRoutes(stack: unknown[], basePath = \"\") {\n const routes: Array<{ path: string; methods: string[] }> = [];\n\n stack.forEach((layer: any) => {\n if (layer.route) {\n // normal route\n const path = basePath + layer.route.path;\n const methods = Object.keys(layer.route.methods).map((m) =>\n m.toUpperCase(),\n );\n routes.push({ path, methods });\n } else if (layer.name === \"router\" && layer.handle.stack) {\n // nested router\n const nestedBase =\n basePath +\n layer.regexp.source\n .replace(\"^\\\\\", \"\")\n .replace(\"\\\\/?(?=\\\\/|$)\", \"\")\n .replace(/\\\\\\//g, \"/\") // convert escaped slashes\n .replace(/\\$$/, \"\") || \"\";\n routes.push(...getRoutes(layer.handle.stack, nestedBase));\n }\n });\n\n return routes;\n}\n\nconst METHOD_COLORS: Record<string, (s: string) => string> = {\n GET: pc.green,\n POST: pc.blue,\n PUT: pc.yellow,\n PATCH: pc.yellow,\n DELETE: pc.red,\n HEAD: pc.magenta,\n OPTIONS: pc.magenta,\n};\n\nexport function printRoutes(\n routes: Array<{ path: string; methods: string[] }>,\n) {\n if (routes.length === 0) return;\n\n const rows = routes\n .flatMap((r) => r.methods.map((m) => ({ method: m, path: r.path })))\n .sort(\n (a, b) =>\n a.method.localeCompare(b.method) || a.path.localeCompare(b.path),\n );\n\n const maxMethodLen = Math.max(...rows.map((r) => r.method.length));\n const separator = pc.dim(\"─\".repeat(50));\n\n const colorizeParams = (p: string) =>\n p.replace(/(:[a-zA-Z_]\\w*)/g, (match) => pc.cyan(match));\n\n console.log(\"\");\n console.log(\n ` ${pc.bold(\"Registered Routes\")} ${pc.dim(`(${rows.length})`)}`,\n );\n console.log(` ${separator}`);\n\n for (const { method, path } of rows) {\n const colorize = METHOD_COLORS[method] || pc.white;\n const methodStr = colorize(pc.bold(method.padEnd(maxMethodLen)));\n console.log(` ${methodStr} ${colorizeParams(path)}`);\n }\n\n console.log(` ${separator}`);\n console.log(\"\");\n}\n\nexport function getQueries(configFolder: string) {\n const queriesFolder = path.join(configFolder, \"queries\");\n\n if (!fs.existsSync(queriesFolder)) {\n return {};\n }\n\n return Object.fromEntries(\n fs\n .readdirSync(queriesFolder)\n .filter((f) => path.extname(f) === \".sql\")\n .map((f) => [path.basename(f, \".sql\"), path.basename(f, \".sql\")]),\n );\n}\n\nexport type { PluginClientConfigs, PluginEndpoints };\n\ninterface RuntimeConfig {\n appName: string;\n queries: Record<string, string>;\n endpoints: PluginEndpoints;\n plugins: PluginClientConfigs;\n}\n\nconst APPKIT_CONFIG_SCRIPT_ID = \"__appkit__\";\nconst EMPTY_RUNTIME_CONFIG: RuntimeConfig = {\n appName: \"\",\n queries: {},\n endpoints: {},\n plugins: {},\n};\nconst EMPTY_RUNTIME_CONFIG_JSON = JSON.stringify(EMPTY_RUNTIME_CONFIG);\nconst JSON_SCRIPT_ESCAPE_MAP: Record<string, string> = {\n \"<\": \"\\\\u003c\",\n \">\": \"\\\\u003e\",\n \"&\": \"\\\\u0026\",\n \"\\u2028\": \"\\\\u2028\",\n \"\\u2029\": \"\\\\u2029\",\n};\n\nexport function getRuntimeConfig(\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n): RuntimeConfig {\n const configFolder = path.join(process.cwd(), \"config\");\n\n return {\n appName: process.env.DATABRICKS_APP_NAME || \"\",\n queries: getQueries(configFolder),\n endpoints,\n plugins: pluginConfigs,\n };\n}\n\nexport function getConfigScript(\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n): string {\n const config = getRuntimeConfig(endpoints, pluginConfigs);\n\n return `\n <script id=\"${APPKIT_CONFIG_SCRIPT_ID}\" type=\"application/json\">\n ${serializeRuntimeConfig(config)}\n </script>\n <script>\n window.__appkit__ = JSON.parse(\n document.getElementById(\"${APPKIT_CONFIG_SCRIPT_ID}\")?.textContent ||\n '${EMPTY_RUNTIME_CONFIG_JSON}',\n );\n </script>\n `;\n}\n\nfunction serializeRuntimeConfig(config: RuntimeConfig): string {\n return JSON.stringify(config).replace(\n /[<>&\\u2028\\u2029]/g,\n (char) => JSON_SCRIPT_ESCAPE_MAP[char] ?? char,\n );\n}\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { appKitServingTypesPlugin } from "../../type-generator/serving/vite-plug
7
7
  import { appKitTypesPlugin } from "../../type-generator/vite-plugin.js";
8
8
  import { reactSourceLocPlugin } from "./react-source-loc-vite-plugin.js";
9
9
  import path from "node:path";
10
- import fsSync from "node:fs";
10
+ import fs from "node:fs";
11
11
 
12
12
  //#region src/plugins/server/vite-dev-server.ts
13
13
  const logger = createLogger("server:vite");
@@ -72,7 +72,7 @@ var ViteDevServer = class extends BaseServer {
72
72
  this.validateVite(vite);
73
73
  try {
74
74
  const indexPath = path.resolve(clientRoot, "index.html");
75
- let html = fsSync.readFileSync(indexPath, "utf-8");
75
+ let html = fs.readFileSync(indexPath, "utf-8");
76
76
  html = html.replace("<body>", `<body>${this.getConfigScript()}`);
77
77
  html = await vite.transformIndexHtml(req.originalUrl, html);
78
78
  res.status(200).set({ "Content-Type": "text/html" }).end(html);
@@ -98,8 +98,8 @@ var ViteDevServer = class extends BaseServer {
98
98
  ];
99
99
  for (const dir of candidates) {
100
100
  const fullPath = path.resolve(cwd, dir);
101
- const hasViteConfig = fsSync.existsSync(path.join(fullPath, "vite.config.ts")) || fsSync.existsSync(path.join(fullPath, "vite.config.js"));
102
- const hasIndexHtml = fsSync.existsSync(path.join(fullPath, "index.html"));
101
+ const hasViteConfig = fs.existsSync(path.join(fullPath, "vite.config.ts")) || fs.existsSync(path.join(fullPath, "vite.config.js"));
102
+ const hasIndexHtml = fs.existsSync(path.join(fullPath, "index.html"));
103
103
  if (hasViteConfig && hasIndexHtml) {
104
104
  logger.debug("Vite dev server: using client root %s", fullPath);
105
105
  return fullPath;
@@ -1 +1 @@
1
- {"version":3,"file":"vite-dev-server.js","names":["fs"],"sources":["../../../src/plugins/server/vite-dev-server.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type express from \"express\";\nimport type { ViteDevServer as ViteDevServerType } from \"vite\";\n\nimport { ServerError } from \"../../errors\";\nimport { createLogger } from \"../../logging/logger\";\nimport { appKitServingTypesPlugin } from \"../../type-generator/serving/vite-plugin\";\nimport { appKitTypesPlugin } from \"../../type-generator/vite-plugin\";\nimport { mergeConfigDedup } from \"../../utils\";\nimport { BaseServer } from \"./base-server\";\nimport { reactSourceLocPlugin } from \"./react-source-loc-vite-plugin\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"./utils\";\n\nconst logger = createLogger(\"server:vite\");\n\n/**\n * Vite dev server for the AppKit.\n *\n * This class is responsible for serving the Vite dev server for the development server.\n * It also handles the index.html file for the development server.\n *\n * @example\n * ```ts\n * const viteDevServer = new ViteDevServer(app, endpoints);\n * await viteDevServer.setup();\n * ```\n */\nexport class ViteDevServer extends BaseServer {\n private vite: ViteDevServerType | null;\n\n constructor(\n app: express.Application,\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n ) {\n super(app, endpoints, pluginConfigs);\n this.vite = null;\n }\n\n /**\n * Setup the Vite dev server.\n *\n * This method sets up the Vite dev server and the index.html file for the development server.\n *\n * @returns\n */\n async setup() {\n const {\n createServer: createViteServer,\n loadConfigFromFile,\n mergeConfig,\n } = await import(\"vite\");\n const react = await import(\"@vitejs/plugin-react\");\n\n const clientRoot = this.findClientRoot();\n const projectRoot = process.cwd();\n\n const loadedConfig = await loadConfigFromFile(\n {\n mode: \"development\",\n command: \"serve\",\n },\n undefined,\n clientRoot,\n );\n\n const userConfig = loadedConfig?.config ?? {};\n const viteClientPort = process.env.VITE_CLIENT_PORT;\n const serverHmr = viteClientPort\n ? { hmr: { clientPort: viteClientPort } }\n : {};\n\n const coreConfig = {\n configFile: false,\n root: clientRoot,\n server: {\n middlewareMode: true,\n ...serverHmr,\n watch: {\n useFsEvents: true,\n ignored: [\"**/node_modules/**\", \"!**/node_modules/@databricks/**\"],\n },\n },\n plugins: [\n react.default(),\n reactSourceLocPlugin({ projectRoot }),\n appKitTypesPlugin(),\n appKitServingTypesPlugin(),\n ],\n appType: \"custom\",\n };\n\n const mergedConfigs = mergeConfigDedup(userConfig, coreConfig, mergeConfig);\n this.vite = await createViteServer(mergedConfigs);\n\n this.app.use(this.vite.middlewares);\n\n this.app.use(\"*\", async (req, res, next) => {\n if (\n req.originalUrl.startsWith(\"/api\") ||\n req.originalUrl.startsWith(\"/query\")\n ) {\n return next();\n }\n const vite = this.vite;\n this.validateVite(vite);\n\n try {\n const indexPath = path.resolve(clientRoot, \"index.html\");\n let html = fs.readFileSync(indexPath, \"utf-8\");\n html = html.replace(\"<body>\", `<body>${this.getConfigScript()}`);\n html = await vite.transformIndexHtml(req.originalUrl, html);\n res.status(200).set({ \"Content-Type\": \"text/html\" }).end(html);\n } catch (e) {\n vite.ssrFixStacktrace(e as Error);\n next(e);\n }\n });\n }\n\n /** Close the Vite dev server. */\n async close() {\n await this.vite?.close();\n }\n\n /** Find the client root. */\n private findClientRoot(): string {\n const cwd = process.cwd();\n const candidates = [\"client\", \"src\", \"app\", \"frontend\", \".\"];\n\n for (const dir of candidates) {\n const fullPath = path.resolve(cwd, dir);\n const hasViteConfig =\n fs.existsSync(path.join(fullPath, \"vite.config.ts\")) ||\n fs.existsSync(path.join(fullPath, \"vite.config.js\"));\n const hasIndexHtml = fs.existsSync(path.join(fullPath, \"index.html\"));\n\n if (hasViteConfig && hasIndexHtml) {\n logger.debug(\"Vite dev server: using client root %s\", fullPath);\n return fullPath;\n }\n }\n\n throw ServerError.clientDirectoryNotFound(candidates);\n }\n\n // type assertion to ensure vite is not null\n private validateVite(\n vite: ViteDevServerType | null,\n ): asserts vite is ViteDevServerType {\n if (!vite) {\n throw ServerError.viteNotInitialized();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,SAAS,aAAa,cAAc;;;;;;;;;;;;;AAc1C,IAAa,gBAAb,cAAmC,WAAW;CAC5C,AAAQ;CAER,YACE,KACA,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EACvC;AACA,QAAM,KAAK,WAAW,cAAc;AACpC,OAAK,OAAO;;;;;;;;;CAUd,MAAM,QAAQ;EACZ,MAAM,EACJ,cAAc,kBACd,oBACA,gBACE,MAAM,OAAO;EACjB,MAAM,QAAQ,MAAM,OAAO;EAE3B,MAAM,aAAa,KAAK,gBAAgB;EACxC,MAAM,cAAc,QAAQ,KAAK;EAWjC,MAAM,cATe,MAAM,mBACzB;GACE,MAAM;GACN,SAAS;GACV,EACD,QACA,WACD,GAEgC,UAAU,EAAE;EAC7C,MAAM,iBAAiB,QAAQ,IAAI;AA0BnC,OAAK,OAAO,MAAM,iBADI,iBAAiB,YApBpB;GACjB,YAAY;GACZ,MAAM;GACN,QAAQ;IACN,gBAAgB;IAChB,GATc,iBACd,EAAE,KAAK,EAAE,YAAY,gBAAgB,EAAE,GACvC,EAAE;IAQF,OAAO;KACL,aAAa;KACb,SAAS,CAAC,sBAAsB,kCAAkC;KACnE;IACF;GACD,SAAS;IACP,MAAM,SAAS;IACf,qBAAqB,EAAE,aAAa,CAAC;IACrC,mBAAmB;IACnB,0BAA0B;IAC3B;GACD,SAAS;GACV,EAE8D,YAAY,CAC1B;AAEjD,OAAK,IAAI,IAAI,KAAK,KAAK,YAAY;AAEnC,OAAK,IAAI,IAAI,KAAK,OAAO,KAAK,KAAK,SAAS;AAC1C,OACE,IAAI,YAAY,WAAW,OAAO,IAClC,IAAI,YAAY,WAAW,SAAS,CAEpC,QAAO,MAAM;GAEf,MAAM,OAAO,KAAK;AAClB,QAAK,aAAa,KAAK;AAEvB,OAAI;IACF,MAAM,YAAY,KAAK,QAAQ,YAAY,aAAa;IACxD,IAAI,OAAOA,OAAG,aAAa,WAAW,QAAQ;AAC9C,WAAO,KAAK,QAAQ,UAAU,SAAS,KAAK,iBAAiB,GAAG;AAChE,WAAO,MAAM,KAAK,mBAAmB,IAAI,aAAa,KAAK;AAC3D,QAAI,OAAO,IAAI,CAAC,IAAI,EAAE,gBAAgB,aAAa,CAAC,CAAC,IAAI,KAAK;YACvD,GAAG;AACV,SAAK,iBAAiB,EAAW;AACjC,SAAK,EAAE;;IAET;;;CAIJ,MAAM,QAAQ;AACZ,QAAM,KAAK,MAAM,OAAO;;;CAI1B,AAAQ,iBAAyB;EAC/B,MAAM,MAAM,QAAQ,KAAK;EACzB,MAAM,aAAa;GAAC;GAAU;GAAO;GAAO;GAAY;GAAI;AAE5D,OAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,WAAW,KAAK,QAAQ,KAAK,IAAI;GACvC,MAAM,gBACJA,OAAG,WAAW,KAAK,KAAK,UAAU,iBAAiB,CAAC,IACpDA,OAAG,WAAW,KAAK,KAAK,UAAU,iBAAiB,CAAC;GACtD,MAAM,eAAeA,OAAG,WAAW,KAAK,KAAK,UAAU,aAAa,CAAC;AAErE,OAAI,iBAAiB,cAAc;AACjC,WAAO,MAAM,yCAAyC,SAAS;AAC/D,WAAO;;;AAIX,QAAM,YAAY,wBAAwB,WAAW;;CAIvD,AAAQ,aACN,MACmC;AACnC,MAAI,CAAC,KACH,OAAM,YAAY,oBAAoB"}
1
+ {"version":3,"file":"vite-dev-server.js","names":[],"sources":["../../../src/plugins/server/vite-dev-server.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type express from \"express\";\nimport type { ViteDevServer as ViteDevServerType } from \"vite\";\n\nimport { ServerError } from \"../../errors\";\nimport { createLogger } from \"../../logging/logger\";\nimport { appKitServingTypesPlugin } from \"../../type-generator/serving/vite-plugin\";\nimport { appKitTypesPlugin } from \"../../type-generator/vite-plugin\";\nimport { mergeConfigDedup } from \"../../utils\";\nimport { BaseServer } from \"./base-server\";\nimport { reactSourceLocPlugin } from \"./react-source-loc-vite-plugin\";\nimport type { PluginClientConfigs, PluginEndpoints } from \"./utils\";\n\nconst logger = createLogger(\"server:vite\");\n\n/**\n * Vite dev server for the AppKit.\n *\n * This class is responsible for serving the Vite dev server for the development server.\n * It also handles the index.html file for the development server.\n *\n * @example\n * ```ts\n * const viteDevServer = new ViteDevServer(app, endpoints);\n * await viteDevServer.setup();\n * ```\n */\nexport class ViteDevServer extends BaseServer {\n private vite: ViteDevServerType | null;\n\n constructor(\n app: express.Application,\n endpoints: PluginEndpoints = {},\n pluginConfigs: PluginClientConfigs = {},\n ) {\n super(app, endpoints, pluginConfigs);\n this.vite = null;\n }\n\n /**\n * Setup the Vite dev server.\n *\n * This method sets up the Vite dev server and the index.html file for the development server.\n *\n * @returns\n */\n async setup() {\n const {\n createServer: createViteServer,\n loadConfigFromFile,\n mergeConfig,\n } = await import(\"vite\");\n const react = await import(\"@vitejs/plugin-react\");\n\n const clientRoot = this.findClientRoot();\n const projectRoot = process.cwd();\n\n const loadedConfig = await loadConfigFromFile(\n {\n mode: \"development\",\n command: \"serve\",\n },\n undefined,\n clientRoot,\n );\n\n const userConfig = loadedConfig?.config ?? {};\n const viteClientPort = process.env.VITE_CLIENT_PORT;\n const serverHmr = viteClientPort\n ? { hmr: { clientPort: viteClientPort } }\n : {};\n\n const coreConfig = {\n configFile: false,\n root: clientRoot,\n server: {\n middlewareMode: true,\n ...serverHmr,\n watch: {\n useFsEvents: true,\n ignored: [\"**/node_modules/**\", \"!**/node_modules/@databricks/**\"],\n },\n },\n plugins: [\n react.default(),\n reactSourceLocPlugin({ projectRoot }),\n appKitTypesPlugin(),\n appKitServingTypesPlugin(),\n ],\n appType: \"custom\",\n };\n\n const mergedConfigs = mergeConfigDedup(userConfig, coreConfig, mergeConfig);\n this.vite = await createViteServer(mergedConfigs);\n\n this.app.use(this.vite.middlewares);\n\n this.app.use(\"*\", async (req, res, next) => {\n if (\n req.originalUrl.startsWith(\"/api\") ||\n req.originalUrl.startsWith(\"/query\")\n ) {\n return next();\n }\n const vite = this.vite;\n this.validateVite(vite);\n\n try {\n const indexPath = path.resolve(clientRoot, \"index.html\");\n let html = fs.readFileSync(indexPath, \"utf-8\");\n html = html.replace(\"<body>\", `<body>${this.getConfigScript()}`);\n html = await vite.transformIndexHtml(req.originalUrl, html);\n res.status(200).set({ \"Content-Type\": \"text/html\" }).end(html);\n } catch (e) {\n vite.ssrFixStacktrace(e as Error);\n next(e);\n }\n });\n }\n\n /** Close the Vite dev server. */\n async close() {\n await this.vite?.close();\n }\n\n /** Find the client root. */\n private findClientRoot(): string {\n const cwd = process.cwd();\n const candidates = [\"client\", \"src\", \"app\", \"frontend\", \".\"];\n\n for (const dir of candidates) {\n const fullPath = path.resolve(cwd, dir);\n const hasViteConfig =\n fs.existsSync(path.join(fullPath, \"vite.config.ts\")) ||\n fs.existsSync(path.join(fullPath, \"vite.config.js\"));\n const hasIndexHtml = fs.existsSync(path.join(fullPath, \"index.html\"));\n\n if (hasViteConfig && hasIndexHtml) {\n logger.debug(\"Vite dev server: using client root %s\", fullPath);\n return fullPath;\n }\n }\n\n throw ServerError.clientDirectoryNotFound(candidates);\n }\n\n // type assertion to ensure vite is not null\n private validateVite(\n vite: ViteDevServerType | null,\n ): asserts vite is ViteDevServerType {\n if (!vite) {\n throw ServerError.viteNotInitialized();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,SAAS,aAAa,cAAc;;;;;;;;;;;;;AAc1C,IAAa,gBAAb,cAAmC,WAAW;CAC5C,AAAQ;CAER,YACE,KACA,YAA6B,EAAE,EAC/B,gBAAqC,EAAE,EACvC;AACA,QAAM,KAAK,WAAW,cAAc;AACpC,OAAK,OAAO;;;;;;;;;CAUd,MAAM,QAAQ;EACZ,MAAM,EACJ,cAAc,kBACd,oBACA,gBACE,MAAM,OAAO;EACjB,MAAM,QAAQ,MAAM,OAAO;EAE3B,MAAM,aAAa,KAAK,gBAAgB;EACxC,MAAM,cAAc,QAAQ,KAAK;EAWjC,MAAM,cATe,MAAM,mBACzB;GACE,MAAM;GACN,SAAS;GACV,EACD,QACA,WACD,GAEgC,UAAU,EAAE;EAC7C,MAAM,iBAAiB,QAAQ,IAAI;AA0BnC,OAAK,OAAO,MAAM,iBADI,iBAAiB,YApBpB;GACjB,YAAY;GACZ,MAAM;GACN,QAAQ;IACN,gBAAgB;IAChB,GATc,iBACd,EAAE,KAAK,EAAE,YAAY,gBAAgB,EAAE,GACvC,EAAE;IAQF,OAAO;KACL,aAAa;KACb,SAAS,CAAC,sBAAsB,kCAAkC;KACnE;IACF;GACD,SAAS;IACP,MAAM,SAAS;IACf,qBAAqB,EAAE,aAAa,CAAC;IACrC,mBAAmB;IACnB,0BAA0B;IAC3B;GACD,SAAS;GACV,EAE8D,YAAY,CAC1B;AAEjD,OAAK,IAAI,IAAI,KAAK,KAAK,YAAY;AAEnC,OAAK,IAAI,IAAI,KAAK,OAAO,KAAK,KAAK,SAAS;AAC1C,OACE,IAAI,YAAY,WAAW,OAAO,IAClC,IAAI,YAAY,WAAW,SAAS,CAEpC,QAAO,MAAM;GAEf,MAAM,OAAO,KAAK;AAClB,QAAK,aAAa,KAAK;AAEvB,OAAI;IACF,MAAM,YAAY,KAAK,QAAQ,YAAY,aAAa;IACxD,IAAI,OAAO,GAAG,aAAa,WAAW,QAAQ;AAC9C,WAAO,KAAK,QAAQ,UAAU,SAAS,KAAK,iBAAiB,GAAG;AAChE,WAAO,MAAM,KAAK,mBAAmB,IAAI,aAAa,KAAK;AAC3D,QAAI,OAAO,IAAI,CAAC,IAAI,EAAE,gBAAgB,aAAa,CAAC,CAAC,IAAI,KAAK;YACvD,GAAG;AACV,SAAK,iBAAiB,EAAW;AACjC,SAAK,EAAE;;IAET;;;CAIJ,MAAM,QAAQ;AACZ,QAAM,KAAK,MAAM,OAAO;;;CAI1B,AAAQ,iBAAyB;EAC/B,MAAM,MAAM,QAAQ,KAAK;EACzB,MAAM,aAAa;GAAC;GAAU;GAAO;GAAO;GAAY;GAAI;AAE5D,OAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,WAAW,KAAK,QAAQ,KAAK,IAAI;GACvC,MAAM,gBACJ,GAAG,WAAW,KAAK,KAAK,UAAU,iBAAiB,CAAC,IACpD,GAAG,WAAW,KAAK,KAAK,UAAU,iBAAiB,CAAC;GACtD,MAAM,eAAe,GAAG,WAAW,KAAK,KAAK,UAAU,aAAa,CAAC;AAErE,OAAI,iBAAiB,cAAc;AACjC,WAAO,MAAM,yCAAyC,SAAS;AAC/D,WAAO;;;AAIX,QAAM,YAAY,wBAAwB,WAAW;;CAIvD,AAAQ,aACN,MACmC;AACnC,MAAI,CAAC,KACH,OAAM,YAAY,oBAAoB"}
@@ -12,12 +12,12 @@ declare const resourceFieldEntrySchema: z.ZodObject<{
12
12
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
13
13
  type: z.ZodLiteral<"kind">;
14
14
  resourceKind: z.ZodEnum<{
15
- volume: "volume";
16
- genie_space: "genie_space";
17
15
  warehouse: "warehouse";
16
+ genie_space: "genie_space";
18
17
  postgres_project: "postgres_project";
19
18
  postgres_branch: "postgres_branch";
20
19
  postgres_database: "postgres_database";
20
+ volume: "volume";
21
21
  }>;
22
22
  select: z.ZodOptional<z.ZodString>;
23
23
  display: z.ZodOptional<z.ZodString>;
@@ -58,12 +58,12 @@ declare const pluginManifestSchema: z.ZodObject<{
58
58
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
59
59
  type: z.ZodLiteral<"kind">;
60
60
  resourceKind: z.ZodEnum<{
61
- volume: "volume";
62
- genie_space: "genie_space";
63
61
  warehouse: "warehouse";
62
+ genie_space: "genie_space";
64
63
  postgres_project: "postgres_project";
65
64
  postgres_branch: "postgres_branch";
66
65
  postgres_database: "postgres_database";
66
+ volume: "volume";
67
67
  }>;
68
68
  select: z.ZodOptional<z.ZodString>;
69
69
  display: z.ZodOptional<z.ZodString>;
@@ -99,12 +99,12 @@ declare const pluginManifestSchema: z.ZodObject<{
99
99
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
100
100
  type: z.ZodLiteral<"kind">;
101
101
  resourceKind: z.ZodEnum<{
102
- volume: "volume";
103
- genie_space: "genie_space";
104
102
  warehouse: "warehouse";
103
+ genie_space: "genie_space";
105
104
  postgres_project: "postgres_project";
106
105
  postgres_branch: "postgres_branch";
107
106
  postgres_database: "postgres_database";
107
+ volume: "volume";
108
108
  }>;
109
109
  select: z.ZodOptional<z.ZodString>;
110
110
  display: z.ZodOptional<z.ZodString>;
@@ -139,12 +139,12 @@ declare const pluginManifestSchema: z.ZodObject<{
139
139
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
140
140
  type: z.ZodLiteral<"kind">;
141
141
  resourceKind: z.ZodEnum<{
142
- volume: "volume";
143
- genie_space: "genie_space";
144
142
  warehouse: "warehouse";
143
+ genie_space: "genie_space";
145
144
  postgres_project: "postgres_project";
146
145
  postgres_branch: "postgres_branch";
147
146
  postgres_database: "postgres_database";
147
+ volume: "volume";
148
148
  }>;
149
149
  select: z.ZodOptional<z.ZodString>;
150
150
  display: z.ZodOptional<z.ZodString>;
@@ -180,12 +180,12 @@ declare const pluginManifestSchema: z.ZodObject<{
180
180
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
181
181
  type: z.ZodLiteral<"kind">;
182
182
  resourceKind: z.ZodEnum<{
183
- volume: "volume";
184
- genie_space: "genie_space";
185
183
  warehouse: "warehouse";
184
+ genie_space: "genie_space";
186
185
  postgres_project: "postgres_project";
187
186
  postgres_branch: "postgres_branch";
188
187
  postgres_database: "postgres_database";
188
+ volume: "volume";
189
189
  }>;
190
190
  select: z.ZodOptional<z.ZodString>;
191
191
  display: z.ZodOptional<z.ZodString>;
@@ -220,12 +220,12 @@ declare const pluginManifestSchema: z.ZodObject<{
220
220
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
221
221
  type: z.ZodLiteral<"kind">;
222
222
  resourceKind: z.ZodEnum<{
223
- volume: "volume";
224
- genie_space: "genie_space";
225
223
  warehouse: "warehouse";
224
+ genie_space: "genie_space";
226
225
  postgres_project: "postgres_project";
227
226
  postgres_branch: "postgres_branch";
228
227
  postgres_database: "postgres_database";
228
+ volume: "volume";
229
229
  }>;
230
230
  select: z.ZodOptional<z.ZodString>;
231
231
  display: z.ZodOptional<z.ZodString>;
@@ -259,12 +259,12 @@ declare const pluginManifestSchema: z.ZodObject<{
259
259
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
260
260
  type: z.ZodLiteral<"kind">;
261
261
  resourceKind: z.ZodEnum<{
262
- volume: "volume";
263
- genie_space: "genie_space";
264
262
  warehouse: "warehouse";
263
+ genie_space: "genie_space";
265
264
  postgres_project: "postgres_project";
266
265
  postgres_branch: "postgres_branch";
267
266
  postgres_database: "postgres_database";
267
+ volume: "volume";
268
268
  }>;
269
269
  select: z.ZodOptional<z.ZodString>;
270
270
  display: z.ZodOptional<z.ZodString>;
@@ -298,12 +298,12 @@ declare const pluginManifestSchema: z.ZodObject<{
298
298
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
299
299
  type: z.ZodLiteral<"kind">;
300
300
  resourceKind: z.ZodEnum<{
301
- volume: "volume";
302
- genie_space: "genie_space";
303
301
  warehouse: "warehouse";
302
+ genie_space: "genie_space";
304
303
  postgres_project: "postgres_project";
305
304
  postgres_branch: "postgres_branch";
306
305
  postgres_database: "postgres_database";
306
+ volume: "volume";
307
307
  }>;
308
308
  select: z.ZodOptional<z.ZodString>;
309
309
  display: z.ZodOptional<z.ZodString>;
@@ -337,12 +337,12 @@ declare const pluginManifestSchema: z.ZodObject<{
337
337
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
338
338
  type: z.ZodLiteral<"kind">;
339
339
  resourceKind: z.ZodEnum<{
340
- volume: "volume";
341
- genie_space: "genie_space";
342
340
  warehouse: "warehouse";
341
+ genie_space: "genie_space";
343
342
  postgres_project: "postgres_project";
344
343
  postgres_branch: "postgres_branch";
345
344
  postgres_database: "postgres_database";
345
+ volume: "volume";
346
346
  }>;
347
347
  select: z.ZodOptional<z.ZodString>;
348
348
  display: z.ZodOptional<z.ZodString>;
@@ -376,12 +376,12 @@ declare const pluginManifestSchema: z.ZodObject<{
376
376
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
377
377
  type: z.ZodLiteral<"kind">;
378
378
  resourceKind: z.ZodEnum<{
379
- volume: "volume";
380
- genie_space: "genie_space";
381
379
  warehouse: "warehouse";
380
+ genie_space: "genie_space";
382
381
  postgres_project: "postgres_project";
383
382
  postgres_branch: "postgres_branch";
384
383
  postgres_database: "postgres_database";
384
+ volume: "volume";
385
385
  }>;
386
386
  select: z.ZodOptional<z.ZodString>;
387
387
  display: z.ZodOptional<z.ZodString>;
@@ -415,12 +415,12 @@ declare const pluginManifestSchema: z.ZodObject<{
415
415
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
416
416
  type: z.ZodLiteral<"kind">;
417
417
  resourceKind: z.ZodEnum<{
418
- volume: "volume";
419
- genie_space: "genie_space";
420
418
  warehouse: "warehouse";
419
+ genie_space: "genie_space";
421
420
  postgres_project: "postgres_project";
422
421
  postgres_branch: "postgres_branch";
423
422
  postgres_database: "postgres_database";
423
+ volume: "volume";
424
424
  }>;
425
425
  select: z.ZodOptional<z.ZodString>;
426
426
  display: z.ZodOptional<z.ZodString>;
@@ -457,12 +457,12 @@ declare const pluginManifestSchema: z.ZodObject<{
457
457
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
458
458
  type: z.ZodLiteral<"kind">;
459
459
  resourceKind: z.ZodEnum<{
460
- volume: "volume";
461
- genie_space: "genie_space";
462
460
  warehouse: "warehouse";
461
+ genie_space: "genie_space";
463
462
  postgres_project: "postgres_project";
464
463
  postgres_branch: "postgres_branch";
465
464
  postgres_database: "postgres_database";
465
+ volume: "volume";
466
466
  }>;
467
467
  select: z.ZodOptional<z.ZodString>;
468
468
  display: z.ZodOptional<z.ZodString>;
@@ -498,12 +498,12 @@ declare const pluginManifestSchema: z.ZodObject<{
498
498
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
499
499
  type: z.ZodLiteral<"kind">;
500
500
  resourceKind: z.ZodEnum<{
501
- volume: "volume";
502
- genie_space: "genie_space";
503
501
  warehouse: "warehouse";
502
+ genie_space: "genie_space";
504
503
  postgres_project: "postgres_project";
505
504
  postgres_branch: "postgres_branch";
506
505
  postgres_database: "postgres_database";
506
+ volume: "volume";
507
507
  }>;
508
508
  select: z.ZodOptional<z.ZodString>;
509
509
  display: z.ZodOptional<z.ZodString>;
@@ -537,12 +537,12 @@ declare const pluginManifestSchema: z.ZodObject<{
537
537
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
538
538
  type: z.ZodLiteral<"kind">;
539
539
  resourceKind: z.ZodEnum<{
540
- volume: "volume";
541
- genie_space: "genie_space";
542
540
  warehouse: "warehouse";
541
+ genie_space: "genie_space";
543
542
  postgres_project: "postgres_project";
544
543
  postgres_branch: "postgres_branch";
545
544
  postgres_database: "postgres_database";
545
+ volume: "volume";
546
546
  }>;
547
547
  select: z.ZodOptional<z.ZodString>;
548
548
  display: z.ZodOptional<z.ZodString>;
@@ -579,12 +579,12 @@ declare const pluginManifestSchema: z.ZodObject<{
579
579
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
580
580
  type: z.ZodLiteral<"kind">;
581
581
  resourceKind: z.ZodEnum<{
582
- volume: "volume";
583
- genie_space: "genie_space";
584
582
  warehouse: "warehouse";
583
+ genie_space: "genie_space";
585
584
  postgres_project: "postgres_project";
586
585
  postgres_branch: "postgres_branch";
587
586
  postgres_database: "postgres_database";
587
+ volume: "volume";
588
588
  }>;
589
589
  select: z.ZodOptional<z.ZodString>;
590
590
  display: z.ZodOptional<z.ZodString>;
@@ -620,12 +620,12 @@ declare const pluginManifestSchema: z.ZodObject<{
620
620
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
621
621
  type: z.ZodLiteral<"kind">;
622
622
  resourceKind: z.ZodEnum<{
623
- volume: "volume";
624
- genie_space: "genie_space";
625
623
  warehouse: "warehouse";
624
+ genie_space: "genie_space";
626
625
  postgres_project: "postgres_project";
627
626
  postgres_branch: "postgres_branch";
628
627
  postgres_database: "postgres_database";
628
+ volume: "volume";
629
629
  }>;
630
630
  select: z.ZodOptional<z.ZodString>;
631
631
  display: z.ZodOptional<z.ZodString>;
@@ -660,12 +660,12 @@ declare const pluginManifestSchema: z.ZodObject<{
660
660
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
661
661
  type: z.ZodLiteral<"kind">;
662
662
  resourceKind: z.ZodEnum<{
663
- volume: "volume";
664
- genie_space: "genie_space";
665
663
  warehouse: "warehouse";
664
+ genie_space: "genie_space";
666
665
  postgres_project: "postgres_project";
667
666
  postgres_branch: "postgres_branch";
668
667
  postgres_database: "postgres_database";
668
+ volume: "volume";
669
669
  }>;
670
670
  select: z.ZodOptional<z.ZodString>;
671
671
  display: z.ZodOptional<z.ZodString>;
@@ -701,12 +701,12 @@ declare const pluginManifestSchema: z.ZodObject<{
701
701
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
702
702
  type: z.ZodLiteral<"kind">;
703
703
  resourceKind: z.ZodEnum<{
704
- volume: "volume";
705
- genie_space: "genie_space";
706
704
  warehouse: "warehouse";
705
+ genie_space: "genie_space";
707
706
  postgres_project: "postgres_project";
708
707
  postgres_branch: "postgres_branch";
709
708
  postgres_database: "postgres_database";
709
+ volume: "volume";
710
710
  }>;
711
711
  select: z.ZodOptional<z.ZodString>;
712
712
  display: z.ZodOptional<z.ZodString>;
@@ -741,12 +741,12 @@ declare const pluginManifestSchema: z.ZodObject<{
741
741
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
742
742
  type: z.ZodLiteral<"kind">;
743
743
  resourceKind: z.ZodEnum<{
744
- volume: "volume";
745
- genie_space: "genie_space";
746
744
  warehouse: "warehouse";
745
+ genie_space: "genie_space";
747
746
  postgres_project: "postgres_project";
748
747
  postgres_branch: "postgres_branch";
749
748
  postgres_database: "postgres_database";
749
+ volume: "volume";
750
750
  }>;
751
751
  select: z.ZodOptional<z.ZodString>;
752
752
  display: z.ZodOptional<z.ZodString>;
@@ -780,12 +780,12 @@ declare const pluginManifestSchema: z.ZodObject<{
780
780
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
781
781
  type: z.ZodLiteral<"kind">;
782
782
  resourceKind: z.ZodEnum<{
783
- volume: "volume";
784
- genie_space: "genie_space";
785
783
  warehouse: "warehouse";
784
+ genie_space: "genie_space";
786
785
  postgres_project: "postgres_project";
787
786
  postgres_branch: "postgres_branch";
788
787
  postgres_database: "postgres_database";
788
+ volume: "volume";
789
789
  }>;
790
790
  select: z.ZodOptional<z.ZodString>;
791
791
  display: z.ZodOptional<z.ZodString>;
@@ -819,12 +819,12 @@ declare const pluginManifestSchema: z.ZodObject<{
819
819
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
820
820
  type: z.ZodLiteral<"kind">;
821
821
  resourceKind: z.ZodEnum<{
822
- volume: "volume";
823
- genie_space: "genie_space";
824
822
  warehouse: "warehouse";
823
+ genie_space: "genie_space";
825
824
  postgres_project: "postgres_project";
826
825
  postgres_branch: "postgres_branch";
827
826
  postgres_database: "postgres_database";
827
+ volume: "volume";
828
828
  }>;
829
829
  select: z.ZodOptional<z.ZodString>;
830
830
  display: z.ZodOptional<z.ZodString>;
@@ -858,12 +858,12 @@ declare const pluginManifestSchema: z.ZodObject<{
858
858
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
859
859
  type: z.ZodLiteral<"kind">;
860
860
  resourceKind: z.ZodEnum<{
861
- volume: "volume";
862
- genie_space: "genie_space";
863
861
  warehouse: "warehouse";
862
+ genie_space: "genie_space";
864
863
  postgres_project: "postgres_project";
865
864
  postgres_branch: "postgres_branch";
866
865
  postgres_database: "postgres_database";
866
+ volume: "volume";
867
867
  }>;
868
868
  select: z.ZodOptional<z.ZodString>;
869
869
  display: z.ZodOptional<z.ZodString>;
@@ -897,12 +897,12 @@ declare const pluginManifestSchema: z.ZodObject<{
897
897
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
898
898
  type: z.ZodLiteral<"kind">;
899
899
  resourceKind: z.ZodEnum<{
900
- volume: "volume";
901
- genie_space: "genie_space";
902
900
  warehouse: "warehouse";
901
+ genie_space: "genie_space";
903
902
  postgres_project: "postgres_project";
904
903
  postgres_branch: "postgres_branch";
905
904
  postgres_database: "postgres_database";
905
+ volume: "volume";
906
906
  }>;
907
907
  select: z.ZodOptional<z.ZodString>;
908
908
  display: z.ZodOptional<z.ZodString>;
@@ -936,12 +936,12 @@ declare const pluginManifestSchema: z.ZodObject<{
936
936
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
937
937
  type: z.ZodLiteral<"kind">;
938
938
  resourceKind: z.ZodEnum<{
939
- volume: "volume";
940
- genie_space: "genie_space";
941
939
  warehouse: "warehouse";
940
+ genie_space: "genie_space";
942
941
  postgres_project: "postgres_project";
943
942
  postgres_branch: "postgres_branch";
944
943
  postgres_database: "postgres_database";
944
+ volume: "volume";
945
945
  }>;
946
946
  select: z.ZodOptional<z.ZodString>;
947
947
  display: z.ZodOptional<z.ZodString>;
@@ -978,12 +978,12 @@ declare const pluginManifestSchema: z.ZodObject<{
978
978
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
979
979
  type: z.ZodLiteral<"kind">;
980
980
  resourceKind: z.ZodEnum<{
981
- volume: "volume";
982
- genie_space: "genie_space";
983
981
  warehouse: "warehouse";
982
+ genie_space: "genie_space";
984
983
  postgres_project: "postgres_project";
985
984
  postgres_branch: "postgres_branch";
986
985
  postgres_database: "postgres_database";
986
+ volume: "volume";
987
987
  }>;
988
988
  select: z.ZodOptional<z.ZodString>;
989
989
  display: z.ZodOptional<z.ZodString>;
@@ -1019,12 +1019,12 @@ declare const pluginManifestSchema: z.ZodObject<{
1019
1019
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1020
1020
  type: z.ZodLiteral<"kind">;
1021
1021
  resourceKind: z.ZodEnum<{
1022
- volume: "volume";
1023
- genie_space: "genie_space";
1024
1022
  warehouse: "warehouse";
1023
+ genie_space: "genie_space";
1025
1024
  postgres_project: "postgres_project";
1026
1025
  postgres_branch: "postgres_branch";
1027
1026
  postgres_database: "postgres_database";
1027
+ volume: "volume";
1028
1028
  }>;
1029
1029
  select: z.ZodOptional<z.ZodString>;
1030
1030
  display: z.ZodOptional<z.ZodString>;
@@ -1058,12 +1058,12 @@ declare const pluginManifestSchema: z.ZodObject<{
1058
1058
  discovery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1059
1059
  type: z.ZodLiteral<"kind">;
1060
1060
  resourceKind: z.ZodEnum<{
1061
- volume: "volume";
1062
- genie_space: "genie_space";
1063
1061
  warehouse: "warehouse";
1062
+ genie_space: "genie_space";
1064
1063
  postgres_project: "postgres_project";
1065
1064
  postgres_branch: "postgres_branch";
1066
1065
  postgres_database: "postgres_database";
1066
+ volume: "volume";
1067
1067
  }>;
1068
1068
  select: z.ZodOptional<z.ZodString>;
1069
1069
  display: z.ZodOptional<z.ZodString>;
@@ -3,7 +3,7 @@ import { walkSchema } from "./walk-schema.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import fs from "node:fs/promises";
5
5
  import path from "node:path";
6
- import fsSync from "node:fs";
6
+ import fs$1 from "node:fs";
7
7
 
8
8
  //#region src/type-generator/database/generate.ts
9
9
  /** Safe diagnostic raised when database declarations cannot be generated. */
@@ -63,7 +63,7 @@ ${walkSchema(schema).map((entry) => ` ${JSON.stringify(entry.name)}: {
63
63
  }
64
64
  /** Atomically replace generated output only when its content changes. */
65
65
  async function writeIfChanged(outFile, content) {
66
- if (fsSync.existsSync(outFile) && await fs.readFile(outFile, "utf8") === content) return;
66
+ if (fs$1.existsSync(outFile) && await fs.readFile(outFile, "utf8") === content) return;
67
67
  await fs.mkdir(path.dirname(outFile), { recursive: true });
68
68
  const temporary = path.join(path.dirname(outFile), `.${path.basename(outFile)}.${randomUUID()}.tmp`);
69
69
  try {
@@ -80,7 +80,7 @@ async function importSchema(schemaFile) {
80
80
  }
81
81
  /** Generate current registry types or neutralize them when loading fails. */
82
82
  async function generateDatabaseTypes(options) {
83
- if (!fsSync.existsSync(options.schemaFile)) {
83
+ if (!fs$1.existsSync(options.schemaFile)) {
84
84
  await writeIfChanged(options.outFile, NEUTRAL_DATABASE_TYPES);
85
85
  return;
86
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","names":[],"sources":["../../../src/type-generator/database/generate.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fsSync from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Schema } from \"../../database/schema-builder\";\nimport { assertFinalizedSchema } from \"../../database/schema-builder/define-schema\";\nimport { walkSchema } from \"./walk-schema\";\n\n/** Safe diagnostic raised when database declarations cannot be generated. */\nexport class DatabaseTypegenError extends Error {\n constructor(message = \"Database schema generation failed\") {\n super(message);\n this.name = \"DatabaseTypegenError\";\n }\n}\n\ninterface GenerateDatabaseTypesOptions {\n readonly schemaFile: string;\n readonly outFile: string;\n}\n\nexport const DATABASE_TYPES_FILE = \"database.d.ts\";\n\nfunction schemaLabel(schemaFile: string): string {\n return path.relative(process.cwd(), schemaFile) || schemaFile;\n}\n\nfunction importFailureReason(error: unknown): string {\n if (error instanceof SyntaxError) return \"could not be parsed\";\n let code: unknown;\n try {\n code =\n error && typeof error === \"object\"\n ? Reflect.get(error, \"code\")\n : undefined;\n } catch {\n code = undefined;\n }\n if (code === \"MODULE_NOT_FOUND\" || code === \"ERR_MODULE_NOT_FOUND\") {\n return \"contains an unresolved import\";\n }\n return \"threw while loading\";\n}\n\n/** Empty augmentation used when no valid database schema is available. */\nexport const NEUTRAL_DATABASE_TYPES = `// Auto-generated by AppKit - DO NOT EDIT\nimport \"@databricks/appkit\";\n\ndeclare module \"@databricks/appkit\" {\n interface DatabaseRegistry {}\n}\n`;\n\n/** Render one `DatabaseRegistry` augmentation from a finalized schema. */\nfunction render(schema: Schema): string {\n const entries = walkSchema(schema)\n .map(\n (entry) => ` ${JSON.stringify(entry.name)}: {\n row: ${entry.row};\n publicRow: ${entry.publicRow};\n insert: ${entry.insert};\n update: ${entry.update};\n filters: ${entry.filters};\n includes: ${entry.includes};\n hasPrimaryKey: ${entry.hasPrimaryKey};\n };`,\n )\n .join(\"\\n\");\n return `// Auto-generated by AppKit - DO NOT EDIT\nimport \"@databricks/appkit\";\n\ndeclare module \"@databricks/appkit\" {\n type DatabaseLogicalFilter<T> = T & {\n and?: readonly DatabaseLogicalFilter<T>[];\n or?: readonly DatabaseLogicalFilter<T>[];\n };\n\n interface DatabaseRegistry {\n${entries}\n }\n}\n`;\n}\n\n/** Atomically replace generated output only when its content changes. */\nasync function writeIfChanged(outFile: string, content: string): Promise<void> {\n if (\n fsSync.existsSync(outFile) &&\n (await fs.readFile(outFile, \"utf8\")) === content\n )\n return;\n await fs.mkdir(path.dirname(outFile), { recursive: true });\n const temporary = path.join(\n path.dirname(outFile),\n `.${path.basename(outFile)}.${randomUUID()}.tmp`,\n );\n try {\n await fs.writeFile(temporary, content, \"utf8\");\n await fs.rename(temporary, outFile);\n } finally {\n await fs.rm(temporary, { force: true });\n }\n}\n\n/** Disable Jiti's module cache so watch-mode runs observe schema edits. */\nasync function importSchema(schemaFile: string): Promise<unknown> {\n const { createJiti } = await import(\"jiti\");\n return createJiti(import.meta.url, { moduleCache: false }).import(schemaFile);\n}\n\n/** Generate current registry types or neutralize them when loading fails. */\nexport async function generateDatabaseTypes(\n options: GenerateDatabaseTypesOptions,\n): Promise<void> {\n if (!fsSync.existsSync(options.schemaFile)) {\n await writeIfChanged(options.outFile, NEUTRAL_DATABASE_TYPES);\n return;\n }\n try {\n const module = (await importSchema(options.schemaFile)) as {\n schema?: Schema;\n };\n if (!(\"schema\" in module)) {\n throw new DatabaseTypegenError(\n `Database schema module \"${schemaLabel(options.schemaFile)}\" must export a named \"schema\"`,\n );\n }\n try {\n assertFinalizedSchema(module.schema);\n } catch {\n throw new DatabaseTypegenError(\n `Database schema \"${schemaLabel(options.schemaFile)}\" is not a finalized AppKit schema`,\n );\n }\n await writeIfChanged(options.outFile, render(module.schema));\n } catch (error) {\n // A failed run must not leave stale entities visible to TypeScript.\n await writeIfChanged(options.outFile, NEUTRAL_DATABASE_TYPES);\n throw error instanceof DatabaseTypegenError\n ? error\n : new DatabaseTypegenError(\n `Database schema \"${schemaLabel(options.schemaFile)}\" ${importFailureReason(error)}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;AAUA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,YAAY,UAAU,qCAAqC;AACzD,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAShB,MAAa,sBAAsB;AAEnC,SAAS,YAAY,YAA4B;AAC/C,QAAO,KAAK,SAAS,QAAQ,KAAK,EAAE,WAAW,IAAI;;AAGrD,SAAS,oBAAoB,OAAwB;AACnD,KAAI,iBAAiB,YAAa,QAAO;CACzC,IAAI;AACJ,KAAI;AACF,SACE,SAAS,OAAO,UAAU,WACtB,QAAQ,IAAI,OAAO,OAAO,GAC1B;SACA;AACN,SAAO;;AAET,KAAI,SAAS,sBAAsB,SAAS,uBAC1C,QAAO;AAET,QAAO;;;AAIT,MAAa,yBAAyB;;;;;;;;AAStC,SAAS,OAAO,QAAwB;AActC,QAAO;;;;;;;;;;EAbS,WAAW,OAAO,CAC/B,KACE,UAAU,OAAO,KAAK,UAAU,MAAM,KAAK,CAAC;aACtC,MAAM,IAAI;mBACJ,MAAM,UAAU;gBACnB,MAAM,OAAO;gBACb,MAAM,OAAO;iBACZ,MAAM,QAAQ;kBACb,MAAM,SAAS;uBACV,MAAM,cAAc;QAEtC,CACA,KAAK,KAAK,CAWL;;;;;;AAOV,eAAe,eAAe,SAAiB,SAAgC;AAC7E,KACE,OAAO,WAAW,QAAQ,IACzB,MAAM,GAAG,SAAS,SAAS,OAAO,KAAM,QAEzC;AACF,OAAM,GAAG,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;CAC1D,MAAM,YAAY,KAAK,KACrB,KAAK,QAAQ,QAAQ,EACrB,IAAI,KAAK,SAAS,QAAQ,CAAC,GAAG,YAAY,CAAC,MAC5C;AACD,KAAI;AACF,QAAM,GAAG,UAAU,WAAW,SAAS,OAAO;AAC9C,QAAM,GAAG,OAAO,WAAW,QAAQ;WAC3B;AACR,QAAM,GAAG,GAAG,WAAW,EAAE,OAAO,MAAM,CAAC;;;;AAK3C,eAAe,aAAa,YAAsC;CAChE,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,QAAO,WAAW,OAAO,KAAK,KAAK,EAAE,aAAa,OAAO,CAAC,CAAC,OAAO,WAAW;;;AAI/E,eAAsB,sBACpB,SACe;AACf,KAAI,CAAC,OAAO,WAAW,QAAQ,WAAW,EAAE;AAC1C,QAAM,eAAe,QAAQ,SAAS,uBAAuB;AAC7D;;AAEF,KAAI;EACF,MAAM,SAAU,MAAM,aAAa,QAAQ,WAAW;AAGtD,MAAI,EAAE,YAAY,QAChB,OAAM,IAAI,qBACR,2BAA2B,YAAY,QAAQ,WAAW,CAAC,gCAC5D;AAEH,MAAI;AACF,yBAAsB,OAAO,OAAO;UAC9B;AACN,SAAM,IAAI,qBACR,oBAAoB,YAAY,QAAQ,WAAW,CAAC,oCACrD;;AAEH,QAAM,eAAe,QAAQ,SAAS,OAAO,OAAO,OAAO,CAAC;UACrD,OAAO;AAEd,QAAM,eAAe,QAAQ,SAAS,uBAAuB;AAC7D,QAAM,iBAAiB,uBACnB,QACA,IAAI,qBACF,oBAAoB,YAAY,QAAQ,WAAW,CAAC,IAAI,oBAAoB,MAAM,GACnF"}
1
+ {"version":3,"file":"generate.js","names":["fsSync"],"sources":["../../../src/type-generator/database/generate.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fsSync from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Schema } from \"../../database/schema-builder\";\nimport { assertFinalizedSchema } from \"../../database/schema-builder/define-schema\";\nimport { walkSchema } from \"./walk-schema\";\n\n/** Safe diagnostic raised when database declarations cannot be generated. */\nexport class DatabaseTypegenError extends Error {\n constructor(message = \"Database schema generation failed\") {\n super(message);\n this.name = \"DatabaseTypegenError\";\n }\n}\n\ninterface GenerateDatabaseTypesOptions {\n readonly schemaFile: string;\n readonly outFile: string;\n}\n\nexport const DATABASE_TYPES_FILE = \"database.d.ts\";\n\nfunction schemaLabel(schemaFile: string): string {\n return path.relative(process.cwd(), schemaFile) || schemaFile;\n}\n\nfunction importFailureReason(error: unknown): string {\n if (error instanceof SyntaxError) return \"could not be parsed\";\n let code: unknown;\n try {\n code =\n error && typeof error === \"object\"\n ? Reflect.get(error, \"code\")\n : undefined;\n } catch {\n code = undefined;\n }\n if (code === \"MODULE_NOT_FOUND\" || code === \"ERR_MODULE_NOT_FOUND\") {\n return \"contains an unresolved import\";\n }\n return \"threw while loading\";\n}\n\n/** Empty augmentation used when no valid database schema is available. */\nexport const NEUTRAL_DATABASE_TYPES = `// Auto-generated by AppKit - DO NOT EDIT\nimport \"@databricks/appkit\";\n\ndeclare module \"@databricks/appkit\" {\n interface DatabaseRegistry {}\n}\n`;\n\n/** Render one `DatabaseRegistry` augmentation from a finalized schema. */\nfunction render(schema: Schema): string {\n const entries = walkSchema(schema)\n .map(\n (entry) => ` ${JSON.stringify(entry.name)}: {\n row: ${entry.row};\n publicRow: ${entry.publicRow};\n insert: ${entry.insert};\n update: ${entry.update};\n filters: ${entry.filters};\n includes: ${entry.includes};\n hasPrimaryKey: ${entry.hasPrimaryKey};\n };`,\n )\n .join(\"\\n\");\n return `// Auto-generated by AppKit - DO NOT EDIT\nimport \"@databricks/appkit\";\n\ndeclare module \"@databricks/appkit\" {\n type DatabaseLogicalFilter<T> = T & {\n and?: readonly DatabaseLogicalFilter<T>[];\n or?: readonly DatabaseLogicalFilter<T>[];\n };\n\n interface DatabaseRegistry {\n${entries}\n }\n}\n`;\n}\n\n/** Atomically replace generated output only when its content changes. */\nasync function writeIfChanged(outFile: string, content: string): Promise<void> {\n if (\n fsSync.existsSync(outFile) &&\n (await fs.readFile(outFile, \"utf8\")) === content\n )\n return;\n await fs.mkdir(path.dirname(outFile), { recursive: true });\n const temporary = path.join(\n path.dirname(outFile),\n `.${path.basename(outFile)}.${randomUUID()}.tmp`,\n );\n try {\n await fs.writeFile(temporary, content, \"utf8\");\n await fs.rename(temporary, outFile);\n } finally {\n await fs.rm(temporary, { force: true });\n }\n}\n\n/** Disable Jiti's module cache so watch-mode runs observe schema edits. */\nasync function importSchema(schemaFile: string): Promise<unknown> {\n const { createJiti } = await import(\"jiti\");\n return createJiti(import.meta.url, { moduleCache: false }).import(schemaFile);\n}\n\n/** Generate current registry types or neutralize them when loading fails. */\nexport async function generateDatabaseTypes(\n options: GenerateDatabaseTypesOptions,\n): Promise<void> {\n if (!fsSync.existsSync(options.schemaFile)) {\n await writeIfChanged(options.outFile, NEUTRAL_DATABASE_TYPES);\n return;\n }\n try {\n const module = (await importSchema(options.schemaFile)) as {\n schema?: Schema;\n };\n if (!(\"schema\" in module)) {\n throw new DatabaseTypegenError(\n `Database schema module \"${schemaLabel(options.schemaFile)}\" must export a named \"schema\"`,\n );\n }\n try {\n assertFinalizedSchema(module.schema);\n } catch {\n throw new DatabaseTypegenError(\n `Database schema \"${schemaLabel(options.schemaFile)}\" is not a finalized AppKit schema`,\n );\n }\n await writeIfChanged(options.outFile, render(module.schema));\n } catch (error) {\n // A failed run must not leave stale entities visible to TypeScript.\n await writeIfChanged(options.outFile, NEUTRAL_DATABASE_TYPES);\n throw error instanceof DatabaseTypegenError\n ? error\n : new DatabaseTypegenError(\n `Database schema \"${schemaLabel(options.schemaFile)}\" ${importFailureReason(error)}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;AAUA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,YAAY,UAAU,qCAAqC;AACzD,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAShB,MAAa,sBAAsB;AAEnC,SAAS,YAAY,YAA4B;AAC/C,QAAO,KAAK,SAAS,QAAQ,KAAK,EAAE,WAAW,IAAI;;AAGrD,SAAS,oBAAoB,OAAwB;AACnD,KAAI,iBAAiB,YAAa,QAAO;CACzC,IAAI;AACJ,KAAI;AACF,SACE,SAAS,OAAO,UAAU,WACtB,QAAQ,IAAI,OAAO,OAAO,GAC1B;SACA;AACN,SAAO;;AAET,KAAI,SAAS,sBAAsB,SAAS,uBAC1C,QAAO;AAET,QAAO;;;AAIT,MAAa,yBAAyB;;;;;;;;AAStC,SAAS,OAAO,QAAwB;AActC,QAAO;;;;;;;;;;EAbS,WAAW,OAAO,CAC/B,KACE,UAAU,OAAO,KAAK,UAAU,MAAM,KAAK,CAAC;aACtC,MAAM,IAAI;mBACJ,MAAM,UAAU;gBACnB,MAAM,OAAO;gBACb,MAAM,OAAO;iBACZ,MAAM,QAAQ;kBACb,MAAM,SAAS;uBACV,MAAM,cAAc;QAEtC,CACA,KAAK,KAAK,CAWL;;;;;;AAOV,eAAe,eAAe,SAAiB,SAAgC;AAC7E,KACEA,KAAO,WAAW,QAAQ,IACzB,MAAM,GAAG,SAAS,SAAS,OAAO,KAAM,QAEzC;AACF,OAAM,GAAG,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;CAC1D,MAAM,YAAY,KAAK,KACrB,KAAK,QAAQ,QAAQ,EACrB,IAAI,KAAK,SAAS,QAAQ,CAAC,GAAG,YAAY,CAAC,MAC5C;AACD,KAAI;AACF,QAAM,GAAG,UAAU,WAAW,SAAS,OAAO;AAC9C,QAAM,GAAG,OAAO,WAAW,QAAQ;WAC3B;AACR,QAAM,GAAG,GAAG,WAAW,EAAE,OAAO,MAAM,CAAC;;;;AAK3C,eAAe,aAAa,YAAsC;CAChE,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,QAAO,WAAW,OAAO,KAAK,KAAK,EAAE,aAAa,OAAO,CAAC,CAAC,OAAO,WAAW;;;AAI/E,eAAsB,sBACpB,SACe;AACf,KAAI,CAACA,KAAO,WAAW,QAAQ,WAAW,EAAE;AAC1C,QAAM,eAAe,QAAQ,SAAS,uBAAuB;AAC7D;;AAEF,KAAI;EACF,MAAM,SAAU,MAAM,aAAa,QAAQ,WAAW;AAGtD,MAAI,EAAE,YAAY,QAChB,OAAM,IAAI,qBACR,2BAA2B,YAAY,QAAQ,WAAW,CAAC,gCAC5D;AAEH,MAAI;AACF,yBAAsB,OAAO,OAAO;UAC9B;AACN,SAAM,IAAI,qBACR,oBAAoB,YAAY,QAAQ,WAAW,CAAC,oCACrD;;AAEH,QAAM,eAAe,QAAQ,SAAS,OAAO,OAAO,OAAO,CAAC;UACrD,OAAO;AAEd,QAAM,eAAe,QAAQ,SAAS,uBAAuB;AAC7D,QAAM,iBAAiB,uBACnB,QACA,IAAI,qBACF,oBAAoB,YAAY,QAAQ,WAAW,CAAC,IAAI,oBAAoB,MAAM,GACnF"}
@@ -2,7 +2,7 @@ import { createLogger } from "../logging/logger.js";
2
2
  import pc from "picocolors";
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
- import fsSync from "node:fs";
5
+ import fs$1 from "node:fs";
6
6
 
7
7
  //#region src/type-generator/migration.ts
8
8
  const logger = createLogger("type-generator:migration");
@@ -16,7 +16,7 @@ const logger = createLogger("type-generator:migration");
16
16
  */
17
17
  function resolveProjectRoot(outFile) {
18
18
  const root = path.resolve(path.dirname(outFile), "..", "..");
19
- if (!fsSync.existsSync(path.join(root, "package.json"))) logger.warn("Resolved project root %s has no package.json — migration may target the wrong directory. Check your outFile path: %s", root, outFile);
19
+ if (!fs$1.existsSync(path.join(root, "package.json"))) logger.warn("Resolved project root %s has no package.json — migration may target the wrong directory. Check your outFile path: %s", root, outFile);
20
20
  return root;
21
21
  }
22
22
  /**