New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@emigrate/cli

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@emigrate/cli - npm Package Compare versions

Comparing version 0.5.1 to 0.6.0

dist/exec.d.ts

4

dist/cli.js

@@ -211,3 +211,3 @@ #!/usr/bin/env node --enable-source-maps

const { default: listCommand } = await import('./commands/list.js');
await listCommand({ directory, storage, reporter });
process.exitCode = await listCommand({ directory, storage, reporter });
}

@@ -283,3 +283,3 @@ catch (error) {

const { default: removeCommand } = await import('./commands/remove.js');
await removeCommand({ directory, storage, reporter, force }, positionals[0] ?? '');
process.exitCode = await removeCommand({ directory, storage, reporter, force }, positionals[0] ?? '');
}

@@ -286,0 +286,0 @@ catch (error) {

import { type Config } from '../types.js';
export default function listCommand({ directory, reporter: reporterConfig, storage: storageConfig }: Config): Promise<void>;
export default function listCommand({ directory, reporter: reporterConfig, storage: storageConfig }: Config): Promise<1 | 0>;
//# sourceMappingURL=list.d.ts.map
import process from 'node:process';
import path from 'node:path';
import { getOrLoadReporter, getOrLoadStorage } from '@emigrate/plugin-tools';
import { BadOptionError, MigrationHistoryError, MissingOptionError } from '../errors.js';
import { BadOptionError, MigrationHistoryError, MissingOptionError, StorageInitError } from '../errors.js';
import { withLeadingPeriod } from '../with-leading-period.js';
import { getMigrations } from '../get-migrations.js';
import { exec } from '../exec.js';
const lazyDefaultReporter = async () => import('../reporters/default.js');

@@ -17,3 +18,2 @@ export default async function listCommand({ directory, reporter: reporterConfig, storage: storageConfig }) {

}
const storage = await storagePlugin.initializeStorage();
const reporter = await getOrLoadReporter([reporterConfig ?? lazyDefaultReporter]);

@@ -24,2 +24,7 @@ if (!reporter) {

await reporter.onInit?.({ command: 'list', cwd, dry: false, directory });
const [storage, storageError] = await exec(async () => storagePlugin.initializeStorage());
if (storageError) {
await reporter.onFinished?.([], new StorageInitError('Could not initialize storage', { cause: storageError }));
return 1;
}
const migrationFiles = await getMigrations(cwd, directory);

@@ -61,3 +66,5 @@ let migrationHistoryError;

await reporter.onFinished?.(finishedMigrations, migrationHistoryError);
await storage.end();
return migrationHistoryError ? 1 : 0;
}
//# sourceMappingURL=list.js.map

@@ -5,4 +5,4 @@ import { type Config } from '../types.js';

};
export default function removeCommand({ directory, reporter: reporterConfig, storage: storageConfig, force }: Config & ExtraFlags, name: string): Promise<void>;
export default function removeCommand({ directory, reporter: reporterConfig, storage: storageConfig, force }: Config & ExtraFlags, name: string): Promise<1 | 0>;
export {};
//# sourceMappingURL=remove.d.ts.map
import process from 'node:process';
import { getOrLoadReporter, getOrLoadStorage } from '@emigrate/plugin-tools';
import { BadOptionError, MigrationNotRunError, MissingArgumentsError, MissingOptionError, OptionNeededError, } from '../errors.js';
import { BadOptionError, MigrationNotRunError, MissingArgumentsError, MissingOptionError, OptionNeededError, StorageInitError, } from '../errors.js';
import { getMigration } from '../get-migration.js';
import { getDuration } from '../get-duration.js';
import { exec } from '../exec.js';
const lazyDefaultReporter = async () => import('../reporters/default.js');

@@ -19,3 +20,2 @@ export default async function removeCommand({ directory, reporter: reporterConfig, storage: storageConfig, force }, name) {

}
const storage = await storagePlugin.initializeStorage();
const reporter = await getOrLoadReporter([reporterConfig ?? lazyDefaultReporter]);

@@ -25,2 +25,8 @@ if (!reporter) {

}
const [storage, storageError] = await exec(async () => storagePlugin.initializeStorage());
if (storageError) {
await reporter.onFinished?.([], new StorageInitError('Could not initialize storage', { cause: storageError }));
return 1;
}
await reporter.onInit?.({ command: 'remove', cwd, dry: false, directory });
const migrationFile = await getMigration(cwd, directory, name, !force);

