@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.
Files changed (165) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +2 -0
  2. package/dist/app/index.d.ts.map +1 -1
  3. package/dist/appkit/package.js +1 -1
  4. package/dist/cache/index.d.ts +1 -1
  5. package/dist/cache/index.d.ts.map +1 -1
  6. package/dist/cli/commands/plugin/add-resource/add-resource.js +10 -4
  7. package/dist/cli/commands/plugin/add-resource/add-resource.js.map +1 -1
  8. package/dist/cli/commands/plugin/create/scaffold.js +10 -16
  9. package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
  10. package/dist/cli/commands/plugin/list/list.js +44 -26
  11. package/dist/cli/commands/plugin/list/list.js.map +1 -1
  12. package/dist/cli/commands/plugin/manifest-resolve.js +57 -0
  13. package/dist/cli/commands/plugin/manifest-resolve.js.map +1 -0
  14. package/dist/cli/commands/plugin/sync/sync.js +121 -71
  15. package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
  16. package/dist/cli/commands/plugin/trusted-js-manifest.js +28 -0
  17. package/dist/cli/commands/plugin/trusted-js-manifest.js.map +1 -0
  18. package/dist/cli/commands/plugin/validate/validate.js +32 -14
  19. package/dist/cli/commands/plugin/validate/validate.js.map +1 -1
  20. package/dist/connectors/genie/client.d.ts +4 -0
  21. package/dist/connectors/genie/client.js +33 -16
  22. package/dist/connectors/genie/client.js.map +1 -1
  23. package/dist/connectors/genie/defaults.js +2 -1
  24. package/dist/connectors/genie/defaults.js.map +1 -1
  25. package/dist/connectors/genie/index.d.ts +3 -0
  26. package/dist/connectors/genie/types.d.ts +1 -0
  27. package/dist/connectors/genie/types.d.ts.map +1 -1
  28. package/dist/connectors/lakebase/index.d.ts +2 -3
  29. package/dist/connectors/lakebase/index.d.ts.map +1 -1
  30. package/dist/connectors/lakebase/index.js.map +1 -1
  31. package/dist/connectors/lakebase-v1/client.js +1 -1
  32. package/dist/context/execution-context.d.ts +0 -1
  33. package/dist/context/execution-context.d.ts.map +1 -1
  34. package/dist/context/index.d.ts +3 -0
  35. package/dist/context/service-context.d.ts +1 -1
  36. package/dist/context/service-context.d.ts.map +1 -1
  37. package/dist/context/user-context.d.ts +1 -2
  38. package/dist/context/user-context.d.ts.map +1 -1
  39. package/dist/core/appkit.d.ts +2 -1
  40. package/dist/core/appkit.d.ts.map +1 -1
  41. package/dist/core/index.d.ts +1 -0
  42. package/dist/errors/authentication.d.ts +0 -1
  43. package/dist/errors/authentication.d.ts.map +1 -1
  44. package/dist/errors/base.d.ts.map +1 -1
  45. package/dist/errors/configuration.d.ts +0 -1
  46. package/dist/errors/configuration.d.ts.map +1 -1
  47. package/dist/errors/connection.d.ts +0 -1
  48. package/dist/errors/connection.d.ts.map +1 -1
  49. package/dist/errors/execution.d.ts +0 -1
  50. package/dist/errors/execution.d.ts.map +1 -1
  51. package/dist/errors/initialization.d.ts +0 -1
  52. package/dist/errors/initialization.d.ts.map +1 -1
  53. package/dist/errors/server.d.ts +0 -1
  54. package/dist/errors/server.d.ts.map +1 -1
  55. package/dist/errors/tunnel.d.ts +0 -1
  56. package/dist/errors/tunnel.d.ts.map +1 -1
  57. package/dist/errors/validation.d.ts +0 -1
  58. package/dist/errors/validation.d.ts.map +1 -1
  59. package/dist/index.d.ts +7 -1
  60. package/dist/plugin/dev-reader.d.ts +5 -4
  61. package/dist/plugin/dev-reader.d.ts.map +1 -1
  62. package/dist/plugin/index.d.ts +4 -0
  63. package/dist/plugin/plugin.d.ts +3 -1
  64. package/dist/plugin/plugin.d.ts.map +1 -1
  65. package/dist/plugin/to-plugin.d.ts +1 -1
  66. package/dist/plugin/to-plugin.d.ts.map +1 -1
  67. package/dist/plugins/analytics/analytics.d.ts +5 -2
  68. package/dist/plugins/analytics/analytics.d.ts.map +1 -1
  69. package/dist/plugins/analytics/analytics.js +2 -2
  70. package/dist/plugins/analytics/analytics.js.map +1 -1
  71. package/dist/plugins/analytics/index.d.ts +2 -0
  72. package/dist/plugins/analytics/index.js +0 -1
  73. package/dist/plugins/analytics/manifest.js +30 -18
  74. package/dist/plugins/analytics/manifest.js.map +1 -1
  75. package/dist/plugins/analytics/types.d.ts +1 -0
  76. package/dist/plugins/analytics/types.d.ts.map +1 -1
  77. package/dist/plugins/genie/genie.d.ts +4 -1
  78. package/dist/plugins/genie/genie.d.ts.map +1 -1
  79. package/dist/plugins/genie/genie.js +10 -6
  80. package/dist/plugins/genie/genie.js.map +1 -1
  81. package/dist/plugins/genie/index.d.ts +4 -0
  82. package/dist/plugins/genie/index.js +0 -1
  83. package/dist/plugins/genie/manifest.js +37 -8
  84. package/dist/plugins/genie/manifest.js.map +1 -1
  85. package/dist/plugins/genie/types.d.ts +2 -0
  86. package/dist/plugins/genie/types.d.ts.map +1 -1
  87. package/dist/plugins/index.d.ts +13 -0
  88. package/dist/plugins/index.js +0 -4
  89. package/dist/plugins/lakebase/index.d.ts +2 -0
  90. package/dist/plugins/lakebase/index.js +0 -1
  91. package/dist/plugins/lakebase/lakebase.d.ts +14 -12
  92. package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
  93. package/dist/plugins/lakebase/lakebase.js +2 -2
  94. package/dist/plugins/lakebase/lakebase.js.map +1 -1
  95. package/dist/plugins/lakebase/manifest.js +14 -8
  96. package/dist/plugins/lakebase/manifest.js.map +1 -1
  97. package/dist/plugins/lakebase/types.d.ts +1 -1
  98. package/dist/plugins/lakebase/types.d.ts.map +1 -1
  99. package/dist/plugins/server/index.d.ts +7 -9
  100. package/dist/plugins/server/index.d.ts.map +1 -1
  101. package/dist/plugins/server/index.js +2 -2
  102. package/dist/plugins/server/index.js.map +1 -1
  103. package/dist/plugins/server/manifest.js +36 -18
  104. package/dist/plugins/server/manifest.js.map +1 -1
  105. package/dist/plugins/server/types.d.ts +2 -0
  106. package/dist/plugins/server/types.d.ts.map +1 -1
  107. package/dist/registry/index.d.ts +4 -0
  108. package/dist/registry/manifest-loader.d.ts +1 -1
  109. package/dist/registry/manifest-loader.d.ts.map +1 -1
  110. package/dist/registry/resource-registry.d.ts +1 -1
  111. package/dist/registry/resource-registry.d.ts.map +1 -1
  112. package/dist/registry/types.d.ts +1 -4
  113. package/dist/registry/types.d.ts.map +1 -1
  114. package/dist/registry/types.generated.d.ts +1 -1
  115. package/dist/registry/types.generated.d.ts.map +1 -1
  116. package/dist/registry/types.generated.js.map +1 -1
  117. package/dist/shared/src/cache.d.ts +1 -1
  118. package/dist/shared/src/cache.d.ts.map +1 -1
  119. package/dist/shared/src/execute.d.ts +1 -1
  120. package/dist/shared/src/execute.d.ts.map +1 -1
  121. package/dist/shared/src/genie.d.ts +6 -0
  122. package/dist/shared/src/genie.d.ts.map +1 -1
  123. package/dist/shared/src/index.d.ts +7 -0
  124. package/dist/shared/src/plugin.d.ts +2 -3
  125. package/dist/shared/src/plugin.d.ts.map +1 -1
  126. package/dist/shared/src/sql/helpers.d.ts +0 -1
  127. package/dist/shared/src/sql/helpers.d.ts.map +1 -1
  128. package/dist/shared/src/sql/types.d.ts.map +1 -1
  129. package/dist/shared/src/tunnel.d.ts +1 -1
  130. package/dist/shared/src/tunnel.d.ts.map +1 -1
  131. package/dist/stream/arrow-stream-processor.d.ts +1 -0
  132. package/dist/stream/buffers.d.ts +1 -0
  133. package/dist/stream/index.d.ts +3 -0
  134. package/dist/stream/stream-manager.d.ts +1 -0
  135. package/dist/stream/stream-manager.d.ts.map +1 -1
  136. package/dist/stream/types.d.ts +3 -0
  137. package/dist/telemetry/config.d.ts +1 -0
  138. package/dist/telemetry/index.d.ts +4 -0
  139. package/dist/telemetry/instrumentations.d.ts +1 -0
  140. package/dist/telemetry/telemetry-manager.d.ts +4 -0
  141. package/dist/telemetry/telemetry-provider.d.ts +6 -0
  142. package/dist/telemetry/types.d.ts.map +1 -1
  143. package/dist/type-generator/cache.js +10 -12
  144. package/dist/type-generator/cache.js.map +1 -1
  145. package/dist/type-generator/index.js +2 -2
  146. package/dist/type-generator/index.js.map +1 -1
  147. package/dist/type-generator/query-registry.js +165 -52
  148. package/dist/type-generator/query-registry.js.map +1 -1
  149. package/dist/type-generator/spinner.js +5 -1
  150. package/dist/type-generator/spinner.js.map +1 -1
  151. package/dist/type-generator/vite-plugin.d.ts +0 -1
  152. package/dist/type-generator/vite-plugin.d.ts.map +1 -1
  153. package/dist/type-generator/vite-plugin.js +2 -2
  154. package/dist/type-generator/vite-plugin.js.map +1 -1
  155. package/docs/api/appkit-ui/genie/GenieChatMessageList.md +7 -5
  156. package/docs/development/project-setup.md +1 -1
  157. package/docs/plugins/plugin-management.md +16 -2
  158. package/package.json +3 -1
  159. package/dist/plugins/analytics/manifest.json +0 -36
  160. package/dist/plugins/genie/manifest.json +0 -43
  161. package/dist/plugins/lakebase/manifest.json +0 -12
  162. package/dist/plugins/server/manifest.json +0 -36
  163. /package/dist/plugins/server/remote-tunnel/{denied.html → denied.html/denied.html} +0 -0
  164. /package/dist/plugins/server/remote-tunnel/{index.html → index.html/index.html} +0 -0
  165. /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 { IAnalyticsConfig } from "./types.js";
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"],"sourcesContent":[],"mappings":";;;;;;;;;cA2Ba,eAAA,SAAwB,MAAA;;;mBAAR;EAAhB,iBAAA,WAAgB,EAAA,MAAA;EAAA,UAAA,MAAA,EAOD,gBAPC;UAAA,SAAA;UAOD,cAAA;aAMN,CAAA,MAAA,EAAA,gBAAA;cAWC,CAAA,MAAA,EAAA,UAAA,CAAA,EAAA,IAAA;;;;;mBAoEN,CAAA,GAAA,EA1CR,OAAA,CAAQ,OA0CA,EAAA,GAAA,EAzCR,OAAA,CAAQ,QAyCA,CAAA,EAxCZ,OAwCY,CAAA,IAAA,CAAA;;;;;mBAkHJ,CAAA,GAAA,EAnHJ,OAAA,CAAQ,OAmHJ,EAAA,GAAA,EAlHJ,OAAA,CAAQ,QAkHJ,CAAA,EAjHR,OAiHQ,CAAA,IAAA,CAAA;;;;;;;;;;;;;;AAsDb;;OAAsB,CAAA,KAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAxDL,MAwDK,CAAA,MAAA,EAxDU,aAwDV,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA,gBAAA,CAAA,EAvDC,MAuDD,CAAA,MAAA,EAAA,GAAA,CAAA,EAAA,MAAA,CAAA,EAtDT,WAsDS,CAAA,EArDjB,OAqDiB,CAAA,GAAA,CAAA;;;;0CA5BD,yCAER,cACR,QAAQ;cAIO;;;;;;;;;wCAnCH,eAAe,sDACT,8BACV,gBACR;;;;;;cAqDQ,WAAS,gBAAA,iBAAA"}
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 { analyticsManifest } from "./manifest.js";
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 = analyticsManifest;
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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"}
@@ -0,0 +1,2 @@
1
+ import { IAnalyticsConfig } from "./types.js";
2
+ import { AnalyticsPlugin, analytics } from "./analytics.js";
@@ -1,4 +1,3 @@
1
- import { analyticsManifest } from "./manifest.js";
2
1
  import { AnalyticsPlugin, analytics } from "./analytics.js";
