Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,6 @@ import { Plugin, toPlugin } from '@databricks/appkit';
class MyPlugin extends Plugin {
name: string = "myPlugin";

// Validate required environment variables
validateEnv() {
// Check process.env for required vars
}

// Async initialization
async setup() {
// Initialize resources
Expand Down
11 changes: 10 additions & 1 deletion apps/dev-playground/server/reconnect-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ interface ReconnectStreamResponse {

export class ReconnectPlugin extends Plugin {
public name = "reconnect";
protected envVars: string[] = [];

static manifest = {
name: "reconnect",
displayName: "Reconnect Plugin",
description: "A plugin that reconnects to the server",
resources: {
required: [],
optional: [],
},
};

injectRoutes(router: IAppRouter): void {
this.route<ReconnectResponse>(router, {
Expand Down
11 changes: 10 additions & 1 deletion apps/dev-playground/server/telemetry-example-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ import type { Request, Response, Router } from "express";

class TelemetryExamples extends Plugin {
public name = "telemetry-examples" as const;
protected envVars: string[] = [];

static manifest = {
name: "telemetry-examples",
displayName: "Telemetry Examples Plugin",
description: "A plugin that provides telemetry examples",
resources: {
required: [],
optional: [],
},
};

private requestCounter: Counter;
private durationHistogram: Histogram;
Expand Down
98 changes: 52 additions & 46 deletions docs/docs/api/appkit/Class.Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,81 @@
Base abstract class for creating AppKit plugins.

All plugins must declare a static `manifest` property with their metadata
and resource requirements. Plugins can also implement a static
`getResourceRequirements()` method for dynamic requirements based on config.
and resource requirements. The manifest defines:
- `required` resources: Always needed for the plugin to function
- `optional` resources: May be needed depending on plugin configuration

## Example
## Static vs Runtime Resource Requirements

The manifest is static and doesn't know the plugin's runtime configuration.
For resources that become required based on config options, plugins can
implement a static `getResourceRequirements(config)` method.

At runtime, this method is called with the actual config to determine
which "optional" resources should be treated as "required".

## Examples

```typescript
import { Plugin, toPlugin, PluginManifest, ResourceType } from '@databricks/appkit';

// Define manifest (required)
const myManifest: PluginManifest = {
name: 'myPlugin',
displayName: 'My Plugin',
description: 'Does something awesome',
resources: {
required: [
{
type: ResourceType.SQL_WAREHOUSE,
alias: 'warehouse',
description: 'SQL Warehouse for queries',
permission: 'CAN_USE',
env: 'DATABRICKS_WAREHOUSE_ID'
}
{ type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }
],
optional: []
}
};

class MyPlugin extends Plugin<MyConfig> {
static manifest = myManifest; // Required!

static manifest = myManifest;
name = 'myPlugin';
protected envVars: string[] = [];
}
```

async setup() {
// Initialize your plugin
```typescript
interface MyConfig extends BasePluginConfig {
enableCaching?: boolean;
}

const myManifest: PluginManifest = {
name: 'myPlugin',
resources: {
required: [
{ type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }
],
optional: [
// Database is optional in the static manifest
{ type: ResourceType.DATABASE, alias: 'cache', description: 'Required if caching enabled', ... }
]
}
};

injectRoutes(router: Router) {
// Register HTTP endpoints
class MyPlugin extends Plugin<MyConfig> {
static manifest = myManifest;
name = 'myPlugin';

// Runtime method: converts optional resources to required based on config
static getResourceRequirements(config: MyConfig) {
const resources = [];
if (config.enableCaching) {
// When caching is enabled, Database becomes required
resources.push({
type: ResourceType.DATABASE,
alias: 'cache',
description: 'Cache storage for query results',
permission: 'CAN_CONNECT_AND_CREATE',
env: 'DATABRICKS_DATABASE_ID',
required: true // Mark as required at runtime
});
}
return resources;
}
}

export const myPlugin = toPlugin(MyPlugin, 'myPlugin');
```

## Type Parameters
Expand Down Expand Up @@ -110,14 +142,6 @@ protected devFileReader: DevFileReader;

***

### envVars

```ts
abstract protected envVars: string[];
```

***

### isReady

```ts
Expand Down Expand Up @@ -400,21 +424,3 @@ setup(): Promise<void>;
```ts
BasePlugin.setup
```

***

### validateEnv()

```ts
validateEnv(): void;
```

#### Returns

`void`

#### Implementation of

```ts
BasePlugin.validateEnv
```
Loading