@@ -35,7 +41,8 @@ const finishedMigrations = [];

if (migrationHistoryEntry.status === 'done' && !force) {
throw new OptionNeededError('force', `The migration "${migrationFile.name}" is not in a failed state. Use the "force" option to force its removal`);
removalError = new OptionNeededError('force', `The migration "${migrationFile.name}" is not in a failed state. Use the "force" option to force its removal`);
}
historyEntry = migrationHistoryEntry;
else {
historyEntry = migrationHistoryEntry;
}
}
await reporter.onInit?.({ command: 'remove', cwd, dry: false, directory });
await reporter.onMigrationRemoveStart?.(migrationFile);

@@ -70,3 +77,5 @@ const start = process.hrtime();

await reporter.onFinished?.(finishedMigrations, removalError);
await storage.end();
return removalError ? 1 : 0;
}
//# sourceMappingURL=remove.js.map
import path from 'node:path';
import process from 'node:process';
import { getOrLoadPlugins, getOrLoadReporter, getOrLoadStorage } from '@emigrate/plugin-tools';
import { BadOptionError, EmigrateError, MigrationHistoryError, MigrationLoadError, MigrationRunError, MissingOptionError, } from '../errors.js';
import { getOrLoadPlugins, getOrLoadReporter, getOrLoadStorage, serializeError } from '@emigrate/plugin-tools';
import { BadOptionError, EmigrateError, MigrationHistoryError, MigrationLoadError, MigrationRunError, MissingOptionError, StorageInitError, toError, } from '../errors.js';
import { withLeadingPeriod } from '../with-leading-period.js';
import { getMigrations as getMigrationsOriginal } from '../get-migrations.js';
import { getDuration } from '../get-duration.js';
import { exec } from '../exec.js';
const lazyDefaultReporter = async () => import('../reporters/default.js');

@@ -18,3 +19,2 @@ const lazyPluginLoaderJs = async () => import('../plugin-loader-js.js');

}
const storage = await storagePlugin.initializeStorage();
const reporter = await getOrLoadReporter([reporterConfig ?? lazyDefaultReporter]);

@@ -24,2 +24,8 @@ if (!reporter) {

}
await reporter.onInit?.({ command: 'up', cwd, dry, directory });
const [storage, storageError] = await exec(async () => storagePlugin.initializeStorage());
if (storageError) {
await reporter.onFinished?.([], new StorageInitError('Could not initialize storage', { cause: storageError }));
return 1;
}
const migrationFiles = await getMigrations(cwd, directory);

@@ -56,8 +62,26 @@ const failedEntries = [];

]));
for (const [extension, loader] of loaderByExtension) {
for await (const [extension, loader] of loaderByExtension) {
if (!loader) {
throw new BadOptionError('plugin', `No loader plugin found for file extension: ${extension}`);
const finishedMigrations = [...failedEntries];
for await (const failedEntry of failedEntries) {
await reporter.onMigrationError?.(failedEntry, failedEntry.error);
}
for await (const migration of migrationFiles) {
if (migration.extension === extension) {
const error = new BadOptionError('plugin', `No loader plugin found for file extension: ${extension}`);
const finishedMigration = { ...migration, duration: 0, status: 'failed', error };
await reporter.onMigrationError?.(finishedMigration, error);
finishedMigrations.push(finishedMigration);
}
else {
const finishedMigration = { ...migration, duration: 0, status: 'skipped' };
await reporter.onMigrationSkip?.(finishedMigration);
finishedMigrations.push(finishedMigration);
}
}
await reporter.onFinished?.(finishedMigrations, new BadOptionError('plugin', `No loader plugin found for file extension: ${extension}`));
await storage.end();
return 1;
}
}
await reporter.onInit?.({ command: 'up', cwd, dry, directory });
await reporter.onCollectedMigrations?.([...failedEntries, ...migrationFiles]);

@@ -79,2 +103,3 @@ if (migrationFiles.length === 0 || dry || failedEntries.length > 0) {

await reporter.onFinished?.([...failedEntries, ...finishedMigrations], error);
await storage.end();
return failedEntries.length > 0 ? 1 : 0;

@@ -91,3 +116,4 @@ }

}
await reporter.onFinished?.([], error instanceof Error ? error : new Error(String(error)));
await reporter.onFinished?.([], toError(error));
await storage.end();
return 1;

@@ -106,3 +132,3 @@ }

