@databricks/appkit 0.15.0 → 0.17.0
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/_virtual/_rolldown/runtime.js +2 -0
- package/dist/app/index.d.ts.map +1 -1
- package/dist/appkit/package.js +1 -1
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cli/commands/plugin/add-resource/add-resource.js +10 -4
- package/dist/cli/commands/plugin/add-resource/add-resource.js.map +1 -1
- package/dist/cli/commands/plugin/create/scaffold.js +10 -16
- package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
- package/dist/cli/commands/plugin/list/list.js +44 -26
- package/dist/cli/commands/plugin/list/list.js.map +1 -1
- package/dist/cli/commands/plugin/manifest-resolve.js +57 -0
- package/dist/cli/commands/plugin/manifest-resolve.js.map +1 -0
- package/dist/cli/commands/plugin/sync/sync.js +121 -71
- package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
- package/dist/cli/commands/plugin/trusted-js-manifest.js +28 -0
- package/dist/cli/commands/plugin/trusted-js-manifest.js.map +1 -0
- package/dist/cli/commands/plugin/validate/validate.js +32 -14
- package/dist/cli/commands/plugin/validate/validate.js.map +1 -1
- package/dist/connectors/genie/client.d.ts +4 -0
- package/dist/connectors/genie/client.js +33 -16
- package/dist/connectors/genie/client.js.map +1 -1
- package/dist/connectors/genie/defaults.js +2 -1
- package/dist/connectors/genie/defaults.js.map +1 -1
- package/dist/connectors/genie/index.d.ts +3 -0
- package/dist/connectors/genie/types.d.ts +1 -0
- package/dist/connectors/genie/types.d.ts.map +1 -1
- package/dist/connectors/lakebase/index.d.ts +2 -3
- package/dist/connectors/lakebase/index.d.ts.map +1 -1
- package/dist/connectors/lakebase/index.js.map +1 -1
- package/dist/connectors/lakebase-v1/client.js +1 -1
- package/dist/context/execution-context.d.ts +0 -1
- package/dist/context/execution-context.d.ts.map +1 -1
- package/dist/context/index.d.ts +3 -0
- package/dist/context/service-context.d.ts +1 -1
- package/dist/context/service-context.d.ts.map +1 -1
- package/dist/context/user-context.d.ts +1 -2
- package/dist/context/user-context.d.ts.map +1 -1
- package/dist/core/appkit.d.ts +2 -1
- package/dist/core/appkit.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/errors/authentication.d.ts +0 -1
- package/dist/errors/authentication.d.ts.map +1 -1
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/configuration.d.ts +0 -1
- package/dist/errors/configuration.d.ts.map +1 -1
- package/dist/errors/connection.d.ts +0 -1
- package/dist/errors/connection.d.ts.map +1 -1
- package/dist/errors/execution.d.ts +0 -1
- package/dist/errors/execution.d.ts.map +1 -1
- package/dist/errors/initialization.d.ts +0 -1
- package/dist/errors/initialization.d.ts.map +1 -1
- package/dist/errors/server.d.ts +0 -1
- package/dist/errors/server.d.ts.map +1 -1
- package/dist/errors/tunnel.d.ts +0 -1
- package/dist/errors/tunnel.d.ts.map +1 -1
- package/dist/errors/validation.d.ts +0 -1
- package/dist/errors/validation.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/plugin/dev-reader.d.ts +5 -4
- package/dist/plugin/dev-reader.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +4 -0
- package/dist/plugin/plugin.d.ts +3 -1
- package/dist/plugin/plugin.d.ts.map +1 -1
- package/dist/plugin/to-plugin.d.ts +1 -1
- package/dist/plugin/to-plugin.d.ts.map +1 -1
- package/dist/plugins/analytics/analytics.d.ts +5 -2
- package/dist/plugins/analytics/analytics.d.ts.map +1 -1
- package/dist/plugins/analytics/analytics.js +2 -2
- package/dist/plugins/analytics/analytics.js.map +1 -1
- package/dist/plugins/analytics/index.d.ts +2 -0
- package/dist/plugins/analytics/index.js +0 -1
- package/dist/plugins/analytics/manifest.js +30 -18
- package/dist/plugins/analytics/manifest.js.map +1 -1
- package/dist/plugins/analytics/types.d.ts +1 -0
- package/dist/plugins/analytics/types.d.ts.map +1 -1
- package/dist/plugins/genie/genie.d.ts +4 -1
- package/dist/plugins/genie/genie.d.ts.map +1 -1
- package/dist/plugins/genie/genie.js +10 -6
- package/dist/plugins/genie/genie.js.map +1 -1
- package/dist/plugins/genie/index.d.ts +4 -0
- package/dist/plugins/genie/index.js +0 -1
- package/dist/plugins/genie/manifest.js +37 -8
- package/dist/plugins/genie/manifest.js.map +1 -1
- package/dist/plugins/genie/types.d.ts +2 -0
- package/dist/plugins/genie/types.d.ts.map +1 -1
- package/dist/plugins/index.d.ts +13 -0
- package/dist/plugins/index.js +0 -4
- package/dist/plugins/lakebase/index.d.ts +2 -0
- package/dist/plugins/lakebase/index.js +0 -1
- package/dist/plugins/lakebase/lakebase.d.ts +14 -12
- package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
- package/dist/plugins/lakebase/lakebase.js +2 -2
- package/dist/plugins/lakebase/lakebase.js.map +1 -1
- package/dist/plugins/lakebase/manifest.js +14 -8
- package/dist/plugins/lakebase/manifest.js.map +1 -1
- package/dist/plugins/lakebase/types.d.ts +1 -1
- package/dist/plugins/lakebase/types.d.ts.map +1 -1
- package/dist/plugins/server/index.d.ts +7 -9
- package/dist/plugins/server/index.d.ts.map +1 -1
- package/dist/plugins/server/index.js +2 -2
- package/dist/plugins/server/index.js.map +1 -1
- package/dist/plugins/server/manifest.js +36 -18
- package/dist/plugins/server/manifest.js.map +1 -1
- package/dist/plugins/server/types.d.ts +2 -0
- package/dist/plugins/server/types.d.ts.map +1 -1
- package/dist/registry/index.d.ts +4 -0
- package/dist/registry/manifest-loader.d.ts +1 -1
- package/dist/registry/manifest-loader.d.ts.map +1 -1
- package/dist/registry/resource-registry.d.ts +1 -1
- package/dist/registry/resource-registry.d.ts.map +1 -1
- package/dist/registry/types.d.ts +1 -4
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/types.generated.d.ts +1 -1
- package/dist/registry/types.generated.d.ts.map +1 -1
- package/dist/registry/types.generated.js.map +1 -1
- package/dist/shared/src/cache.d.ts +1 -1
- package/dist/shared/src/cache.d.ts.map +1 -1
- package/dist/shared/src/execute.d.ts +1 -1
- package/dist/shared/src/execute.d.ts.map +1 -1
- package/dist/shared/src/genie.d.ts +6 -0
- package/dist/shared/src/genie.d.ts.map +1 -1
- package/dist/shared/src/index.d.ts +7 -0
- package/dist/shared/src/plugin.d.ts +2 -3
- package/dist/shared/src/plugin.d.ts.map +1 -1
- package/dist/shared/src/sql/helpers.d.ts +0 -1
- package/dist/shared/src/sql/helpers.d.ts.map +1 -1
- package/dist/shared/src/sql/types.d.ts.map +1 -1
- package/dist/shared/src/tunnel.d.ts +1 -1
- package/dist/shared/src/tunnel.d.ts.map +1 -1
- package/dist/stream/arrow-stream-processor.d.ts +1 -0
- package/dist/stream/buffers.d.ts +1 -0
- package/dist/stream/index.d.ts +3 -0
- package/dist/stream/stream-manager.d.ts +1 -0
- package/dist/stream/stream-manager.d.ts.map +1 -1
- package/dist/stream/types.d.ts +3 -0
- package/dist/telemetry/config.d.ts +1 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/instrumentations.d.ts +1 -0
- package/dist/telemetry/telemetry-manager.d.ts +4 -0
- package/dist/telemetry/telemetry-provider.d.ts +6 -0
- package/dist/telemetry/types.d.ts.map +1 -1
- package/dist/type-generator/cache.js +10 -12
- package/dist/type-generator/cache.js.map +1 -1
- package/dist/type-generator/index.js +2 -2
- package/dist/type-generator/index.js.map +1 -1
- package/dist/type-generator/query-registry.js +165 -52
- package/dist/type-generator/query-registry.js.map +1 -1
- package/dist/type-generator/spinner.js +5 -1
- package/dist/type-generator/spinner.js.map +1 -1
- package/dist/type-generator/vite-plugin.d.ts +0 -1
- package/dist/type-generator/vite-plugin.d.ts.map +1 -1
- package/dist/type-generator/vite-plugin.js +2 -2
- package/dist/type-generator/vite-plugin.js.map +1 -1
- package/docs/api/appkit-ui/genie/GenieChatMessageList.md +7 -5
- package/docs/development/project-setup.md +1 -1
- package/docs/plugins/plugin-management.md +16 -2
- package/package.json +3 -1
- package/dist/plugins/analytics/manifest.json +0 -36
- package/dist/plugins/genie/manifest.json +0 -43
- package/dist/plugins/lakebase/manifest.json +0 -12
- package/dist/plugins/server/manifest.json +0 -36
- /package/dist/plugins/server/remote-tunnel/{denied.html → denied.html/denied.html} +0 -0
- /package/dist/plugins/server/remote-tunnel/{index.html → index.html/index.html} +0 -0
- /package/dist/plugins/server/remote-tunnel/{wait.html → wait.html/wait.html} +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { IAppRouter, ToPlugin } from "../../shared/src/plugin.js";
|
|
2
2
|
import { SQLTypeMarker } from "../../shared/src/sql/types.js";
|
|
3
|
+
import "../../shared/src/index.js";
|
|
3
4
|
import { Plugin } from "../../plugin/plugin.js";
|
|
4
|
-
import
|
|
5
|
+
import "../../plugin/index.js";
|
|
5
6
|
import { PluginManifest } from "../../registry/types.js";
|
|
7
|
+
import "../../registry/index.js";
|
|
8
|
+
import { IAnalyticsConfig } from "./types.js";
|
|
6
9
|
import { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
7
10
|
import express from "express";
|
|
8
11
|
|
|
@@ -64,5 +67,5 @@ declare class AnalyticsPlugin extends Plugin {
|
|
|
64
67
|
*/
|
|
65
68
|
declare const analytics: ToPlugin<typeof AnalyticsPlugin, IAnalyticsConfig, "analytics">;
|
|
66
69
|
//#endregion
|
|
67
|
-
export { analytics };
|
|
70
|
+
export { AnalyticsPlugin, analytics };
|
|
68
71
|
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.d.ts","names":[],"sources":["../../../src/plugins/analytics/analytics.ts"],"
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","names":[],"sources":["../../../src/plugins/analytics/analytics.ts"],"mappings":";;;;;;;;;;;;cA4Ba,eAAA,SAAwB,MAAA;EACnC,IAAA;;SAGO,QAAA,EAAuB,cAAA;EAAA,iBAEb,WAAA;EAAA,UACC,MAAA,EAAQ,gBAAA;EAAA,QAGlB,SAAA;EAAA,QACA,cAAA;cAEI,MAAA,EAAQ,gBAAA;EAWpB,YAAA,CAAa,MAAA,EAAQ,UAAA;EAjBK;;;;EA0CpB,iBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAAA;;;;EAsCG,iBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EA+GY;;;;;;;;;;;;;;;EAFT,KAAA,CACJ,KAAA,UACA,UAAA,GAAa,MAAA,SAAe,aAAA,sBAC5B,gBAAA,GAAmB,MAAA,eACnB,MAAA,GAAS,WAAA,GACR,OAAA;EA/MsC;;;EAAA,UAuOzB,YAAA,CACd,eAAA,EAAiB,eAAA,EACjB,KAAA,UACA,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,UAAA,aAAuB,SAAA,CAAU,YAAA;EAItC,QAAA,CAAA,GAAY,OAAA;EAzOD;;;;EAiPjB,OAAA,CAAA;;;;2BA5Ce,UAAA,GACA,MAAA,SAAe,aAAA,sBAAiC,gBAAA,GAC1C,MAAA,eAAmB,MAAA,GAC7B,WAAA,KACR,OAAA;EAAA;AAAA;;;;cAqDQ,SAAA,EAAS,QAAA,QAAA,eAAA,EAAA,gBAAA"}
|
|
@@ -7,7 +7,7 @@ import "../../plugin/index.js";
|
|
|
7
7
|
import { SQLWarehouseConnector } from "../../connectors/sql-warehouse/client.js";
|
|
8
8
|
import "../../connectors/index.js";
|
|
9
9
|
import { queryDefaults } from "./defaults.js";
|
|
10
|
-
import
|
|
10
|
+
import manifest_default from "./manifest.js";
|
|
11
11
|
import { QueryProcessor } from "./query.js";
|
|
12
12
|
|
|
13
13
|
//#region src/plugins/analytics/analytics.ts
|
|
@@ -16,7 +16,7 @@ const logger = createLogger("analytics");
|
|
|
16
16
|
var AnalyticsPlugin = class extends Plugin {
|
|
17
17
|
name = "analytics";
|
|
18
18
|
/** Plugin manifest declaring metadata and resource requirements */
|
|
19
|
-
static manifest =
|
|
19
|
+
static manifest = manifest_default;
|
|
20
20
|
static description = "Analytics plugin for data analysis";
|
|
21
21
|
SQLClient;
|
|
22
22
|
queryProcessor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","names":[],"sources":["../../../src/plugins/analytics/analytics.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport type express from \"express\";\nimport type {\n IAppRouter,\n PluginExecuteConfig,\n SQLTypeMarker,\n StreamExecutionSettings,\n} from \"shared\";\nimport { SQLWarehouseConnector } from \"../../connectors\";\nimport {\n getCurrentUserId,\n getWarehouseId,\n getWorkspaceClient,\n} from \"../../context\";\nimport { createLogger } from \"../../logging/logger\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport { queryDefaults } from \"./defaults\";\nimport { analyticsManifest } from \"./manifest\";\nimport { QueryProcessor } from \"./query\";\nimport type {\n AnalyticsQueryResponse,\n IAnalyticsConfig,\n IAnalyticsQueryRequest,\n} from \"./types\";\n\nconst logger = createLogger(\"analytics\");\n\nexport class AnalyticsPlugin extends Plugin {\n name = \"analytics\";\n\n /** Plugin manifest declaring metadata and resource requirements */\n static manifest = analyticsManifest;\n\n protected static description = \"Analytics plugin for data analysis\";\n protected declare config: IAnalyticsConfig;\n\n // analytics services\n private SQLClient: SQLWarehouseConnector;\n private queryProcessor: QueryProcessor;\n\n constructor(config: IAnalyticsConfig) {\n super(config);\n this.config = config;\n this.queryProcessor = new QueryProcessor();\n\n this.SQLClient = new SQLWarehouseConnector({\n timeout: config.timeout,\n telemetry: config.telemetry,\n });\n }\n\n injectRoutes(router: IAppRouter) {\n // Service principal endpoints\n this.route(router, {\n name: \"arrow\",\n method: \"get\",\n path: \"/arrow-result/:jobId\",\n handler: async (req: express.Request, res: express.Response) => {\n await this._handleArrowRoute(req, res);\n },\n });\n\n this.route<AnalyticsQueryResponse>(router, {\n name: \"query\",\n method: \"post\",\n path: \"/query/:query_key\",\n handler: async (req: express.Request, res: express.Response) => {\n await this._handleQueryRoute(req, res);\n },\n });\n }\n\n /**\n * Handle Arrow data download requests.\n * When called via asUser(req), uses the user's Databricks credentials.\n */\n async _handleArrowRoute(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n try {\n const { jobId } = req.params;\n const workspaceClient = getWorkspaceClient();\n\n logger.debug(\"Processing Arrow job request for jobId=%s\", jobId);\n\n const event = logger.event(req);\n event?.setComponent(\"analytics\", \"getArrowData\").setContext(\"analytics\", {\n job_id: jobId,\n plugin: this.name,\n });\n\n const result = await this.getArrowData(workspaceClient, jobId);\n\n res.setHeader(\"Content-Type\", \"application/octet-stream\");\n res.setHeader(\"Content-Length\", result.data.length.toString());\n res.setHeader(\"Cache-Control\", \"public, max-age=3600\");\n\n logger.debug(\n \"Sending Arrow buffer: %d bytes for job %s\",\n result.data.length,\n jobId,\n );\n res.send(Buffer.from(result.data));\n } catch (error) {\n logger.error(\"Arrow job error: %O\", error);\n res.status(404).json({\n error: error instanceof Error ? error.message : \"Arrow job not found\",\n plugin: this.name,\n });\n }\n }\n\n /**\n * Handle SQL query execution requests.\n * When called via asUser(req), uses the user's Databricks credentials.\n */\n async _handleQueryRoute(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { query_key } = req.params;\n const { parameters, format = \"JSON\" } = req.body as IAnalyticsQueryRequest;\n\n // Request-scoped logging with WideEvent tracking\n logger.debug(req, \"Executing query: %s (format=%s)\", query_key, format);\n\n const event = logger.event(req);\n event?.setComponent(\"analytics\", \"executeQuery\").setContext(\"analytics\", {\n query_key,\n format,\n parameter_count: parameters ? Object.keys(parameters).length : 0,\n plugin: this.name,\n });\n\n if (!query_key) {\n res.status(400).json({ error: \"query_key is required\" });\n return;\n }\n\n const queryResult = await this.app.getAppQuery(\n query_key,\n req,\n this.devFileReader,\n );\n\n if (!queryResult) {\n res.status(404).json({ error: \"Query not found\" });\n return;\n }\n\n const { query, isAsUser } = queryResult;\n\n // get execution context - user-scoped if .obo.sql, otherwise service principal\n const executor = isAsUser ? this.asUser(req) : this;\n const userKey = getCurrentUserId();\n const executorKey = isAsUser ? userKey : \"global\";\n\n const queryParameters =\n format === \"ARROW\"\n ? {\n formatParameters: {\n disposition: \"EXTERNAL_LINKS\",\n format: \"ARROW_STREAM\",\n },\n type: \"arrow\",\n }\n : {\n type: \"result\",\n };\n\n const hashedQuery = this.queryProcessor.hashQuery(query);\n\n const defaultConfig: PluginExecuteConfig = {\n ...queryDefaults,\n cache: {\n ...queryDefaults.cache,\n cacheKey: [\n \"analytics:query\",\n query_key,\n JSON.stringify(parameters),\n JSON.stringify(format),\n hashedQuery,\n executorKey,\n ],\n },\n };\n\n const streamExecutionSettings: StreamExecutionSettings = {\n default: defaultConfig,\n };\n\n await executor.executeStream(\n res,\n async (signal) => {\n const processedParams = await this.queryProcessor.processQueryParams(\n query,\n parameters,\n );\n\n const result = await executor.query(\n query,\n processedParams,\n queryParameters.formatParameters,\n signal,\n );\n\n return { type: queryParameters.type, ...result };\n },\n streamExecutionSettings,\n executorKey,\n );\n }\n\n /**\n * Execute a SQL query using the current execution context.\n *\n * When called directly: uses service principal credentials.\n * When called via asUser(req).query(...): uses user's credentials.\n *\n * @example\n * ```typescript\n * // Service principal execution\n * const result = await analytics.query(\"SELECT * FROM table\")\n *\n * // User context execution (in route handler)\n * const result = await this.asUser(req).query(\"SELECT * FROM table\")\n * ```\n */\n async query(\n query: string,\n parameters?: Record<string, SQLTypeMarker | null | undefined>,\n formatParameters?: Record<string, any>,\n signal?: AbortSignal,\n ): Promise<any> {\n const workspaceClient = getWorkspaceClient();\n const warehouseId = await getWarehouseId();\n\n const { statement, parameters: sqlParameters } =\n this.queryProcessor.convertToSQLParameters(query, parameters);\n\n const response = await this.SQLClient.executeStatement(\n workspaceClient,\n {\n statement,\n warehouse_id: warehouseId,\n parameters: sqlParameters,\n ...formatParameters,\n },\n signal,\n );\n\n return response.result;\n }\n\n /**\n * Get Arrow-formatted data for a completed query job.\n */\n protected async getArrowData(\n workspaceClient: WorkspaceClient,\n jobId: string,\n signal?: AbortSignal,\n ): Promise<ReturnType<typeof this.SQLClient.getArrowData>> {\n return await this.SQLClient.getArrowData(workspaceClient, jobId, signal);\n }\n\n async shutdown(): Promise<void> {\n this.streamManager.abortAll();\n }\n\n /**\n * Returns the public exports for the analytics plugin.\n * Note: `asUser()` is automatically added by AppKit.\n */\n exports() {\n return {\n /**\n * Execute a SQL query using service principal credentials.\n */\n query: this.query,\n };\n }\n}\n\n/**\n * @internal\n */\nexport const analytics = toPlugin<\n typeof AnalyticsPlugin,\n IAnalyticsConfig,\n \"analytics\"\n>(AnalyticsPlugin, \"analytics\");\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analytics.js","names":["manifest"],"sources":["../../../src/plugins/analytics/analytics.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport type express from \"express\";\nimport type {\n IAppRouter,\n PluginExecuteConfig,\n SQLTypeMarker,\n StreamExecutionSettings,\n} from \"shared\";\nimport { SQLWarehouseConnector } from \"../../connectors\";\nimport {\n getCurrentUserId,\n getWarehouseId,\n getWorkspaceClient,\n} from \"../../context\";\nimport { createLogger } from \"../../logging/logger\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport type { PluginManifest } from \"../../registry\";\nimport { queryDefaults } from \"./defaults\";\nimport manifest from \"./manifest.json\";\nimport { QueryProcessor } from \"./query\";\nimport type {\n AnalyticsQueryResponse,\n IAnalyticsConfig,\n IAnalyticsQueryRequest,\n} from \"./types\";\n\nconst logger = createLogger(\"analytics\");\n\nexport class AnalyticsPlugin extends Plugin {\n name = \"analytics\";\n\n /** Plugin manifest declaring metadata and resource requirements */\n static manifest = manifest as PluginManifest;\n\n protected static description = \"Analytics plugin for data analysis\";\n protected declare config: IAnalyticsConfig;\n\n // analytics services\n private SQLClient: SQLWarehouseConnector;\n private queryProcessor: QueryProcessor;\n\n constructor(config: IAnalyticsConfig) {\n super(config);\n this.config = config;\n this.queryProcessor = new QueryProcessor();\n\n this.SQLClient = new SQLWarehouseConnector({\n timeout: config.timeout,\n telemetry: config.telemetry,\n });\n }\n\n injectRoutes(router: IAppRouter) {\n // Service principal endpoints\n this.route(router, {\n name: \"arrow\",\n method: \"get\",\n path: \"/arrow-result/:jobId\",\n handler: async (req: express.Request, res: express.Response) => {\n await this._handleArrowRoute(req, res);\n },\n });\n\n this.route<AnalyticsQueryResponse>(router, {\n name: \"query\",\n method: \"post\",\n path: \"/query/:query_key\",\n handler: async (req: express.Request, res: express.Response) => {\n await this._handleQueryRoute(req, res);\n },\n });\n }\n\n /**\n * Handle Arrow data download requests.\n * When called via asUser(req), uses the user's Databricks credentials.\n */\n async _handleArrowRoute(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n try {\n const { jobId } = req.params;\n const workspaceClient = getWorkspaceClient();\n\n logger.debug(\"Processing Arrow job request for jobId=%s\", jobId);\n\n const event = logger.event(req);\n event?.setComponent(\"analytics\", \"getArrowData\").setContext(\"analytics\", {\n job_id: jobId,\n plugin: this.name,\n });\n\n const result = await this.getArrowData(workspaceClient, jobId);\n\n res.setHeader(\"Content-Type\", \"application/octet-stream\");\n res.setHeader(\"Content-Length\", result.data.length.toString());\n res.setHeader(\"Cache-Control\", \"public, max-age=3600\");\n\n logger.debug(\n \"Sending Arrow buffer: %d bytes for job %s\",\n result.data.length,\n jobId,\n );\n res.send(Buffer.from(result.data));\n } catch (error) {\n logger.error(\"Arrow job error: %O\", error);\n res.status(404).json({\n error: error instanceof Error ? error.message : \"Arrow job not found\",\n plugin: this.name,\n });\n }\n }\n\n /**\n * Handle SQL query execution requests.\n * When called via asUser(req), uses the user's Databricks credentials.\n */\n async _handleQueryRoute(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { query_key } = req.params;\n const { parameters, format = \"JSON\" } = req.body as IAnalyticsQueryRequest;\n\n // Request-scoped logging with WideEvent tracking\n logger.debug(req, \"Executing query: %s (format=%s)\", query_key, format);\n\n const event = logger.event(req);\n event?.setComponent(\"analytics\", \"executeQuery\").setContext(\"analytics\", {\n query_key,\n format,\n parameter_count: parameters ? Object.keys(parameters).length : 0,\n plugin: this.name,\n });\n\n if (!query_key) {\n res.status(400).json({ error: \"query_key is required\" });\n return;\n }\n\n const queryResult = await this.app.getAppQuery(\n query_key,\n req,\n this.devFileReader,\n );\n\n if (!queryResult) {\n res.status(404).json({ error: \"Query not found\" });\n return;\n }\n\n const { query, isAsUser } = queryResult;\n\n // get execution context - user-scoped if .obo.sql, otherwise service principal\n const executor = isAsUser ? this.asUser(req) : this;\n const userKey = getCurrentUserId();\n const executorKey = isAsUser ? userKey : \"global\";\n\n const queryParameters =\n format === \"ARROW\"\n ? {\n formatParameters: {\n disposition: \"EXTERNAL_LINKS\",\n format: \"ARROW_STREAM\",\n },\n type: \"arrow\",\n }\n : {\n type: \"result\",\n };\n\n const hashedQuery = this.queryProcessor.hashQuery(query);\n\n const defaultConfig: PluginExecuteConfig = {\n ...queryDefaults,\n cache: {\n ...queryDefaults.cache,\n cacheKey: [\n \"analytics:query\",\n query_key,\n JSON.stringify(parameters),\n JSON.stringify(format),\n hashedQuery,\n executorKey,\n ],\n },\n };\n\n const streamExecutionSettings: StreamExecutionSettings = {\n default: defaultConfig,\n };\n\n await executor.executeStream(\n res,\n async (signal) => {\n const processedParams = await this.queryProcessor.processQueryParams(\n query,\n parameters,\n );\n\n const result = await executor.query(\n query,\n processedParams,\n queryParameters.formatParameters,\n signal,\n );\n\n return { type: queryParameters.type, ...result };\n },\n streamExecutionSettings,\n executorKey,\n );\n }\n\n /**\n * Execute a SQL query using the current execution context.\n *\n * When called directly: uses service principal credentials.\n * When called via asUser(req).query(...): uses user's credentials.\n *\n * @example\n * ```typescript\n * // Service principal execution\n * const result = await analytics.query(\"SELECT * FROM table\")\n *\n * // User context execution (in route handler)\n * const result = await this.asUser(req).query(\"SELECT * FROM table\")\n * ```\n */\n async query(\n query: string,\n parameters?: Record<string, SQLTypeMarker | null | undefined>,\n formatParameters?: Record<string, any>,\n signal?: AbortSignal,\n ): Promise<any> {\n const workspaceClient = getWorkspaceClient();\n const warehouseId = await getWarehouseId();\n\n const { statement, parameters: sqlParameters } =\n this.queryProcessor.convertToSQLParameters(query, parameters);\n\n const response = await this.SQLClient.executeStatement(\n workspaceClient,\n {\n statement,\n warehouse_id: warehouseId,\n parameters: sqlParameters,\n ...formatParameters,\n },\n signal,\n );\n\n return response.result;\n }\n\n /**\n * Get Arrow-formatted data for a completed query job.\n */\n protected async getArrowData(\n workspaceClient: WorkspaceClient,\n jobId: string,\n signal?: AbortSignal,\n ): Promise<ReturnType<typeof this.SQLClient.getArrowData>> {\n return await this.SQLClient.getArrowData(workspaceClient, jobId, signal);\n }\n\n async shutdown(): Promise<void> {\n this.streamManager.abortAll();\n }\n\n /**\n * Returns the public exports for the analytics plugin.\n * Note: `asUser()` is automatically added by AppKit.\n */\n exports() {\n return {\n /**\n * Execute a SQL query using service principal credentials.\n */\n query: this.query,\n };\n }\n}\n\n/**\n * @internal\n */\nexport const analytics = toPlugin<\n typeof AnalyticsPlugin,\n IAnalyticsConfig,\n \"analytics\"\n>(AnalyticsPlugin, \"analytics\");\n"],"mappings":"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"}
|
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
//#region src/plugins/analytics/manifest.json
|
|
2
|
+
var manifest_default = {
|
|
3
|
+
$schema: "https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json",
|
|
4
|
+
name: "analytics",
|
|
5
|
+
displayName: "Analytics Plugin",
|
|
6
|
+
description: "SQL query execution against Databricks SQL Warehouses",
|
|
7
|
+
resources: {
|
|
8
|
+
"required": [{
|
|
9
|
+
"type": "sql_warehouse",
|
|
10
|
+
"alias": "SQL Warehouse",
|
|
11
|
+
"resourceKey": "sql-warehouse",
|
|
12
|
+
"description": "SQL Warehouse for executing analytics queries",
|
|
13
|
+
"permission": "CAN_USE",
|
|
14
|
+
"fields": { "id": {
|
|
15
|
+
"env": "DATABRICKS_WAREHOUSE_ID",
|
|
16
|
+
"description": "SQL Warehouse ID"
|
|
17
|
+
} }
|
|
18
|
+
}],
|
|
19
|
+
"optional": []
|
|
20
|
+
},
|
|
21
|
+
config: { "schema": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"properties": { "timeout": {
|
|
24
|
+
"type": "number",
|
|
25
|
+
"default": 3e4,
|
|
26
|
+
"description": "Query execution timeout in milliseconds"
|
|
27
|
+
} }
|
|
28
|
+
} }
|
|
29
|
+
};
|
|
18
30
|
|
|
19
31
|
//#endregion
|
|
20
|
-
export {
|
|
32
|
+
export { manifest_default as default };
|
|
21
33
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/analytics/manifest.
|
|
1
|
+
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/analytics/manifest.json"],"sourcesContent":[""],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/plugins/analytics/types.ts"],"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/plugins/analytics/types.ts"],"mappings":";;;;UAEiB,gBAAA,SAAyB,gBAAA;EACxC,OAAA;AAAA"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { IAppRouter, ToPlugin } from "../../shared/src/plugin.js";
|
|
2
2
|
import { GenieStreamEvent } from "../../shared/src/genie.js";
|
|
3
|
+
import "../../shared/src/index.js";
|
|
3
4
|
import { Plugin } from "../../plugin/plugin.js";
|
|
5
|
+
import "../../plugin/index.js";
|
|
4
6
|
import { PluginManifest } from "../../registry/types.js";
|
|
7
|
+
import "../../registry/index.js";
|
|
5
8
|
import { GenieConversationHistoryResponse } from "../../connectors/genie/types.js";
|
|
6
9
|
import { IGenieConfig } from "./types.js";
|
|
7
10
|
import express from "express";
|
|
@@ -40,5 +43,5 @@ declare class GeniePlugin extends Plugin {
|
|
|
40
43
|
*/
|
|
41
44
|
declare const genie: ToPlugin<typeof GeniePlugin, IGenieConfig, "genie">;
|
|
42
45
|
//#endregion
|
|
43
|
-
export { genie };
|
|
46
|
+
export { GeniePlugin, genie };
|
|
44
47
|
//# sourceMappingURL=genie.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genie.d.ts","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"
|
|
1
|
+
{"version":3,"file":"genie.d.ts","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"mappings":";;;;;;;;;;;;cAmBa,WAAA,SAAoB,MAAA;EAC/B,IAAA;EAAA,OAEO,QAAA,EAAuB,cAAA;EAAA,iBAEb,WAAA;EAAA,UAEC,MAAA,EAAQ,YAAA;EAAA,iBAET,cAAA;cAEL,MAAA,EAAQ,YAAA;EAAA,QAYZ,aAAA;EAAA,QAKA,cAAA;EAIR,YAAA,CAAa,MAAA,EAAQ,UAAA;EAoBf,kBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAwDG,sBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAgDG,eAAA,CACJ,KAAA,UACA,cAAA,WACC,OAAA,CAAQ,gCAAA;EArIU;;;;EAyJd,WAAA,CACL,KAAA,UACA,OAAA,UACA,cAAA,WACA,OAAA;IAAY,OAAA;EAAA,IACX,cAAA,CAAe,gBAAA;EAgBZ,QAAA,CAAA,GAAY,OAAA;EAIlB,OAAA,CAAA;iCAxBe,OAAA,UACE,cAAA,WACQ,OAAA;MACX,OAAA;IAAA,MACX,cAAA,CAAe,gBAAA;qCA3BH,cAAA,aAEZ,OAAA,CAAQ,gCAAA;EAAA;AAAA;;;;cAwDA,KAAA,EAAK,QAAA,QAAA,WAAA,EAAA,YAAA"}
|
|
@@ -8,7 +8,7 @@ import "../../logging/index.js";
|
|
|
8
8
|
import { GenieConnector } from "../../connectors/genie/client.js";
|
|
9
9
|
import "../../connectors/index.js";
|
|
10
10
|
import { genieStreamDefaults } from "./defaults.js";
|
|
11
|
-
import
|
|
11
|
+
import manifest_default from "./manifest.js";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
|
|
14
14
|
//#region src/plugins/genie/genie.ts
|
|
@@ -16,7 +16,7 @@ init_context();
|
|
|
16
16
|
const logger = createLogger("genie");
|
|
17
17
|
var GeniePlugin = class extends Plugin {
|
|
18
18
|
name = "genie";
|
|
19
|
-
static manifest =
|
|
19
|
+
static manifest = manifest_default;
|
|
20
20
|
static description = "AI/BI Genie space integration for natural language data queries";
|
|
21
21
|
genieConnector;
|
|
22
22
|
constructor(config) {
|
|
@@ -69,7 +69,7 @@ var GeniePlugin = class extends Plugin {
|
|
|
69
69
|
}
|
|
70
70
|
logger.debug("Sending message to space %s (alias=%s, conversationId=%s)", spaceId, alias, conversationId ?? "new");
|
|
71
71
|
const timeout = this.config.timeout ?? 12e4;
|
|
72
|
-
const requestId = req.query.requestId || randomUUID();
|
|
72
|
+
const requestId = typeof req.query.requestId === "string" && req.query.requestId || randomUUID();
|
|
73
73
|
const streamSettings = {
|
|
74
74
|
...genieStreamDefaults,
|
|
75
75
|
default: {
|
|
@@ -92,8 +92,9 @@ var GeniePlugin = class extends Plugin {
|
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
const includeQueryResults = req.query.includeQueryResults !== "false";
|
|
95
|
-
const
|
|
96
|
-
|
|
95
|
+
const pageToken = typeof req.query.pageToken === "string" ? req.query.pageToken : void 0;
|
|
96
|
+
const requestId = typeof req.query.requestId === "string" && req.query.requestId || randomUUID();
|
|
97
|
+
logger.debug("Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s, pageToken=%s)", conversationId, spaceId, alias, includeQueryResults, pageToken ?? "none");
|
|
97
98
|
const streamSettings = {
|
|
98
99
|
...genieStreamDefaults,
|
|
99
100
|
stream: {
|
|
@@ -102,7 +103,10 @@ var GeniePlugin = class extends Plugin {
|
|
|
102
103
|
}
|
|
103
104
|
};
|
|
104
105
|
const workspaceClient = getWorkspaceClient();
|
|
105
|
-
await this.executeStream(res, () => this.genieConnector.streamConversation(workspaceClient, spaceId, conversationId, {
|
|
106
|
+
await this.executeStream(res, () => this.genieConnector.streamConversation(workspaceClient, spaceId, conversationId, {
|
|
107
|
+
includeQueryResults,
|
|
108
|
+
pageToken
|
|
109
|
+
}), streamSettings);
|
|
106
110
|
}
|
|
107
111
|
async getConversation(alias, conversationId) {
|
|
108
112
|
const spaceId = this.resolveSpaceId(alias);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genie.js","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type express from \"express\";\nimport type { IAppRouter, StreamExecutionSettings } from \"shared\";\nimport { GenieConnector } from \"../../connectors\";\nimport { getWorkspaceClient } from \"../../context\";\nimport { createLogger } from \"../../logging\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport {
|
|
1
|
+
{"version":3,"file":"genie.js","names":["manifest"],"sources":["../../../src/plugins/genie/genie.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type express from \"express\";\nimport type { IAppRouter, StreamExecutionSettings } from \"shared\";\nimport { GenieConnector } from \"../../connectors\";\nimport { getWorkspaceClient } from \"../../context\";\nimport { createLogger } from \"../../logging\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport type { PluginManifest } from \"../../registry\";\nimport { genieStreamDefaults } from \"./defaults\";\nimport manifest from \"./manifest.json\";\nimport type {\n GenieConversationHistoryResponse,\n GenieSendMessageRequest,\n GenieStreamEvent,\n IGenieConfig,\n} from \"./types\";\n\nconst logger = createLogger(\"genie\");\n\nexport class GeniePlugin extends Plugin {\n name = \"genie\";\n\n static manifest = manifest as PluginManifest;\n\n protected static description =\n \"AI/BI Genie space integration for natural language data queries\";\n protected declare config: IGenieConfig;\n\n private readonly genieConnector: GenieConnector;\n\n constructor(config: IGenieConfig) {\n super(config);\n this.config = {\n ...config,\n spaces: config.spaces ?? this.defaultSpaces(),\n };\n this.genieConnector = new GenieConnector({\n timeout: this.config.timeout,\n maxMessages: 200,\n });\n }\n\n private defaultSpaces(): Record<string, string> {\n const spaceId = process.env.DATABRICKS_GENIE_SPACE_ID;\n return spaceId ? { default: spaceId } : {};\n }\n\n private resolveSpaceId(alias: string): string | null {\n return this.config.spaces?.[alias] ?? null;\n }\n\n injectRoutes(router: IAppRouter) {\n this.route(router, {\n name: \"sendMessage\",\n method: \"post\",\n path: \"/:alias/messages\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleSendMessage(req, res);\n },\n });\n\n this.route(router, {\n name: \"getConversation\",\n method: \"get\",\n path: \"/:alias/conversations/:conversationId\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleGetConversation(req, res);\n },\n });\n }\n\n async _handleSendMessage(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const { content, conversationId } = req.body as GenieSendMessageRequest;\n\n if (!content) {\n res.status(400).json({ error: \"content is required\" });\n return;\n }\n\n logger.debug(\n \"Sending message to space %s (alias=%s, conversationId=%s)\",\n spaceId,\n alias,\n conversationId ?? \"new\",\n );\n\n const timeout = this.config.timeout ?? 120_000;\n const requestId =\n (typeof req.query.requestId === \"string\" && req.query.requestId) ||\n randomUUID();\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n default: {\n ...genieStreamDefaults.default,\n timeout,\n },\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n ),\n streamSettings,\n );\n }\n\n async _handleGetConversation(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias, conversationId } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const includeQueryResults = req.query.includeQueryResults !== \"false\";\n const pageToken =\n typeof req.query.pageToken === \"string\" ? req.query.pageToken : undefined;\n const requestId =\n (typeof req.query.requestId === \"string\" && req.query.requestId) ||\n randomUUID();\n\n logger.debug(\n \"Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s, pageToken=%s)\",\n conversationId,\n spaceId,\n alias,\n includeQueryResults,\n pageToken ?? \"none\",\n );\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamConversation(\n workspaceClient,\n spaceId,\n conversationId,\n { includeQueryResults, pageToken },\n ),\n streamSettings,\n );\n }\n\n async getConversation(\n alias: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n\n const workspaceClient = getWorkspaceClient();\n\n return this.genieConnector.getConversation(\n workspaceClient,\n spaceId,\n conversationId,\n );\n }\n\n /**\n * Send a message and consume events as a stream (message_start, status,\n * message_result, query_result, error).\n */\n async *sendMessage(\n alias: string,\n content: string,\n conversationId?: string,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n const spaceId = this.resolveSpaceId(alias);\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n const workspaceClient = getWorkspaceClient();\n const timeout = options?.timeout ?? this.config.timeout ?? 120_000;\n yield* this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n );\n }\n\n async shutdown(): Promise<void> {\n this.streamManager.abortAll();\n }\n\n exports() {\n return {\n sendMessage: this.sendMessage,\n getConversation: this.getConversation,\n };\n }\n}\n\n/**\n * @internal\n */\nexport const genie = toPlugin<typeof GeniePlugin, IGenieConfig, \"genie\">(\n GeniePlugin,\n \"genie\",\n);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
2
|
+
import { GenieConversationHistoryResponse } from "../../connectors/genie/types.js";
|
|
3
|
+
import { IGenieConfig } from "./types.js";
|
|
4
|
+
import { GeniePlugin, genie } from "./genie.js";
|
|
@@ -1,11 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
//#region src/plugins/genie/manifest.json
|
|
2
|
+
var manifest_default = {
|
|
3
|
+
name: "genie",
|
|
4
|
+
displayName: "Genie Plugin",
|
|
5
|
+
description: "AI/BI Genie space integration for natural language data queries",
|
|
6
|
+
resources: {
|
|
7
|
+
"required": [{
|
|
8
|
+
"type": "genie_space",
|
|
9
|
+
"alias": "Genie Space",
|
|
10
|
+
"resourceKey": "genie-space",
|
|
11
|
+
"description": "Genie Space for AI-powered data queries. Space IDs configured via plugin config.",
|
|
12
|
+
"permission": "CAN_RUN",
|
|
13
|
+
"fields": { "id": {
|
|
14
|
+
"env": "DATABRICKS_GENIE_SPACE_ID",
|
|
15
|
+
"description": "Default Genie Space ID"
|
|
16
|
+
} }
|
|
17
|
+
}],
|
|
18
|
+
"optional": []
|
|
19
|
+
},
|
|
20
|
+
config: { "schema": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"spaces": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"description": "Map of alias names to Genie Space IDs",
|
|
26
|
+
"additionalProperties": { "type": "string" }
|
|
27
|
+
},
|
|
28
|
+
"timeout": {
|
|
29
|
+
"type": "number",
|
|
30
|
+
"default": 12e4,
|
|
31
|
+
"description": "Genie polling timeout in ms. Set to 0 for indefinite."
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"required": ["spaces"]
|
|
35
|
+
} }
|
|
36
|
+
};
|
|
8
37
|
|
|
9
38
|
//#endregion
|
|
10
|
-
export {
|
|
39
|
+
export { manifest_default as default };
|
|
11
40
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/genie/manifest.
|
|
1
|
+
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/genie/manifest.json"],"sourcesContent":[""],"mappings":""}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BasePluginConfig } from "../../shared/src/plugin.js";
|
|
2
2
|
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
3
|
+
import "../../shared/src/index.js";
|
|
3
4
|
import { GenieConversationHistoryResponse } from "../../connectors/genie/types.js";
|
|
5
|
+
import "../../connectors/genie/index.js";
|
|
4
6
|
|
|
5
7
|
//#region src/plugins/genie/types.d.ts
|
|
6
8
|
interface IGenieConfig extends BasePluginConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/plugins/genie/types.ts"],"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/plugins/genie/types.ts"],"mappings":";;;;;;;UAUiB,YAAA,SAAqB,gBAAA;;EAEpC,MAAA,GAAS,MAAA;;EAET,OAAA;AAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../shared/src/genie.js";
|
|
2
|
+
import { IAnalyticsConfig } from "./analytics/types.js";
|
|
3
|
+
import { AnalyticsPlugin, analytics } from "./analytics/analytics.js";
|
|
4
|
+
import "./analytics/index.js";
|
|
5
|
+
import { GenieConversationHistoryResponse } from "../connectors/genie/types.js";
|
|
6
|
+
import { IGenieConfig } from "./genie/types.js";
|
|
7
|
+
import { GeniePlugin, genie } from "./genie/genie.js";
|
|
8
|
+
import "./genie/index.js";
|
|
9
|
+
import { ILakebaseConfig } from "./lakebase/types.js";
|
|
10
|
+
import { LakebasePlugin, lakebase } from "./lakebase/lakebase.js";
|
|
11
|
+
import "./lakebase/index.js";
|
|
12
|
+
import { ServerConfig } from "./server/types.js";
|
|
13
|
+
import { ServerPlugin, server } from "./server/index.js";
|
package/dist/plugins/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { analyticsManifest } from "./analytics/manifest.js";
|
|
2
1
|
import { AnalyticsPlugin, analytics } from "./analytics/analytics.js";
|
|
3
2
|
import "./analytics/index.js";
|
|
4
|
-
import { genieManifest } from "./genie/manifest.js";
|
|
5
3
|
import { GeniePlugin, genie } from "./genie/genie.js";
|
|
6
4
|
import "./genie/index.js";
|
|
7
|
-
import { lakebaseManifest } from "./lakebase/manifest.js";
|
|
8
5
|
import { LakebasePlugin, lakebase } from "./lakebase/lakebase.js";
|
|
9
6
|
import "./lakebase/index.js";
|
|
10
|
-
import { serverManifest } from "./server/manifest.js";
|
|
11
7
|
import { ServerPlugin, server } from "./server/index.js";
|
|
12
8
|
|
|
13
9
|
export { };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { ToPlugin } from "../../shared/src/plugin.js";
|
|
2
|
+
import "../../shared/src/index.js";
|
|
2
3
|
import { Plugin } from "../../plugin/plugin.js";
|
|
4
|
+
import "../../plugin/index.js";
|
|
3
5
|
import { PluginManifest } from "../../registry/types.js";
|
|
6
|
+
import "../../registry/index.js";
|
|
4
7
|
import { ILakebaseConfig } from "./types.js";
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
7
|
-
import * as
|
|
8
|
+
import * as pg from "pg";
|
|
9
|
+
import { Pool, QueryResult, QueryResultRow } from "pg";
|
|
10
|
+
import * as stream from "stream";
|
|
8
11
|
|
|
9
12
|
//#region src/plugins/lakebase/lakebase.d.ts
|
|
10
|
-
|
|
11
13
|
/**
|
|
12
14
|
* AppKit plugin for Databricks Lakebase Autoscaling.
|
|
13
15
|
*
|
|
@@ -55,7 +57,7 @@ declare class LakebasePlugin extends Plugin {
|
|
|
55
57
|
* );
|
|
56
58
|
* ```
|
|
57
59
|
*/
|
|
58
|
-
query<T extends
|
|
60
|
+
query<T extends QueryResultRow = any>(text: string, values?: unknown[]): Promise<QueryResult<T>>;
|
|
59
61
|
/**
|
|
60
62
|
* Gracefully drains and closes the connection pool.
|
|
61
63
|
* Called automatically by AppKit during shutdown.
|
|
@@ -70,8 +72,8 @@ declare class LakebasePlugin extends Plugin {
|
|
|
70
72
|
* - `getPgConfig()` — Returns a `pg.PoolConfig` object for manual pool construction
|
|
71
73
|
*/
|
|
72
74
|
exports(): {
|
|
73
|
-
pool:
|
|
74
|
-
query: <T extends
|
|
75
|
+
pool: Pool;
|
|
76
|
+
query: <T extends QueryResultRow = any>(text: string, values?: unknown[]) => Promise<QueryResult<T>>;
|
|
75
77
|
getOrmConfig: () => {
|
|
76
78
|
username: string | undefined;
|
|
77
79
|
password: string | (() => string) | (() => Promise<string>) | undefined;
|
|
@@ -86,13 +88,13 @@ declare class LakebasePlugin extends Plugin {
|
|
|
86
88
|
allowExitOnIdle?: boolean | undefined;
|
|
87
89
|
maxUses?: number | undefined;
|
|
88
90
|
maxLifetimeSeconds?: number | undefined;
|
|
89
|
-
Client?: (new () =>
|
|
91
|
+
Client?: (new () => pg.ClientBase) | undefined;
|
|
90
92
|
database?: string | undefined;
|
|
91
93
|
port?: number | undefined;
|
|
92
94
|
host?: string | undefined;
|
|
93
95
|
connectionString?: string | undefined;
|
|
94
96
|
keepAlive?: boolean | undefined;
|
|
95
|
-
stream?: () =>
|
|
97
|
+
stream?: () => stream.Duplex | undefined;
|
|
96
98
|
statement_timeout?: false | number | undefined;
|
|
97
99
|
query_timeout?: number | undefined;
|
|
98
100
|
lock_timeout?: number | undefined;
|
|
@@ -101,11 +103,11 @@ declare class LakebasePlugin extends Plugin {
|
|
|
101
103
|
application_name?: string | undefined;
|
|
102
104
|
fallback_application_name?: string | undefined;
|
|
103
105
|
connectionTimeoutMillis?: number | undefined;
|
|
104
|
-
types?:
|
|
106
|
+
types?: pg.CustomTypesConfig | undefined;
|
|
105
107
|
options?: string | undefined;
|
|
106
108
|
client_encoding?: string | undefined;
|
|
107
109
|
};
|
|
108
|
-
getPgConfig: () =>
|
|
110
|
+
getPgConfig: () => pg.PoolConfig;
|
|
109
111
|
};
|
|
110
112
|
}
|
|
111
113
|
/**
|
|
@@ -113,5 +115,5 @@ declare class LakebasePlugin extends Plugin {
|
|
|
113
115
|
*/
|
|
114
116
|
declare const lakebase: ToPlugin<typeof LakebasePlugin, ILakebaseConfig, "lakebase">;
|
|
115
117
|
//#endregion
|
|
116
|
-
export { lakebase };
|
|
118
|
+
export { LakebasePlugin, lakebase };
|
|
117
119
|
//# sourceMappingURL=lakebase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lakebase.d.ts","names":[],"sources":["../../../src/plugins/lakebase/lakebase.ts"],"
|
|
1
|
+
{"version":3,"file":"lakebase.d.ts","names":[],"sources":["../../../src/plugins/lakebase/lakebase.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA;;;;;;;;;cAAa,cAAA,SAAuB,MAAA;EAClC,IAAA;;SAGO,QAAA,EAAuB,cAAA;EAAA,UAEZ,MAAA,EAAQ,eAAA;EAAA,QAClB,IAAA;cAEI,MAAA,EAAQ,eAAA;;;;;;;;EAYd,KAAA,CAAA,GAAK,OAAA;EArB6B;;;;;;;;;;;;;;;EA2ClC,KAAA,WAAgB,cAAA,OAAA,CACpB,IAAA,UACA,MAAA,eACC,OAAA,CAAQ,WAAA,CAAY,CAAA;EAFrB;;;;EAWF,qBAAA,CAAA;EAAA;;;;;;;;EAmBA,OAAA,CAAA;;sBA/BsB,cAAA,QAAc,IAAA,UACtB,MAAA,iBAEX,OAAA,CAAQ,WAAA,CAAY,CAAA;;;;;;;;;;iBAtBY,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgExB,QAAA,EAAQ,QAAA,QAAA,cAAA,EAAA,eAAA"}
|
|
@@ -3,7 +3,7 @@ import { createLakebasePool, getLakebaseOrmConfig, getLakebasePgConfig, getUsern
|
|
|
3
3
|
import { Plugin } from "../../plugin/plugin.js";
|
|
4
4
|
import { toPlugin } from "../../plugin/to-plugin.js";
|
|
5
5
|
import "../../plugin/index.js";
|
|
6
|
-
import
|
|
6
|
+
import manifest_default from "./manifest.js";
|
|
7
7
|
|
|
8
8
|
//#region src/plugins/lakebase/lakebase.ts
|
|
9
9
|
const logger = createLogger("lakebase");
|
|
@@ -27,7 +27,7 @@ const logger = createLogger("lakebase");
|
|
|
27
27
|
var LakebasePlugin = class extends Plugin {
|
|
28
28
|
name = "lakebase";
|
|
29
29
|
/** Plugin manifest declaring metadata and resource requirements */
|
|
30
|
-
static manifest =
|
|
30
|
+
static manifest = manifest_default;
|
|
31
31
|
pool = null;
|
|
32
32
|
constructor(config) {
|
|
33
33
|
super(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lakebase.js","names":[],"sources":["../../../src/plugins/lakebase/lakebase.ts"],"sourcesContent":["import type
|
|
1
|
+
{"version":3,"file":"lakebase.js","names":["manifest"],"sources":["../../../src/plugins/lakebase/lakebase.ts"],"sourcesContent":["import type { Pool, QueryResult, QueryResultRow } from \"pg\";\nimport {\n createLakebasePool,\n getLakebaseOrmConfig,\n getLakebasePgConfig,\n getUsernameWithApiLookup,\n} from \"../../connectors/lakebase\";\nimport { createLogger } from \"../../logging/logger\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport type { PluginManifest } from \"../../registry\";\nimport manifest from \"./manifest.json\";\nimport type { ILakebaseConfig } from \"./types\";\n\nconst logger = createLogger(\"lakebase\");\n\n/**\n * AppKit plugin for Databricks Lakebase Autoscaling.\n *\n * Wraps `@databricks/lakebase` to provide a standard `pg.Pool` with automatic\n * OAuth token refresh, integrated with AppKit's logger and OpenTelemetry setup.\n *\n * @example\n * ```ts\n * import { createApp, lakebase, server } from \"@databricks/appkit\";\n *\n * const AppKit = await createApp({\n * plugins: [server(), lakebase()],\n * });\n *\n * const result = await AppKit.lakebase.query(\"SELECT * FROM users WHERE id = $1\", [userId]);\n * ```\n */\nexport class LakebasePlugin extends Plugin {\n name = \"lakebase\";\n\n /** Plugin manifest declaring metadata and resource requirements */\n static manifest = manifest as PluginManifest;\n\n protected declare config: ILakebaseConfig;\n private pool: Pool | null = null;\n\n constructor(config: ILakebaseConfig) {\n super(config);\n this.config = config;\n }\n\n /**\n * Initializes the Lakebase connection pool.\n * Called automatically by AppKit during the plugin setup phase.\n *\n * Resolves the PostgreSQL username via {@link getUsernameWithApiLookup},\n * which tries config, env vars, and finally the Databricks workspace API.\n */\n async setup() {\n const poolConfig = this.config.pool;\n const user = await getUsernameWithApiLookup(poolConfig);\n this.pool = createLakebasePool({ ...poolConfig, user });\n logger.info(\"Lakebase pool initialized\");\n }\n\n /**\n * Executes a parameterized SQL query against the Lakebase pool.\n *\n * @param text - SQL query string, using `$1`, `$2`, ... placeholders\n * @param values - Parameter values corresponding to placeholders\n * @returns Query result with typed rows\n *\n * @example\n * ```ts\n * const result = await AppKit.lakebase.query<{ id: number; name: string }>(\n * \"SELECT id, name FROM users WHERE active = $1\",\n * [true],\n * );\n * ```\n */\n async query<T extends QueryResultRow = any>(\n text: string,\n values?: unknown[],\n ): Promise<QueryResult<T>> {\n // biome-ignore lint/style/noNonNullAssertion: pool is guaranteed non-null after setup(), which AppKit always awaits before exposing the plugin API\n return this.pool!.query<T>(text, values);\n }\n\n /**\n * Gracefully drains and closes the connection pool.\n * Called automatically by AppKit during shutdown.\n */\n abortActiveOperations(): void {\n super.abortActiveOperations();\n if (this.pool) {\n logger.info(\"Closing Lakebase pool\");\n this.pool.end().catch((err) => {\n logger.error(\"Error closing Lakebase pool: %O\", err);\n });\n this.pool = null;\n }\n }\n\n /**\n * Returns the plugin's public API, accessible via `AppKit.lakebase`.\n *\n * - `pool` — The raw `pg.Pool` instance, for use with ORMs or advanced scenarios\n * - `query` — Convenience method for executing parameterized SQL queries\n * - `getOrmConfig()` — Returns a config object compatible with Drizzle, TypeORM, Sequelize, etc.\n * - `getPgConfig()` — Returns a `pg.PoolConfig` object for manual pool construction\n */\n exports() {\n return {\n // biome-ignore lint/style/noNonNullAssertion: pool is guaranteed non-null after setup(), which AppKit always awaits before exposing the plugin API\n pool: this.pool!,\n query: this.query.bind(this),\n getOrmConfig: () => getLakebaseOrmConfig(this.config.pool),\n getPgConfig: () => getLakebasePgConfig(this.config.pool),\n };\n }\n}\n\n/**\n * @internal\n */\nexport const lakebase = toPlugin<\n typeof LakebasePlugin,\n ILakebaseConfig,\n \"lakebase\"\n>(LakebasePlugin, \"lakebase\");\n"],"mappings":";;;;;;;;AAaA,MAAM,SAAS,aAAa,WAAW;;;;;;;;;;;;;;;;;;AAmBvC,IAAa,iBAAb,cAAoC,OAAO;CACzC,OAAO;;CAGP,OAAO,WAAWA;CAGlB,AAAQ,OAAoB;CAE5B,YAAY,QAAyB;AACnC,QAAM,OAAO;AACb,OAAK,SAAS;;;;;;;;;CAUhB,MAAM,QAAQ;EACZ,MAAM,aAAa,KAAK,OAAO;EAC/B,MAAM,OAAO,MAAM,yBAAyB,WAAW;AACvD,OAAK,OAAO,mBAAmB;GAAE,GAAG;GAAY;GAAM,CAAC;AACvD,SAAO,KAAK,4BAA4B;;;;;;;;;;;;;;;;;CAkB1C,MAAM,MACJ,MACA,QACyB;AAEzB,SAAO,KAAK,KAAM,MAAS,MAAM,OAAO;;;;;;CAO1C,wBAA8B;AAC5B,QAAM,uBAAuB;AAC7B,MAAI,KAAK,MAAM;AACb,UAAO,KAAK,wBAAwB;AACpC,QAAK,KAAK,KAAK,CAAC,OAAO,QAAQ;AAC7B,WAAO,MAAM,mCAAmC,IAAI;KACpD;AACF,QAAK,OAAO;;;;;;;;;;;CAYhB,UAAU;AACR,SAAO;GAEL,MAAM,KAAK;GACX,OAAO,KAAK,MAAM,KAAK,KAAK;GAC5B,oBAAoB,qBAAqB,KAAK,OAAO,KAAK;GAC1D,mBAAmB,oBAAoB,KAAK,OAAO,KAAK;GACzD;;;;;;AAOL,MAAa,WAAW,SAItB,gBAAgB,WAAW"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
//#region src/plugins/lakebase/manifest.json
|
|
2
|
+
var manifest_default = {
|
|
3
|
+
$schema: "https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json",
|
|
4
|
+
name: "lakebase",
|
|
5
|
+
displayName: "Lakebase",
|
|
6
|
+
description: "SQL query execution against Databricks Lakebase Autoscaling",
|
|
7
|
+
onSetupMessage: "Configure environment variables before running or deploying the app.\nSee: https://databricks.github.io/appkit/docs/plugins/lakebase",
|
|
8
|
+
hidden: false,
|
|
9
|
+
resources: {
|
|
10
|
+
"required": [],
|
|
11
|
+
"optional": []
|
|
12
|
+
}
|
|
13
|
+
};
|
|
8
14
|
|
|
9
15
|
//#endregion
|
|
10
|
-
export {
|
|
16
|
+
export { manifest_default as default };
|
|
11
17
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/lakebase/manifest.
|
|
1
|
+
{"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/lakebase/manifest.json"],"sourcesContent":[""],"mappings":""}
|