0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

refactor(cli): add oraPromise() util

This commit is contained in:
Gao Sun 2022-10-07 23:31:13 +08:00
parent a3dc967442
commit aba872ea4b
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
3 changed files with 44 additions and 37 deletions

View file

@ -3,21 +3,16 @@ import path from 'path';
import { seeds } from '@logto/schemas';
import chalk from 'chalk';
import ora from 'ora';
import { DatabasePool, DatabaseTransactionConnection, sql } from 'slonik';
import { raw } from 'slonik-sql-tag-raw';
import { CommandModule } from 'yargs';
import { createPoolAndDatabaseIfNeeded, insertInto } from '../../database';
import { updateDatabaseTimestamp } from '../../queries/logto-config';
import { buildApplicationSecret, getPathInModule, log } from '../../utilities';
import { buildApplicationSecret, getPathInModule, log, oraPromise } from '../../utilities';
import { getLatestAlterationTimestamp } from './alteration';
const createTables = async (connection: DatabaseTransactionConnection) => {
const spinner = ora({
text: 'Create tables',
prefixText: chalk.blue('[info]'),
}).start();
const tableDirectory = getPathInModule('@logto/schemas', 'tables');
const directoryFiles = await readdir(tableDirectory);
const tableFiles = directoryFiles.filter((file) => file.endsWith('.sql'));
@ -28,17 +23,11 @@ const createTables = async (connection: DatabaseTransactionConnection) => {
])
);
// Disable for spinner
/* eslint-disable @silverhand/fp/no-mutation */
// Await in loop is intended for better error handling
for (const [file, query] of queries) {
for (const [, query] of queries) {
// eslint-disable-next-line no-await-in-loop
await connection.query(sql`${raw(query)}`);
spinner.text = `Run ${file} succeeded`;
}
spinner.succeed(`Created ${queries.length} tables`);
/* eslint-enable @silverhand/fp/no-mutation */
};
const seedTables = async (connection: DatabaseTransactionConnection) => {
@ -50,11 +39,6 @@ const seedTables = async (connection: DatabaseTransactionConnection) => {
defaultRole,
} = seeds;
const spinner = ora({
text: 'Seed data',
prefixText: chalk.blue('[info]'),
}).start();
await Promise.all([
connection.query(insertInto(managementResource, 'resources')),
connection.query(insertInto(createDefaultSetting(), 'settings')),
@ -65,14 +49,18 @@ const seedTables = async (connection: DatabaseTransactionConnection) => {
connection.query(insertInto(defaultRole, 'roles')),
updateDatabaseTimestamp(connection, await getLatestAlterationTimestamp()),
]);
spinner.succeed();
};
export const seedByPool = async (pool: DatabasePool) => {
await pool.transaction(async (connection) => {
await createTables(connection);
await seedTables(connection);
await oraPromise(createTables(connection), {
text: 'Create tables',
prefixText: chalk.blue('[info]'),
});
await oraPromise(seedTables(connection), {
text: 'Seed data',
prefixText: chalk.blue('[info]'),
});
});
};

View file

@ -8,13 +8,12 @@ import { conditional } from '@silverhand/essentials';
import chalk from 'chalk';
import { remove, writeFile } from 'fs-extra';
import inquirer from 'inquirer';
import ora from 'ora';
import * as semver from 'semver';
import tar from 'tar';
import { CommandModule } from 'yargs';
import { createPoolAndDatabaseIfNeeded, getDatabaseUrlFromConfig } from '../database';
import { downloadFile, log, safeExecSync } from '../utilities';
import { downloadFile, log, oraPromise, safeExecSync } from '../utilities';
import { seedByPool } from './database/seed';
export type InstallArgs = {
@ -92,20 +91,12 @@ const downloadRelease = async () => {
};
const decompress = async (toPath: string, tarPath: string) => {
const decompressSpinner = ora({
text: `Decompress to ${toPath}`,
prefixText: chalk.blue('[info]'),
}).start();
try {
await mkdir(toPath);
await tar.extract({ file: tarPath, cwd: toPath, strip: 1 });
} catch (error: unknown) {
decompressSpinner.fail();
log.error(error);
}
decompressSpinner.succeed();
};
const installLogto = async ({ path: pathArgument = defaultPath, silent = false }: InstallArgs) => {
@ -119,7 +110,14 @@ const installLogto = async ({ path: pathArgument = defaultPath, silent = false }
// Download and decompress
const tarPath = await downloadRelease();
await decompress(instancePath, tarPath);
await oraPromise(
decompress(instancePath, tarPath),
{
text: `Decompress to ${instancePath}`,
prefixText: chalk.blue('[info]'),
},
true
);
try {
// Seed database
@ -138,13 +136,11 @@ const installLogto = async ({ path: pathArgument = defaultPath, silent = false }
});
if (!value) {
const spinner = ora({
await oraPromise(remove(instancePath), {
text: 'Clean up',
prefixText: chalk.blue('[info]'),
}).start();
});
await remove(instancePath);
spinner.succeed();
// eslint-disable-next-line unicorn/no-process-exit
process.exit(1);
}

View file

@ -80,6 +80,29 @@ export const getPathInModule = (moduleName: string, relativePath = '/') =>
relativePath
);
export const oraPromise = async <T>(
promise: PromiseLike<T>,
options?: ora.Options,
exitOnError = false
) => {
const spinner = ora(options).start();
try {
const result = await promise;
spinner.succeed();
return result;
} catch (error: unknown) {
spinner.fail();
if (exitOnError) {
log.error(error);
}
throw error;
}
};
// TODO: Move to `@silverhand/essentials`
// Intended
// eslint-disable-next-line @typescript-eslint/no-empty-function