3
2
 
4
3
  export { };
@@ -1,21 +1,33 @@
1
- import { dirname, join } from "node:path";
2
- import { readFileSync } from "node:fs";
3
- import { fileURLToPath } from "node:url";
4
-
5
- //#region src/plugins/analytics/manifest.ts
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- /**
8
- * Analytics plugin manifest.
9
- *
10
- * The analytics plugin requires a SQL Warehouse for executing queries
11
- * against Databricks data sources.
12
- *
13
- * @remarks
14
- * The source of truth for this manifest is `manifest.json` in the same directory.
15
- * This file loads the JSON and exports it with proper TypeScript typing.
16
- */
17
- const analyticsManifest = JSON.parse(readFileSync(join(__dirname, "manifest.json"), "utf-8"));
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 { analyticsManifest };
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.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { PluginManifest } from \"../../registry\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Analytics plugin manifest.\n *\n * The analytics plugin requires a SQL Warehouse for executing queries\n * against Databricks data sources.\n *\n * @remarks\n * The source of truth for this manifest is `manifest.json` in the same directory.\n * This file loads the JSON and exports it with proper TypeScript typing.\n */\nexport const analyticsManifest: PluginManifest = JSON.parse(\n readFileSync(join(__dirname, \"manifest.json\"), \"utf-8\"),\n) as PluginManifest;\n"],"mappings":";;;;;AAKA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;;;;;;;;;;;AAYzD,MAAa,oBAAoC,KAAK,MACpD,aAAa,KAAK,WAAW,gBAAgB,EAAE,QAAQ,CACxD"}
1
+ {"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/analytics/manifest.json"],"sourcesContent":[""],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import { BasePluginConfig } from "../../shared/src/plugin.js";
2
+ import "../../shared/src/index.js";
2
3
 
