@databricks/appkit 0.8.0 → 0.9.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 (180) hide show
  1. package/CLAUDE.md +2 -1
  2. package/NOTICE.md +1 -0
  3. package/dist/appkit/package.js +1 -1
  4. package/dist/cli/commands/plugin/add-resource/add-resource.js +61 -0
  5. package/dist/cli/commands/plugin/add-resource/add-resource.js.map +1 -0
  6. package/dist/cli/commands/plugin/create/create.js +162 -0
  7. package/dist/cli/commands/plugin/create/create.js.map +1 -0
  8. package/dist/cli/commands/plugin/create/prompt-resource.js +95 -0
  9. package/dist/cli/commands/plugin/create/prompt-resource.js.map +1 -0
  10. package/dist/cli/commands/plugin/create/resource-defaults.js +105 -0
  11. package/dist/cli/commands/plugin/create/resource-defaults.js.map +1 -0
  12. package/dist/cli/commands/plugin/create/scaffold.js +195 -0
  13. package/dist/cli/commands/plugin/create/scaffold.js.map +1 -0
  14. package/dist/cli/commands/plugin/index.js +22 -0
  15. package/dist/cli/commands/plugin/index.js.map +1 -0
  16. package/dist/cli/commands/plugin/list/list.js +113 -0
  17. package/dist/cli/commands/plugin/list/list.js.map +1 -0
  18. package/dist/cli/commands/plugin/schema-resources.js +82 -0
  19. package/dist/cli/commands/plugin/schema-resources.js.map +1 -0
  20. package/dist/cli/commands/{plugins-sync.js → plugin/sync/sync.js} +98 -79
  21. package/dist/cli/commands/plugin/sync/sync.js.map +1 -0
  22. package/dist/cli/commands/plugin/validate/validate-manifest.js +216 -0
  23. package/dist/cli/commands/plugin/validate/validate-manifest.js.map +1 -0
  24. package/dist/cli/commands/plugin/validate/validate.js +67 -0
  25. package/dist/cli/commands/plugin/validate/validate.js.map +1 -0
  26. package/dist/cli/index.js +2 -2
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/index.d.ts +4 -3
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/registry/index.js +2 -1
  32. package/dist/registry/manifest-loader.d.ts +2 -1
  33. package/dist/registry/manifest-loader.d.ts.map +1 -1
  34. package/dist/registry/manifest-loader.js +2 -1
  35. package/dist/registry/manifest-loader.js.map +1 -1
  36. package/dist/registry/resource-registry.js +2 -1
  37. package/dist/registry/resource-registry.js.map +1 -1
  38. package/dist/registry/types.d.ts +2 -70
  39. package/dist/registry/types.d.ts.map +1 -1
  40. package/dist/registry/types.generated.d.ts +45 -0
  41. package/dist/registry/types.generated.d.ts.map +1 -0
  42. package/dist/registry/types.generated.js +59 -0
  43. package/dist/registry/types.generated.js.map +1 -0
  44. package/dist/registry/types.js +5 -77
  45. package/dist/registry/types.js.map +1 -1
  46. package/dist/schemas/plugin-manifest.schema.json +439 -0
  47. package/dist/schemas/template-plugins.schema.json +103 -0
  48. package/docs/docs/api/appkit/Class.AppKitError/index.html +3 -3
  49. package/docs/docs/api/appkit/Class.AuthenticationError/index.html +3 -3
  50. package/docs/docs/api/appkit/Class.ConfigurationError/index.html +3 -3
  51. package/docs/docs/api/appkit/Class.ConnectionError/index.html +3 -3
  52. package/docs/docs/api/appkit/Class.ExecutionError/index.html +3 -3
  53. package/docs/docs/api/appkit/Class.InitializationError/index.html +3 -3
  54. package/docs/docs/api/appkit/Class.Plugin/index.html +3 -3
  55. package/docs/docs/api/appkit/Class.ResourceRegistry/index.html +3 -3
  56. package/docs/docs/api/appkit/Class.ServerError/index.html +3 -3
  57. package/docs/docs/api/appkit/Class.TunnelError/index.html +3 -3
  58. package/docs/docs/api/appkit/Class.ValidationError/index.html +3 -3
  59. package/docs/docs/api/appkit/Enumeration.RequestedClaimsPermissionSet/index.html +3 -3
  60. package/docs/docs/api/appkit/Enumeration.ResourceType/index.html +6 -19
  61. package/docs/docs/api/appkit/Enumeration.ResourceType.md +1 -25
  62. package/docs/docs/api/appkit/Function.appKitTypesPlugin/index.html +3 -3
  63. package/docs/docs/api/appkit/Function.createApp/index.html +3 -3
  64. package/docs/docs/api/appkit/Function.createLakebasePool/index.html +3 -3
  65. package/docs/docs/api/appkit/Function.generateDatabaseCredential/index.html +3 -3
  66. package/docs/docs/api/appkit/Function.getExecutionContext/index.html +3 -3
  67. package/docs/docs/api/appkit/Function.getLakebaseOrmConfig/index.html +3 -3
  68. package/docs/docs/api/appkit/Function.getLakebasePgConfig/index.html +3 -3
  69. package/docs/docs/api/appkit/Function.getPluginManifest/index.html +3 -3
  70. package/docs/docs/api/appkit/Function.getResourceRequirements/index.html +3 -3
  71. package/docs/docs/api/appkit/Function.getWorkspaceClient/index.html +3 -3
  72. package/docs/docs/api/appkit/Function.isSQLTypeMarker/index.html +3 -3
  73. package/docs/docs/api/appkit/Interface.BasePluginConfig/index.html +3 -3
  74. package/docs/docs/api/appkit/Interface.CacheConfig/index.html +3 -3
  75. package/docs/docs/api/appkit/Interface.DatabaseCredential/index.html +3 -3
  76. package/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest/index.html +3 -3
  77. package/docs/docs/api/appkit/Interface.ITelemetry/index.html +3 -3
  78. package/docs/docs/api/appkit/Interface.LakebasePoolConfig/index.html +3 -3
  79. package/docs/docs/api/appkit/Interface.PluginManifest/index.html +3 -3
  80. package/docs/docs/api/appkit/Interface.RequestedClaims/index.html +3 -3
  81. package/docs/docs/api/appkit/Interface.RequestedResource/index.html +3 -3
  82. package/docs/docs/api/appkit/Interface.ResourceEntry/index.html +3 -3
  83. package/docs/docs/api/appkit/Interface.ResourceFieldEntry/index.html +3 -3
  84. package/docs/docs/api/appkit/Interface.ResourceRequirement/index.html +3 -3
  85. package/docs/docs/api/appkit/Interface.StreamExecutionSettings/index.html +3 -3
  86. package/docs/docs/api/appkit/Interface.TelemetryConfig/index.html +3 -3
  87. package/docs/docs/api/appkit/Interface.ValidationResult/index.html +3 -3
  88. package/docs/docs/api/appkit/TypeAlias.ConfigSchema/index.html +3 -3
  89. package/docs/docs/api/appkit/TypeAlias.IAppRouter/index.html +3 -3
  90. package/docs/docs/api/appkit/TypeAlias.ResourcePermission/index.html +4 -4
  91. package/docs/docs/api/appkit/TypeAlias.ToPlugin/index.html +23 -0
  92. package/docs/docs/api/appkit/TypeAlias.ToPlugin.md +24 -0
  93. package/docs/docs/api/appkit/Variable.sql/index.html +4 -4
  94. package/docs/docs/api/appkit/index.html +5 -5
  95. package/docs/docs/api/appkit-ui/data/AreaChart/index.html +2 -2
  96. package/docs/docs/api/appkit-ui/data/BarChart/index.html +2 -2
  97. package/docs/docs/api/appkit-ui/data/DataTable/index.html +2 -2
  98. package/docs/docs/api/appkit-ui/data/DonutChart/index.html +2 -2
  99. package/docs/docs/api/appkit-ui/data/HeatmapChart/index.html +2 -2
  100. package/docs/docs/api/appkit-ui/data/LineChart/index.html +2 -2
  101. package/docs/docs/api/appkit-ui/data/PieChart/index.html +2 -2
  102. package/docs/docs/api/appkit-ui/data/RadarChart/index.html +2 -2
  103. package/docs/docs/api/appkit-ui/data/ScatterChart/index.html +2 -2
  104. package/docs/docs/api/appkit-ui/index.html +2 -2
  105. package/docs/docs/api/appkit-ui/styling/index.html +2 -2
  106. package/docs/docs/api/appkit-ui/ui/Accordion/index.html +2 -2
  107. package/docs/docs/api/appkit-ui/ui/Alert/index.html +2 -2
  108. package/docs/docs/api/appkit-ui/ui/AlertDialog/index.html +2 -2
  109. package/docs/docs/api/appkit-ui/ui/AspectRatio/index.html +2 -2
  110. package/docs/docs/api/appkit-ui/ui/Avatar/index.html +2 -2
  111. package/docs/docs/api/appkit-ui/ui/Badge/index.html +2 -2
  112. package/docs/docs/api/appkit-ui/ui/Breadcrumb/index.html +2 -2
  113. package/docs/docs/api/appkit-ui/ui/Button/index.html +2 -2
  114. package/docs/docs/api/appkit-ui/ui/ButtonGroup/index.html +2 -2
  115. package/docs/docs/api/appkit-ui/ui/Calendar/index.html +2 -2
  116. package/docs/docs/api/appkit-ui/ui/Card/index.html +2 -2
  117. package/docs/docs/api/appkit-ui/ui/Carousel/index.html +2 -2
  118. package/docs/docs/api/appkit-ui/ui/ChartContainer/index.html +2 -2
  119. package/docs/docs/api/appkit-ui/ui/Checkbox/index.html +2 -2
  120. package/docs/docs/api/appkit-ui/ui/Collapsible/index.html +2 -2
  121. package/docs/docs/api/appkit-ui/ui/Command/index.html +2 -2
  122. package/docs/docs/api/appkit-ui/ui/ContextMenu/index.html +2 -2
  123. package/docs/docs/api/appkit-ui/ui/Dialog/index.html +2 -2
  124. package/docs/docs/api/appkit-ui/ui/Drawer/index.html +2 -2
  125. package/docs/docs/api/appkit-ui/ui/DropdownMenu/index.html +2 -2
  126. package/docs/docs/api/appkit-ui/ui/Empty/index.html +2 -2
  127. package/docs/docs/api/appkit-ui/ui/Field/index.html +2 -2
  128. package/docs/docs/api/appkit-ui/ui/FormControl/index.html +2 -2
  129. package/docs/docs/api/appkit-ui/ui/HoverCard/index.html +2 -2
  130. package/docs/docs/api/appkit-ui/ui/Input/index.html +2 -2
  131. package/docs/docs/api/appkit-ui/ui/InputGroup/index.html +2 -2
  132. package/docs/docs/api/appkit-ui/ui/InputOTP/index.html +2 -2
  133. package/docs/docs/api/appkit-ui/ui/Item/index.html +2 -2
  134. package/docs/docs/api/appkit-ui/ui/Kbd/index.html +2 -2
  135. package/docs/docs/api/appkit-ui/ui/Label/index.html +2 -2
  136. package/docs/docs/api/appkit-ui/ui/Menubar/index.html +2 -2
  137. package/docs/docs/api/appkit-ui/ui/NavigationMenu/index.html +2 -2
  138. package/docs/docs/api/appkit-ui/ui/Pagination/index.html +2 -2
  139. package/docs/docs/api/appkit-ui/ui/Popover/index.html +2 -2
  140. package/docs/docs/api/appkit-ui/ui/Progress/index.html +2 -2
  141. package/docs/docs/api/appkit-ui/ui/RadioGroup/index.html +2 -2
  142. package/docs/docs/api/appkit-ui/ui/ResizableHandle/index.html +2 -2
  143. package/docs/docs/api/appkit-ui/ui/ScrollArea/index.html +2 -2
  144. package/docs/docs/api/appkit-ui/ui/Select/index.html +2 -2
  145. package/docs/docs/api/appkit-ui/ui/Separator/index.html +2 -2
  146. package/docs/docs/api/appkit-ui/ui/Sheet/index.html +2 -2
  147. package/docs/docs/api/appkit-ui/ui/Sidebar/index.html +2 -2
  148. package/docs/docs/api/appkit-ui/ui/Skeleton/index.html +2 -2
  149. package/docs/docs/api/appkit-ui/ui/Slider/index.html +2 -2
  150. package/docs/docs/api/appkit-ui/ui/Spinner/index.html +2 -2
  151. package/docs/docs/api/appkit-ui/ui/Switch/index.html +2 -2
  152. package/docs/docs/api/appkit-ui/ui/Table/index.html +2 -2
  153. package/docs/docs/api/appkit-ui/ui/Tabs/index.html +2 -2
  154. package/docs/docs/api/appkit-ui/ui/Textarea/index.html +2 -2
  155. package/docs/docs/api/appkit-ui/ui/Toaster/index.html +2 -2
  156. package/docs/docs/api/appkit-ui/ui/Toggle/index.html +2 -2
  157. package/docs/docs/api/appkit-ui/ui/ToggleGroup/index.html +2 -2
  158. package/docs/docs/api/appkit-ui/ui/Tooltip/index.html +2 -2
  159. package/docs/docs/api/appkit.md +5 -4
  160. package/docs/docs/api/index.html +2 -2
  161. package/docs/docs/app-management/index.html +2 -2
  162. package/docs/docs/architecture/index.html +2 -2
  163. package/docs/docs/category/development/index.html +2 -2
  164. package/docs/docs/configuration/index.html +2 -2
  165. package/docs/docs/core-principles/index.html +2 -2
  166. package/docs/docs/development/ai-assisted-development/index.html +2 -2
  167. package/docs/docs/development/index.html +2 -2
  168. package/docs/docs/development/llm-guide/index.html +2 -2
  169. package/docs/docs/development/local-development/index.html +2 -2
  170. package/docs/docs/development/project-setup/index.html +2 -2
  171. package/docs/docs/development/remote-bridge/index.html +2 -2
  172. package/docs/docs/development/type-generation/index.html +2 -2
  173. package/docs/docs/index.html +2 -2
  174. package/docs/docs/plugins/index.html +35 -4
  175. package/docs/docs/plugins.md +97 -1
  176. package/llms.txt +2 -1
  177. package/package.json +3 -2
  178. package/dist/cli/commands/plugins-sync.js.map +0 -1
  179. package/dist/cli/commands/plugins.js +0 -19
  180. package/dist/cli/commands/plugins.js.map +0 -1
package/dist/cli/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { docsCommand } from "./commands/docs.js";
3
3
  import { generateTypesCommand } from "./commands/generate-types.js";
4
4
  import { lintCommand } from "./commands/lint.js";
5
- import { pluginsCommand } from "./commands/plugins.js";
5
+ import { pluginCommand } from "./commands/plugin/index.js";
6
6
  import { setupCommand } from "./commands/setup.js";
7
7
  import { readFileSync } from "node:fs";
8
8
  import { dirname, join } from "node:path";
@@ -18,7 +18,7 @@ cmd.addCommand(setupCommand);
18
18
  cmd.addCommand(generateTypesCommand);
19
19
  cmd.addCommand(lintCommand);
20
20
  cmd.addCommand(docsCommand);
21
- cmd.addCommand(pluginsCommand);
21
+ cmd.addCommand(pluginCommand);
22
22
  cmd.parse();
23
23
 
24
24
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { docsCommand } from \"./commands/docs.js\";\nimport { generateTypesCommand } from \"./commands/generate-types.js\";\nimport { lintCommand } from \"./commands/lint.js\";\nimport { pluginsCommand } from \"./commands/plugins.js\";\nimport { setupCommand } from \"./commands/setup.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgPath = join(__dirname, \"../../package.json\");\nconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n\nconst cmd = new Command();\n\ncmd\n .name(\"appkit\")\n .description(\"CLI tools for Databricks AppKit\")\n .version(pkg.version);\n\ncmd.addCommand(setupCommand);\ncmd.addCommand(generateTypesCommand);\ncmd.addCommand(lintCommand);\ncmd.addCommand(docsCommand);\ncmd.addCommand(pluginsCommand);\n\ncmd.parse();\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,UAAU,KADE,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACzB,qBAAqB;AACrD,MAAM,MAAM,KAAK,MAAM,aAAa,SAAS,QAAQ,CAAC;AAEtD,MAAM,MAAM,IAAI,SAAS;AAEzB,IACG,KAAK,SAAS,CACd,YAAY,kCAAkC,CAC9C,QAAQ,IAAI,QAAQ;AAEvB,IAAI,WAAW,aAAa;AAC5B,IAAI,WAAW,qBAAqB;AACpC,IAAI,WAAW,YAAY;AAC3B,IAAI,WAAW,YAAY;AAC3B,IAAI,WAAW,eAAe;AAE9B,IAAI,OAAO"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { docsCommand } from \"./commands/docs.js\";\nimport { generateTypesCommand } from \"./commands/generate-types.js\";\nimport { lintCommand } from \"./commands/lint.js\";\nimport { pluginCommand } from \"./commands/plugin/index.js\";\nimport { setupCommand } from \"./commands/setup.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgPath = join(__dirname, \"../../package.json\");\nconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n\nconst cmd = new Command();\n\ncmd\n .name(\"appkit\")\n .description(\"CLI tools for Databricks AppKit\")\n .version(pkg.version);\n\ncmd.addCommand(setupCommand);\ncmd.addCommand(generateTypesCommand);\ncmd.addCommand(lintCommand);\ncmd.addCommand(docsCommand);\ncmd.addCommand(pluginCommand);\n\ncmd.parse();\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,UAAU,KADE,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACzB,qBAAqB;AACrD,MAAM,MAAM,KAAK,MAAM,aAAa,SAAS,QAAQ,CAAC;AAEtD,MAAM,MAAM,IAAI,SAAS;AAEzB,IACG,KAAK,SAAS,CACd,YAAY,kCAAkC,CAC9C,QAAQ,IAAI,QAAQ;AAEvB,IAAI,WAAW,aAAa;AAC5B,IAAI,WAAW,qBAAqB;AACpC,IAAI,WAAW,YAAY;AAC3B,IAAI,WAAW,YAAY;AAC3B,IAAI,WAAW,cAAc;AAE7B,IAAI,OAAO"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BasePluginConfig, IAppRouter } from "./shared/src/plugin.js";
1
+ import { BasePluginConfig, IAppRouter, ToPlugin } from "./shared/src/plugin.js";
2
2
  import { CacheConfig } from "./shared/src/cache.js";
3
3
  import { StreamExecutionSettings } from "./shared/src/execute.js";
4
4
  import { isSQLTypeMarker, sql } from "./shared/src/sql/helpers.js";
@@ -20,9 +20,10 @@ import { ValidationError } from "./errors/validation.js";
20
20
  import { Plugin } from "./plugin/plugin.js";
21
21
  import { toPlugin } from "./plugin/to-plugin.js";
22
22
  import { analytics } from "./plugins/analytics/analytics.js";
23
- import { ConfigSchema, PluginManifest, ResourceEntry, ResourceFieldEntry, ResourcePermission, ResourceRequirement, ResourceType, ValidationResult } from "./registry/types.js";
23
+ import { ResourcePermission, ResourceType } from "./registry/types.generated.js";
24
+ import { ConfigSchema, PluginManifest, ResourceEntry, ResourceFieldEntry, ResourceRequirement, ValidationResult } from "./registry/types.js";
24
25
  import { getPluginManifest, getResourceRequirements } from "./registry/manifest-loader.js";
25
26
  import { ResourceRegistry } from "./registry/resource-registry.js";
26
27
  import { server } from "./plugins/server/index.js";
27
28
  import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
28
- export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, ExecutionError, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginManifest, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, TunnelError, ValidationError, type ValidationResult, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getWorkspaceClient, isSQLTypeMarker, server, sql, toPlugin };
29
+ export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, ExecutionError, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginManifest, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, type ToPlugin, TunnelError, ValidationError, type ValidationResult, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getWorkspaceClient, isSQLTypeMarker, server, sql, toPlugin };
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import { SeverityNumber, SpanStatusCode } from "./telemetry/index.js";
14
14
  import { CacheManager } from "./cache/index.js";
15
15
  import { getExecutionContext } from "./context/execution-context.js";
16
16
  import { init_context } from "./context/index.js";
17
- import { ResourceType } from "./registry/types.js";
17
+ import { ResourceType } from "./registry/types.generated.js";
18
18
  import { getPluginManifest, getResourceRequirements } from "./registry/manifest-loader.js";
19
19
  import { ResourceRegistry } from "./registry/resource-registry.js";
20
20
  import "./registry/index.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @packageDocumentation\n *\n * Core library for building Databricks applications with type-safe SQL queries,\n * plugin architecture, and React integration.\n */\n\n// Types from shared\nexport type {\n BasePluginConfig,\n CacheConfig,\n IAppRouter,\n StreamExecutionSettings,\n} from \"shared\";\nexport { isSQLTypeMarker, sql } from \"shared\";\nexport { CacheManager } from \"./cache\";\nexport type {\n DatabaseCredential,\n GenerateDatabaseCredentialRequest,\n LakebasePoolConfig,\n RequestedClaims,\n RequestedResource,\n} from \"./connectors/lakebase\";\n// Lakebase Autoscaling connector\nexport {\n createLakebasePool,\n generateDatabaseCredential,\n getLakebaseOrmConfig,\n getLakebasePgConfig,\n getWorkspaceClient,\n RequestedClaimsPermissionSet,\n} from \"./connectors/lakebase\";\nexport { getExecutionContext } from \"./context\";\nexport { createApp } from \"./core\";\n// Errors\nexport {\n AppKitError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n ExecutionError,\n InitializationError,\n ServerError,\n TunnelError,\n ValidationError,\n} from \"./errors\";\n// Plugin authoring\nexport { Plugin, toPlugin } from \"./plugin\";\nexport { analytics, server } from \"./plugins\";\n// Registry types and utilities for plugin manifests\nexport type {\n ConfigSchema,\n PluginManifest,\n ResourceEntry,\n ResourceFieldEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./registry\";\nexport {\n getPluginManifest,\n getResourceRequirements,\n ResourceRegistry,\n ResourceType,\n} from \"./registry\";\n// Telemetry (for advanced custom telemetry)\nexport {\n type Counter,\n type Histogram,\n type ITelemetry,\n SeverityNumber,\n type Span,\n SpanStatusCode,\n type TelemetryConfig,\n} from \"./telemetry\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgCgD;aAa9B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @packageDocumentation\n *\n * Core library for building Databricks applications with type-safe SQL queries,\n * plugin architecture, and React integration.\n */\n\n// Types from shared\nexport type {\n BasePluginConfig,\n CacheConfig,\n IAppRouter,\n StreamExecutionSettings,\n} from \"shared\";\nexport { isSQLTypeMarker, sql } from \"shared\";\nexport { CacheManager } from \"./cache\";\nexport type {\n DatabaseCredential,\n GenerateDatabaseCredentialRequest,\n LakebasePoolConfig,\n RequestedClaims,\n RequestedResource,\n} from \"./connectors/lakebase\";\n// Lakebase Autoscaling connector\nexport {\n createLakebasePool,\n generateDatabaseCredential,\n getLakebaseOrmConfig,\n getLakebasePgConfig,\n getWorkspaceClient,\n RequestedClaimsPermissionSet,\n} from \"./connectors/lakebase\";\nexport { getExecutionContext } from \"./context\";\nexport { createApp } from \"./core\";\n// Errors\nexport {\n AppKitError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n ExecutionError,\n InitializationError,\n ServerError,\n TunnelError,\n ValidationError,\n} from \"./errors\";\n// Plugin authoring\nexport { Plugin, type ToPlugin, toPlugin } from \"./plugin\";\nexport { analytics, server } from \"./plugins\";\n// Registry types and utilities for plugin manifests\nexport type {\n ConfigSchema,\n PluginManifest,\n ResourceEntry,\n ResourceFieldEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./registry\";\nexport {\n getPluginManifest,\n getResourceRequirements,\n ResourceRegistry,\n ResourceType,\n} from \"./registry\";\n// Telemetry (for advanced custom telemetry)\nexport {\n type Counter,\n type Histogram,\n type ITelemetry,\n SeverityNumber,\n type Span,\n SpanStatusCode,\n type TelemetryConfig,\n} from \"./telemetry\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgCgD;aAa9B"}
@@ -1,4 +1,5 @@
1
- import { PERMISSIONS_BY_TYPE, PERMISSION_HIERARCHY_BY_TYPE, ResourceType } from "./types.js";
1
+ import { PERMISSIONS_BY_TYPE, PERMISSION_HIERARCHY_BY_TYPE, ResourceType } from "./types.generated.js";
2
+ import "./types.js";
2
3
  import { getPluginManifest, getResourceRequirements } from "./manifest-loader.js";
3
4
  import { ResourceRegistry } from "./resource-registry.js";
4
5
 
@@ -1,5 +1,6 @@
1
1
  import { PluginConstructor } from "../shared/src/plugin.js";
2
- import { PluginManifest, ResourceFieldEntry, ResourcePermission, ResourceType } from "./types.js";
2
+ import { ResourcePermission, ResourceType } from "./types.generated.js";
3
+ import { PluginManifest, ResourceFieldEntry } from "./types.js";
3
4
 
