0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

refactor(cli): add official connectors during init (#2132)

This commit is contained in:
Gao Sun 2022-10-12 17:53:38 +08:00 committed by GitHub
parent 27d3c2c00f
commit 926394030d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 52 deletions

View file

@ -1,13 +1,7 @@
import chalk from 'chalk';
import { CommandModule } from 'yargs';
import { oraPromise } from '../../utilities';
import {
addConnectors,
fetchOfficialConnectorList,
inquireInstancePath,
normalizePackageName,
} from './utils';
import { log } from '../../utilities';
import { addConnectors, addOfficialConnectors, inquireInstancePath } from './utils';
const add: CommandModule<unknown, { packages: string[]; path?: string; official: boolean }> = {
command: ['add [packages...]', 'a', 'install', 'i'],
@ -32,14 +26,13 @@ const add: CommandModule<unknown, { packages: string[]; path?: string; official:
handler: async ({ packages: packageNames, path, official }) => {
const instancePath = await inquireInstancePath(path);
const packages = official
? await oraPromise(fetchOfficialConnectorList(), {
text: 'Fetch official connector list',
prefixText: chalk.blue('[info]'),
})
: packageNames.map((name) => normalizePackageName(name));
if (official) {
await addOfficialConnectors(instancePath);
}
await addConnectors(instancePath, packages);
await addConnectors(instancePath, packageNames);
log.info('Restart your Logto instance to get the changes reflected.');
},
};

View file

@ -13,7 +13,7 @@ import tar from 'tar';
import { z } from 'zod';
import { connectorDirectory } from '../../constants';
import { log } from '../../utilities';
import { log, oraPromise } from '../../utilities';
import { defaultPath } from '../install/utils';
const coreDirectory = 'packages/core';
@ -96,38 +96,40 @@ export const addConnectors = async (instancePath: string, packageNames: string[]
log.info('Fetch connector metadata');
const results = await Promise.all(
packageNames.map(async (packageName) => {
const run = async () => {
const { stdout } = await execPromise(`npm pack ${packageName} --json`, { cwd });
const result = npmPackResultGuard.parse(JSON.parse(stdout));
packageNames
.map((name) => normalizePackageName(name))
.map(async (packageName) => {
const run = async () => {
const { stdout } = await execPromise(`npm pack ${packageName} --json`, { cwd });
const result = npmPackResultGuard.parse(JSON.parse(stdout));
if (!result[0]) {
throw new Error(
`Unable to execute ${chalk.green('npm pack')} on package ${chalk.green(packageName)}`
);
if (!result[0]) {
throw new Error(
`Unable to execute ${chalk.green('npm pack')} on package ${chalk.green(packageName)}`
);
}
const { filename, name } = result[0];
const escapedFilename = filename.replace(/\//g, '-').replace(/@/g, '');
const tarPath = path.join(cwd, escapedFilename);
const packageDirectory = path.join(cwd, name.replace(/\//g, '-'));
await remove(packageDirectory);
await ensureDir(packageDirectory);
await tar.extract({ cwd: packageDirectory, file: tarPath, strip: 1 });
await unlink(tarPath);
log.succeed(`Added ${chalk.green(name)}`);
};
try {
await pRetry(run, { retries: 2 });
} catch (error: unknown) {
console.warn(`[${packageName}]`, error);
return packageName;
}
const { filename, name } = result[0];
const escapedFilename = filename.replace(/\//g, '-').replace(/@/g, '');
const tarPath = path.join(cwd, escapedFilename);
const packageDirectory = path.join(cwd, name.replace(/\//g, '-'));
await remove(packageDirectory);
await ensureDir(packageDirectory);
await tar.extract({ cwd: packageDirectory, file: tarPath, strip: 1 });
await unlink(tarPath);
log.succeed(`Added ${chalk.green(name)}`);
};
try {
await pRetry(run, { retries: 2 });
} catch (error: unknown) {
console.warn(`[${packageName}]`, error);
return packageName;
}
})
})
);
const errorPackages = results.filter(Boolean);
@ -146,7 +148,7 @@ export const addConnectors = async (instancePath: string, packageNames: string[]
const officialConnectorPrefix = '@logto/connector-';
export const fetchOfficialConnectorList = async () => {
const fetchOfficialConnectorList = async () => {
const { stdout } = await execPromise(`npm search ${officialConnectorPrefix} --json`);
const packages = z
.object({ name: z.string() })
@ -160,3 +162,11 @@ export const fetchOfficialConnectorList = async () => {
)
);
};
export const addOfficialConnectors = async (instancePath: string) => {
const packages = await oraPromise(fetchOfficialConnectorList(), {
text: 'Fetch official connector list',
prefixText: chalk.blue('[info]'),
});
await addConnectors(instancePath, packages);
};

View file

@ -3,6 +3,7 @@ import { CommandModule } from 'yargs';
import { getDatabaseUrlFromConfig } from '../../database';
import { log } from '../../utilities';
import { addOfficialConnectors } from '../connector/utils';
import {
validateNodeVersion,
inquireInstancePath,
@ -12,14 +13,16 @@ import {
createEnv,
logFinale,
decompress,
inquireOfficialConnectors,
} from './utils';
export type InstallArgs = {
path?: string;
skipSeed: boolean;
officialConnectors?: boolean;
};
const installLogto = async ({ path, skipSeed }: InstallArgs) => {
const installLogto = async ({ path, skipSeed, officialConnectors }: InstallArgs) => {
validateNodeVersion();
// Get instance path
@ -34,7 +37,11 @@ const installLogto = async ({ path, skipSeed }: InstallArgs) => {
// Seed database
if (skipSeed) {
log.info(`You can use ${chalk.green('db seed')} command to seed database when ready.`);
log.info(
`Skipped database seeding.\n\n' + ' You can use the ${chalk.green(
'db seed'
)} command to seed database when ready.\n`
);
} else {
await seedDatabase(instancePath);
}
@ -42,11 +49,21 @@ const installLogto = async ({ path, skipSeed }: InstallArgs) => {
// Save to dot env
await createEnv(instancePath, await getDatabaseUrlFromConfig());
// Add official connectors
if (await inquireOfficialConnectors(officialConnectors)) {
await addOfficialConnectors(instancePath);
} else {
log.info(
'Skipped adding official connectors.\n\n' +
` You can use the ${chalk.green('connector add')} command to add connectors at any time.\n`
);
}
// Finale
logFinale(instancePath);
};
const install: CommandModule<unknown, { path?: string; skipSeed: boolean }> = {
const install: CommandModule<unknown, InstallArgs> = {
command: ['init', 'i', 'install'],
describe: 'Download and run the latest Logto release',
builder: (yargs) =>
@ -62,9 +79,14 @@ const install: CommandModule<unknown, { path?: string; skipSeed: boolean }> = {
type: 'boolean',
default: false,
},
officialConnectors: {
alias: 'oc',
describe: 'Add official connectors after downloading Logto',
type: 'boolean',
},
}),
handler: async ({ path, skipSeed }) => {
await installLogto({ path, skipSeed });
handler: async ({ path, skipSeed, officialConnectors }) => {
await installLogto({ path, skipSeed, officialConnectors });
},
};

View file

@ -152,3 +152,17 @@ export const logFinale = (instancePath: string) => {
`Use the command below to start Logto. Happy hacking!\n\n ${chalk.green(startCommand)}`
);
};
export const inquireOfficialConnectors = async (initialAnswer?: boolean) => {
const { value } = await inquirer.prompt<{ value: boolean }>(
{
name: 'value',
message: 'Do you want to add official connectors?',
type: 'confirm',
default: true,
},
{ value: initialAnswer }
);
return value;
};