3
4
  //#region src/plugins/analytics/types.d.ts
4
5
  interface IAnalyticsConfig extends BasePluginConfig {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/plugins/analytics/types.ts"],"sourcesContent":[],"mappings":";;;UAEiB,gBAAA,SAAyB;;AAA1C"}
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"],"sourcesContent":[],"mappings":";;;;;;;;;cAkBa,WAAA,SAAoB,MAAA;;mBAAR;;oBAOG;EAPf,iBAAY,cAAA;EAAA,WAAA,CAAA,MAAA,EAWH,YAXG;UAAA,aAAA;UAOG,cAAA;cAIN,CAAA,MAAA,EAqBC,UArBD,CAAA,EAAA,IAAA;oBAqBC,CAAA,GAAA,EAqBd,OAAA,CAAQ,OArBM,EAAA,GAAA,EAsBd,OAAA,CAAQ,QAtBM,CAAA,EAuBlB,OAvBkB,CAAA,IAAA,CAAA;wBAqBN,CAAA,GAAA,EAyDR,OAAA,CAAQ,OAzDA,EAAA,GAAA,EA0DR,OAAA,CAAQ,QA1DA,CAAA,EA2DZ,OA3DY,CAAA,IAAA,CAAA;iBACA,CAAA,KAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,CAAA,EAwGZ,OAxGY,CAwGJ,gCAxGI,CAAA;;;;;aAwGJ,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,MAAA,EAAA,QAAA,EAAA;IAAR,OAAA,CAAA,EAAA,MAAA;MAyBA,cAAe,CAAA,gBAAA,CAAA;UAAf,CAAA,CAAA,EAgBe,OAhBf,CAAA,IAAA,CAAA;SAgBe,CAAA,CAAA,EAAA;IAhBA,WAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,MAAA,EAAA,OAzBP,CAyBO,EAAA;MAAf,OAAA,CAAA,EAAA,MAAA;IAzBQ,CAAA,EAAA,GAyBR,cAzBQ,CAyBO,gBAzBP,CAAA;IAAR,eAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,EAAA,GAAA,OAAA,CAAQ,gCAAR,CAAA;;;AAwDL;;;AAAkB,cAAL,KAAK,EAAA,QAAA,CAAA,OAAA,WAAA,EAAA,YAAA,EAAA,OAAA,CAAA"}
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 { genieManifest } from "./manifest.js";
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 = genieManifest;
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 requestId = req.query.requestId || randomUUID();
96
- logger.debug("Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s)", conversationId, spaceId, alias, includeQueryResults);
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, { includeQueryResults }), streamSettings);
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 { genieStreamDefaults } from \"./defaults\";\nimport { genieManifest } from \"./manifest\";\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 = genieManifest;\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 = (req.query.requestId as string) || 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 requestId = (req.query.requestId as string) || randomUUID();\n\n logger.debug(\n \"Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s)\",\n conversationId,\n spaceId,\n alias,\n includeQueryResults,\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 },\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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"}
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,4 +1,3 @@
1
- import { genieManifest } from "./manifest.js";
2
1
  import { GeniePlugin, genie } from "./genie.js";
