From 3b36b3de52da6cf1ff444000b227cb1cf9f84f76 Mon Sep 17 00:00:00 2001 From: Joakim Carlstein Date: Thu, 16 Nov 2023 10:58:35 +0100 Subject: [PATCH] feat(cli): implement a default "loader" for JavaScript files Supports any of the `.js`, `.cjs` and `.mjs` file extensions --- .changeset/tame-fans-clap.md | 5 ++++ packages/cli/src/plugin-loader-js.ts | 44 ++++++++++++++++++++++++++++ packages/cli/src/up-command.ts | 9 ++++-- 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 .changeset/tame-fans-clap.md create mode 100644 packages/cli/src/plugin-loader-js.ts diff --git a/.changeset/tame-fans-clap.md b/.changeset/tame-fans-clap.md new file mode 100644 index 0000000..de23cf4 --- /dev/null +++ b/.changeset/tame-fans-clap.md @@ -0,0 +1,5 @@ +--- +'@emigrate/cli': minor +--- + +Implement a default "loader" plugin for JavaScript files (supports `.js`, `.cjs` and `.mjs` file extensions) diff --git a/packages/cli/src/plugin-loader-js.ts b/packages/cli/src/plugin-loader-js.ts new file mode 100644 index 0000000..f8f5e62 --- /dev/null +++ b/packages/cli/src/plugin-loader-js.ts @@ -0,0 +1,44 @@ +import { type LoaderPlugin } from '@emigrate/plugin-tools/types'; + +const loaderJs: LoaderPlugin = { + loadableExtensions: ['.js', '.cjs', '.mjs'], + async loadMigration(migration) { + const migrationModule: unknown = await import(migration.filePath); + + if (typeof migrationModule === 'function') { + return async () => { + await migrationModule(); + }; + } + + if ( + migrationModule && + typeof migrationModule === 'object' && + 'default' in migrationModule && + typeof migrationModule.default === 'function' + ) { + const migrationFunction = migrationModule.default; + return async () => { + await migrationFunction(); + }; + } + + if ( + migrationModule && + typeof migrationModule === 'object' && + 'up' in migrationModule && + typeof migrationModule.up === 'function' + ) { + const migrationFunction = migrationModule.up; + return async () => { + await migrationFunction(); + }; + } + + return async () => { + throw new Error(`Migration file does not export a function: ${migration.relativeFilePath}`); + }; + }, +}; + +export default loaderJs; diff --git a/packages/cli/src/up-command.ts b/packages/cli/src/up-command.ts index b007edc..124dcb3 100644 --- a/packages/cli/src/up-command.ts +++ b/packages/cli/src/up-command.ts @@ -4,6 +4,7 @@ import { type LoaderPlugin } from '@emigrate/plugin-tools/types'; import { ShowUsageError } from './show-usage-error.js'; import { type Config } from './types.js'; import { stripLeadingPeriod } from './strip-leading-period.js'; +import pluginLoaderJs from './plugin-loader-js.js'; type ExtraFlags = { dry?: boolean; @@ -40,7 +41,7 @@ export default async function upCommand({ directory, dry, plugins = [] }: Config } const migrationFileExtensions = new Set(migrationFiles.map((file) => stripLeadingPeriod(path.extname(file)))); - const loaderPlugins = await getOrLoadPlugins('loader', plugins); + const loaderPlugins = await getOrLoadPlugins('loader', [...plugins, pluginLoaderJs]); const loaderByExtension = new Map( [...migrationFileExtensions].map( @@ -91,10 +92,12 @@ export default async function upCommand({ directory, dry, plugins = [] }: Config console.log(' -', name, '...'); const extension = stripLeadingPeriod(path.extname(name)); - const filename = path.resolve(process.cwd(), directory, name); + const cwd = process.cwd(); + const filePath = path.resolve(cwd, directory, name); + const relativeFilePath = path.relative(cwd, filePath); const loader = loaderByExtension.get(extension)!; - const migration = await loader.loadMigration({ name, filename, extension }); + const migration = await loader.loadMigration({ name, filePath, relativeFilePath, cwd, directory, extension }); try { await migration();