4
5
  //#region src/registry/manifest-loader.d.ts
5
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.d.ts","names":[],"sources":["../../src/registry/manifest-loader.ts"],"sourcesContent":[],"mappings":";;;;;;AA4DA;;;;;AA4FA;;AAAgD,iBA5FhC,iBAAA,CA4FgC,MAAA,EA5FN,iBA4FM,CAAA,EA5Fc,cA4Fd;;;;;;;;;;;;;;;;;;;iBAAhC,uBAAA,SAAgC"}
1
+ {"version":3,"file":"manifest-loader.d.ts","names":[],"sources":["../../src/registry/manifest-loader.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA4DA;;;;;AA4FA;AAAuC,iBA5FvB,iBAAA,CA4FuB,MAAA,EA5FG,iBA4FH,CAAA,EA5FuB,cA4FvB;;;;;;;;;;;;;;;;;;;iBAAvB,uBAAA,SAAgC"}
@@ -1,7 +1,8 @@
1
1
  import { createLogger } from "../logging/logger.js";
2
2
  import { ConfigurationError } from "../errors/configuration.js";
3
3
  import { init_errors } from "../errors/index.js";
4
- import { PERMISSIONS_BY_TYPE, ResourceType } from "./types.js";
4
+ import { PERMISSIONS_BY_TYPE, ResourceType } from "./types.generated.js";
5
+ import "./types.js";
5
6
 
6
7
  //#region src/registry/manifest-loader.ts
7
8
  init_errors();
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.js","names":[],"sources":["../../src/registry/manifest-loader.ts"],"sourcesContent":["import type { PluginConstructor } from \"shared\";\nimport { ConfigurationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport type {\n PluginManifest,\n ResourcePermission,\n ResourceRequirement,\n} from \"./types\";\nimport { PERMISSIONS_BY_TYPE, ResourceType } from \"./types\";\n\nconst logger = createLogger(\"manifest-loader\");\n\n/** Loose resource from shared/manifest (string type and permission). */\ninterface LooseResource {\n type: string;\n alias: string;\n resourceKey: string;\n description: string;\n permission: string;\n fields: Record<string, { env: string; description?: string }>;\n}\n\nfunction normalizeType(s: string): ResourceType {\n const v = Object.values(ResourceType).find((x) => x === s);\n if (v !== undefined) return v;\n throw new ConfigurationError(\n `Invalid resource type: \"${s}\". Valid: ${Object.values(ResourceType).join(\", \")}`,\n );\n}\n\nfunction normalizePermission(\n type: ResourceType,\n s: string,\n): ResourcePermission {\n const allowed = PERMISSIONS_BY_TYPE[type];\n if (allowed.includes(s as ResourcePermission)) return s as ResourcePermission;\n throw new ConfigurationError(\n `Invalid permission \"${s}\" for type ${type}. Valid: ${allowed.join(\", \")}`,\n );\n}\n\nfunction normalizeResource(r: LooseResource): ResourceRequirement {\n const type = normalizeType(r.type);\n const permission = normalizePermission(type, r.permission);\n return {\n ...r,\n type,\n permission,\n required: false,\n };\n}\n\n/**\n * Loads and validates the manifest from a plugin constructor.\n * Normalizes string type/permission to strict ResourceType/ResourcePermission.\n *\n * @param plugin - The plugin constructor class\n * @returns The validated, normalized plugin manifest\n * @throws {ConfigurationError} If the manifest is missing, invalid, or has invalid resource type/permission\n */\nexport function getPluginManifest(plugin: PluginConstructor): PluginManifest {\n const pluginName = plugin.name || \"unknown\";\n\n if (!plugin.manifest) {\n throw new ConfigurationError(\n `Plugin ${pluginName} is missing a manifest. All plugins must declare a static manifest property.`,\n );\n }\n\n const raw = plugin.manifest;\n\n if (!raw.name || typeof raw.name !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${pluginName} manifest has missing or invalid 'name' field`,\n );\n }\n\n if (!raw.displayName || typeof raw.displayName !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has missing or invalid 'displayName' field`,\n );\n }\n\n if (!raw.description || typeof raw.description !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has missing or invalid 'description' field`,\n );\n }\n\n if (!raw.resources) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest is missing 'resources' field`,\n );\n }\n\n if (!Array.isArray(raw.resources.required)) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has invalid 'resources.required' field (expected array)`,\n );\n }\n\n if (\n raw.resources.optional !== undefined &&\n !Array.isArray(raw.resources.optional)\n ) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has invalid 'resources.optional' field (expected array)`,\n );\n }\n\n const required = raw.resources.required.map((r) => {\n const norm = normalizeResource(r as LooseResource);\n const { required: _, ...rest } = norm;\n return rest;\n });\n const optional = (raw.resources.optional || []).map((r) => {\n const norm = normalizeResource(r as LooseResource);\n const { required: _, ...rest } = norm;\n return rest;\n });\n\n logger.debug(\n \"Loaded manifest for plugin %s: %d required resources, %d optional resources\",\n raw.name,\n required.length,\n optional.length,\n );\n\n return {\n ...raw,\n resources: { required, optional },\n };\n}\n\n/**\n * Gets the resource requirements from a plugin's manifest.\n *\n * Combines required and optional resources into a single array with the\n * `required` flag set appropriately.\n *\n * @param plugin - The plugin constructor class\n * @returns Combined array of required and optional resources\n * @throws {ConfigurationError} If the plugin manifest is missing or invalid\n *\n * @example\n * ```typescript\n * const resources = getResourceRequirements(AnalyticsPlugin);\n * for (const resource of resources) {\n * console.log(`${resource.type}: ${resource.description} (required: ${resource.required})`);\n * }\n * ```\n */\nexport function getResourceRequirements(plugin: PluginConstructor) {\n const manifest = getPluginManifest(plugin);\n\n const required = manifest.resources.required.map((r) => ({\n ...r,\n required: true,\n }));\n const optional = (manifest.resources.optional || []).map((r) => ({\n ...r,\n required: false,\n }));\n\n return [...required, ...optional];\n}\n\n/**\n * Validates a manifest object structure.\n *\n * @param manifest - The manifest object to validate\n * @returns true if the manifest is valid, false otherwise\n *\n * @internal\n */\nexport function isValidManifest(manifest: unknown): manifest is PluginManifest {\n if (!manifest || typeof manifest !== \"object\") {\n return false;\n }\n\n const m = manifest as Record<string, unknown>;\n\n // Check required fields\n if (typeof m.name !== \"string\") return false;\n if (typeof m.displayName !== \"string\") return false;\n if (typeof m.description !== \"string\") return false;\n\n // Check resources structure\n if (!m.resources || typeof m.resources !== \"object\") return false;\n\n const resources = m.resources as Record<string, unknown>;\n if (!Array.isArray(resources.required)) return false;\n\n // Optional field can be missing or must be an array\n if (resources.optional !== undefined && !Array.isArray(resources.optional)) {\n return false;\n }\n\n return true;\n}\n"],"mappings":";;;;;;aAC+C;AAS/C,MAAM,SAAS,aAAa,kBAAkB;AAY9C,SAAS,cAAc,GAAyB;CAC9C,MAAM,IAAI,OAAO,OAAO,aAAa,CAAC,MAAM,MAAM,MAAM,EAAE;AAC1D,KAAI,MAAM,OAAW,QAAO;AAC5B,OAAM,IAAI,mBACR,2BAA2B,EAAE,YAAY,OAAO,OAAO,aAAa,CAAC,KAAK,KAAK,GAChF;;AAGH,SAAS,oBACP,MACA,GACoB;CACpB,MAAM,UAAU,oBAAoB;AACpC,KAAI,QAAQ,SAAS,EAAwB,CAAE,QAAO;AACtD,OAAM,IAAI,mBACR,uBAAuB,EAAE,aAAa,KAAK,WAAW,QAAQ,KAAK,KAAK,GACzE;;AAGH,SAAS,kBAAkB,GAAuC;CAChE,MAAM,OAAO,cAAc,EAAE,KAAK;CAClC,MAAM,aAAa,oBAAoB,MAAM,EAAE,WAAW;AAC1D,QAAO;EACL,GAAG;EACH;EACA;EACA,UAAU;EACX;;;;;;;;;;AAWH,SAAgB,kBAAkB,QAA2C;CAC3E,MAAM,aAAa,OAAO,QAAQ;AAElC,KAAI,CAAC,OAAO,SACV,OAAM,IAAI,mBACR,UAAU,WAAW,8EACtB;CAGH,MAAM,MAAM,OAAO;AAEnB,KAAI,CAAC,IAAI,QAAQ,OAAO,IAAI,SAAS,SACnC,OAAM,IAAI,mBACR,UAAU,WAAW,+CACtB;AAGH,KAAI,CAAC,IAAI,eAAe,OAAO,IAAI,gBAAgB,SACjD,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,sDACpB;AAGH,KAAI,CAAC,IAAI,eAAe,OAAO,IAAI,gBAAgB,SACjD,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,sDACpB;AAGH,KAAI,CAAC,IAAI,UACP,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,wCACpB;AAGH,KAAI,CAAC,MAAM,QAAQ,IAAI,UAAU,SAAS,CACxC,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,mEACpB;AAGH,KACE,IAAI,UAAU,aAAa,UAC3B,CAAC,MAAM,QAAQ,IAAI,UAAU,SAAS,CAEtC,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,mEACpB;CAGH,MAAM,WAAW,IAAI,UAAU,SAAS,KAAK,MAAM;EAEjD,MAAM,EAAE,UAAU,GAAG,GAAG,SADX,kBAAkB,EAAmB;AAElD,SAAO;GACP;CACF,MAAM,YAAY,IAAI,UAAU,YAAY,EAAE,EAAE,KAAK,MAAM;EAEzD,MAAM,EAAE,UAAU,GAAG,GAAG,SADX,kBAAkB,EAAmB;AAElD,SAAO;GACP;AAEF,QAAO,MACL,+EACA,IAAI,MACJ,SAAS,QACT,SAAS,OACV;AAED,QAAO;EACL,GAAG;EACH,WAAW;GAAE;GAAU;GAAU;EAClC;;;;;;;;;;;;;;;;;;;;AAqBH,SAAgB,wBAAwB,QAA2B;CACjE,MAAM,WAAW,kBAAkB,OAAO;CAE1C,MAAM,WAAW,SAAS,UAAU,SAAS,KAAK,OAAO;EACvD,GAAG;EACH,UAAU;EACX,EAAE;CACH,MAAM,YAAY,SAAS,UAAU,YAAY,EAAE,EAAE,KAAK,OAAO;EAC/D,GAAG;EACH,UAAU;EACX,EAAE;AAEH,QAAO,CAAC,GAAG,UAAU,GAAG,SAAS"}
1
+ {"version":3,"file":"manifest-loader.js","names":[],"sources":["../../src/registry/manifest-loader.ts"],"sourcesContent":["import type { PluginConstructor } from \"shared\";\nimport { ConfigurationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport type {\n PluginManifest,\n ResourcePermission,\n ResourceRequirement,\n} from \"./types\";\nimport { PERMISSIONS_BY_TYPE, ResourceType } from \"./types\";\n\nconst logger = createLogger(\"manifest-loader\");\n\n/** Loose resource from shared/manifest (string type and permission). */\ninterface LooseResource {\n type: string;\n alias: string;\n resourceKey: string;\n description: string;\n permission: string;\n fields: Record<string, { env: string; description?: string }>;\n}\n\nfunction normalizeType(s: string): ResourceType {\n const v = Object.values(ResourceType).find((x) => x === s);\n if (v !== undefined) return v;\n throw new ConfigurationError(\n `Invalid resource type: \"${s}\". Valid: ${Object.values(ResourceType).join(\", \")}`,\n );\n}\n\nfunction normalizePermission(\n type: ResourceType,\n s: string,\n): ResourcePermission {\n const allowed = PERMISSIONS_BY_TYPE[type];\n if (allowed.includes(s as ResourcePermission)) return s as ResourcePermission;\n throw new ConfigurationError(\n `Invalid permission \"${s}\" for type ${type}. Valid: ${allowed.join(\", \")}`,\n );\n}\n\nfunction normalizeResource(r: LooseResource): ResourceRequirement {\n const type = normalizeType(r.type);\n const permission = normalizePermission(type, r.permission);\n return {\n ...r,\n type,\n permission,\n required: false,\n };\n}\n\n/**\n * Loads and validates the manifest from a plugin constructor.\n * Normalizes string type/permission to strict ResourceType/ResourcePermission.\n *\n * @param plugin - The plugin constructor class\n * @returns The validated, normalized plugin manifest\n * @throws {ConfigurationError} If the manifest is missing, invalid, or has invalid resource type/permission\n */\nexport function getPluginManifest(plugin: PluginConstructor): PluginManifest {\n const pluginName = plugin.name || \"unknown\";\n\n if (!plugin.manifest) {\n throw new ConfigurationError(\n `Plugin ${pluginName} is missing a manifest. All plugins must declare a static manifest property.`,\n );\n }\n\n const raw = plugin.manifest;\n\n if (!raw.name || typeof raw.name !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${pluginName} manifest has missing or invalid 'name' field`,\n );\n }\n\n if (!raw.displayName || typeof raw.displayName !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has missing or invalid 'displayName' field`,\n );\n }\n\n if (!raw.description || typeof raw.description !== \"string\") {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has missing or invalid 'description' field`,\n );\n }\n\n if (!raw.resources) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest is missing 'resources' field`,\n );\n }\n\n if (!Array.isArray(raw.resources.required)) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has invalid 'resources.required' field (expected array)`,\n );\n }\n\n if (\n raw.resources.optional !== undefined &&\n !Array.isArray(raw.resources.optional)\n ) {\n throw new ConfigurationError(\n `Plugin ${raw.name} manifest has invalid 'resources.optional' field (expected array)`,\n );\n }\n\n const required = raw.resources.required.map((r) => {\n const norm = normalizeResource(r as LooseResource);\n const { required: _, ...rest } = norm;\n return rest;\n });\n const optional = (raw.resources.optional || []).map((r) => {\n const norm = normalizeResource(r as LooseResource);\n const { required: _, ...rest } = norm;\n return rest;\n });\n\n logger.debug(\n \"Loaded manifest for plugin %s: %d required resources, %d optional resources\",\n raw.name,\n required.length,\n optional.length,\n );\n\n return {\n ...raw,\n resources: { required, optional },\n };\n}\n\n/**\n * Gets the resource requirements from a plugin's manifest.\n *\n * Combines required and optional resources into a single array with the\n * `required` flag set appropriately.\n *\n * @param plugin - The plugin constructor class\n * @returns Combined array of required and optional resources\n * @throws {ConfigurationError} If the plugin manifest is missing or invalid\n *\n * @example\n * ```typescript\n * const resources = getResourceRequirements(AnalyticsPlugin);\n * for (const resource of resources) {\n * console.log(`${resource.type}: ${resource.description} (required: ${resource.required})`);\n * }\n * ```\n */\nexport function getResourceRequirements(plugin: PluginConstructor) {\n const manifest = getPluginManifest(plugin);\n\n const required = manifest.resources.required.map((r) => ({\n ...r,\n required: true,\n }));\n const optional = (manifest.resources.optional || []).map((r) => ({\n ...r,\n required: false,\n }));\n\n return [...required, ...optional];\n}\n\n/**\n * Validates a manifest object structure.\n *\n * @param manifest - The manifest object to validate\n * @returns true if the manifest is valid, false otherwise\n *\n * @internal\n */\nexport function isValidManifest(manifest: unknown): manifest is PluginManifest {\n if (!manifest || typeof manifest !== \"object\") {\n return false;\n }\n\n const m = manifest as Record<string, unknown>;\n\n // Check required fields\n if (typeof m.name !== \"string\") return false;\n if (typeof m.displayName !== \"string\") return false;\n if (typeof m.description !== \"string\") return false;\n\n // Check resources structure\n if (!m.resources || typeof m.resources !== \"object\") return false;\n\n const resources = m.resources as Record<string, unknown>;\n if (!Array.isArray(resources.required)) return false;\n\n // Optional field can be missing or must be an array\n if (resources.optional !== undefined && !Array.isArray(resources.optional)) {\n return false;\n }\n\n return true;\n}\n"],"mappings":";;;;;;;aAC+C;AAS/C,MAAM,SAAS,aAAa,kBAAkB;AAY9C,SAAS,cAAc,GAAyB;CAC9C,MAAM,IAAI,OAAO,OAAO,aAAa,CAAC,MAAM,MAAM,MAAM,EAAE;AAC1D,KAAI,MAAM,OAAW,QAAO;AAC5B,OAAM,IAAI,mBACR,2BAA2B,EAAE,YAAY,OAAO,OAAO,aAAa,CAAC,KAAK,KAAK,GAChF;;AAGH,SAAS,oBACP,MACA,GACoB;CACpB,MAAM,UAAU,oBAAoB;AACpC,KAAI,QAAQ,SAAS,EAAwB,CAAE,QAAO;AACtD,OAAM,IAAI,mBACR,uBAAuB,EAAE,aAAa,KAAK,WAAW,QAAQ,KAAK,KAAK,GACzE;;AAGH,SAAS,kBAAkB,GAAuC;CAChE,MAAM,OAAO,cAAc,EAAE,KAAK;CAClC,MAAM,aAAa,oBAAoB,MAAM,EAAE,WAAW;AAC1D,QAAO;EACL,GAAG;EACH;EACA;EACA,UAAU;EACX;;;;;;;;;;AAWH,SAAgB,kBAAkB,QAA2C;CAC3E,MAAM,aAAa,OAAO,QAAQ;AAElC,KAAI,CAAC,OAAO,SACV,OAAM,IAAI,mBACR,UAAU,WAAW,8EACtB;CAGH,MAAM,MAAM,OAAO;AAEnB,KAAI,CAAC,IAAI,QAAQ,OAAO,IAAI,SAAS,SACnC,OAAM,IAAI,mBACR,UAAU,WAAW,+CACtB;AAGH,KAAI,CAAC,IAAI,eAAe,OAAO,IAAI,gBAAgB,SACjD,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,sDACpB;AAGH,KAAI,CAAC,IAAI,eAAe,OAAO,IAAI,gBAAgB,SACjD,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,sDACpB;AAGH,KAAI,CAAC,IAAI,UACP,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,wCACpB;AAGH,KAAI,CAAC,MAAM,QAAQ,IAAI,UAAU,SAAS,CACxC,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,mEACpB;AAGH,KACE,IAAI,UAAU,aAAa,UAC3B,CAAC,MAAM,QAAQ,IAAI,UAAU,SAAS,CAEtC,OAAM,IAAI,mBACR,UAAU,IAAI,KAAK,mEACpB;CAGH,MAAM,WAAW,IAAI,UAAU,SAAS,KAAK,MAAM;EAEjD,MAAM,EAAE,UAAU,GAAG,GAAG,SADX,kBAAkB,EAAmB;AAElD,SAAO;GACP;CACF,MAAM,YAAY,IAAI,UAAU,YAAY,EAAE,EAAE,KAAK,MAAM;EAEzD,MAAM,EAAE,UAAU,GAAG,GAAG,SADX,kBAAkB,EAAmB;AAElD,SAAO;GACP;AAEF,QAAO,MACL,+EACA,IAAI,MACJ,SAAS,QACT,SAAS,OACV;AAED,QAAO;EACL,GAAG;EACH,WAAW;GAAE;GAAU;GAAU;EAClC;;;;;;;;;;;;;;;;;;;;AAqBH,SAAgB,wBAAwB,QAA2B;CACjE,MAAM,WAAW,kBAAkB,OAAO;CAE1C,MAAM,WAAW,SAAS,UAAU,SAAS,KAAK,OAAO;EACvD,GAAG;EACH,UAAU;EACX,EAAE;CACH,MAAM,YAAY,SAAS,UAAU,YAAY,EAAE,EAAE,KAAK,OAAO;EAC/D,GAAG;EACH,UAAU;EACX,EAAE;AAEH,QAAO,CAAC,GAAG,UAAU,GAAG,SAAS"}
@@ -1,7 +1,8 @@
1
1
  import { createLogger } from "../logging/logger.js";
