From 85a77f89c71b6f2133983e5d9ce6714dfd4a9610 Mon Sep 17 00:00:00 2001 From: MarioCadenas Date: Wed, 24 Dec 2025 10:12:57 +0100 Subject: [PATCH] fix(appkit): query cache generation --- .gitignore | 3 -- .../config/queries/.appkit-types-cache.json | 41 ------------------- docs/package.json | 2 +- packages/appkit/src/type-generator/cache.ts | 20 ++++++--- .../src/type-generator/query-registry.ts | 6 +-- .../appkit/src/type-generator/vite-plugin.ts | 24 +++++++++-- 6 files changed, 38 insertions(+), 58 deletions(-) delete mode 100644 apps/dev-playground/config/queries/.appkit-types-cache.json diff --git a/.gitignore b/.gitignore index 782031b..3b6cc96 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,3 @@ coverage *.tsbuildinfo .turbo - -# AppKit type generation cache -.appkit-types-cache.json diff --git a/apps/dev-playground/config/queries/.appkit-types-cache.json b/apps/dev-playground/config/queries/.appkit-types-cache.json deleted file mode 100644 index aaba841..0000000 --- a/apps/dev-playground/config/queries/.appkit-types-cache.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "1", - "queries": { - "app_activity_heatmap": { - "hash": "744281be86b14c2b14ed76b94060e4af", - "type": "{\n name: \"app_activity_heatmap\";\n parameters: {\n /** DATE - use sql.date() */\n startDate: SQLDateMarker;\n /** DATE - use sql.date() */\n endDate: SQLDateMarker;\n };\n result: Array<{\n /** @sqlType STRING */\n app_name: string;\n /** @sqlType STRING */\n day_of_week: string;\n /** @sqlType DECIMAL(35,2) */\n spend: number;\n }>;\n }" - }, - "apps_list": { - "hash": "4b7393b43f8e7beaa52174ed4d918c04", - "type": "{\n name: \"apps_list\";\n parameters: Record;\n result: Array<{\n /** @sqlType STRING */\n id: string;\n /** @sqlType STRING */\n name: string;\n /** @sqlType STRING */\n creator: string;\n /** @sqlType STRING */\n tags: string;\n /** @sqlType DECIMAL(38,6) */\n totalSpend: number;\n /** @sqlType DATE */\n createdAt: string;\n }>;\n }" - }, - "cost_recommendations": { - "hash": "730c7d8b5e2726981088b5975157b0da", - "type": "{\n name: \"cost_recommendations\";\n parameters: Record;\n result: Array<{\n /** @sqlType INT */\n dummy: number;\n }>;\n }" - }, - "example": { - "hash": "aeb02ed3e8a6c77279099406f8709543", - "type": "{\n name: \"example\";\n parameters: Record;\n result: Array<{\n /** @sqlType BOOLEAN */\n \"(1 = 1)\": boolean;\n }>;\n }" - }, - "spend_data": { - "hash": "caa0430652fe15eff658e48e6dac2446", - "type": "{\n name: \"spend_data\";\n parameters: {\n /** STRING - use sql.string() */\n groupBy: SQLStringMarker;\n /** STRING - use sql.string() */\n aggregationLevel: SQLStringMarker;\n /** DATE - use sql.date() */\n startDate: SQLDateMarker;\n /** DATE - use sql.date() */\n endDate: SQLDateMarker;\n /** STRING - use sql.string() */\n appId: SQLStringMarker;\n /** STRING - use sql.string() */\n creator: SQLStringMarker;\n };\n result: Array<{\n /** @sqlType STRING */\n group_key: string;\n /** @sqlType TIMESTAMP */\n aggregation_period: string;\n /** @sqlType DECIMAL(38,6) */\n cost_usd: number;\n }>;\n }" - }, - "spend_summary": { - "hash": "bbe188624c3f5904c3a7593cb32982d5", - "type": "{\n name: \"spend_summary\";\n parameters: {\n /** STRING - use sql.string() */\n aggregationLevel: SQLStringMarker;\n /** DATE - use sql.date() */\n endDate: SQLDateMarker;\n /** DATE - use sql.date() */\n startDate: SQLDateMarker;\n };\n result: Array<{\n /** @sqlType DECIMAL(33,0) */\n total: number;\n /** @sqlType DECIMAL(33,0) */\n average: number;\n /** @sqlType DECIMAL(33,0) */\n forecasted: number;\n }>;\n }" - }, - "sql_helpers_test": { - "hash": "1322df4ba9c107e8d23e2a04bae860c5", - "type": "{\n name: \"sql_helpers_test\";\n parameters: {\n /** STRING - use sql.string() */\n stringParam: SQLStringMarker;\n /** NUMERIC - use sql.number() */\n numberParam: SQLNumberMarker;\n /** BOOLEAN - use sql.boolean() */\n booleanParam: SQLBooleanMarker;\n /** DATE - use sql.date() */\n dateParam: SQLDateMarker;\n /** TIMESTAMP - use sql.timestamp() */\n timestampParam: SQLTimestampMarker;\n /** STRING - use sql.string() */\n binaryParam: SQLStringMarker;\n };\n result: Array<{\n /** @sqlType STRING */\n string_value: string;\n /** @sqlType STRING */\n number_value: string;\n /** @sqlType STRING */\n boolean_value: string;\n /** @sqlType STRING */\n date_value: string;\n /** @sqlType STRING */\n timestamp_value: string;\n /** @sqlType BINARY */\n binary_value: string;\n /** @sqlType STRING */\n binary_hex: string;\n /** @sqlType INT */\n binary_length: number;\n }>;\n }" - }, - "top_contributors": { - "hash": "2d58759cca2fe31dae06475a23080120", - "type": "{\n name: \"top_contributors\";\n parameters: {\n /** STRING - use sql.string() */\n aggregationLevel: SQLStringMarker;\n /** DATE - use sql.date() */\n startDate: SQLDateMarker;\n /** DATE - use sql.date() */\n endDate: SQLDateMarker;\n };\n result: Array<{\n /** @sqlType STRING */\n app_name: string;\n /** @sqlType DECIMAL(38,6) */\n total_cost_usd: number;\n }>;\n }" - }, - "untagged_apps": { - "hash": "5946262b49710b8ab458d1bf950ff8c9", - "type": "{\n name: \"untagged_apps\";\n parameters: {\n /** STRING - use sql.string() */\n aggregationLevel: SQLStringMarker;\n /** DATE - use sql.date() */\n startDate: SQLDateMarker;\n /** DATE - use sql.date() */\n endDate: SQLDateMarker;\n };\n result: Array<{\n /** @sqlType STRING */\n app_name: string;\n /** @sqlType STRING */\n creator: string;\n /** @sqlType DECIMAL(38,6) */\n total_cost_usd: number;\n /** @sqlType DECIMAL(38,10) */\n avg_period_cost_usd: number;\n }>;\n }" - } - } -} diff --git a/docs/package.json b/docs/package.json index 24f8652..017893d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "dev": "docusaurus start", + "dev": "docusaurus start --no-open", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", diff --git a/packages/appkit/src/type-generator/cache.ts b/packages/appkit/src/type-generator/cache.ts index 78cc26c..d838000 100644 --- a/packages/appkit/src/type-generator/cache.ts +++ b/packages/appkit/src/type-generator/cache.ts @@ -24,6 +24,12 @@ interface Cache { export const CACHE_VERSION = "1"; const CACHE_FILE = ".appkit-types-cache.json"; +const CACHE_DIR = path.join( + process.cwd(), + "node_modules", + ".databricks", + "appkit", +); /** * Hash the SQL query @@ -38,12 +44,15 @@ export function hashSQL(sql: string): string { /** * Load the cache from the file system * If the cache is not found, run the query explain - * @param cacheDir - the directory to load the cache from * @returns - the cache */ -export function loadCache(cacheDir: string): Cache { - const cachePath = path.join(cacheDir, CACHE_FILE); +export function loadCache(): Cache { + const cachePath = path.join(CACHE_DIR, CACHE_FILE); try { + if (!fs.existsSync(CACHE_DIR)) { + fs.mkdirSync(CACHE_DIR, { recursive: true }); + } + if (fs.existsSync(cachePath)) { const cache = JSON.parse(fs.readFileSync(cachePath, "utf8")) as Cache; if (cache.version === CACHE_VERSION) { @@ -59,10 +68,9 @@ export function loadCache(cacheDir: string): Cache { /** * Save the cache to the file system * The cache is saved as a JSON file, it is used to avoid running the query explain multiple times - * @param cacheDir - the directory to save the cache to * @param cache - cache object to save */ -export function saveCache(cacheDir: string, cache: Cache): void { - const cachePath = path.join(cacheDir, CACHE_FILE); +export function saveCache(cache: Cache): void { + const cachePath = path.join(CACHE_DIR, CACHE_FILE); fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2), "utf8"); } diff --git a/packages/appkit/src/type-generator/query-registry.ts b/packages/appkit/src/type-generator/query-registry.ts index caeaa24..4842b81 100644 --- a/packages/appkit/src/type-generator/query-registry.ts +++ b/packages/appkit/src/type-generator/query-registry.ts @@ -124,9 +124,7 @@ export async function generateQueriesFromDescribe( console.log(` Found ${queryFiles.length} SQL queries\n`); // load cache - const cache = noCache - ? { version: CACHE_VERSION, queries: {} } - : loadCache(queryFolder); + const cache = noCache ? { version: CACHE_VERSION, queries: {} } : loadCache(); const client = new WorkspaceClient({}); const querySchemas: QuerySchema[] = []; @@ -191,7 +189,7 @@ export async function generateQueriesFromDescribe( } // save cache - saveCache(queryFolder, cache); + saveCache(cache); // log warning if there are failed queries if (failedQueries.length > 0) { diff --git a/packages/appkit/src/type-generator/vite-plugin.ts b/packages/appkit/src/type-generator/vite-plugin.ts index a5b2875..67480d7 100644 --- a/packages/appkit/src/type-generator/vite-plugin.ts +++ b/packages/appkit/src/type-generator/vite-plugin.ts @@ -1,5 +1,6 @@ import path from "node:path"; import type { Plugin } from "vite"; +import fs from "node:fs"; import { generateFromEntryPoint } from "./index"; /** @@ -52,12 +53,29 @@ export function appKitTypesPlugin(options?: AppKitTypesPluginOptions): Plugin { return { name: "appkit-types", + apply() { + const warehouseId = process.env.DATABRICKS_WAREHOUSE_ID || ""; + + if (!warehouseId) { + console.warn( + "[AppKit] Warehouse ID not found. Skipping type generation.", + ); + return false; + } + + if (!fs.existsSync(path.join(process.cwd(), "config", "queries"))) { + return false; + } + + return true; + }, + configResolved(config) { root = config.root; outFile = path.resolve(root, options?.outFile ?? "src/appKitTypes.d.ts"); - watchFolders = (options?.watchFolders ?? ["../config/queries"]).map( - (folder) => path.resolve(root, folder), - ); + watchFolders = options?.watchFolders ?? [ + path.join(process.cwd(), "config", "queries"), + ]; }, buildStart() {