process.off('SIGTERM', cleanup);
cleaningUp = storage.unlock(lockedMigrationFiles);
cleaningUp = storage.unlock(lockedMigrationFiles).then(async () => storage.end());
return cleaningUp;

@@ -143,3 +169,4 @@ };

catch (error) {
const errorInstance = error instanceof Error ? error : new Error(String(error));
const errorInstance = toError(error);
const serializedError = serializeError(errorInstance);
const duration = getDuration(start);

@@ -150,5 +177,5 @@ const finishedMigration = {

duration,
error: errorInstance,
error: serializedError,
};
await storage.onError(finishedMigration, errorInstance);
await storage.onError(finishedMigration, serializedError);
await reporter.onMigrationError?.(finishedMigration, errorInstance);

@@ -155,0 +182,0 @@ finishedMigrations.push(finishedMigration);

@@ -7,3 +7,3 @@ import { describe, it, mock } from 'node:test';

it('returns 0 and finishes without an error when there are no migrations to run', async () => {
const { reporter, run } = getUpCommand([], []);
const { reporter, run } = getUpCommand([], getStorage([]));
const exitCode = await run();

@@ -29,11 +29,7 @@ assert.strictEqual(exitCode, 0);

});
it('throws when there are migration file extensions without a corresponding loader plugin', async () => {
const { reporter, run } = getUpCommand(['some_file.sql'], []);
await assert.rejects(async () => {
return run();
}, {
name: 'Error [ERR_BAD_OPT]',
message: 'No loader plugin found for file extension: .sql',
});
assert.strictEqual(reporter.onInit.mock.calls.length, 0);
it('returns 1 and finishes with an error when there are migration file extensions without a corresponding loader plugin', async () => {
const { reporter, run } = getUpCommand(['some_other.js', 'some_file.sql'], getStorage([]));
const exitCode = await run();
assert.strictEqual(exitCode, 1);
assert.strictEqual(reporter.onInit.mock.calls.length, 1);
assert.strictEqual(reporter.onCollectedMigrations.mock.calls.length, 0);

@@ -43,15 +39,17 @@ assert.strictEqual(reporter.onLockedMigrations.mock.calls.length, 0);

assert.strictEqual(reporter.onMigrationSuccess.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationError.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationSkip.mock.calls.length, 0);
assert.strictEqual(reporter.onFinished.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationError.mock.calls.length, 1);
assert.strictEqual(reporter.onMigrationSkip.mock.calls.length, 1);
const args = reporter.onFinished.mock.calls[0]?.arguments;
assert.strictEqual(args?.length, 2);
const entries = args[0];
const error = args[1];
assert.strictEqual(entries.length, 2);
assert.deepStrictEqual(entries.map((entry) => `${entry.name} (${entry.status})`), ['some_other.js (skipped)', 'some_file.sql (failed)']);
assert.strictEqual(error?.message, 'No loader plugin found for file extension: .sql');
});
it('throws when there are migration file extensions without a corresponding loader plugin in dry-run mode as well', async () => {
const { reporter, run } = getUpCommand(['some_file.sql'], []);
await assert.rejects(async () => {
return run(true);
}, {
name: 'Error [ERR_BAD_OPT]',
message: 'No loader plugin found for file extension: .sql',
});
assert.strictEqual(reporter.onInit.mock.calls.length, 0);
it('returns 1 and finishes with an error when there are migration file extensions without a corresponding loader plugin in dry-run mode as well', async () => {
const { reporter, run } = getUpCommand(['some_other.js', 'some_file.sql'], getStorage([]));
const exitCode = await run();
assert.strictEqual(exitCode, 1);
assert.strictEqual(reporter.onInit.mock.calls.length, 1);
assert.strictEqual(reporter.onCollectedMigrations.mock.calls.length, 0);

@@ -61,9 +59,15 @@ assert.strictEqual(reporter.onLockedMigrations.mock.calls.length, 0);

assert.strictEqual(reporter.onMigrationSuccess.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationError.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationSkip.mock.calls.length, 0);
assert.strictEqual(reporter.onFinished.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationError.mock.calls.length, 1);
assert.strictEqual(reporter.onMigrationSkip.mock.calls.length, 1);
const args = reporter.onFinished.mock.calls[0]?.arguments;
assert.strictEqual(args?.length, 2);
const entries = args[0];
const error = args[1];
assert.strictEqual(entries.length, 2);
assert.deepStrictEqual(entries.map((entry) => `${entry.name} (${entry.status})`), ['some_other.js (skipped)', 'some_file.sql (failed)']);
assert.strictEqual(error?.message, 'No loader plugin found for file extension: .sql');
});
it('returns 1 and finishes with an error when there are failed migrations in the history', async () => {
const failedEntry = toEntry('some_failed_migration.js', 'failed');
const { reporter, run } = getUpCommand([failedEntry.name], [failedEntry]);
const { reporter, run } = getUpCommand([failedEntry.name], getStorage([failedEntry]));
const exitCode = await run();

@@ -97,3 +101,38 @@ assert.strictEqual(exitCode, 1);

});
it("returns 1 and finishes with an error when the storage couldn't be initialized", async () => {
const { reporter, run } = getUpCommand(['some_migration.js']);
const exitCode = await run();
assert.strictEqual(exitCode, 1);
assert.strictEqual(reporter.onInit.mock.calls.length, 1);
assert.deepStrictEqual(reporter.onInit.mock.calls[0]?.arguments, [
{
command: 'up',
cwd: '/emigrate',
dry: false,
directory: 'migrations',
},
]);
assert.strictEqual(reporter.onCollectedMigrations.mock.calls.length, 0);
assert.strictEqual(reporter.onLockedMigrations.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationStart.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationSuccess.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationError.mock.calls.length, 0);
assert.strictEqual(reporter.onMigrationSkip.mock.calls.length, 0);
assert.strictEqual(reporter.onFinished.mock.calls.length, 1);
const args = reporter.onFinished.mock.calls[0]?.arguments;
assert.strictEqual(args?.length, 2);
const entries = args[0];
const error = args[1];
const cause = getErrorCause(error);
assert.deepStrictEqual(entries, []);
assert.strictEqual(error?.message, 'Could not initialize storage');
assert.strictEqual(cause?.message, 'No storage configured');
});
});
function getErrorCause(error) {
if (error?.cause instanceof Error) {
return error.cause;
}
return undefined;
}
function toMigration(cwd, directory, name) {

@@ -129,3 +168,17 @@ return {

}
function getUpCommand(migrationFiles, historyEntries, plugins) {
function getStorage(historyEntries) {
const storage = {
lock: mock.fn(),
unlock: mock.fn(),
getHistory: mock.fn(async function* () {
yield* toEntries(historyEntries);
}),
remove: mock.fn(),
onSuccess: mock.fn(),
onError: mock.fn(),
end: mock.fn(),
};
return storage;
}
function getUpCommand(migrationFiles, storage, plugins) {
const reporter = {

@@ -145,12 +198,2 @@ onFinished: mock.fn(noop),

};
const storage = {
lock: mock.fn(),
unlock: mock.fn(),
getHistory: mock.fn(async function* () {
yield* toEntries(historyEntries);
}),
remove: mock.fn(),
onSuccess: mock.fn(),
onError: mock.fn(),
};
const run = async (dry = false) => {

@@ -162,2 +205,5 @@ return upCommand({

async initializeStorage() {
if (!storage) {
throw new Error('No storage configured');
}
return storage;

@@ -164,0 +210,0 @@ },

import { type MigrationHistoryEntry, type MigrationMetadata } from '@emigrate/plugin-tools/types';
export declare const toError: (error: unknown) => Error;
export declare class EmigrateError extends Error {

@@ -43,2 +44,5 @@ code: string;

}
export declare class StorageInitError extends EmigrateError {
constructor(message: string, options?: ErrorOptions);
}
//# sourceMappingURL=errors.d.ts.map
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'disjunction' });
export const toError = (error) => (error instanceof Error ? error : new Error(String(error)));
export class EmigrateError extends Error {

@@ -73,2 +74,7 @@ code;

}
export class StorageInitError extends EmigrateError {
constructor(message, options) {
super('ERR_STORAGE_INIT', message, options);
}
}
//# sourceMappingURL=errors.js.map
{
"name": "@emigrate/cli",
"version": "0.5.1",
"version": "0.6.0",
"publishConfig": {

@@ -46,3 +46,3 @@ "access": "public"

"pretty-ms": "8.0.0",
"@emigrate/plugin-tools": "0.4.1"
"@emigrate/plugin-tools": "0.5.0"
},

@@ -49,0 +49,0 @@ "volta": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc