@databricks/appkit 0.24.0 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CLAUDE.md +8 -1
  2. package/dist/appkit/package.js +1 -1
  3. package/dist/context/execution-context.js +1 -7
  4. package/dist/context/execution-context.js.map +1 -1
  5. package/dist/context/index.js +1 -1
  6. package/dist/context/index.js.map +1 -1
  7. package/dist/index.d.ts +2 -1
  8. package/dist/index.js +2 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/plugin/interceptors/retry.js +22 -0
  11. package/dist/plugin/interceptors/retry.js.map +1 -1
  12. package/dist/plugins/files/plugin.d.ts +46 -15
  13. package/dist/plugins/files/plugin.d.ts.map +1 -1
  14. package/dist/plugins/files/plugin.js +182 -103
  15. package/dist/plugins/files/plugin.js.map +1 -1
  16. package/dist/plugins/files/policy.d.ts +45 -0
  17. package/dist/plugins/files/policy.d.ts.map +1 -0
  18. package/dist/plugins/files/policy.js +63 -0
  19. package/dist/plugins/files/policy.js.map +1 -0
  20. package/dist/plugins/files/types.d.ts +16 -8
  21. package/dist/plugins/files/types.d.ts.map +1 -1
  22. package/dist/registry/manifest-loader.d.ts +2 -2
  23. package/dist/registry/manifest-loader.d.ts.map +1 -1
  24. package/docs/api/appkit/Class.PolicyDeniedError.md +52 -0
  25. package/docs/api/appkit/Interface.FilePolicyUser.md +23 -0
  26. package/docs/api/appkit/Interface.FileResource.md +36 -0
  27. package/docs/api/appkit/TypeAlias.FileAction.md +18 -0
  28. package/docs/api/appkit/TypeAlias.FilePolicy.md +20 -0
  29. package/docs/api/appkit/Variable.READ_ACTIONS.md +8 -0
  30. package/docs/api/appkit/Variable.WRITE_ACTIONS.md +8 -0
  31. package/docs/api/appkit.md +19 -12
  32. package/docs/faq.md +8 -8
  33. package/docs/plugins/execution-context.md +0 -1
  34. package/docs/plugins/files.md +150 -2
  35. package/docs/plugins/{serving.md → model-serving.md} +1 -1
  36. package/llms.txt +8 -1
  37. package/package.json +1 -1
  38. package/sbom.cdx.json +1 -1
package/CLAUDE.md CHANGED
@@ -49,9 +49,9 @@ npx @databricks/appkit docs <query>
49
49
  - [Files plugin](./docs/plugins/files.md): File operations against Databricks Unity Catalog Volumes. Supports listing, reading, downloading, uploading, deleting, and previewing files with built-in caching, retry, and timeout handling via the execution interceptor pipeline.
50
50
  - [Genie plugin](./docs/plugins/genie.md): Integrates Databricks AI/BI Genie spaces into your AppKit application, enabling natural language data queries via a conversational interface.
51
51
  - [Lakebase plugin](./docs/plugins/lakebase.md): Provides a PostgreSQL connection pool for Databricks Lakebase Autoscaling with automatic OAuth token refresh.
52
+ - [Model Serving plugin](./docs/plugins/model-serving.md): Provides an authenticated proxy to Databricks Model Serving endpoints, with invoke and streaming support.
52
53
  - [Plugin management](./docs/plugins/plugin-management.md): AppKit includes a CLI for managing plugins. All commands are available under npx @databricks/appkit plugin.
53
54
  - [Server plugin](./docs/plugins/server.md): Provides HTTP server capabilities with development and production modes.
54
- - [Serving plugin](./docs/plugins/serving.md): Provides an authenticated proxy to Databricks Model Serving endpoints, with invoke and streaming support.
55
55
  - [Vector Search plugin](./docs/plugins/vector-search.md): Query Databricks Vector Search indexes with hybrid search, reranking, and cursor pagination from your AppKit application.
56
56
 
57
57
  ## appkit API reference [collapsed]
@@ -64,6 +64,7 @@ npx @databricks/appkit docs <query>
64
64
  - [Class: ExecutionError](./docs/api/appkit/Class.ExecutionError.md): Error thrown when an operation execution fails.
65
65
  - [Class: InitializationError](./docs/api/appkit/Class.InitializationError.md): Error thrown when a service or component is not properly initialized.
66
66
  - [Abstract Class: Plugin<TConfig>](./docs/api/appkit/Class.Plugin.md): Base abstract class for creating AppKit plugins.
67
+ - [Class: PolicyDeniedError](./docs/api/appkit/Class.PolicyDeniedError.md): Thrown when a policy denies an action.
67
68
  - [Class: ResourceRegistry](./docs/api/appkit/Class.ResourceRegistry.md): Central registry for tracking plugin resource requirements.
68
69
  - [Class: ServerError](./docs/api/appkit/Class.ServerError.md): Error thrown when server lifecycle operations fail.
69
70
  - [Class: TunnelError](./docs/api/appkit/Class.TunnelError.md): Error thrown when remote tunnel operations fail.
@@ -89,6 +90,8 @@ npx @databricks/appkit docs <query>
89
90
  - [Interface: CacheConfig](./docs/api/appkit/Interface.CacheConfig.md): Configuration for the CacheInterceptor. Controls TTL, size limits, storage backend, and probabilistic cleanup.
90
91
  - [Interface: DatabaseCredential](./docs/api/appkit/Interface.DatabaseCredential.md): Database credentials with OAuth token for Postgres connection
91
92
  - [Interface: EndpointConfig](./docs/api/appkit/Interface.EndpointConfig.md): Properties
