Plugins

Creating a Plugin

Build your own Universal Data Layer plugin

Creating Your First Plugin

Creating a UDL plugin is straightforward. A plugin is essentially a package with a udl.config.js file that defines its configuration and behavior.

Plugin Structure

At minimum, a plugin needs:

my-plugin/
├── package.json
├── udl.config.js
└── ... (your plugin code)

Basic Plugin Configuration

Create a udl.config.js file at the root of your plugin:

udl.config.js
export const config = {
  type: 'source',           // Plugin type: 'source' or 'core'
  name: 'my-plugin',        // Plugin name
  version: '1.0.0',         // Plugin version
};

export function onLoad({ options, config }) {
  console.log('My plugin loaded!');
  console.log('Options:', options);
  console.log('App config:', config);
}

Plugin Types

Source Plugin

Source plugins connect to external data sources:

udl.config.js
export const config = {
  type: 'source',
  name: 'my-data-source',
  version: '1.0.0',
};

export function onLoad({ options, config }) {
  // Initialize your data source connection
  const apiKey = options?.apiKey;
  const spaceId = options?.spaceId;

  console.log(`Connecting to data source with space: ${spaceId}`);

  // Set up data fetching logic, GraphQL schema extensions, etc.
}

The onLoad Hook

The onLoad function is your plugin's initialization point. It receives a context object with:

Context Properties

options (object)

Plugin-specific options passed during registration:

udl.config.js
export function onLoad({ options }) {
  const {
    apiKey,
    environment,
    customSetting,
  } = options || {};

  // Use options to configure your plugin
}

config (object)

The application's UDL configuration:

udl.config.js
export function onLoad({ config }) {
  const { port, host, endpoint } = config;

  // Access app-level configuration
  console.log(`Server will run on ${host}:${port}`);
}

Plugin Best Practices

1. Validate Options

Always validate required options in your onLoad hook:

udl.config.js
export function onLoad({ options }) {
  if (!options?.apiKey) {
    throw new Error('apiKey is required for my-plugin');
  }

  if (!options?.spaceId) {
    throw new Error('spaceId is required for my-plugin');
  }
}

2. Handle Errors Gracefully

Wrap initialization logic in try-catch blocks:

udl.config.js
export async function onLoad({ options }) {
  try {
    await initializeClient(options);
    console.log('Plugin initialized successfully');
  } catch (error) {
    console.error('Failed to initialize plugin:', error);
    throw error;
  }
}

3. Use Async/Await

The onLoad hook supports async operations:

udl.config.js
export async function onLoad({ options }) {
  // Async initialization
  await setupDatabase(options);
  await loadSchemaExtensions();
  console.log('Async initialization complete');
}

4. Export Type Definitions (TypeScript)

If using TypeScript, export your types:

export interface MyPluginOptions {
  apiKey: string;
  environment?: 'production' | 'staging';
}

Publishing Your Plugin

As an npm Package

  1. Add UDL as a peer dependency:
package.json
{
  "name": "udl-plugin-myservice",
  "version": "1.0.0",
  "peerDependencies": {
    "universal-data-layer": "^0.0.1"
  }
}
  1. Ensure udl.config.js is included in published files:
package.json
{
  "files": [
    "dist",
    "udl.config.js"
  ]
}
  1. Publish to npm:
Terminal
npm publish

As a Local Plugin

You can also use plugins locally without publishing:

udl.config.js
export const config = {
  plugins: [
    './local-plugins/my-plugin',  // Relative path
  ],
};

Next Steps