2
2
  import { ConfigurationError } from "../errors/configuration.js";
3
3
  import { init_errors } from "../errors/index.js";
4
- import { PERMISSION_HIERARCHY_BY_TYPE } from "./types.js";
4
+ import { PERMISSION_HIERARCHY_BY_TYPE } from "./types.generated.js";
5
+ import "./types.js";
5
6
  import { getPluginManifest } from "./manifest-loader.js";
6
7
 
7
8
  //#region src/registry/resource-registry.ts
@@ -1 +1 @@
1
- {"version":3,"file":"resource-registry.js","names":[],"sources":["../../src/registry/resource-registry.ts"],"sourcesContent":["/**\n * Resource Registry\n *\n * Central registry that tracks all resource requirements across all plugins.\n * Provides visibility into Databricks resources needed by the application\n * and handles deduplication when multiple plugins require the same resource\n * (dedup key: type + resourceKey).\n *\n * Use `new ResourceRegistry()` for instance-scoped usage (e.g. createApp).\n * getInstance() / resetInstance() remain for backward compatibility in tests.\n */\n\nimport type { BasePluginConfig, PluginConstructor, PluginData } from \"shared\";\nimport { ConfigurationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport { getPluginManifest } from \"./manifest-loader\";\nimport type {\n ResourceEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./types\";\nimport { PERMISSION_HIERARCHY_BY_TYPE, type ResourceType } from \"./types\";\n\nconst logger = createLogger(\"resource-registry\");\n\n/**\n * Dedup key for registry: type + resourceKey (machine-stable).\n * alias is for UI/display only.\n */\nfunction getDedupKey(type: string, resourceKey: string): string {\n return `${type}:${resourceKey}`;\n}\n\n/**\n * Returns the most permissive permission for a given resource type.\n * Uses per-type hierarchy; unknown permissions are treated as least permissive.\n */\nfunction getMostPermissivePermission(\n resourceType: ResourceType,\n p1: ResourcePermission,\n p2: ResourcePermission,\n): ResourcePermission {\n const hierarchy = PERMISSION_HIERARCHY_BY_TYPE[resourceType as ResourceType];\n const index1 = hierarchy?.indexOf(p1) ?? -1;\n const index2 = hierarchy?.indexOf(p2) ?? -1;\n return index1 > index2 ? p1 : p2;\n}\n\n/**\n * Central registry for tracking plugin resource requirements.\n * Deduplication uses type + resourceKey (machine-stable); alias is for display only.\n */\nexport class ResourceRegistry {\n private resources: Map<string, ResourceEntry> = new Map();\n\n /**\n * Registers a resource requirement for a plugin.\n * If a resource with the same type+resourceKey already exists, merges them:\n * - Combines plugin names (comma-separated)\n * - Uses the most permissive permission (per-type hierarchy)\n * - Marks as required if any plugin requires it\n * - Combines descriptions if they differ\n * - Merges fields; warns when same field name uses different env vars\n *\n * @param plugin - Name of the plugin registering the resource\n * @param resource - Resource requirement specification\n */\n public register(plugin: string, resource: ResourceRequirement): void {\n const key = getDedupKey(resource.type, resource.resourceKey);\n const existing = this.resources.get(key);\n\n if (existing) {\n // Merge with existing resource\n const merged = this.mergeResources(existing, plugin, resource);\n this.resources.set(key, merged);\n } else {\n // Create new resource entry with permission source tracking\n const entry: ResourceEntry = {\n ...resource,\n plugin,\n resolved: false,\n permissionSources: { [plugin]: resource.permission },\n };\n this.resources.set(key, entry);\n }\n }\n\n /**\n * Collects and registers resource requirements from an array of plugins.\n * For each plugin, loads its manifest (required) and runtime resource requirements.\n *\n * @param rawPlugins - Array of plugin data entries from createApp configuration\n * @throws {ConfigurationError} If any plugin is missing a manifest or manifest is invalid\n */\n public collectResources(\n rawPlugins: PluginData<PluginConstructor, unknown, string>[],\n ): void {\n for (const pluginData of rawPlugins) {\n if (!pluginData?.plugin) continue;\n\n const pluginName = pluginData.name;\n const manifest = getPluginManifest(pluginData.plugin);\n\n // Register required resources\n for (const resource of manifest.resources.required) {\n this.register(pluginName, { ...resource, required: true });\n }\n\n // Register optional resources\n for (const resource of manifest.resources.optional || []) {\n this.register(pluginName, { ...resource, required: false });\n }\n\n // Check for runtime resource requirements\n if (typeof pluginData.plugin.getResourceRequirements === \"function\") {\n const runtimeResources = pluginData.plugin.getResourceRequirements(\n pluginData.config as BasePluginConfig,\n );\n for (const resource of runtimeResources) {\n this.register(pluginName, resource as ResourceRequirement);\n }\n }\n\n logger.debug(\n \"Collected resources from plugin %s: %d total\",\n pluginName,\n this.getByPlugin(pluginName).length,\n );\n }\n }\n\n /**\n * Merges a new resource requirement with an existing entry.\n * Applies intelligent merging logic for conflicting properties.\n */\n private mergeResources(\n existing: ResourceEntry,\n newPlugin: string,\n newResource: ResourceRequirement,\n ): ResourceEntry {\n // Combine plugin names if not already included\n const plugins = existing.plugin.split(\", \");\n if (!plugins.includes(newPlugin)) {\n plugins.push(newPlugin);\n }\n\n // Track per-plugin permission sources\n const permissionSources: Record<string, ResourcePermission> = {\n ...(existing.permissionSources ?? {}),\n [newPlugin]: newResource.permission,\n };\n\n // Use the most permissive permission for this resource type; warn when escalating\n const permission = getMostPermissivePermission(\n existing.type as ResourceType,\n existing.permission,\n newResource.permission,\n );\n\n if (permission !== existing.permission) {\n logger.warn(\n 'Resource %s:%s permission escalated from \"%s\" to \"%s\" due to plugin \"%s\" ' +\n \"(previously requested by: %s). Review plugin permissions to ensure least-privilege.\",\n existing.type,\n existing.resourceKey,\n existing.permission,\n permission,\n newPlugin,\n existing.plugin,\n );\n }\n\n // Mark as required if any plugin requires it\n const required = existing.required || newResource.required;\n\n // Combine descriptions if they differ\n let description = existing.description;\n if (\n newResource.description &&\n newResource.description !== existing.description\n ) {\n if (!existing.description.includes(newResource.description)) {\n description = `${existing.description}; ${newResource.description}`;\n }\n }\n\n // Merge fields: union of field names; warn when same field name uses different env\n const fields = { ...(existing.fields ?? {}) };\n for (const [fieldName, newField] of Object.entries(\n newResource.fields ?? {},\n )) {\n const existingField = fields[fieldName];\n if (existingField) {\n if (existingField.env !== newField.env) {\n logger.warn(\n 'Resource %s:%s field \"%s\": conflicting env vars \"%s\" (from %s) vs \"%s\" (from %s). Using first.',\n existing.type,\n existing.resourceKey,\n fieldName,\n existingField.env,\n existing.plugin,\n newField.env,\n newPlugin,\n );\n }\n // keep existing\n } else {\n fields[fieldName] = newField;\n }\n }\n\n return {\n ...existing,\n plugin: plugins.join(\", \"),\n permission,\n permissionSources,\n required,\n description,\n fields,\n };\n }\n\n /**\n * Retrieves all registered resources.\n * Returns a copy of the array to prevent external mutations.\n *\n * @returns Array of all registered resource entries\n */\n public getAll(): ResourceEntry[] {\n return Array.from(this.resources.values());\n }\n\n /**\n * Gets a specific resource by type and resourceKey (dedup key).\n *\n * @param type - Resource type\n * @param resourceKey - Stable machine key (not alias; alias is for display only)\n * @returns The resource entry if found, undefined otherwise\n */\n public get(type: string, resourceKey: string): ResourceEntry | undefined {\n return this.resources.get(getDedupKey(type, resourceKey));\n }\n\n /**\n * Clears all registered resources.\n * Useful for testing or when rebuilding the registry.\n */\n public clear(): void {\n this.resources.clear();\n }\n\n /**\n * Returns the number of registered resources.\n */\n public size(): number {\n return this.resources.size;\n }\n\n /**\n * Gets all resources required by a specific plugin.\n *\n * @param pluginName - Name of the plugin\n * @returns Array of resources where the plugin is listed as a requester\n */\n public getByPlugin(pluginName: string): ResourceEntry[] {\n return this.getAll().filter((entry) =>\n entry.plugin.split(\", \").includes(pluginName),\n );\n }\n\n /**\n * Gets all required resources (where required=true).\n *\n * @returns Array of required resource entries\n */\n public getRequired(): ResourceEntry[] {\n return this.getAll().filter((entry) => entry.required);\n }\n\n /**\n * Gets all optional resources (where required=false).\n *\n * @returns Array of optional resource entries\n */\n public getOptional(): ResourceEntry[] {\n return this.getAll().filter((entry) => !entry.required);\n }\n\n /**\n * Validates all registered resources against the environment.\n *\n * Checks each resource's field environment variables to determine if it's resolved.\n * Updates the `resolved` and `values` fields on each resource entry.\n *\n * Only required resources affect the `valid` status - optional resources\n * are checked but don't cause validation failure.\n *\n * @returns ValidationResult with validity status, missing resources, and all resources\n *\n * @example\n * ```typescript\n * const registry = ResourceRegistry.getInstance();\n * const result = registry.validate();\n *\n * if (!result.valid) {\n * console.error(\"Missing resources:\", result.missing.map(r => Object.values(r.fields).map(f => f.env)));\n * }\n * ```\n */\n public validate(): ValidationResult {\n const missing: ResourceEntry[] = [];\n\n for (const entry of this.resources.values()) {\n const values: Record<string, string> = {};\n let allSet = true;\n for (const [fieldName, fieldDef] of Object.entries(entry.fields)) {\n const val = process.env[fieldDef.env];\n if (val !== undefined && val !== \"\") {\n values[fieldName] = val;\n } else {\n allSet = false;\n }\n }\n if (allSet) {\n entry.resolved = true;\n entry.values = values;\n logger.debug(\n \"Resource %s:%s resolved from fields\",\n entry.type,\n entry.alias,\n );\n } else {\n entry.resolved = false;\n entry.values = Object.keys(values).length > 0 ? values : undefined;\n if (entry.required) {\n missing.push(entry);\n logger.debug(\n \"Required resource %s:%s missing (fields: %s)\",\n entry.type,\n entry.alias,\n Object.keys(entry.fields).join(\", \"),\n );\n } else {\n logger.debug(\n \"Optional resource %s:%s not configured (fields: %s)\",\n entry.type,\n entry.alias,\n Object.keys(entry.fields).join(\", \"),\n );\n }\n }\n }\n\n return {\n valid: missing.length === 0,\n missing,\n all: this.getAll(),\n };\n }\n\n /**\n * Validates all registered resources and enforces the result.\n *\n * - In production: throws a {@link ConfigurationError} if any required resources are missing.\n * - In development (`NODE_ENV=development`): logs a warning but continues, unless\n * `APPKIT_STRICT_VALIDATION=true` is set, in which case throws like production.\n * - When all resources are valid: logs a debug message with the count.\n *\n * @returns ValidationResult with validity status, missing resources, and all resources\n * @throws {ConfigurationError} In production when required resources are missing, or in dev when APPKIT_STRICT_VALIDATION=true\n */\n public enforceValidation(): ValidationResult {\n const validation = this.validate();\n const isDevelopment = process.env.NODE_ENV === \"development\";\n const strictValidation =\n process.env.APPKIT_STRICT_VALIDATION === \"true\" ||\n process.env.APPKIT_STRICT_VALIDATION === \"1\";\n\n if (!validation.valid) {\n const errorMessage = ResourceRegistry.formatMissingResources(\n validation.missing,\n );\n\n const shouldThrow = !isDevelopment || strictValidation;\n\n if (shouldThrow) {\n throw new ConfigurationError(errorMessage, {\n context: {\n missingResources: validation.missing.map((r) => ({\n type: r.type,\n alias: r.alias,\n plugin: r.plugin,\n envVars: Object.values(r.fields).map((f) => f.env),\n })),\n },\n });\n }\n\n // Dev mode without strict: use a visually prominent box so the warning can't be missed\n const banner = ResourceRegistry.formatDevWarningBanner(\n validation.missing,\n );\n logger.warn(\"\\n%s\", banner);\n } else if (this.size() > 0) {\n logger.debug(\"All %d resources validated successfully\", this.size());\n }\n\n return validation;\n }\n\n /**\n * Formats missing resources into a human-readable error message.\n *\n * @param missing - Array of missing resource entries\n * @returns Formatted error message string\n */\n public static formatMissingResources(missing: ResourceEntry[]): string {\n if (missing.length === 0) {\n return \"No missing resources\";\n }\n\n const lines = missing.map((entry) => {\n const envVars = Object.values(entry.fields).map((f) => f.env);\n const envHint = ` (set ${envVars.join(\", \")})`;\n return ` - ${entry.type}:${entry.alias} [${entry.plugin}]${envHint}`;\n });\n\n return `Missing required resources:\\n${lines.join(\"\\n\")}`;\n }\n\n /**\n * Formats a highly visible warning banner for dev-mode missing resources.\n * Uses box drawing to ensure the message is impossible to miss in scrolling logs.\n *\n * @param missing - Array of missing resource entries\n * @returns Formatted banner string\n */\n public static formatDevWarningBanner(missing: ResourceEntry[]): string {\n const contentLines: string[] = [\n \"MISSING REQUIRED RESOURCES (dev mode — would fail in production)\",\n \"\",\n ];\n\n for (const entry of missing) {\n const envVars = Object.values(entry.fields).map((f) => f.env);\n contentLines.push(\n ` ${entry.type}:${entry.alias} (plugin: ${entry.plugin})`,\n );\n contentLines.push(` Set: ${envVars.join(\", \")}`);\n }\n\n contentLines.push(\"\");\n contentLines.push(\n \"Add these to your .env file or environment to suppress this warning.\",\n );\n\n const maxLen = Math.max(...contentLines.map((l) => l.length));\n const border = \"=\".repeat(maxLen + 4);\n\n const boxed = contentLines.map((line) => `| ${line.padEnd(maxLen)} |`);\n\n return [border, ...boxed, border].join(\"\\n\");\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resource-registry.js","names":[],"sources":["../../src/registry/resource-registry.ts"],"sourcesContent":["/**\n * Resource Registry\n *\n * Central registry that tracks all resource requirements across all plugins.\n * Provides visibility into Databricks resources needed by the application\n * and handles deduplication when multiple plugins require the same resource\n * (dedup key: type + resourceKey).\n *\n * Use `new ResourceRegistry()` for instance-scoped usage (e.g. createApp).\n * getInstance() / resetInstance() remain for backward compatibility in tests.\n */\n\nimport type { BasePluginConfig, PluginConstructor, PluginData } from \"shared\";\nimport { ConfigurationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport { getPluginManifest } from \"./manifest-loader\";\nimport type {\n ResourceEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./types\";\nimport { PERMISSION_HIERARCHY_BY_TYPE, type ResourceType } from \"./types\";\n\nconst logger = createLogger(\"resource-registry\");\n\n/**\n * Dedup key for registry: type + resourceKey (machine-stable).\n * alias is for UI/display only.\n */\nfunction getDedupKey(type: string, resourceKey: string): string {\n return `${type}:${resourceKey}`;\n}\n\n/**\n * Returns the most permissive permission for a given resource type.\n * Uses per-type hierarchy; unknown permissions are treated as least permissive.\n */\nfunction getMostPermissivePermission(\n resourceType: ResourceType,\n p1: ResourcePermission,\n p2: ResourcePermission,\n): ResourcePermission {\n const hierarchy = PERMISSION_HIERARCHY_BY_TYPE[resourceType as ResourceType];\n const index1 = hierarchy?.indexOf(p1) ?? -1;\n const index2 = hierarchy?.indexOf(p2) ?? -1;\n return index1 > index2 ? p1 : p2;\n}\n\n/**\n * Central registry for tracking plugin resource requirements.\n * Deduplication uses type + resourceKey (machine-stable); alias is for display only.\n */\nexport class ResourceRegistry {\n private resources: Map<string, ResourceEntry> = new Map();\n\n /**\n * Registers a resource requirement for a plugin.\n * If a resource with the same type+resourceKey already exists, merges them:\n * - Combines plugin names (comma-separated)\n * - Uses the most permissive permission (per-type hierarchy)\n * - Marks as required if any plugin requires it\n * - Combines descriptions if they differ\n * - Merges fields; warns when same field name uses different env vars\n *\n * @param plugin - Name of the plugin registering the resource\n * @param resource - Resource requirement specification\n */\n public register(plugin: string, resource: ResourceRequirement): void {\n const key = getDedupKey(resource.type, resource.resourceKey);\n const existing = this.resources.get(key);\n\n if (existing) {\n // Merge with existing resource\n const merged = this.mergeResources(existing, plugin, resource);\n this.resources.set(key, merged);\n } else {\n // Create new resource entry with permission source tracking\n const entry: ResourceEntry = {\n ...resource,\n plugin,\n resolved: false,\n permissionSources: { [plugin]: resource.permission },\n };\n this.resources.set(key, entry);\n }\n }\n\n /**\n * Collects and registers resource requirements from an array of plugins.\n * For each plugin, loads its manifest (required) and runtime resource requirements.\n *\n * @param rawPlugins - Array of plugin data entries from createApp configuration\n * @throws {ConfigurationError} If any plugin is missing a manifest or manifest is invalid\n */\n public collectResources(\n rawPlugins: PluginData<PluginConstructor, unknown, string>[],\n ): void {\n for (const pluginData of rawPlugins) {\n if (!pluginData?.plugin) continue;\n\n const pluginName = pluginData.name;\n const manifest = getPluginManifest(pluginData.plugin);\n\n // Register required resources\n for (const resource of manifest.resources.required) {\n this.register(pluginName, { ...resource, required: true });\n }\n\n // Register optional resources\n for (const resource of manifest.resources.optional || []) {\n this.register(pluginName, { ...resource, required: false });\n }\n\n // Check for runtime resource requirements\n if (typeof pluginData.plugin.getResourceRequirements === \"function\") {\n const runtimeResources = pluginData.plugin.getResourceRequirements(\n pluginData.config as BasePluginConfig,\n );\n for (const resource of runtimeResources) {\n this.register(pluginName, resource as ResourceRequirement);\n }\n }\n\n logger.debug(\n \"Collected resources from plugin %s: %d total\",\n pluginName,\n this.getByPlugin(pluginName).length,\n );\n }\n }\n\n /**\n * Merges a new resource requirement with an existing entry.\n * Applies intelligent merging logic for conflicting properties.\n */\n private mergeResources(\n existing: ResourceEntry,\n newPlugin: string,\n newResource: ResourceRequirement,\n ): ResourceEntry {\n // Combine plugin names if not already included\n const plugins = existing.plugin.split(\", \");\n if (!plugins.includes(newPlugin)) {\n plugins.push(newPlugin);\n }\n\n // Track per-plugin permission sources\n const permissionSources: Record<string, ResourcePermission> = {\n ...(existing.permissionSources ?? {}),\n [newPlugin]: newResource.permission,\n };\n\n // Use the most permissive permission for this resource type; warn when escalating\n const permission = getMostPermissivePermission(\n existing.type as ResourceType,\n existing.permission,\n newResource.permission,\n );\n\n if (permission !== existing.permission) {\n logger.warn(\n 'Resource %s:%s permission escalated from \"%s\" to \"%s\" due to plugin \"%s\" ' +\n \"(previously requested by: %s). Review plugin permissions to ensure least-privilege.\",\n existing.type,\n existing.resourceKey,\n existing.permission,\n permission,\n newPlugin,\n existing.plugin,\n );\n }\n\n // Mark as required if any plugin requires it\n const required = existing.required || newResource.required;\n\n // Combine descriptions if they differ\n let description = existing.description;\n if (\n newResource.description &&\n newResource.description !== existing.description\n ) {\n if (!existing.description.includes(newResource.description)) {\n description = `${existing.description}; ${newResource.description}`;\n }\n }\n\n // Merge fields: union of field names; warn when same field name uses different env\n const fields = { ...(existing.fields ?? {}) };\n for (const [fieldName, newField] of Object.entries(\n newResource.fields ?? {},\n )) {\n const existingField = fields[fieldName];\n if (existingField) {\n if (existingField.env !== newField.env) {\n logger.warn(\n 'Resource %s:%s field \"%s\": conflicting env vars \"%s\" (from %s) vs \"%s\" (from %s). Using first.',\n existing.type,\n existing.resourceKey,\n fieldName,\n existingField.env,\n existing.plugin,\n newField.env,\n newPlugin,\n );\n }\n // keep existing\n } else {\n fields[fieldName] = newField;\n }\n }\n\n return {\n ...existing,\n plugin: plugins.join(\", \"),\n permission,\n permissionSources,\n required,\n description,\n fields,\n };\n }\n\n /**\n * Retrieves all registered resources.\n * Returns a copy of the array to prevent external mutations.\n *\n * @returns Array of all registered resource entries\n */\n public getAll(): ResourceEntry[] {\n return Array.from(this.resources.values());\n }\n\n /**\n * Gets a specific resource by type and resourceKey (dedup key).\n *\n * @param type - Resource type\n * @param resourceKey - Stable machine key (not alias; alias is for display only)\n * @returns The resource entry if found, undefined otherwise\n */\n public get(type: string, resourceKey: string): ResourceEntry | undefined {\n return this.resources.get(getDedupKey(type, resourceKey));\n }\n\n /**\n * Clears all registered resources.\n * Useful for testing or when rebuilding the registry.\n */\n public clear(): void {\n this.resources.clear();\n }\n\n /**\n * Returns the number of registered resources.\n */\n public size(): number {\n return this.resources.size;\n }\n\n /**\n * Gets all resources required by a specific plugin.\n *\n * @param pluginName - Name of the plugin\n * @returns Array of resources where the plugin is listed as a requester\n */\n public getByPlugin(pluginName: string): ResourceEntry[] {\n return this.getAll().filter((entry) =>\n entry.plugin.split(\", \").includes(pluginName),\n );\n }\n\n /**\n * Gets all required resources (where required=true).\n *\n * @returns Array of required resource entries\n */\n public getRequired(): ResourceEntry[] {\n return this.getAll().filter((entry) => entry.required);\n }\n\n /**\n * Gets all optional resources (where required=false).\n *\n * @returns Array of optional resource entries\n */\n public getOptional(): ResourceEntry[] {\n return this.getAll().filter((entry) => !entry.required);\n }\n\n /**\n * Validates all registered resources against the environment.\n *\n * Checks each resource's field environment variables to determine if it's resolved.\n * Updates the `resolved` and `values` fields on each resource entry.\n *\n * Only required resources affect the `valid` status - optional resources\n * are checked but don't cause validation failure.\n *\n * @returns ValidationResult with validity status, missing resources, and all resources\n *\n * @example\n * ```typescript\n * const registry = ResourceRegistry.getInstance();\n * const result = registry.validate();\n *\n * if (!result.valid) {\n * console.error(\"Missing resources:\", result.missing.map(r => Object.values(r.fields).map(f => f.env)));\n * }\n * ```\n */\n public validate(): ValidationResult {\n const missing: ResourceEntry[] = [];\n\n for (const entry of this.resources.values()) {\n const values: Record<string, string> = {};\n let allSet = true;\n for (const [fieldName, fieldDef] of Object.entries(entry.fields)) {\n const val = process.env[fieldDef.env];\n if (val !== undefined && val !== \"\") {\n values[fieldName] = val;\n } else {\n allSet = false;\n }\n }\n if (allSet) {\n entry.resolved = true;\n entry.values = values;\n logger.debug(\n \"Resource %s:%s resolved from fields\",\n entry.type,\n entry.alias,\n );\n } else {\n entry.resolved = false;\n entry.values = Object.keys(values).length > 0 ? values : undefined;\n if (entry.required) {\n missing.push(entry);\n logger.debug(\n \"Required resource %s:%s missing (fields: %s)\",\n entry.type,\n entry.alias,\n Object.keys(entry.fields).join(\", \"),\n );\n } else {\n logger.debug(\n \"Optional resource %s:%s not configured (fields: %s)\",\n entry.type,\n entry.alias,\n Object.keys(entry.fields).join(\", \"),\n );\n }\n }\n }\n\n return {\n valid: missing.length === 0,\n missing,\n all: this.getAll(),\n };\n }\n\n /**\n * Validates all registered resources and enforces the result.\n *\n * - In production: throws a {@link ConfigurationError} if any required resources are missing.\n * - In development (`NODE_ENV=development`): logs a warning but continues, unless\n * `APPKIT_STRICT_VALIDATION=true` is set, in which case throws like production.\n * - When all resources are valid: logs a debug message with the count.\n *\n * @returns ValidationResult with validity status, missing resources, and all resources\n * @throws {ConfigurationError} In production when required resources are missing, or in dev when APPKIT_STRICT_VALIDATION=true\n */\n public enforceValidation(): ValidationResult {\n const validation = this.validate();\n const isDevelopment = process.env.NODE_ENV === \"development\";\n const strictValidation =\n process.env.APPKIT_STRICT_VALIDATION === \"true\" ||\n process.env.APPKIT_STRICT_VALIDATION === \"1\";\n\n if (!validation.valid) {\n const errorMessage = ResourceRegistry.formatMissingResources(\n validation.missing,\n );\n\n const shouldThrow = !isDevelopment || strictValidation;\n\n if (shouldThrow) {\n throw new ConfigurationError(errorMessage, {\n context: {\n missingResources: validation.missing.map((r) => ({\n type: r.type,\n alias: r.alias,\n plugin: r.plugin,\n envVars: Object.values(r.fields).map((f) => f.env),\n })),\n },\n });\n }\n\n // Dev mode without strict: use a visually prominent box so the warning can't be missed\n const banner = ResourceRegistry.formatDevWarningBanner(\n validation.missing,\n );\n logger.warn(\"\\n%s\", banner);\n } else if (this.size() > 0) {\n logger.debug(\"All %d resources validated successfully\", this.size());\n }\n\n return validation;\n }\n\n /**\n * Formats missing resources into a human-readable error message.\n *\n * @param missing - Array of missing resource entries\n * @returns Formatted error message string\n */\n public static formatMissingResources(missing: ResourceEntry[]): string {\n if (missing.length === 0) {\n return \"No missing resources\";\n }\n\n const lines = missing.map((entry) => {\n const envVars = Object.values(entry.fields).map((f) => f.env);\n const envHint = ` (set ${envVars.join(\", \")})`;\n return ` - ${entry.type}:${entry.alias} [${entry.plugin}]${envHint}`;\n });\n\n return `Missing required resources:\\n${lines.join(\"\\n\")}`;\n }\n\n /**\n * Formats a highly visible warning banner for dev-mode missing resources.\n * Uses box drawing to ensure the message is impossible to miss in scrolling logs.\n *\n * @param missing - Array of missing resource entries\n * @returns Formatted banner string\n */\n public static formatDevWarningBanner(missing: ResourceEntry[]): string {\n const contentLines: string[] = [\n \"MISSING REQUIRED RESOURCES (dev mode — would fail in production)\",\n \"\",\n ];\n\n for (const entry of missing) {\n const envVars = Object.values(entry.fields).map((f) => f.env);\n contentLines.push(\n ` ${entry.type}:${entry.alias} (plugin: ${entry.plugin})`,\n );\n contentLines.push(` Set: ${envVars.join(\", \")}`);\n }\n\n contentLines.push(\"\");\n contentLines.push(\n \"Add these to your .env file or environment to suppress this warning.\",\n );\n\n const maxLen = Math.max(...contentLines.map((l) => l.length));\n const border = \"=\".repeat(maxLen + 4);\n\n const boxed = contentLines.map((line) => `| ${line.padEnd(maxLen)} |`);\n\n return [border, ...boxed, border].join(\"\\n\");\n }\n}\n"],"mappings":"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"}
@@ -1,76 +1,8 @@
1
+ import { AppPermission, DatabasePermission, ExperimentPermission, GenieSpacePermission, JobPermission, ResourcePermission, ResourceType, SecretPermission, ServingEndpointPermission, SqlWarehousePermission, UcConnectionPermission, UcFunctionPermission, VectorSearchIndexPermission, VolumePermission } from "./types.generated.js";
1
2
  import { JSONSchema7 } from "json-schema";
2
3
 
3
4
  //#region src/registry/types.d.ts
4
5
 
5
- /**
6
- * Resource Registry Type System
7
- *
8
- * This module defines the type system for the AppKit Resource Registry,
9
- * which enables plugins to declare their Databricks resource requirements
10
- * in a machine-readable format.
11
- *
12
- * Resource types are exposed as first-class citizens with their specific
13
- * permissions, making it simple for users to declare dependencies.
14
- * Internal tooling handles conversion to Databricks app.yaml format.
15
- */
16
- /**
17
- * Supported resource types that plugins can depend on.
18
- * Each type has its own set of valid permissions.
19
- */
20
- declare enum ResourceType {
21
- /** Secret scope for secure credential storage */
22
- SECRET = "secret",
23
- /** Databricks Job for scheduled or triggered workflows */
24
- JOB = "job",
25
- /** Databricks SQL Warehouse for query execution */
26
- SQL_WAREHOUSE = "sql_warehouse",
27
- /** Model serving endpoint for ML inference */
28
- SERVING_ENDPOINT = "serving_endpoint",
29
- /** Unity Catalog Volume for file storage */
30
- VOLUME = "volume",
31
- /** Vector Search Index for similarity search */
32
- VECTOR_SEARCH_INDEX = "vector_search_index",
33
- /** Unity Catalog Function */
34
- UC_FUNCTION = "uc_function",
35
- /** Unity Catalog Connection for external data sources */
36
- UC_CONNECTION = "uc_connection",
37
- /** Database (Lakebase) for persistent storage */
38
- DATABASE = "database",
39
- /** Genie Space for AI assistant */
40
- GENIE_SPACE = "genie_space",
41
- /** MLflow Experiment for ML tracking */
42
- EXPERIMENT = "experiment",
43
- /** Databricks App dependency */
44
- APP = "app",
45
- }
46
- /** Permissions for SECRET resources */
47
- type SecretPermission = "MANAGE" | "READ" | "WRITE";
48
- /** Permissions for JOB resources */
49
- type JobPermission = "CAN_MANAGE" | "CAN_MANAGE_RUN" | "CAN_VIEW";
50
- /** Permissions for SQL_WAREHOUSE resources */
51
- type SqlWarehousePermission = "CAN_MANAGE" | "CAN_USE";
52
- /** Permissions for SERVING_ENDPOINT resources */
53
- type ServingEndpointPermission = "CAN_MANAGE" | "CAN_QUERY" | "CAN_VIEW";
54
- /** Permissions for VOLUME resources */
55
- type VolumePermission = "READ_VOLUME" | "WRITE_VOLUME";
56
- /** Permissions for VECTOR_SEARCH_INDEX resources */
57
- type VectorSearchIndexPermission = "SELECT";
58
- /** Permissions for UC_FUNCTION resources */
59
- type UcFunctionPermission = "EXECUTE";
60
- /** Permissions for UC_CONNECTION resources */
61
- type UcConnectionPermission = "USE_CONNECTION";
62
- /** Permissions for DATABASE resources */
63
- type DatabasePermission = "CAN_CONNECT_AND_CREATE";
64
- /** Permissions for GENIE_SPACE resources */
65
- type GenieSpacePermission = "CAN_EDIT" | "CAN_VIEW" | "CAN_RUN" | "CAN_MANAGE";
66
- /** Permissions for EXPERIMENT resources */
67
- type ExperimentPermission = "CAN_READ" | "CAN_EDIT" | "CAN_MANAGE";
68
- /** Permissions for APP resources */
69
- type AppPermission = "CAN_USE";
70
- /**
71
- * Union of all possible permission levels across all resource types.
72
- */
73
- type ResourcePermission = SecretPermission | JobPermission | SqlWarehousePermission | ServingEndpointPermission | VolumePermission | VectorSearchIndexPermission | UcFunctionPermission | UcConnectionPermission | DatabasePermission | GenieSpacePermission | ExperimentPermission | AppPermission;
74
6
  /**
75
7
  * Defines a single field for a resource. Each field has its own environment variable and optional description.
76
8
  * Single-value types use one key (e.g. id); multi-value types (database, secret) use multiple (e.g. instance_name, database_name or scope, key).
@@ -177,5 +109,5 @@ interface PluginManifest {
177
109
  license?: string;
178
110
  }
179
111
  //#endregion
180
- export { ConfigSchema, PluginManifest, ResourceEntry, ResourceFieldEntry, ResourcePermission, ResourceRequirement, ResourceType, ValidationResult };
112
+ export { ConfigSchema, PluginManifest, ResourceEntry, ResourceFieldEntry, ResourceRequirement, ValidationResult };
181
113
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/registry/types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgBA;AA2CA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAGA;AAOA;AAGY,aAhFA,YAAA;EAqFA;EAAkB,MAAA,GAAA,QAAA;;KAE1B,GAAA,KAAA;;eAEA,GAAA,eAAA;;kBAEA,GAAA,kBAAA;;QAEA,GAAA,QAAA;;qBAEA,GAAA,qBAAA;;aAEA,GAAA,aAAA;EAAa;EAmCA,aAAA,GAAA,eAAkB;EAWlB;EAAmB,QAAA,GAAA,UAAA;;aActB,GAAA,aAAA;;YAMJ,GAAA,YAAA;EAAM;EAUC,GAAA,GAAA,KAAA;;;AAeoB,KAjJzB,gBAAA,GAiJyB,QAAA,GAAA,MAAA,GAAA,OAAA;;AAfE,KA/H3B,aAAA,GA+H2B,YAAA,GAAA,gBAAA,GAAA,UAAA;;AAqBtB,KAjJL,sBAAA,GAiJqB,YAAA,GAAA,SAAA;;AAKtB,KAnJC,yBAAA,GAmJD,YAAA,GAAA,WAAA,GAAA,UAAA;;AAGS,KAnJR,gBAAA,GAmJQ,aAAA,GAAA,cAAA;AAWpB;AAMiB,KAjKL,2BAAA,GAiKmB,QAAA;;AAeZ,KA7KP,oBAAA,GA6KO,SAAA;;AAGA,KA7KP,sBAAA,GA6KO,gBAAA;;AAQP,KAlLA,kBAAA,GAkLA,wBAAA;;KA/KA,oBAAA;;KAOA,oBAAA;;KAGA,aAAA;;;;KAKA,kBAAA,GACR,mBACA,gBACA,yBACA,4BACA,mBACA,8BACA,uBACA,yBACA,qBACA,uBACA,uBACA;;;;;UAmCa,kBAAA;;;;;;;;;;UAWA,mBAAA;;QAET;;;;;;;;cAYM;;;;;UAMJ,eAAe;;;;;;;;UAUR,aAAA,SAAsB;;;;;;WAQ5B;;;;;;sBAOW,eAAe;;;;;UAMpB,gBAAA;;;;WAKN;;OAGJ;;;;;;;;KAWK,YAAA,GAAe;;;;;UAMV,cAAA;;;;;;;;;;;;cAeH,KAAK;;cAGL,KAAK;;;;;;;YAQP"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/registry/types.ts"],"sourcesContent":[],"mappings":";;;;;AAmGA;;;;AAesB,UAxDL,kBAAA,CAwDK;;EAfoC,GAAA,EAAA,MAAA;EAqBzC;EAAgB,WAAA,CAAA,EAAA,MAAA;;;;AAmBjC;AAMA;AAA+B,UA5Ed,mBAAA,CA4Ec;;MAejB,EAzFN,YAyFM;;OAGA,EAAA,MAAA;;EAQU,WAAA,EAAA,MAAA;;;;cAxFV;;;;;UAMJ,eAAe;;;;;;;;UAUR,aAAA,SAAsB;;;;;;WAQ5B;;;;;;sBAOW,eAAe;;;;;UAMpB,gBAAA;;;;WAKN;;OAGJ;;;;;;;;KAWK,YAAA,GAAe;;;;;UAMV,cAAA;;;;;;;;;;;;cAeH,KAAK;;cAGL,KAAK;;;;;;;YAQP"}
@@ -0,0 +1,45 @@
1
+ //#region src/registry/types.generated.d.ts
2
+ /** Resource types from schema $defs.resourceType.enum */
3
+ declare enum ResourceType {
4
+ SECRET = "secret",
5
+ JOB = "job",
6
+ SQL_WAREHOUSE = "sql_warehouse",
7
+ SERVING_ENDPOINT = "serving_endpoint",
8
+ VOLUME = "volume",
9
+ VECTOR_SEARCH_INDEX = "vector_search_index",
10
+ UC_FUNCTION = "uc_function",
11
+ UC_CONNECTION = "uc_connection",
12
+ DATABASE = "database",
13
+ GENIE_SPACE = "genie_space",
14
+ EXPERIMENT = "experiment",
15
+ APP = "app",
16
+ }
17
+ /** Permissions for SECRET resources */
18
+ type SecretPermission = "READ" | "WRITE" | "MANAGE";
19
+ /** Permissions for JOB resources */
20
+ type JobPermission = "CAN_VIEW" | "CAN_MANAGE_RUN" | "CAN_MANAGE";
21
+ /** Permissions for SQL_WAREHOUSE resources */
22
+ type SqlWarehousePermission = "CAN_USE" | "CAN_MANAGE";
23
+ /** Permissions for SERVING_ENDPOINT resources */
24
+ type ServingEndpointPermission = "CAN_VIEW" | "CAN_QUERY" | "CAN_MANAGE";
25
+ /** Permissions for VOLUME resources */
26
+ type VolumePermission = "READ_VOLUME" | "WRITE_VOLUME";
27
+ /** Permissions for VECTOR_SEARCH_INDEX resources */
28
+ type VectorSearchIndexPermission = "SELECT";
29
+ /** Permissions for UC_FUNCTION resources */
30
+ type UcFunctionPermission = "EXECUTE";
31
+ /** Permissions for UC_CONNECTION resources */
32
+ type UcConnectionPermission = "USE_CONNECTION";
33
+ /** Permissions for DATABASE resources */
34
+ type DatabasePermission = "CAN_CONNECT_AND_CREATE";
35
+ /** Permissions for GENIE_SPACE resources */
36
+ type GenieSpacePermission = "CAN_VIEW" | "CAN_RUN" | "CAN_EDIT" | "CAN_MANAGE";
37
+ /** Permissions for EXPERIMENT resources */
38
+ type ExperimentPermission = "CAN_READ" | "CAN_EDIT" | "CAN_MANAGE";
39
+ /** Permissions for APP resources */
40
+ type AppPermission = "CAN_USE";
41
+ /** Union of all possible permission levels across all resource types. */
42
+ type ResourcePermission = SecretPermission | JobPermission | SqlWarehousePermission | ServingEndpointPermission | VolumePermission | VectorSearchIndexPermission | UcFunctionPermission | UcConnectionPermission | DatabasePermission | GenieSpacePermission | ExperimentPermission | AppPermission;
43
+ //#endregion
44
+ export { AppPermission, DatabasePermission, ExperimentPermission, GenieSpacePermission, JobPermission, ResourcePermission, ResourceType, SecretPermission, ServingEndpointPermission, SqlWarehousePermission, UcConnectionPermission, UcFunctionPermission, VectorSearchIndexPermission, VolumePermission };
45
+ //# sourceMappingURL=types.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.generated.d.ts","names":[],"sources":["../../src/registry/types.generated.ts"],"sourcesContent":[],"mappings":";;AAIY,aAAA,YAAA;EAmBA,MAAA,GAAA,QAAA;EAGA,GAAA,GAAA,KAAA;EAGA,aAAA,GAAA,eAAsB;EAGtB,gBAAA,GAAA,kBAAyB;EAGzB,MAAA,GAAA,QAAA;EAGA,mBAAA,GAAA,qBAA2B;EAG3B,WAAA,GAAA,aAAoB;EAGpB,aAAA,GAAA,eAAsB;EAGtB,QAAA,GAAA,UAAkB;EAGlB,WAAA,GAAA,aAAoB;EAGpB,UAAA,GAAA,YAAoB;EAGpB,GAAA,GAAA,KAAA;AAGZ;;AACI,KArCQ,gBAAA,GAqCR,MAAA,GAAA,OAAA,GAAA,QAAA;;AAEA,KApCQ,aAAA,GAoCR,UAAA,GAAA,gBAAA,GAAA,YAAA;;AAEA,KAnCQ,sBAAA,GAmCR,SAAA,GAAA,YAAA;;AAEA,KAlCQ,yBAAA,GAkCR,UAAA,GAAA,WAAA,GAAA,YAAA;;AAEA,KAjCQ,gBAAA,GAiCR,aAAA,GAAA,cAAA;;AAEA,KAhCQ,2BAAA,GAgCR,QAAA;;AACa,KA9BL,oBAAA,GA8BK,SAAA;;KA3BL,sBAAA;;KAGA,kBAAA;;KAGA,oBAAA;;KAGA,oBAAA;;KAGA,aAAA;;KAGA,kBAAA,GACR,mBACA,gBACA,yBACA,4BACA,mBACA,8BACA,uBACA,yBACA,qBACA,uBACA,uBACA"}
@@ -0,0 +1,59 @@
1
+ //#region src/registry/types.generated.ts
2
+ /** Resource types from schema $defs.resourceType.enum */
3
+ let ResourceType = /* @__PURE__ */ function(ResourceType) {
4
+ ResourceType["SECRET"] = "secret";
5
+ ResourceType["JOB"] = "job";
6
+ ResourceType["SQL_WAREHOUSE"] = "sql_warehouse";
7
+ ResourceType["SERVING_ENDPOINT"] = "serving_endpoint";
8
+ ResourceType["VOLUME"] = "volume";
9
+ ResourceType["VECTOR_SEARCH_INDEX"] = "vector_search_index";
10
+ ResourceType["UC_FUNCTION"] = "uc_function";
11
+ ResourceType["UC_CONNECTION"] = "uc_connection";
12
+ ResourceType["DATABASE"] = "database";
13
+ ResourceType["GENIE_SPACE"] = "genie_space";
14
+ ResourceType["EXPERIMENT"] = "experiment";
15
+ ResourceType["APP"] = "app";
16
+ return ResourceType;
17
+ }({});
18
+ /** Permission hierarchy per resource type (weakest to strongest). Schema enum order. */
19
+ const PERMISSION_HIERARCHY_BY_TYPE = {
20
+ [ResourceType.SECRET]: [
21
+ "READ",
22
+ "WRITE",
23
+ "MANAGE"
24
+ ],
25
+ [ResourceType.JOB]: [
26
+ "CAN_VIEW",
27
+ "CAN_MANAGE_RUN",
28
+ "CAN_MANAGE"
29
+ ],
30
+ [ResourceType.SQL_WAREHOUSE]: ["CAN_USE", "CAN_MANAGE"],
31
+ [ResourceType.SERVING_ENDPOINT]: [
32
+ "CAN_VIEW",
33
+ "CAN_QUERY",
34
+ "CAN_MANAGE"
35
+ ],
36
+ [ResourceType.VOLUME]: ["READ_VOLUME", "WRITE_VOLUME"],
37
+ [ResourceType.VECTOR_SEARCH_INDEX]: ["SELECT"],
38
+ [ResourceType.UC_FUNCTION]: ["EXECUTE"],
39
+ [ResourceType.UC_CONNECTION]: ["USE_CONNECTION"],
40
+ [ResourceType.DATABASE]: ["CAN_CONNECT_AND_CREATE"],
41
+ [ResourceType.GENIE_SPACE]: [
42
+ "CAN_VIEW",
43
+ "CAN_RUN",
44
+ "CAN_EDIT",
45
+ "CAN_MANAGE"
46
+ ],
47
+ [ResourceType.EXPERIMENT]: [
48
+ "CAN_READ",
49
+ "CAN_EDIT",
50
+ "CAN_MANAGE"
51
+ ],
52
+ [ResourceType.APP]: ["CAN_USE"]
53
+ };
54
+ /** Set of valid permissions per type (for validation). */
55
+ const PERMISSIONS_BY_TYPE = PERMISSION_HIERARCHY_BY_TYPE;
56
+
57
+ //#endregion
58
+ export { PERMISSIONS_BY_TYPE, PERMISSION_HIERARCHY_BY_TYPE, ResourceType };
59
+ //# sourceMappingURL=types.generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.generated.js","names":[],"sources":["../../src/registry/types.generated.ts"],"sourcesContent":["// AUTO-GENERATED from packages/shared/src/schemas/plugin-manifest.schema.json\n// Do not edit. Run: pnpm exec tsx tools/generate-registry-types.ts\n\n/** Resource types from schema $defs.resourceType.enum */\nexport enum ResourceType {\n SECRET = \"secret\",\n JOB = \"job\",\n SQL_WAREHOUSE = \"sql_warehouse\",\n SERVING_ENDPOINT = \"serving_endpoint\",\n VOLUME = \"volume\",\n VECTOR_SEARCH_INDEX = \"vector_search_index\",\n UC_FUNCTION = \"uc_function\",\n UC_CONNECTION = \"uc_connection\",\n DATABASE = \"database\",\n GENIE_SPACE = \"genie_space\",\n EXPERIMENT = \"experiment\",\n APP = \"app\",\n}\n\n// ============================================================================\n// Permissions per resource type (from schema permission $defs)\n// ============================================================================\n/** Permissions for SECRET resources */\nexport type SecretPermission = \"READ\" | \"WRITE\" | \"MANAGE\";\n\n/** Permissions for JOB resources */\nexport type JobPermission = \"CAN_VIEW\" | \"CAN_MANAGE_RUN\" | \"CAN_MANAGE\";\n\n/** Permissions for SQL_WAREHOUSE resources */\nexport type SqlWarehousePermission = \"CAN_USE\" | \"CAN_MANAGE\";\n\n/** Permissions for SERVING_ENDPOINT resources */\nexport type ServingEndpointPermission = \"CAN_VIEW\" | \"CAN_QUERY\" | \"CAN_MANAGE\";\n\n/** Permissions for VOLUME resources */\nexport type VolumePermission = \"READ_VOLUME\" | \"WRITE_VOLUME\";\n\n/** Permissions for VECTOR_SEARCH_INDEX resources */\nexport type VectorSearchIndexPermission = \"SELECT\";\n\n/** Permissions for UC_FUNCTION resources */\nexport type UcFunctionPermission = \"EXECUTE\";\n\n/** Permissions for UC_CONNECTION resources */\nexport type UcConnectionPermission = \"USE_CONNECTION\";\n\n/** Permissions for DATABASE resources */\nexport type DatabasePermission = \"CAN_CONNECT_AND_CREATE\";\n\n/** Permissions for GENIE_SPACE resources */\nexport type GenieSpacePermission = \"CAN_VIEW\" | \"CAN_RUN\" | \"CAN_EDIT\" | \"CAN_MANAGE\";\n\n/** Permissions for EXPERIMENT resources */\nexport type ExperimentPermission = \"CAN_READ\" | \"CAN_EDIT\" | \"CAN_MANAGE\";\n\n/** Permissions for APP resources */\nexport type AppPermission = \"CAN_USE\";\n\n/** Union of all possible permission levels across all resource types. */\nexport type ResourcePermission =\n | SecretPermission\n | JobPermission\n | SqlWarehousePermission\n | ServingEndpointPermission\n | VolumePermission\n | VectorSearchIndexPermission\n | UcFunctionPermission\n | UcConnectionPermission\n | DatabasePermission\n | GenieSpacePermission\n | ExperimentPermission\n | AppPermission;\n\n/** Permission hierarchy per resource type (weakest to strongest). Schema enum order. */\nexport const PERMISSION_HIERARCHY_BY_TYPE: Record<ResourceType, readonly ResourcePermission[]> = {\n [ResourceType.SECRET]: [\"READ\", \"WRITE\", \"MANAGE\"],\n [ResourceType.JOB]: [\"CAN_VIEW\", \"CAN_MANAGE_RUN\", \"CAN_MANAGE\"],\n [ResourceType.SQL_WAREHOUSE]: [\"CAN_USE\", \"CAN_MANAGE\"],\n [ResourceType.SERVING_ENDPOINT]: [\"CAN_VIEW\", \"CAN_QUERY\", \"CAN_MANAGE\"],\n [ResourceType.VOLUME]: [\"READ_VOLUME\", \"WRITE_VOLUME\"],\n [ResourceType.VECTOR_SEARCH_INDEX]: [\"SELECT\"],\n [ResourceType.UC_FUNCTION]: [\"EXECUTE\"],\n [ResourceType.UC_CONNECTION]: [\"USE_CONNECTION\"],\n [ResourceType.DATABASE]: [\"CAN_CONNECT_AND_CREATE\"],\n [ResourceType.GENIE_SPACE]: [\"CAN_VIEW\", \"CAN_RUN\", \"CAN_EDIT\", \"CAN_MANAGE\"],\n [ResourceType.EXPERIMENT]: [\"CAN_READ\", \"CAN_EDIT\", \"CAN_MANAGE\"],\n [ResourceType.APP]: [\"CAN_USE\"],\n} as const;\n\n/** Set of valid permissions per type (for validation). */\nexport const PERMISSIONS_BY_TYPE: Record<ResourceType, readonly ResourcePermission[]> = PERMISSION_HIERARCHY_BY_TYPE;\n"],"mappings":";;AAIA,IAAY,sDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AA0DF,MAAa,+BAAoF;EAC9F,aAAa,SAAS;EAAC;EAAQ;EAAS;EAAS;EACjD,aAAa,MAAM;EAAC;EAAY;EAAkB;EAAa;EAC/D,aAAa,gBAAgB,CAAC,WAAW,aAAa;EACtD,aAAa,mBAAmB;EAAC;EAAY;EAAa;EAAa;EACvE,aAAa,SAAS,CAAC,eAAe,eAAe;EACrD,aAAa,sBAAsB,CAAC,SAAS;EAC7C,aAAa,cAAc,CAAC,UAAU;EACtC,aAAa,gBAAgB,CAAC,iBAAiB;EAC/C,aAAa,WAAW,CAAC,yBAAyB;EAClD,aAAa,cAAc;EAAC;EAAY;EAAW;EAAY;EAAa;EAC5E,aAAa,aAAa;EAAC;EAAY;EAAY;EAAa;EAChE,aAAa,MAAM,CAAC,UAAU;CAChC;;AAGD,MAAa,sBAA2E"}
@@ -1,3 +1,5 @@
1
+ import { PERMISSIONS_BY_TYPE, PERMISSION_HIERARCHY_BY_TYPE, ResourceType } from "./types.generated.js";
2
+
1
3
  //#region src/registry/types.ts
2
4
  /**
3
5
  * Resource Registry Type System
@@ -6,84 +8,10 @@
6
8
  * which enables plugins to declare their Databricks resource requirements
7
9
  * in a machine-readable format.
8
10
  *
9
- * Resource types are exposed as first-class citizens with their specific
10
- * permissions, making it simple for users to declare dependencies.
11
- * Internal tooling handles conversion to Databricks app.yaml format.
12
- */
13
- /**
14
- * Supported resource types that plugins can depend on.
15
- * Each type has its own set of valid permissions.
16
- */
17
- let ResourceType = /* @__PURE__ */ function(ResourceType) {
18
- /** Secret scope for secure credential storage */
19
- ResourceType["SECRET"] = "secret";
20
- /** Databricks Job for scheduled or triggered workflows */
21
- ResourceType["JOB"] = "job";
22
- /** Databricks SQL Warehouse for query execution */
23
- ResourceType["SQL_WAREHOUSE"] = "sql_warehouse";
24
- /** Model serving endpoint for ML inference */
25
- ResourceType["SERVING_ENDPOINT"] = "serving_endpoint";
26
- /** Unity Catalog Volume for file storage */
27
- ResourceType["VOLUME"] = "volume";
28
- /** Vector Search Index for similarity search */
29
- ResourceType["VECTOR_SEARCH_INDEX"] = "vector_search_index";
30
- /** Unity Catalog Function */
31
- ResourceType["UC_FUNCTION"] = "uc_function";
32
- /** Unity Catalog Connection for external data sources */
33
- ResourceType["UC_CONNECTION"] = "uc_connection";
34
- /** Database (Lakebase) for persistent storage */
35
- ResourceType["DATABASE"] = "database";
36
- /** Genie Space for AI assistant */
37
- ResourceType["GENIE_SPACE"] = "genie_space";
38
- /** MLflow Experiment for ML tracking */
39
- ResourceType["EXPERIMENT"] = "experiment";
40
- /** Databricks App dependency */
41
- ResourceType["APP"] = "app";
42
- return ResourceType;
43
- }({});
44
- /**
45
- * Permission hierarchy per resource type (weakest to strongest).
46
- * Used to compare permissions when merging; higher index = more permissive.
47
- * Unknown permissions are treated as less than any known permission.
11
+ * Resource types and permissions are generated from plugin-manifest.schema.json
12
+ * (see types.generated.ts). Hand-written interfaces below define the registry API.
48
13
  */
49
- const PERMISSION_HIERARCHY_BY_TYPE = {
50
- [ResourceType.SECRET]: [
51
- "READ",
52
- "WRITE",
53
- "MANAGE"
54
- ],
55
- [ResourceType.JOB]: [
56
- "CAN_VIEW",
57
- "CAN_MANAGE_RUN",
58
- "CAN_MANAGE"
59
- ],
60
- [ResourceType.SQL_WAREHOUSE]: ["CAN_USE", "CAN_MANAGE"],
61
- [ResourceType.SERVING_ENDPOINT]: [
62
- "CAN_VIEW",
63
- "CAN_QUERY",
64
- "CAN_MANAGE"
65
- ],
66
- [ResourceType.VOLUME]: ["READ_VOLUME", "WRITE_VOLUME"],
67
- [ResourceType.VECTOR_SEARCH_INDEX]: ["SELECT"],
68
- [ResourceType.UC_FUNCTION]: ["EXECUTE"],
69
- [ResourceType.UC_CONNECTION]: ["USE_CONNECTION"],
70
- [ResourceType.DATABASE]: ["CAN_CONNECT_AND_CREATE"],
71
- [ResourceType.GENIE_SPACE]: [
72
- "CAN_VIEW",
73
- "CAN_RUN",
74
- "CAN_EDIT",
75
- "CAN_MANAGE"
76
- ],
77
- [ResourceType.EXPERIMENT]: [
78
- "CAN_READ",
79
- "CAN_EDIT",
80
- "CAN_MANAGE"
81
- ],
82
- [ResourceType.APP]: ["CAN_USE"]
83
- };
84
- /** Set of valid permissions per type (for validation). */
85
- const PERMISSIONS_BY_TYPE = PERMISSION_HIERARCHY_BY_TYPE;
86
14
 
87
15
  //#endregion
88
- export { PERMISSIONS_BY_TYPE, PERMISSION_HIERARCHY_BY_TYPE, ResourceType };
16
+ export { };
89
17
  //# sourceMappingURL=types.js.map