93
+ - [Interface: FilePolicyUser](./docs/api/appkit/Interface.FilePolicyUser.md): Minimal user identity passed to the policy function.
94
+ - [Interface: FileResource](./docs/api/appkit/Interface.FileResource.md): Describes the file or directory being acted upon.
92
95
  - [Interface: GenerateDatabaseCredentialRequest](./docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md): Request parameters for generating database OAuth credentials
93
96
  - [Interface: ITelemetry](./docs/api/appkit/Interface.ITelemetry.md): Plugin-facing interface for OpenTelemetry instrumentation.
94
97
  - [Interface: LakebasePoolConfig](./docs/api/appkit/Interface.LakebasePoolConfig.md): Configuration for creating a Lakebase connection pool
@@ -105,12 +108,16 @@ npx @databricks/appkit docs <query>
105
108
  - [Interface: ValidationResult](./docs/api/appkit/Interface.ValidationResult.md): Result of validating all registered resources against the environment.
106
109
  - [Type Alias: ConfigSchema](./docs/api/appkit/TypeAlias.ConfigSchema.md): Configuration schema definition for plugin config.
107
110
  - [Type Alias: ExecutionResult<T>](./docs/api/appkit/TypeAlias.ExecutionResult.md): Discriminated union for plugin execution results.
111
+ - [Type Alias: FileAction](./docs/api/appkit/TypeAlias.FileAction.md): Every action the files plugin can perform.
112
+ - [Type Alias: FilePolicy()](./docs/api/appkit/TypeAlias.FilePolicy.md): A policy function that decides whether user may perform action on
108
113
  - [Type Alias: IAppRouter](./docs/api/appkit/TypeAlias.IAppRouter.md): Express router type for plugin route registration
109
114
  - [Type Alias: PluginData<T, U, N>](./docs/api/appkit/TypeAlias.PluginData.md): Tuple of plugin class, config, and name. Created by toPlugin() and passed to createApp().
110
115
  - [Type Alias: ResourcePermission](./docs/api/appkit/TypeAlias.ResourcePermission.md): Union of all possible permission levels across all resource types.
111
116
  - [Type Alias: ServingFactory](./docs/api/appkit/TypeAlias.ServingFactory.md): Factory function returned by AppKit.serving.
112
117
  - [Type Alias: ToPlugin()<T, U, N>](./docs/api/appkit/TypeAlias.ToPlugin.md): Factory function type returned by toPlugin(). Accepts optional config and returns a PluginData tuple.
118
+ - [Variable: READ_ACTIONS](./docs/api/appkit/Variable.READ_ACTIONS.md): Actions that only read data.
113
119
  - [Variable: sql](./docs/api/appkit/Variable.sql.md): SQL helper namespace
120
+ - [Variable: WRITE_ACTIONS](./docs/api/appkit/Variable.WRITE_ACTIONS.md): Actions that mutate data.
114
121
 
115
122
  ## appkit-ui API reference [collapsed]
116
123
 
@@ -1,6 +1,6 @@
1
1
  //#region package.json
2
2
  var name = "@databricks/appkit";
3
- var version = "0.24.0";
3
+ var version = "0.25.1";
4
4
 
5
5
  //#endregion
6
6
  export { name, version };
