mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(cli): database config command
This commit is contained in:
parent
f05691b431
commit
0eb306a61c
7 changed files with 92 additions and 27 deletions
|
@ -35,13 +35,15 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
|
"find-up": "^5.0.0",
|
||||||
"got": "^11.8.2",
|
"got": "^11.8.2",
|
||||||
"hpagent": "^1.0.0",
|
"hpagent": "^1.0.0",
|
||||||
"inquirer": "^8.2.2",
|
"inquirer": "^8.2.2",
|
||||||
"ora": "^5.0.0",
|
"ora": "^5.0.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"tar": "^6.1.11",
|
"tar": "^6.1.11",
|
||||||
"yargs": "^17.6.0"
|
"yargs": "^17.6.0",
|
||||||
|
"zod": "^3.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@silverhand/eslint-config": "1.0.0",
|
"@silverhand/eslint-config": "1.0.0",
|
||||||
|
|
13
packages/cli/src/commands/database/index.ts
Normal file
13
packages/cli/src/commands/database/index.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { CommandModule } from 'yargs';
|
||||||
|
|
||||||
|
import { noop } from '../../utilities';
|
||||||
|
import { getUrl } from './url';
|
||||||
|
|
||||||
|
const database: CommandModule = {
|
||||||
|
command: ['database <command>', 'db'],
|
||||||
|
describe: 'Commands for Logto database',
|
||||||
|
builder: (yargs) => yargs.command(getUrl),
|
||||||
|
handler: noop,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default database;
|
12
packages/cli/src/commands/database/url.ts
Normal file
12
packages/cli/src/commands/database/url.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { CommandModule } from 'yargs';
|
||||||
|
|
||||||
|
import { getConfig } from '../../utilities';
|
||||||
|
|
||||||
|
export const getUrl: CommandModule = {
|
||||||
|
command: 'get-url',
|
||||||
|
describe: 'Get database URL in Logto config file',
|
||||||
|
handler: async () => {
|
||||||
|
const { databaseUrl } = await getConfig();
|
||||||
|
console.log(databaseUrl);
|
||||||
|
},
|
||||||
|
};
|
|
@ -9,6 +9,7 @@ import inquirer from 'inquirer';
|
||||||
import ora from 'ora';
|
import ora from 'ora';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import tar from 'tar';
|
import tar from 'tar';
|
||||||
|
import { CommandModule } from 'yargs';
|
||||||
|
|
||||||
import { downloadFile, log, safeExecSync } from '../utilities';
|
import { downloadFile, log, safeExecSync } from '../utilities';
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ const decompress = async (toPath: string, tarPath: string) => {
|
||||||
decompressSpinner.succeed();
|
decompressSpinner.succeed();
|
||||||
};
|
};
|
||||||
|
|
||||||
const install = async ({ path: pathArgument = defaultPath, silent = false }: InstallArgs) => {
|
const installLogto = async ({ path: pathArgument = defaultPath, silent = false }: InstallArgs) => {
|
||||||
validateNodeVersion();
|
validateNodeVersion();
|
||||||
|
|
||||||
const instancePath = (!silent && (await getInstancePath())) || pathArgument;
|
const instancePath = (!silent && (await getInstancePath())) || pathArgument;
|
||||||
|
@ -122,4 +123,25 @@ const install = async ({ path: pathArgument = defaultPath, silent = false }: Ins
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const install: CommandModule<Record<string, unknown>, { path?: string; silent?: boolean }> = {
|
||||||
|
command: ['init', 'i', 'install'],
|
||||||
|
describe: 'Download and run the latest Logto release',
|
||||||
|
builder: (yargs) =>
|
||||||
|
yargs.options({
|
||||||
|
path: {
|
||||||
|
alias: 'p',
|
||||||
|
describe: 'Path of Logto, must be a non-existing path',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
silent: {
|
||||||
|
alias: 's',
|
||||||
|
describe: 'Entering non-interactive mode',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
handler: async ({ path, silent }) => {
|
||||||
|
await installLogto({ path, silent });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default install;
|
export default install;
|
||||||
|
|
|
@ -1,28 +1,12 @@
|
||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import { hideBin } from 'yargs/helpers';
|
import { hideBin } from 'yargs/helpers';
|
||||||
|
|
||||||
|
import database from './commands/database';
|
||||||
import install from './commands/install';
|
import install from './commands/install';
|
||||||
|
|
||||||
void yargs(hideBin(process.argv))
|
void yargs(hideBin(process.argv))
|
||||||
.command(
|
.command(install)
|
||||||
['init', 'i', 'install'],
|
.command(database)
|
||||||
'Download and run the latest Logto release',
|
|
||||||
{
|
|
||||||
path: {
|
|
||||||
alias: 'p',
|
|
||||||
describe: 'Path of Logto, must be a non-existing path',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
silent: {
|
|
||||||
alias: 's',
|
|
||||||
describe: 'Entering non-interactive mode',
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async ({ path, silent }) => {
|
|
||||||
await install({ path, silent });
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.demandCommand(1)
|
.demandCommand(1)
|
||||||
.showHelpOnFail(true)
|
.showHelpOnFail(true)
|
||||||
.strict()
|
.strict()
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import { createWriteStream } from 'fs';
|
import { createWriteStream } from 'fs';
|
||||||
|
import { readFile } from 'fs/promises';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import findUp from 'find-up';
|
||||||
import got, { Progress } from 'got';
|
import got, { Progress } from 'got';
|
||||||
import { HttpsProxyAgent } from 'hpagent';
|
import { HttpsProxyAgent } from 'hpagent';
|
||||||
import ora from 'ora';
|
import ora from 'ora';
|
||||||
|
// eslint-disable-next-line id-length
|
||||||
|
import z from 'zod';
|
||||||
|
|
||||||
export const safeExecSync = (command: string) => {
|
export const safeExecSync = (command: string) => {
|
||||||
try {
|
try {
|
||||||
|
@ -68,3 +74,31 @@ export const downloadFile = async (url: string, destination: string) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Intended
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
|
export const noop = () => {};
|
||||||
|
|
||||||
|
// Logto config
|
||||||
|
const logtoConfig = '.logto.json';
|
||||||
|
|
||||||
|
const getConfigJson = async () => {
|
||||||
|
const configPath = (await findUp(logtoConfig)) ?? path.join(os.homedir(), logtoConfig);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const raw = await readFile(configPath, 'utf8');
|
||||||
|
|
||||||
|
// Prefer `unknown` over the original return type `any`, will guard later
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
return JSON.parse(raw) as unknown;
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getConfig = async () => {
|
||||||
|
return z
|
||||||
|
.object({
|
||||||
|
databaseUrl: z.string().optional(),
|
||||||
|
})
|
||||||
|
.default({})
|
||||||
|
.parse(await getConfigJson());
|
||||||
|
};
|
||||||
|
|
|
@ -30,6 +30,7 @@ importers:
|
||||||
'@types/yargs': ^17.0.13
|
'@types/yargs': ^17.0.13
|
||||||
chalk: ^4.1.2
|
chalk: ^4.1.2
|
||||||
eslint: ^8.21.0
|
eslint: ^8.21.0
|
||||||
|
find-up: ^5.0.0
|
||||||
got: ^11.8.2
|
got: ^11.8.2
|
||||||
hpagent: ^1.0.0
|
hpagent: ^1.0.0
|
||||||
inquirer: ^8.2.2
|
inquirer: ^8.2.2
|
||||||
|
@ -42,8 +43,10 @@ importers:
|
||||||
ts-node: ^10.9.1
|
ts-node: ^10.9.1
|
||||||
typescript: ^4.7.4
|
typescript: ^4.7.4
|
||||||
yargs: ^17.6.0
|
yargs: ^17.6.0
|
||||||
|
zod: ^3.18.0
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
|
find-up: 5.0.0
|
||||||
got: 11.8.3
|
got: 11.8.3
|
||||||
hpagent: 1.0.0
|
hpagent: 1.0.0
|
||||||
inquirer: 8.2.2
|
inquirer: 8.2.2
|
||||||
|
@ -51,6 +54,7 @@ importers:
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
yargs: 17.6.0
|
yargs: 17.6.0
|
||||||
|
zod: 3.18.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@silverhand/eslint-config': 1.0.0_swk2g7ygmfleszo5c33j4vooni
|
'@silverhand/eslint-config': 1.0.0_swk2g7ygmfleszo5c33j4vooni
|
||||||
'@silverhand/ts-config': 1.0.0_typescript@4.7.4
|
'@silverhand/ts-config': 1.0.0_typescript@4.7.4
|
||||||
|
@ -7493,7 +7497,6 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
locate-path: 6.0.0
|
locate-path: 6.0.0
|
||||||
path-exists: 4.0.0
|
path-exists: 4.0.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/flat-cache/3.0.4:
|
/flat-cache/3.0.4:
|
||||||
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
|
||||||
|
@ -10290,7 +10293,6 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/lodash._reinterpolate/3.0.0:
|
/lodash._reinterpolate/3.0.0:
|
||||||
resolution: {integrity: sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=}
|
resolution: {integrity: sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=}
|
||||||
|
@ -11920,7 +11922,6 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
yocto-queue: 0.1.0
|
yocto-queue: 0.1.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/p-locate/2.0.0:
|
/p-locate/2.0.0:
|
||||||
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
|
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
|
||||||
|
@ -11941,7 +11942,6 @@ packages:
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
p-limit: 3.1.0
|
p-limit: 3.1.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/p-map-series/2.1.0:
|
/p-map-series/2.1.0:
|
||||||
resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==}
|
resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==}
|
||||||
|
@ -12205,7 +12205,6 @@ packages:
|
||||||
/path-exists/4.0.0:
|
/path-exists/4.0.0:
|
||||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/path-is-absolute/1.0.1:
|
/path-is-absolute/1.0.1:
|
||||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||||
|
@ -15764,7 +15763,6 @@ packages:
|
||||||
/yocto-queue/0.1.0:
|
/yocto-queue/0.1.0:
|
||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/zod/3.18.0:
|
/zod/3.18.0:
|
||||||
resolution: {integrity: sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==}
|
resolution: {integrity: sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==}
|
||||||
|
|
Loading…
Reference in a new issue