3
2
 
4
3
  export { };
@@ -1,11 +1,40 @@
1
- import { dirname, join } from "node:path";
2
- import { readFileSync } from "node:fs";
3
- import { fileURLToPath } from "node:url";
4
-
5
- //#region src/plugins/genie/manifest.ts
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- const genieManifest = JSON.parse(readFileSync(join(__dirname, "manifest.json"), "utf-8"));
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 { genieManifest };
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.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { PluginManifest } from \"../../registry\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const genieManifest: PluginManifest = JSON.parse(\n readFileSync(join(__dirname, \"manifest.json\"), \"utf-8\"),\n) as PluginManifest;\n"],"mappings":";;;;;AAKA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEzD,MAAa,gBAAgC,KAAK,MAChD,aAAa,KAAK,WAAW,gBAAgB,EAAE,QAAQ,CACxD"}
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"],"sourcesContent":[],"mappings":";;;;;UAUiB,YAAA,SAAqB;;EAArB,MAAA,CAAA,EAEN,MAFmB,CAAA,MAAA,EAAA,MAAA,CAAA;EAAA;SAEnB,CAAA,EAAA,MAAA"}
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";
@@ -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 { };
@@ -0,0 +1,2 @@
1
+ import { ILakebaseConfig } from "./types.js";
2
+ import { LakebasePlugin, lakebase } from "./lakebase.js";
@@ -1,4 +1,3 @@
1
- import { lakebaseManifest } from "./manifest.js";
2
1
  import { LakebasePlugin, lakebase } from "./lakebase.js";
