Note
💡 Some helpful utils when developing directus extensions.
Warning
This is not an extension itself! It's a dev-util that can be used by developers while developing extensions.
- Add migrations from an extension
- Require extensions
- Require environmental variables
npm i -D directus-dev-utils
or
pnpm i -D directus-dev-utils
This helper allows you to make sure a specific env exists. It's recommended to use it in a server start hook. The function takes two parameters:
- The name of the env
- An optional config object (full config options)
Example
export default ({ filter, action }, apiExtensionContext) => {
const hookUtils = new HookUtils('<yourExtensionName>', apiExtensionContext);
action('server.start', () => {
hookUtils.requireEnv('myEnv');
});
};
This helper allows you to make sure a specific extension exists and is enabled. It's recommended to use it in a server start hook. The function takes three parameters:
- The bundle name of the extension (
null
if it's not part of an extension) - The name of the extension
- An optional config object (full config options)
Example
export default ({ filter, action }, apiExtensionContext) => {
const hookUtils = new HookUtils('<yourExtensionName>', apiExtensionContext);
action('server.start', () => {
hookUtils.requireExtension('display', 'directus-extension-field-actions'); // NOTE: you can add optional options
});
};
The MigrationUtils
allows you to add and require migrations from your extension. Please note that the end user still needs to run a sync-command before they can be applied (see #Sync & run migrations)
- Add a
./migrations
folder to your extensions./src
folder - Add new migration files to your folder. Make sure to use a unique name. Directus requires the schema:
[identifier]-[name].js
(read docs). We recommend to add your extension-name as a prefix, e.g:20231202A-myExtension-my-custom-migration.js
. - Configure your extension to include the folder in the final bundle (see #Extensions-SDK Configuration if you bundle your extension with the directus-extensions sdk)
- Create an
MigrationUtils
instance as a top-level function inside thedefineHook
function
Example
import { defineHook } from '@directus/extensions-sdk';
import { HookExtensionContext, RegisterFunctions } from '@directus/extensions';
import { MigrationUtils } from 'directus-dev-utils';
export default defineHook((registerFunctions: RegisterFunctions, apiExtensionContext: HookExtensionContext) => {
// Init the migrationUtils automatically registeres the emitter, CLI-Command, and Migration check on server startup
const migrationUtils = new MigrationUtils('gravatar', registerFunctions, apiExtensionContext);
migrationUtils.initMigrationUtils();
// That's all - keep coding!
});
Tip
The MigrationUtils
class is an extension of HookUtils
. Therewith you can use all HookUtils functions from a MigrationUtils instance too!
Important
When using the dev-utils you can use typescript to write your extensions. They will be transpiled while bundeling. This may slow down the build process a bit, as we spin up a tsc compiler.
Note that imported dependencies in migrations won't be bundled into the final migration! This means that any dependency you use, must also be installed on the final directus project!
The extensions migrations still needs to be pushed to the directus migrations folder. This dev-utils automatically registeres a cli command for that. When running the following command, all extensions using the dev-uils will sync their migrations to the migrations directory. If a file already exists, it will not be replaced! Afterwards the directus migrations can be applied as usual.
# Sync all extensions migrations to the directus migration folder
npx directus devUtils syncMigrations
# Apply all new migrations
npx directus database migrate:latest
If you're building your extension with the directus extensions-sdk you'll need to create and add the migrations folder to the dist output of the build process. You can do that by installing rollup-plugin-copy
in your extension and add it as a plugin. We already provide a full config for the plugin.
// extension.config.js
import copy from 'rollup-plugin-copy';
import { ExtensionConfig } from 'directus-dev-utils';
export default {
plugins: [
copy(new ExtensionConfig().getRollupCopyConfig()),
],
};
Important
Note that changes to the migrations won't be detected automatically. You'll need to re-build the extension and also manually update the extension on your directus instance after changes. This also applies when using the extension watch/dev mode and the directus auto-reload config.
- Add this as a file-dependency to a package-json of a directus-extension (e.g
"directus-dev-utils": "file:../../github-utomic/directus-dev-utils"
) - Run
pnpm i
&pmpm dev
on this repo - Run
pnpm i
&pmpm dev
on the extension - Check in the directus project (here you also can install the extension as a local dependency)
- --> repeat (note:
pnpm i
will always re-install local dependencies to make sure they're up to date!)