@@ -60,12 +60,6 @@ function getWarehouseId() {
60
60
  function getWorkspaceId() {
61
61
  return getExecutionContext().workspaceId;
62
62
  }
63
- /**
64
- * Check if currently running in a user context.
65
- */
66
- function isInUserContext() {
67
- return executionContextStorage.getStore() !== void 0;
68
- }
69
63
  var executionContextStorage;
70
64
  var init_execution_context = __esmMin((() => {
71
65
  init_errors();
@@ -76,5 +70,5 @@ var init_execution_context = __esmMin((() => {
76
70
 
77
71
  //#endregion
78
72
  init_execution_context();
79
- export { getCurrentUserId, getExecutionContext, getWarehouseId, getWorkspaceClient, getWorkspaceId, init_execution_context, isInUserContext, runInUserContext };
73
+ export { getCurrentUserId, getExecutionContext, getWarehouseId, getWorkspaceClient, getWorkspaceId, init_execution_context, runInUserContext };
80
74
  //# sourceMappingURL=execution-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.js","names":[],"sources":["../../src/context/execution-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ConfigurationError } from \"../errors\";\nimport { ServiceContext } from \"./service-context\";\nimport {\n type ExecutionContext,\n isUserContext,\n type UserContext,\n} from \"./user-context\";\n\n/**\n * AsyncLocalStorage for execution context.\n * Used to pass user context through the call stack without explicit parameters.\n */\nconst executionContextStorage = new AsyncLocalStorage<UserContext>();\n\n/**\n * Run a function in the context of a user.\n * All calls within the function will have access to the user context.\n *\n * @param userContext - The user context to use\n * @param fn - The function to run\n * @returns The result of the function\n */\nexport function runInUserContext<T>(userContext: UserContext, fn: () => T): T {\n return executionContextStorage.run(userContext, fn);\n}\n\n/**\n * Get the current execution context.\n *\n * - If running inside a user context (via asUser), returns the user context\n * - Otherwise, returns the service context\n *\n * @throws Error if ServiceContext is not initialized\n */\nexport function getExecutionContext(): ExecutionContext {\n const userContext = executionContextStorage.getStore();\n if (userContext) {\n return userContext;\n }\n return ServiceContext.get();\n}\n\n/**\n * Get the current user ID for cache keying and telemetry.\n *\n * Returns the user ID if in user context, otherwise the service user ID.\n */\nexport function getCurrentUserId(): string {\n const ctx = getExecutionContext();\n if (isUserContext(ctx)) {\n return ctx.userId;\n }\n return ctx.serviceUserId;\n}\n\n/**\n * Get the WorkspaceClient for the current execution context.\n */\nexport function getWorkspaceClient() {\n return getExecutionContext().client;\n}\n\n/**\n * Get the warehouse ID promise.\n */\nexport function getWarehouseId(): Promise<string> {\n const ctx = getExecutionContext();\n if (!ctx.warehouseId) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"No plugin requires a SQL Warehouse. Add a sql_warehouse resource to your plugin manifest, or set DATABRICKS_WAREHOUSE_ID\",\n );\n }\n return ctx.warehouseId;\n}\n\n/**\n * Get the workspace ID promise.\n */\nexport function getWorkspaceId(): Promise<string> {\n return getExecutionContext().workspaceId;\n}\n\n/**\n * Check if currently running in a user context.\n */\nexport function isInUserContext(): boolean {\n const ctx = executionContextStorage.getStore();\n return ctx !== undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,SAAgB,iBAAoB,aAA0B,IAAgB;AAC5E,QAAO,wBAAwB,IAAI,aAAa,GAAG;;;;;;;;;;AAWrD,SAAgB,sBAAwC;CACtD,MAAM,cAAc,wBAAwB,UAAU;AACtD,KAAI,YACF,QAAO;AAET,QAAO,eAAe,KAAK;;;;;;;AAQ7B,SAAgB,mBAA2B;CACzC,MAAM,MAAM,qBAAqB;AACjC,KAAI,cAAc,IAAI,CACpB,QAAO,IAAI;AAEb,QAAO,IAAI;;;;;AAMb,SAAgB,qBAAqB;AACnC,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,iBAAkC;CAChD,MAAM,MAAM,qBAAqB;AACjC,KAAI,CAAC,IAAI,YACP,OAAM,mBAAmB,iBACvB,gBACA,2HACD;AAEH,QAAO,IAAI;;;;;AAMb,SAAgB,iBAAkC;AAChD,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,kBAA2B;AAEzC,QADY,wBAAwB,UAAU,KAC/B;;;;cAxF8B;uBACI;oBAK3B;CAMlB,0BAA0B,IAAI,mBAAgC"}
1
+ {"version":3,"file":"execution-context.js","names":[],"sources":["../../src/context/execution-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ConfigurationError } from \"../errors\";\nimport { ServiceContext } from \"./service-context\";\nimport {\n type ExecutionContext,\n isUserContext,\n type UserContext,\n} from \"./user-context\";\n\n/**\n * AsyncLocalStorage for execution context.\n * Used to pass user context through the call stack without explicit parameters.\n */\nconst executionContextStorage = new AsyncLocalStorage<UserContext>();\n\n/**\n * Run a function in the context of a user.\n * All calls within the function will have access to the user context.\n *\n * @param userContext - The user context to use\n * @param fn - The function to run\n * @returns The result of the function\n */\nexport function runInUserContext<T>(userContext: UserContext, fn: () => T): T {\n return executionContextStorage.run(userContext, fn);\n}\n\n/**\n * Get the current execution context.\n *\n * - If running inside a user context (via asUser), returns the user context\n * - Otherwise, returns the service context\n *\n * @throws Error if ServiceContext is not initialized\n */\nexport function getExecutionContext(): ExecutionContext {\n const userContext = executionContextStorage.getStore();\n if (userContext) {\n return userContext;\n }\n return ServiceContext.get();\n}\n\n/**\n * Get the current user ID for cache keying and telemetry.\n *\n * Returns the user ID if in user context, otherwise the service user ID.\n */\nexport function getCurrentUserId(): string {\n const ctx = getExecutionContext();\n if (isUserContext(ctx)) {\n return ctx.userId;\n }\n return ctx.serviceUserId;\n}\n\n/**\n * Get the WorkspaceClient for the current execution context.\n */\nexport function getWorkspaceClient() {\n return getExecutionContext().client;\n}\n\n/**\n * Get the warehouse ID promise.\n */\nexport function getWarehouseId(): Promise<string> {\n const ctx = getExecutionContext();\n if (!ctx.warehouseId) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"No plugin requires a SQL Warehouse. Add a sql_warehouse resource to your plugin manifest, or set DATABRICKS_WAREHOUSE_ID\",\n );\n }\n return ctx.warehouseId;\n}\n\n/**\n * Get the workspace ID promise.\n */\nexport function getWorkspaceId(): Promise<string> {\n return getExecutionContext().workspaceId;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,SAAgB,iBAAoB,aAA0B,IAAgB;AAC5E,QAAO,wBAAwB,IAAI,aAAa,GAAG;;;;;;;;;;AAWrD,SAAgB,sBAAwC;CACtD,MAAM,cAAc,wBAAwB,UAAU;AACtD,KAAI,YACF,QAAO;AAET,QAAO,eAAe,KAAK;;;;;;;AAQ7B,SAAgB,mBAA2B;CACzC,MAAM,MAAM,qBAAqB;AACjC,KAAI,cAAc,IAAI,CACpB,QAAO,IAAI;AAEb,QAAO,IAAI;;;;;AAMb,SAAgB,qBAAqB;AACnC,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,iBAAkC;CAChD,MAAM,MAAM,qBAAqB;AACjC,KAAI,CAAC,IAAI,YACP,OAAM,mBAAmB,iBACvB,gBACA,2HACD;AAEH,QAAO,IAAI;;;;;AAMb,SAAgB,iBAAkC;AAChD,QAAO,qBAAqB,CAAC;;;;cAhFgB;uBACI;oBAK3B;CAMlB,0BAA0B,IAAI,mBAAgC"}
@@ -1,6 +1,6 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { ServiceContext, init_service_context } from "./service-context.js";
3
- import { getCurrentUserId, getExecutionContext, getWarehouseId, getWorkspaceClient, getWorkspaceId, init_execution_context, isInUserContext, runInUserContext } from "./execution-context.js";
3
+ import { getCurrentUserId, getExecutionContext, getWarehouseId, getWorkspaceClient, getWorkspaceId, init_execution_context, runInUserContext } from "./execution-context.js";
4
4
 
5
5
  //#region src/context/index.ts
6
6
  var init_context = __esmMin((() => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/context/index.ts"],"sourcesContent":["export {\n getCurrentUserId,\n getExecutionContext,\n getWarehouseId,\n getWorkspaceClient,\n getWorkspaceId,\n isInUserContext,\n runInUserContext,\n} from \"./execution-context\";\nexport { ServiceContext } from \"./service-context\";\nexport type { UserContext } from \"./user-context\";\n"],"mappings":";;;;;;yBAQ6B;uBACsB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/context/index.ts"],"sourcesContent":["export {\n getCurrentUserId,\n getExecutionContext,\n getWarehouseId,\n getWorkspaceClient,\n getWorkspaceId,\n runInUserContext,\n} from \"./execution-context\";\nexport { ServiceContext } from \"./service-context\";\nexport type { UserContext } from \"./user-context\";\n"],"mappings":";;;;;;yBAO6B;uBACsB"}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ import { getPluginManifest, getResourceRequirements } from "./registry/manifest-
31
31
  import { ResourceRegistry } from "./registry/resource-registry.js";
32
32
  import "./registry/index.js";
33
33
  import { analytics } from "./plugins/analytics/analytics.js";
34
+ import { FileAction, FilePolicy, FilePolicyUser, FileResource, PolicyDeniedError, READ_ACTIONS, WRITE_ACTIONS } from "./plugins/files/policy.js";
34
35
  import { files } from "./plugins/files/plugin.js";
35
36
  import { genie } from "./plugins/genie/genie.js";
36
37
  import { lakebase } from "./plugins/lakebase/lakebase.js";
@@ -41,4 +42,4 @@ import "./plugins/index.js";
41
42
  import { extractServingEndpoints, findServerFile } from "./type-generator/serving/server-file-extractor.js";
42
43
  import { appKitServingTypesPlugin } from "./type-generator/serving/vite-plugin.js";
43
44
  import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
44
- export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, type EndpointConfig, ExecutionError, type ExecutionResult, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginData, type PluginManifest, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, type ServingEndpointEntry, type ServingEndpointRegistry, type ServingFactory, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, type ToPlugin, TunnelError, ValidationError, type ValidationResult, analytics, appKitServingTypesPlugin, appKitTypesPlugin, createApp, createLakebasePool, extractServingEndpoints, files, findServerFile, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, serving, sql, toPlugin };
45
+ export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, type EndpointConfig, ExecutionError, type ExecutionResult, type FileAction, type FilePolicy, type FilePolicyUser, type FileResource, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginData, type PluginManifest, PolicyDeniedError, READ_ACTIONS, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, type ServingEndpointEntry, type ServingEndpointRegistry, type ServingFactory, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, type ToPlugin, TunnelError, ValidationError, type ValidationResult, WRITE_ACTIONS, analytics, appKitServingTypesPlugin, appKitTypesPlugin, createApp, createLakebasePool, extractServingEndpoints, files, findServerFile, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, serving, sql, toPlugin };
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ import { Plugin } from "./plugin/plugin.js";
24
24
  import { toPlugin } from "./plugin/to-plugin.js";
25
25
  import "./plugin/index.js";
26
26
  import { analytics } from "./plugins/analytics/analytics.js";
27
+ import { PolicyDeniedError, READ_ACTIONS, WRITE_ACTIONS } from "./plugins/files/policy.js";
27
28
  import { files } from "./plugins/files/plugin.js";
28
29
  import { genie } from "./plugins/genie/genie.js";
29
30
  import { lakebase } from "./plugins/lakebase/lakebase.js";
@@ -39,5 +40,5 @@ init_context();
39
40
  init_errors();
40
41
 
41
42
  //#endregion
42
- export { AppKitError, AuthenticationError, CacheManager, ConfigurationError, ConnectionError, ExecutionError, InitializationError, Plugin, RequestedClaimsPermissionSet, ResourceRegistry, ResourceType, ServerError, SeverityNumber, SpanStatusCode, TunnelError, ValidationError, analytics, appKitServingTypesPlugin, appKitTypesPlugin, createApp, createLakebasePool, extractServingEndpoints, files, findServerFile, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, serving, sql, toPlugin };
43
+ export { AppKitError, AuthenticationError, CacheManager, ConfigurationError, ConnectionError, ExecutionError, InitializationError, Plugin, PolicyDeniedError, READ_ACTIONS, RequestedClaimsPermissionSet, ResourceRegistry, ResourceType, ServerError, SeverityNumber, SpanStatusCode, TunnelError, ValidationError, WRITE_ACTIONS, analytics, appKitServingTypesPlugin, appKitTypesPlugin, createApp, createLakebasePool, extractServingEndpoints, files, findServerFile, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, serving, sql, toPlugin };
43
44
  //# sourceMappingURL=index.js.map
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 PluginData,\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 getUsernameWithApiLookup,\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 {\n type ExecutionResult,\n Plugin,\n type ToPlugin,\n toPlugin,\n} from \"./plugin\";\nexport { analytics, files, genie, lakebase, server, serving } from \"./plugins\";\nexport type {\n EndpointConfig,\n ServingEndpointEntry,\n ServingEndpointRegistry,\n ServingFactory,\n} from \"./plugins/serving/types\";\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\";\nexport {\n extractServingEndpoints,\n findServerFile,\n} from \"./type-generator/serving/server-file-extractor\";\nexport { appKitServingTypesPlugin } from \"./type-generator/serving/vite-plugin\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkCgD;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 PluginData,\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 getUsernameWithApiLookup,\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 {\n type ExecutionResult,\n Plugin,\n type ToPlugin,\n toPlugin,\n} from \"./plugin\";\nexport { analytics, files, genie, lakebase, server, serving } from \"./plugins\";\n// Files plugin types (for custom policy authoring)\nexport type {\n FileAction,\n FilePolicy,\n FilePolicyUser,\n FileResource,\n} from \"./plugins/files/policy\";\nexport {\n PolicyDeniedError,\n READ_ACTIONS,\n WRITE_ACTIONS,\n} from \"./plugins/files/policy\";\nexport type {\n EndpointConfig,\n ServingEndpointEntry,\n ServingEndpointRegistry,\n ServingFactory,\n} from \"./plugins/serving/types\";\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\";\nexport {\n extractServingEndpoints,\n findServerFile,\n} from \"./type-generator/serving/server-file-extractor\";\nexport { appKitServingTypesPlugin } from \"./type-generator/serving/vite-plugin\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkCgD;aAa9B"}
@@ -1,7 +1,28 @@
1
1
  import { createLogger } from "../../logging/logger.js";
2
+ import { AppKitError, init_base } from "../../errors/base.js";
2
3
 
3
4
  //#region src/plugin/interceptors/retry.ts
5
+ init_base();
4
6
  const logger = createLogger("interceptors:retry");
7
+ /**
8
+ * Determines whether an error is safe to retry.
9
+ *
10
+ * Priority:
11
+ * 1. AppKitError — reads the `isRetryable` boolean property.
12
+ * 2. Databricks SDK ApiError (duck-typed) — calls `isRetryable()` method,
13
+ * or falls back to status-code heuristic (5xx / 429 → retryable).
14
+ * 3. Unknown errors — treated as retryable to preserve backward compatibility.
15
+ */
16
+ function isRetryableError(error) {
17
+ if (error instanceof AppKitError) return error.isRetryable;
18
+ if (error instanceof Error && "statusCode" in error) {
19
+ const record = error;
20
+ if (typeof record.statusCode !== "number") return true;
21
+ if (typeof record.isRetryable === "function") return record.isRetryable();
22
+ return record.statusCode >= 500 || record.statusCode === 429;
23
+ }
24
+ return true;
25
+ }
5
26
  var RetryInterceptor = class {
6
27
  attempts;
7
28
  initialDelay;
@@ -24,6 +45,7 @@ var RetryInterceptor = class {
24
45
  throw error;
25
46
  }
26
47
  if (context.signal?.aborted) throw error;
48
+ if (!isRetryableError(error)) throw error;
27
49
  const delay = this.calculateDelay(attempt);
28
50
  await this.sleep(delay);
29
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","names":[],"sources":["../../../src/plugin/interceptors/retry.ts"],"sourcesContent":["import type { RetryConfig } from \"shared\";\nimport { createLogger } from \"../../logging/logger\";\nimport type { ExecutionInterceptor, InterceptorContext } from \"./types\";\n\nconst logger = createLogger(\"interceptors:retry\");\n\n// interceptor to handle retry logic\nexport class RetryInterceptor implements ExecutionInterceptor {\n private attempts: number;\n private initialDelay: number;\n private maxDelay: number;\n\n constructor(config: RetryConfig) {\n this.attempts = config.attempts ?? 3;\n this.initialDelay = config.initialDelay ?? 1000;\n this.maxDelay = config.maxDelay ?? 30000;\n }\n\n async intercept<T>(\n fn: () => Promise<T>,\n context: InterceptorContext,\n ): Promise<T> {\n let lastError: Error | unknown;\n\n for (let attempt = 1; attempt <= this.attempts; attempt++) {\n try {\n const result = await fn();\n\n if (attempt > 1) {\n logger.event()?.setExecution({\n retry_attempts: attempt - 1,\n });\n }\n\n return result;\n } catch (error) {\n lastError = error;\n\n // last attempt, rethrow the error\n if (attempt === this.attempts) {\n logger.event()?.setExecution({\n retry_attempts: attempt - 1,\n });\n throw error;\n }\n\n // don't retry if was already aborted\n if (context.signal?.aborted) {\n throw error;\n }\n\n const delay = this.calculateDelay(attempt);\n await this.sleep(delay);\n }\n }\n\n // type guard\n throw lastError;\n }\n\n private calculateDelay(attempt: number): number {\n const delay = this.initialDelay * 2 ** (attempt - 1);\n const capped = Math.min(delay, this.maxDelay);\n\n return capped * Math.random();\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"],"mappings":";;;AAIA,MAAM,SAAS,aAAa,qBAAqB;AAGjD,IAAa,mBAAb,MAA8D;CAC5D,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,QAAqB;AAC/B,OAAK,WAAW,OAAO,YAAY;AACnC,OAAK,eAAe,OAAO,gBAAgB;AAC3C,OAAK,WAAW,OAAO,YAAY;;CAGrC,MAAM,UACJ,IACA,SACY;EACZ,IAAI;AAEJ,OAAK,IAAI,UAAU,GAAG,WAAW,KAAK,UAAU,UAC9C,KAAI;GACF,MAAM,SAAS,MAAM,IAAI;AAEzB,OAAI,UAAU,EACZ,QAAO,OAAO,EAAE,aAAa,EAC3B,gBAAgB,UAAU,GAC3B,CAAC;AAGJ,UAAO;WACA,OAAO;AACd,eAAY;AAGZ,OAAI,YAAY,KAAK,UAAU;AAC7B,WAAO,OAAO,EAAE,aAAa,EAC3B,gBAAgB,UAAU,GAC3B,CAAC;AACF,UAAM;;AAIR,OAAI,QAAQ,QAAQ,QAClB,OAAM;GAGR,MAAM,QAAQ,KAAK,eAAe,QAAQ;AAC1C,SAAM,KAAK,MAAM,MAAM;;AAK3B,QAAM;;CAGR,AAAQ,eAAe,SAAyB;EAC9C,MAAM,QAAQ,KAAK,eAAe,MAAM,UAAU;AAGlD,SAFe,KAAK,IAAI,OAAO,KAAK,SAAS,GAE7B,KAAK,QAAQ;;CAG/B,AAAQ,MAAM,IAA2B;AACvC,SAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC"}
1
+ {"version":3,"file":"retry.js","names":[],"sources":["../../../src/plugin/interceptors/retry.ts"],"sourcesContent":["import type { RetryConfig } from \"shared\";\nimport { AppKitError } from \"../../errors/base\";\nimport { createLogger } from \"../../logging/logger\";\nimport type { ExecutionInterceptor, InterceptorContext } from \"./types\";\n\nconst logger = createLogger(\"interceptors:retry\");\n\n/**\n * Determines whether an error is safe to retry.\n *\n * Priority:\n * 1. AppKitError — reads the `isRetryable` boolean property.\n * 2. Databricks SDK ApiError (duck-typed) — calls `isRetryable()` method,\n * or falls back to status-code heuristic (5xx / 429 → retryable).\n * 3. Unknown errors — treated as retryable to preserve backward compatibility.\n */\nfunction isRetryableError(error: unknown): boolean {\n if (error instanceof AppKitError) {\n return error.isRetryable;\n }\n\n if (error instanceof Error && \"statusCode\" in error) {\n const record = error as Record<string, unknown>;\n if (typeof record.statusCode !== \"number\") {\n return true;\n }\n if (typeof record.isRetryable === \"function\") {\n return (record.isRetryable as () => boolean)();\n }\n return record.statusCode >= 500 || record.statusCode === 429;\n }\n\n return true;\n}\n\nexport class RetryInterceptor implements ExecutionInterceptor {\n private attempts: number;\n private initialDelay: number;\n private maxDelay: number;\n\n constructor(config: RetryConfig) {\n this.attempts = config.attempts ?? 3;\n this.initialDelay = config.initialDelay ?? 1000;\n this.maxDelay = config.maxDelay ?? 30000;\n }\n\n async intercept<T>(\n fn: () => Promise<T>,\n context: InterceptorContext,\n ): Promise<T> {\n let lastError: Error | unknown;\n\n for (let attempt = 1; attempt <= this.attempts; attempt++) {\n try {\n const result = await fn();\n\n if (attempt > 1) {\n logger.event()?.setExecution({\n retry_attempts: attempt - 1,\n });\n }\n\n return result;\n } catch (error) {\n lastError = error;\n\n if (attempt === this.attempts) {\n logger.event()?.setExecution({\n retry_attempts: attempt - 1,\n });\n throw error;\n }\n\n if (context.signal?.aborted) {\n throw error;\n }\n\n if (!isRetryableError(error)) {\n throw error;\n }\n\n const delay = this.calculateDelay(attempt);\n await this.sleep(delay);\n }\n }\n\n throw lastError;\n }\n\n private calculateDelay(attempt: number): number {\n const delay = this.initialDelay * 2 ** (attempt - 1);\n const capped = Math.min(delay, this.maxDelay);\n\n return capped * Math.random();\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"],"mappings":";;;;WACgD;AAIhD,MAAM,SAAS,aAAa,qBAAqB;;;;;;;;;;AAWjD,SAAS,iBAAiB,OAAyB;AACjD,KAAI,iBAAiB,YACnB,QAAO,MAAM;AAGf,KAAI,iBAAiB,SAAS,gBAAgB,OAAO;EACnD,MAAM,SAAS;AACf,MAAI,OAAO,OAAO,eAAe,SAC/B,QAAO;AAET,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAQ,OAAO,aAA+B;AAEhD,SAAO,OAAO,cAAc,OAAO,OAAO,eAAe;;AAG3D,QAAO;;AAGT,IAAa,mBAAb,MAA8D;CAC5D,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,QAAqB;AAC/B,OAAK,WAAW,OAAO,YAAY;AACnC,OAAK,eAAe,OAAO,gBAAgB;AAC3C,OAAK,WAAW,OAAO,YAAY;;CAGrC,MAAM,UACJ,IACA,SACY;EACZ,IAAI;AAEJ,OAAK,IAAI,UAAU,GAAG,WAAW,KAAK,UAAU,UAC9C,KAAI;GACF,MAAM,SAAS,MAAM,IAAI;AAEzB,OAAI,UAAU,EACZ,QAAO,OAAO,EAAE,aAAa,EAC3B,gBAAgB,UAAU,GAC3B,CAAC;AAGJ,UAAO;WACA,OAAO;AACd,eAAY;AAEZ,OAAI,YAAY,KAAK,UAAU;AAC7B,WAAO,OAAO,EAAE,aAAa,EAC3B,gBAAgB,UAAU,GAC3B,CAAC;AACF,UAAM;;AAGR,OAAI,QAAQ,QAAQ,QAClB,OAAM;AAGR,OAAI,CAAC,iBAAiB,MAAM,CAC1B,OAAM;GAGR,MAAM,QAAQ,KAAK,eAAe,QAAQ;AAC1C,SAAM,KAAK,MAAM,MAAM;;AAI3B,QAAM;;CAGR,AAAQ,eAAe,SAAyB;EAC9C,MAAM,QAAQ,KAAK,eAAe,MAAM,UAAU;AAGlD,SAFe,KAAK,IAAI,OAAO,KAAK,SAAS,GAE7B,KAAK,QAAQ;;CAG/B,AAAQ,MAAM,IAA2B;AACvC,SAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC"}
@@ -4,6 +4,7 @@ import { Plugin } from "../../plugin/plugin.js";
4
4
  import "../../plugin/index.js";
5
5
  import { PluginManifest, ResourceRequirement } from "../../registry/types.js";
6
6
  import "../../registry/index.js";
7
+ import { FilePolicy, FilePolicyUser } from "./policy.js";
7
8
  import { FilesExport, IFilesConfig, VolumeAPI, VolumeConfig } from "./types.js";
8
9
 
9
10
  //#region src/plugins/files/plugin.d.ts
@@ -28,21 +29,22 @@ declare class FilesPlugin extends Plugin {
28
29
  */
29
30
  static getResourceRequirements(config: IFilesConfig): ResourceRequirement[];
30
31
  /**
31
- * Warns when a method is called without a user context (i.e. as service principal).
32
- * OBO access via `asUser(req)` is strongly recommended.
32
+ * Extract user identity from the request.
33
+ * Falls back to `getCurrentUserId()` in development mode.
33
34
  */
34
- private warnIfNoUserContext;
35
+ private _extractUser;
35
36
  /**
36
- * Throws when a method is called without a user context (i.e. as service principal).
37
- * OBO access via `asUser(req)` is enforced for now.
37
+ * Check the policy for a volume. No-op if no policy is configured.
38
+ * Throws `PolicyDeniedError` if denied.
38
39
  */
39
- private throwIfNoUserContext;
40
- constructor(config: IFilesConfig);
40
+ private _checkPolicy;
41
41
  /**
42
- * Creates a VolumeAPI for a specific volume key.
43
- * Each method warns if called outside a user context (service principal).
42
+ * HTTP-level wrapper around `_checkPolicy`.
43
+ * Extracts user (401 on failure), runs policy (403 on denial).
44
+ * Returns `true` if the request may proceed, `false` if a response was sent.
44
45
  */
45
- protected createVolumeAPI(volumeKey: string): VolumeAPI;
46
+ private _enforcePolicy;
47
+ constructor(config: IFilesConfig);
46
48
  injectRoutes(router: IAppRouter): void;
47
49
  /**
48
50
  * Resolve `:volumeKey` from the request. Returns the connector and key,
@@ -59,6 +61,10 @@ declare class FilesPlugin extends Plugin {
59
61
  * Invalidate cached list entries for a directory after a write operation.
60
62
  * Uses the same cache-key format as `_handleList`: resolved path for
61
63
  * subdirectories, `"__root__"` for the volume root.
64
+ *
65
+ * Cache keys include `getCurrentUserId()` — must match the identity used
66
+ * by `this.execute()` in `_handleList`. Both run in service-principal
67
+ * context; wrapping either in `runInUserContext` would break invalidation.
62
68
  */
63
69
  private _invalidateListCache;
64
70
  private _handleApiError;
@@ -79,6 +85,19 @@ declare class FilesPlugin extends Plugin {
79
85
  private _handleUpload;
80
86
  private _handleMkdir;
81
87
  private _handleDelete;
88
+ /**
89
+ * Creates a VolumeAPI for a specific volume key.
90
+ *
91
+ * By default, enforces the volume's policy before each operation.
92
+ * Pass `bypassPolicy: true` to skip policy checks — useful for
93
+ * background jobs or migrations that should bypass user-facing policies.
94
+ *
95
+ * @security When `bypassPolicy` is `true`, no policy enforcement runs.
96
+ * Do not expose bypassed APIs to HTTP routes or end-user code paths.
97
+ */
98
+ protected createVolumeAPI(volumeKey: string, user: FilePolicyUser, options?: {
99
+ bypassPolicy?: boolean;
100
+ }): VolumeAPI;
82
101
  private inflightWrites;
83
102
  private trackWrite;
84
103
  shutdown(): Promise<void>;
@@ -86,13 +105,16 @@ declare class FilesPlugin extends Plugin {
86
105
  * Returns the programmatic API for the Files plugin.
87
106
  * Callable with a volume key to get a volume-scoped handle.
88
107
  *
108
+ * All operations execute as the service principal.
109
+ * Use policies to control per-user access.
110
+ *
89
111
  * @example
90
112
  * ```ts
91
- * // OBO access (recommended)
92
- * appKit.files("uploads").asUser(req).list()
93
- *
94
- * // Service principal access (logs a warning)
113
+ * // Service principal access
95
114
  * appKit.files("uploads").list()
115
+ *
116
+ * // With policy: pass user identity for access control
117
+ * appKit.files("uploads").asUser(req).list()
96
118
  * ```
97
119
  */
98
120
  exports(): FilesExport;
@@ -101,7 +123,16 @@ declare class FilesPlugin extends Plugin {
101
123
  /**
102
124
  * @internal
103
125
  */
104
- declare const files: ToPlugin<typeof FilesPlugin, IFilesConfig, string>;
126
+ declare const files: ToPlugin<typeof FilesPlugin, IFilesConfig, string> & {
127
+ policy: {
128
+ readonly all: (...policies: FilePolicy[]) => FilePolicy;
129
+ readonly any: (...policies: FilePolicy[]) => FilePolicy;
130
+ readonly not: (p: FilePolicy) => FilePolicy;
131
+ readonly publicRead: () => FilePolicy;
132
+ readonly denyAll: () => FilePolicy;
133
+ readonly allowAll: () => FilePolicy;
134
+ };
135
+ };
105
136
  //#endregion
106
137
  export { FilesPlugin, files };
107
138
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","names":[],"sources":["../../../src/plugins/files/plugin.ts"],"mappings":";;;;;;;;;cAoCa,WAAA,SAAoB,MAAA;EAC/B,IAAA;;SAGO,QAAA,EAAuB,cAAA;EAAA,iBACb,WAAA;EAAA,UACC,MAAA,EAAQ,YAAA;EAAA,QAElB,gBAAA;EAAA,QACA,aAAA;EAAA,QACA,UAAA;EAJkB;;;;;EAAA,OAWnB,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,SAAe,YAAA;EAkEzC;;;;EAAA,OA3Cb,uBAAA,CAAwB,MAAA,EAAQ,YAAA,GAAe,mBAAA;EAu4BtC;;;;EAAA,QAj3BR,mBAAA;EA7DR;;;;EAAA,QA0EQ,oBAAA;cAQI,MAAA,EAAQ,YAAA;EA3EZ;;;;EAAA,UAgHE,eAAA,CAAgB,SAAA,WAAoB,SAAA;EAmD9C,YAAA,CAAa,MAAA,EAAQ,UAAA;EA1JyB;;;;EAAA,QAwRtC,cAAA;EAjQ8C;;;;EAAA,QAwR9C,YAAA;EAAA,QAQA,aAAA;EAhNE;;;;;EAAA,QAgOF,oBAAA;EAAA,QAiBA,eAAA;EAAA,QA8BA,gBAAA;EAAA,QAOM,WAAA;EAAA,QA+BA,WAAA;EAAA,QAoCA,eAAA;EAAA,QAWA,UAAA;EA9EA;;;;;EAAA,QA8FA,UAAA;EAAA,QA8EA,aAAA;EAAA,QAoCA,eAAA;EAAA,QAoCA,cAAA;EAAA,QAoCA,aAAA;EAAA,QA2GA,YAAA;EAAA,QA6CA,aAAA;EAAA,QA6CN,cAAA;EAAA,QAEA,UAAA;EAOF,QAAA,CAAA,GAAY,OAAA;EAgClB;;;;;;AAmCF;;;;;;;EAnCE,OAAA,CAAA,GAAW,WAAA;EA2BX,YAAA,CAAA,GAAgB,MAAA;AAAA;;;;cAQL,KAAA,EAAK,QAAA,QAAA,WAAA,EAAA,YAAA"}
1
+ {"version":3,"file":"plugin.d.ts","names":[],"sources":["../../../src/plugins/files/plugin.ts"],"mappings":";;;;;;;;;;cA2Ca,WAAA,SAAoB,MAAA;EAC/B,IAAA;;SAGO,QAAA,EAAuB,cAAA;EAAA,iBACb,WAAA;EAAA,UACC,MAAA,EAAQ,YAAA;EAAA,QAElB,gBAAA;EAAA,QACA,aAAA;EAAA,QACA,UAAA;EAJkB;;;;;EAAA,OAWnB,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,SAAe,YAAA;EAuIzC;;;;EAAA,OAhHb,uBAAA,CAAwB,MAAA,EAAQ,YAAA,GAAe,mBAAA;EAs9B3C;;;;EAAA,QAh8BH,YAAA;EA9DuB;;;;EAAA,QAiFjB,YAAA;EA3EI;;;;;EAAA,QA4GJ,cAAA;cAsCF,MAAA,EAAQ,YAAA;EA8CpB,YAAA,CAAa,MAAA,EAAQ,UAAA;EArLyB;;;;EAAA,QAmTtC,cAAA;EA5R8C;;;;EAAA,QAmT9C,YAAA;EAAA,QAQA,aAAA;EA3MI;;;;;;;;;EAAA,QA+NJ,oBAAA;EAAA,QAgBA,eAAA;EAAA,QAqCA,gBAAA;EAAA,QAOM,WAAA;EAAA,QA8BA,WAAA;EAAA,QAmCA,eAAA;EAAA,QAWA,UAAA;EAqIA;;;;;EAAA,QArHA,UAAA;EAAA,QAiFA,aAAA;EAAA,QAoCA,eAAA;EAAA,QAoCA,cAAA;EAAA,QAoCA,aAAA;EAAA,QAgHA,YAAA;EAAA,QA0CA,aAAA;EA4GN;;;;;;;;;;EAAA,UAxDE,eAAA,CACR,SAAA,UACA,IAAA,EAAM,cAAA,EACN,OAAA;IAAY,YAAA;EAAA,IACX,SAAA;EAAA,QAoDK,cAAA;EAAA,QAEA,UAAA;EAOF,QAAA,CAAA,GAAY,OAAA;EA6EF;;;;;;;;;;;;;;;;EA1ChB,OAAA,CAAA,GAAW,WAAA;EAkCX,YAAA,CAAA,GAAgB,MAAA;AAAA;;;;cAQL,KAAA,EAAK,QAAA,QAAA,WAAA,EAAA,YAAA;;gCAAA,UAAA"}