3
2
 
4
3
  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 pg0 from "pg";
6
- import pg from "pg";
7
- import * as stream0 from "stream";
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 pg.QueryResultRow = any>(text: string, values?: unknown[]): Promise<pg.QueryResult<T>>;
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: pg0.Pool;
74
- query: <T extends pg.QueryResultRow = any>(text: string, values?: unknown[]) => Promise<pg.QueryResult<T>>;
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 () => pg0.ClientBase) | undefined;
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?: () => stream0.Duplex | undefined;
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?: pg0.CustomTypesConfig | undefined;
106
+ types?: pg.CustomTypesConfig | undefined;
105
107
  options?: string | undefined;
106
108
  client_encoding?: string | undefined;
107
109
  };
108
- getPgConfig: () => pg0.PoolConfig;
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"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AA+BA;;;;;;;;;;;AA2CwB,cA3CX,cAAA,SAAuB,MAAA,CA2CT;MAGC,EAAA,MAAA;;SAAvB,QAAA,EA9CuB,cA8CvB;oBAxCuB;;sBAGN;;;;;;AA+EtB;;OAAqB,CAAA,CAAA,EAnER,OAmEQ,CAAA,IAAA,CAAA;;;;;;;;;;;;;;;;kBA7CG,EAAA,CAAG,yDAGtB,QAAQ,EAAA,CAAG,YAAY;;;;;;;;;;;;;;;UAAhB,GAAA,CAAA;sBAHY,EAAA,CAAG,2DAGtB,QAAQ,EAAA,CAAG,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0Cf,UAAQ,gBAAA,gBAAA"}
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 { lakebaseManifest } from "./manifest.js";
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 = lakebaseManifest;
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 pg 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 { lakebaseManifest } from \"./manifest\";\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 = lakebaseManifest;\n\n protected declare config: ILakebaseConfig;\n private pool: pg.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 pg.QueryResultRow = any>(\n text: string,\n values?: unknown[],\n ): Promise<pg.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":";;;;;;;;AAYA,MAAM,SAAS,aAAa,WAAW;;;;;;;;;;;;;;;;;;AAmBvC,IAAa,iBAAb,cAAoC,OAAO;CACzC,OAAO;;CAGP,OAAO,WAAW;CAGlB,AAAQ,OAAuB;CAE/B,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,QAC4B;AAE5B,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
+ {"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
- import { dirname, join } from "node:path";
2
- import { readFileSync } from "node:fs";
3
- import { fileURLToPath } from "node:url";
4
-
5
- //#region src/plugins/lakebase/manifest.ts
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- const lakebaseManifest = JSON.parse(readFileSync(join(__dirname, "manifest.json"), "utf-8"));
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 { lakebaseManifest };
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.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { PluginManifest } from \"../../registry\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const lakebaseManifest: PluginManifest = JSON.parse(\n readFileSync(join(__dirname, \"manifest.json\"), \"utf-8\"),\n) as PluginManifest;\n"],"mappings":";;;;;AAKA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEzD,MAAa,mBAAmC,KAAK,MACnD,aAAa,KAAK,WAAW,gBAAgB,EAAE,QAAQ,CACxD"}
1
+ {"version":3,"file":"manifest.js","names":[],"sources":["../../../src/plugins/lakebase/manifest.json"],"sourcesContent":[""],"mappings":""}