feat(cli): storage and reporter are now their own options
Instead of mixing storages and reporters with other plugins in the plugin option they now have their own separate options. This is for increased future flexibility and to be more similar to other CLI tools. BREAKING CHANGE: the storage to use must now be specified using the "storage" configuration option or the "--storage" CLI option instead of having it among other plugins.
This commit is contained in:
parent
509cd41663
commit
8e87ade5c0
9 changed files with 150 additions and 95 deletions
6
.changeset/gold-eggs-argue.md
Normal file
6
.changeset/gold-eggs-argue.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'@emigrate/plugin-tools': minor
|
||||||
|
'@emigrate/cli': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Move storages and reporters out from the plugin option into their own separate options (i.e. "--reporter" and "--storage" respectively). This makes it easier to change the interfaces of storages and reporters, and it's also more similar to other tools.
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# emigrate
|
# @emigrate/cli
|
||||||
|
|
||||||
## 0.4.0
|
## 0.4.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,14 @@ const up: Action = async (args) => {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
short: 'd',
|
short: 'd',
|
||||||
},
|
},
|
||||||
|
reporter: {
|
||||||
|
type: 'string',
|
||||||
|
short: 'r',
|
||||||
|
},
|
||||||
|
storage: {
|
||||||
|
type: 'string',
|
||||||
|
short: 's',
|
||||||
|
},
|
||||||
dry: {
|
dry: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
|
|
@ -40,14 +48,16 @@ Options:
|
||||||
|
|
||||||
-h, --help Show this help message and exit
|
-h, --help Show this help message and exit
|
||||||
-d, --directory The directory where the migration files are located (required)
|
-d, --directory The directory where the migration files are located (required)
|
||||||
|
-s, --storage The storage to use for where to store the migration history (required)
|
||||||
-p, --plugin The plugin(s) to use (can be specified multiple times)
|
-p, --plugin The plugin(s) to use (can be specified multiple times)
|
||||||
|
-r, --reporter The reporter to use for reporting the migration progress
|
||||||
--dry List the pending migrations that would be run without actually running them
|
--dry List the pending migrations that would be run without actually running them
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
emigrate up --directory src/migrations
|
emigrate up --directory src/migrations -s fs
|
||||||
emigrate up -d ./migrations --plugin @emigrate/plugin-storage-mysql
|
emigrate up -d ./migrations --storage @emigrate/storage-mysql
|
||||||
emigrate up -d src/migrations --dry
|
emigrate up -d src/migrations -s postgres -r json --dry
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (values.help) {
|
if (values.help) {
|
||||||
|
|
@ -56,12 +66,12 @@ Examples:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { directory = config.directory, dry } = values;
|
const { directory = config.directory, storage = config.storage, reporter = config.reporter, dry } = values;
|
||||||
const plugins = [...(config.plugins ?? []), ...(values.plugin ?? [])];
|
const plugins = [...(config.plugins ?? []), ...(values.plugin ?? [])];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { default: upCommand } = await import('./up-command.js');
|
const { default: upCommand } = await import('./up-command.js');
|
||||||
await upCommand({ directory, plugins, dry });
|
await upCommand({ storage, reporter, directory, plugins, dry });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof ShowUsageError) {
|
if (error instanceof ShowUsageError) {
|
||||||
console.error(error.message, '\n');
|
console.error(error.message, '\n');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import { cosmiconfig } from 'cosmiconfig';
|
import { cosmiconfig } from 'cosmiconfig';
|
||||||
import { type Config, type EmigrateConfig } from './types.js';
|
import { type Config, type EmigrateConfig } from './types.js';
|
||||||
|
|
||||||
export const getConfig = async (command: 'up' | 'list' | 'new'): Promise<Config> => {
|
const commands = ['up', 'list', 'new'] as const;
|
||||||
|
type Command = (typeof commands)[number];
|
||||||
|
|
||||||
|
export const getConfig = async (command: Command): Promise<Config> => {
|
||||||
const explorer = cosmiconfig('emigrate');
|
const explorer = cosmiconfig('emigrate');
|
||||||
|
|
||||||
const result = await explorer.search();
|
const result = await explorer.search();
|
||||||
|
|
@ -10,11 +13,14 @@ export const getConfig = async (command: 'up' | 'list' | 'new'): Promise<Config>
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { plugins, directory, template, ...commandsConfig } = result.config as EmigrateConfig;
|
const config = result.config as EmigrateConfig;
|
||||||
|
|
||||||
if (commandsConfig[command]) {
|
const commandConfig = config[command];
|
||||||
return { plugins, directory, template, ...commandsConfig[command] };
|
|
||||||
|
for (const command of commands) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
|
delete config[command];
|
||||||
}
|
}
|
||||||
|
|
||||||
return { plugins, directory, template };
|
return { ...config, ...commandConfig };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import prettyMs from 'pretty-ms';
|
||||||
import {
|
import {
|
||||||
type MigrationMetadata,
|
type MigrationMetadata,
|
||||||
type MigrationMetadataFinished,
|
type MigrationMetadataFinished,
|
||||||
type ReporterPlugin,
|
type EmigrateReporter,
|
||||||
} from '@emigrate/plugin-tools/types';
|
} from '@emigrate/plugin-tools/types';
|
||||||
|
|
||||||
type Status = ReturnType<typeof getMigrationStatus>;
|
type Status = ReturnType<typeof getMigrationStatus>;
|
||||||
|
|
@ -202,7 +202,7 @@ const getHeaderMessage = (migrations?: MigrationMetadata[], lockedMigrations?: M
|
||||||
)} ${ansis.yellow(`(${migrations.length - lockedMigrations.length} locked)`)}`;
|
)} ${ansis.yellow(`(${migrations.length - lockedMigrations.length} locked)`)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefaultFancyReporter implements Required<ReporterPlugin> {
|
class DefaultFancyReporter implements Required<EmigrateReporter> {
|
||||||
#migrations: Array<MigrationMetadata | MigrationMetadataFinished> | undefined;
|
#migrations: Array<MigrationMetadata | MigrationMetadataFinished> | undefined;
|
||||||
#lockedMigrations: MigrationMetadata[] | undefined;
|
#lockedMigrations: MigrationMetadata[] | undefined;
|
||||||
#activeMigration: MigrationMetadata | undefined;
|
#activeMigration: MigrationMetadata | undefined;
|
||||||
|
|
@ -290,7 +290,7 @@ class DefaultFancyReporter implements Required<ReporterPlugin> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultReporter implements Required<ReporterPlugin> {
|
class DefaultReporter implements Required<EmigrateReporter> {
|
||||||
#migrations?: MigrationMetadata[];
|
#migrations?: MigrationMetadata[];
|
||||||
#lockedMigrations?: MigrationMetadata[];
|
#lockedMigrations?: MigrationMetadata[];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
import { type Plugin } from '@emigrate/plugin-tools/types';
|
import { type EmigrateStorage, type Awaitable, type Plugin, type EmigrateReporter } from '@emigrate/plugin-tools/types';
|
||||||
|
|
||||||
export type EmigratePlugin = Plugin;
|
export type EmigratePlugin = Plugin;
|
||||||
|
|
||||||
|
type StringOrModule<T> = string | T | (() => Awaitable<T>) | (() => Awaitable<{ default: T }>);
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
plugins?: Array<string | EmigratePlugin>;
|
storage?: StringOrModule<EmigrateStorage>;
|
||||||
|
reporter?: StringOrModule<EmigrateReporter>;
|
||||||
|
plugins?: Array<StringOrModule<EmigratePlugin>>;
|
||||||
directory?: string;
|
directory?: string;
|
||||||
template?: string;
|
template?: string;
|
||||||
extension?: string;
|
extension?: string;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { getOrLoadPlugin, getOrLoadPlugins } from '@emigrate/plugin-tools';
|
import { getOrLoadPlugins, getOrLoadReporter, getOrLoadStorage } from '@emigrate/plugin-tools';
|
||||||
import {
|
import {
|
||||||
type LoaderPlugin,
|
type LoaderPlugin,
|
||||||
type MigrationFunction,
|
type MigrationFunction,
|
||||||
type Plugin,
|
|
||||||
type PluginType,
|
|
||||||
type PluginFromType,
|
|
||||||
type MigrationMetadata,
|
type MigrationMetadata,
|
||||||
type MigrationMetadataFinished,
|
type MigrationMetadataFinished,
|
||||||
} from '@emigrate/plugin-tools/types';
|
} from '@emigrate/plugin-tools/types';
|
||||||
|
|
@ -20,42 +17,42 @@ import {
|
||||||
import { type Config } from './types.js';
|
import { type Config } from './types.js';
|
||||||
import { withLeadingPeriod } from './with-leading-period.js';
|
import { withLeadingPeriod } from './with-leading-period.js';
|
||||||
import pluginLoaderJs from './plugin-loader-js.js';
|
import pluginLoaderJs from './plugin-loader-js.js';
|
||||||
import pluginReporterDefault from './plugin-reporter-default.js';
|
|
||||||
|
|
||||||
type ExtraFlags = {
|
type ExtraFlags = {
|
||||||
dry?: boolean;
|
dry?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const requirePlugin = async <T extends PluginType>(
|
|
||||||
type: T,
|
|
||||||
plugins: Array<Plugin | string>,
|
|
||||||
): Promise<PluginFromType<T>> => {
|
|
||||||
const plugin = await getOrLoadPlugin(type, plugins);
|
|
||||||
|
|
||||||
if (!plugin) {
|
|
||||||
throw new BadOptionError(
|
|
||||||
'plugin',
|
|
||||||
`No ${type} plugin found, please specify a ${type} plugin using the plugin option`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugin;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getDuration = (start: [number, number]) => {
|
const getDuration = (start: [number, number]) => {
|
||||||
const [seconds, nanoseconds] = process.hrtime(start);
|
const [seconds, nanoseconds] = process.hrtime(start);
|
||||||
return seconds * 1000 + nanoseconds / 1_000_000;
|
return seconds * 1000 + nanoseconds / 1_000_000;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function upCommand({ directory, dry = false, plugins = [] }: Config & ExtraFlags) {
|
const lazyDefaultReporter = async () => import('./plugin-reporter-default.js');
|
||||||
|
|
||||||
|
export default async function upCommand({
|
||||||
|
storage: storageConfig,
|
||||||
|
reporter: reporterConfig,
|
||||||
|
directory,
|
||||||
|
dry = false,
|
||||||
|
plugins = [],
|
||||||
|
}: Config & ExtraFlags) {
|
||||||
if (!directory) {
|
if (!directory) {
|
||||||
throw new MissingOptionError('directory');
|
throw new MissingOptionError('directory');
|
||||||
}
|
}
|
||||||
|
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
const storagePlugin = await requirePlugin('storage', plugins);
|
const storagePlugin = await getOrLoadStorage([storageConfig]);
|
||||||
|
|
||||||
|
if (!storagePlugin) {
|
||||||
|
throw new BadOptionError('storage', 'No storage found, please specify a storage using the storage option');
|
||||||
|
}
|
||||||
|
|
||||||
const storage = await storagePlugin.initializeStorage();
|
const storage = await storagePlugin.initializeStorage();
|
||||||
const reporter = await requirePlugin('reporter', [pluginReporterDefault, ...plugins]);
|
const reporter = await getOrLoadReporter([lazyDefaultReporter, reporterConfig]);
|
||||||
|
|
||||||
|
if (!reporter) {
|
||||||
|
throw new BadOptionError('reporter', 'No reporter found, please specify a reporter using the reporter option');
|
||||||
|
}
|
||||||
|
|
||||||
await reporter.onInit?.({ cwd, dry, directory });
|
await reporter.onInit?.({ cwd, dry, directory });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import {
|
||||||
type PluginFromType,
|
type PluginFromType,
|
||||||
type PluginType,
|
type PluginType,
|
||||||
type GeneratorPlugin,
|
type GeneratorPlugin,
|
||||||
type StoragePlugin,
|
type EmigrateReporter,
|
||||||
type Plugin,
|
type EmigrateStorage,
|
||||||
type LoaderPlugin,
|
type LoaderPlugin,
|
||||||
type ReporterPlugin,
|
type StringOrModule,
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
|
|
||||||
export const isGeneratorPlugin = (plugin: any): plugin is GeneratorPlugin => {
|
export const isGeneratorPlugin = (plugin: any): plugin is GeneratorPlugin => {
|
||||||
|
|
@ -17,7 +17,7 @@ export const isGeneratorPlugin = (plugin: any): plugin is GeneratorPlugin => {
|
||||||
return typeof plugin.generateMigration === 'function';
|
return typeof plugin.generateMigration === 'function';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isStoragePlugin = (plugin: any): plugin is StoragePlugin => {
|
export const isEmigrateStorage = (plugin: any): plugin is EmigrateStorage => {
|
||||||
if (!plugin || typeof plugin !== 'object') {
|
if (!plugin || typeof plugin !== 'object') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ export const isLoaderPlugin = (plugin: any): plugin is LoaderPlugin => {
|
||||||
return typeof plugin.loadMigration === 'function' && Array.isArray(plugin.loadableExtensions);
|
return typeof plugin.loadMigration === 'function' && Array.isArray(plugin.loadableExtensions);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isReporterPlugin = (plugin: any): plugin is ReporterPlugin => {
|
export const isEmigrateReporter = (plugin: any): plugin is EmigrateReporter => {
|
||||||
if (!plugin || typeof plugin !== 'object') {
|
if (!plugin || typeof plugin !== 'object') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -57,50 +57,44 @@ export const isPluginOfType = <T extends PluginType>(type: T, plugin: any): plug
|
||||||
return isGeneratorPlugin(plugin);
|
return isGeneratorPlugin(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'storage') {
|
|
||||||
return isStoragePlugin(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'loader') {
|
if (type === 'loader') {
|
||||||
return isLoaderPlugin(plugin);
|
return isLoaderPlugin(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'reporter') {
|
|
||||||
return isReporterPlugin(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Unknown plugin type: ${type}`);
|
throw new Error(`Unknown plugin type: ${type}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getOrLoadStorage = async (
|
||||||
|
potentialStorages: Array<StringOrModule<unknown>>,
|
||||||
|
): Promise<EmigrateStorage | undefined> => {
|
||||||
|
return getOrLoad(potentialStorages, isEmigrateStorage);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOrLoadReporter = async (
|
||||||
|
potentialReporters: Array<StringOrModule<unknown>>,
|
||||||
|
): Promise<EmigrateReporter | undefined> => {
|
||||||
|
return getOrLoad(potentialReporters, isEmigrateReporter);
|
||||||
|
};
|
||||||
|
|
||||||
export const getOrLoadPlugin = async <T extends PluginType>(
|
export const getOrLoadPlugin = async <T extends PluginType>(
|
||||||
type: T,
|
type: T,
|
||||||
plugins: Array<Plugin | string>,
|
plugins: Array<StringOrModule<unknown>>,
|
||||||
): Promise<PluginFromType<T> | undefined> => {
|
): Promise<PluginFromType<T> | undefined> => {
|
||||||
const reversePlugins = [...plugins].reverse();
|
return getOrLoad(plugins, (value: unknown): value is PluginFromType<T> => isPluginOfType(type, value));
|
||||||
|
|
||||||
for await (const plugin of reversePlugins) {
|
|
||||||
if (isPluginOfType(type, plugin)) {
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadedPlugin = typeof plugin === 'string' ? await loadPlugin(type, plugin) : undefined;
|
|
||||||
|
|
||||||
if (loadedPlugin) {
|
|
||||||
return loadedPlugin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOrLoadPlugins = async <T extends PluginType>(
|
export const getOrLoadPlugins = async <T extends PluginType>(
|
||||||
type: T,
|
type: T,
|
||||||
plugins: Array<Plugin | string>,
|
plugins: Array<StringOrModule<unknown>>,
|
||||||
): Promise<Array<PluginFromType<T>>> => {
|
): Promise<Array<PluginFromType<T>>> => {
|
||||||
const result: Array<PluginFromType<T>> = [];
|
const result: Array<PluginFromType<T>> = [];
|
||||||
const reversePlugins = [...plugins].reverse();
|
const reversePlugins = [...plugins].reverse();
|
||||||
|
|
||||||
for await (const plugin of reversePlugins) {
|
for await (let plugin of reversePlugins) {
|
||||||
|
if (typeof plugin === 'function') {
|
||||||
|
plugin = await plugin();
|
||||||
|
}
|
||||||
|
|
||||||
if (isPluginOfType(type, plugin)) {
|
if (isPluginOfType(type, plugin)) {
|
||||||
result.push(plugin);
|
result.push(plugin);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -116,10 +110,28 @@ export const getOrLoadPlugins = async <T extends PluginType>(
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadPlugin = async <T extends PluginType>(
|
const getOrLoad = async <T>(potentials: Array<StringOrModule<unknown>>, check: (value: unknown) => value is T) => {
|
||||||
type: T,
|
const reversed = [...potentials].reverse();
|
||||||
plugin: string,
|
|
||||||
): Promise<PluginFromType<T> | undefined> => {
|
for await (let potential of reversed) {
|
||||||
|
if (typeof potential === 'function') {
|
||||||
|
potential = await potential();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check(potential)) {
|
||||||
|
return potential;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support export default ...
|
||||||
|
if (potential && typeof potential === 'object' && 'default' in potential && check(potential.default)) {
|
||||||
|
return potential.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getImportFromEsm = async () => {
|
||||||
let importFromEsm = await import('import-from-esm');
|
let importFromEsm = await import('import-from-esm');
|
||||||
|
|
||||||
// Because of "allowSyntheticDefaultImports" we need to do this ugly hack
|
// Because of "allowSyntheticDefaultImports" we need to do this ugly hack
|
||||||
|
|
@ -127,27 +139,47 @@ export const loadPlugin = async <T extends PluginType>(
|
||||||
importFromEsm = (importFromEsm as any).default as unknown as typeof importFromEsm;
|
importFromEsm = (importFromEsm as any).default as unknown as typeof importFromEsm;
|
||||||
}
|
}
|
||||||
|
|
||||||
const importsToTry = plugin.startsWith('.')
|
return importFromEsm;
|
||||||
? [plugin]
|
};
|
||||||
: [plugin, `@emigrate/plugin-${plugin}`, `emigrate-plugin-${plugin}`];
|
|
||||||
|
export const loadStorage = async (name: string): Promise<EmigrateStorage | undefined> => {
|
||||||
|
return load(name, ['@emigrate/storage-', 'emigrate-storage-', '@emigrate/plugin-storage-'], isEmigrateStorage);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadReporter = async (name: string): Promise<EmigrateReporter | undefined> => {
|
||||||
|
return load(name, ['@emigrate/reporter-', 'emigrate-reporter-'], isEmigrateReporter);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadPlugin = async <T extends PluginType>(
|
||||||
|
type: T,
|
||||||
|
plugin: string,
|
||||||
|
): Promise<PluginFromType<T> | undefined> => {
|
||||||
|
return load(plugin, ['@emigrate/plugin-', 'emigrate-plugin-'], (value: unknown): value is PluginFromType<T> => {
|
||||||
|
return isPluginOfType(type, value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const load = async <T>(
|
||||||
|
name: string,
|
||||||
|
prefixes: string[],
|
||||||
|
check: (value: unknown) => value is T,
|
||||||
|
): Promise<T | undefined> => {
|
||||||
|
const importFromEsm = await getImportFromEsm();
|
||||||
|
|
||||||
|
const importsToTry = name.startsWith('.') ? [name] : [name, ...prefixes.map((prefix) => `${prefix}${name}`)];
|
||||||
|
|
||||||
for await (const importPath of importsToTry) {
|
for await (const importPath of importsToTry) {
|
||||||
try {
|
try {
|
||||||
const pluginModule: unknown = await importFromEsm(process.cwd(), importPath);
|
const module: unknown = await importFromEsm(process.cwd(), importPath);
|
||||||
|
|
||||||
// Support module.exports = ...
|
// Support module.exports = ...
|
||||||
if (isPluginOfType(type, pluginModule)) {
|
if (check(module)) {
|
||||||
return pluginModule;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support export default ...
|
// Support export default ...
|
||||||
if (
|
if (module && typeof module === 'object' && 'default' in module && check(module.default)) {
|
||||||
pluginModule &&
|
return module.default;
|
||||||
typeof pluginModule === 'object' &&
|
|
||||||
'default' in pluginModule &&
|
|
||||||
isPluginOfType(type, pluginModule.default)
|
|
||||||
) {
|
|
||||||
return pluginModule.default;
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
type Awaitable<T> = T | PromiseLike<T>;
|
export type Awaitable<T> = T | PromiseLike<T>;
|
||||||
|
|
||||||
|
export type StringOrModule<T> = string | T | (() => Awaitable<T>) | (() => Awaitable<{ default: T }>);
|
||||||
|
|
||||||
export type MigrationStatus = 'failed' | 'done';
|
export type MigrationStatus = 'failed' | 'done';
|
||||||
|
|
||||||
|
|
@ -58,11 +60,11 @@ export type Storage = {
|
||||||
onError(migration: MigrationMetadataFinished, error: Error): Promise<void>;
|
onError(migration: MigrationMetadataFinished, error: Error): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StoragePlugin = {
|
export type EmigrateStorage = {
|
||||||
initializeStorage(): Promise<Storage>;
|
initializeStorage(): Promise<Storage>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InitializeStorageFunction = StoragePlugin['initializeStorage'];
|
export type InitializeStorageFunction = EmigrateStorage['initializeStorage'];
|
||||||
|
|
||||||
export type MigrationFile = {
|
export type MigrationFile = {
|
||||||
/**
|
/**
|
||||||
|
|
@ -163,7 +165,7 @@ type InitParameters = {
|
||||||
dry: boolean;
|
dry: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReporterPlugin = Partial<{
|
export type EmigrateReporter = Partial<{
|
||||||
/**
|
/**
|
||||||
* Called when the plugin is initialized, which happens before the migrations are collected.
|
* Called when the plugin is initialized, which happens before the migrations are collected.
|
||||||
*/
|
*/
|
||||||
|
|
@ -219,13 +221,11 @@ export type ReporterPlugin = Partial<{
|
||||||
onFinished(migrations: MigrationMetadataFinished[], error?: Error): Awaitable<void>;
|
onFinished(migrations: MigrationMetadataFinished[], error?: Error): Awaitable<void>;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type Plugin = StoragePlugin | GeneratorPlugin | LoaderPlugin | ReporterPlugin;
|
export type Plugin = GeneratorPlugin | LoaderPlugin;
|
||||||
|
|
||||||
type PluginTypeMap = {
|
type PluginTypeMap = {
|
||||||
storage: StoragePlugin;
|
|
||||||
generator: GeneratorPlugin;
|
generator: GeneratorPlugin;
|
||||||
loader: LoaderPlugin;
|
loader: LoaderPlugin;
|
||||||
reporter: ReporterPlugin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PluginType = keyof PluginTypeMap;
|
export type PluginType = keyof PluginTypeMap;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue