mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(cli): get/set db config key
This commit is contained in:
parent
880d07ebf7
commit
0eff1e3591
17 changed files with 277 additions and 24 deletions
|
@ -22,7 +22,7 @@
|
||||||
"precommit": "lint-staged",
|
"precommit": "lint-staged",
|
||||||
"build": "rimraf lib && tsc",
|
"build": "rimraf lib && tsc",
|
||||||
"start": "node .",
|
"start": "node .",
|
||||||
"dev": "ts-node src/index.ts",
|
"dev": "ts-node --files src/index.ts",
|
||||||
"lint": "eslint --ext .ts src",
|
"lint": "eslint --ext .ts src",
|
||||||
"lint:report": "pnpm lint --format json --output-file report.json",
|
"lint:report": "pnpm lint --format json --output-file report.json",
|
||||||
"prepack": "pnpm build"
|
"prepack": "pnpm build"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
"url": "https://github.com/logto-io/logto/issues"
|
"url": "https://github.com/logto-io/logto/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@logto/schemas": "^1.0.0-beta.10",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"find-up": "^5.0.0",
|
"find-up": "^5.0.0",
|
||||||
"got": "^11.8.2",
|
"got": "^11.8.2",
|
||||||
|
@ -41,6 +42,8 @@
|
||||||
"inquirer": "^8.2.2",
|
"inquirer": "^8.2.2",
|
||||||
"ora": "^5.0.0",
|
"ora": "^5.0.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
|
"slonik": "^30.0.0",
|
||||||
|
"slonik-interceptor-preset": "^1.2.10",
|
||||||
"tar": "^6.1.11",
|
"tar": "^6.1.11",
|
||||||
"yargs": "^17.6.0",
|
"yargs": "^17.6.0",
|
||||||
"zod": "^3.18.0"
|
"zod": "^3.18.0"
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import { CommandModule } from 'yargs';
|
import { CommandModule } from 'yargs';
|
||||||
|
|
||||||
import { noop } from '../../utilities';
|
import { noop } from '../../utilities';
|
||||||
|
import { getKey, setKey } from './key';
|
||||||
import { getUrl, setUrl } from './url';
|
import { getUrl, setUrl } from './url';
|
||||||
|
|
||||||
const database: CommandModule = {
|
const database: CommandModule = {
|
||||||
command: ['database', 'db'],
|
command: ['database', 'db'],
|
||||||
describe: 'Commands for Logto database',
|
describe: 'Commands for Logto database',
|
||||||
builder: (yargs) => yargs.command(getUrl).command(setUrl).strict(),
|
builder: (yargs) =>
|
||||||
|
yargs.command(getUrl).command(setUrl).command(getKey).command(setKey).demandCommand(1),
|
||||||
handler: noop,
|
handler: noop,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
96
packages/cli/src/commands/database/key.ts
Normal file
96
packages/cli/src/commands/database/key.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import { logtoConfigGuards, LogtoConfigKey, logtoConfigKeys } from '@logto/schemas';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import { CommandModule } from 'yargs';
|
||||||
|
|
||||||
|
import { createPoolFromConfig } from '../../database';
|
||||||
|
import { getRowsByKeys, updateValueByKey } from '../../queries/logto-config';
|
||||||
|
import { deduplicate, log } from '../../utilities';
|
||||||
|
|
||||||
|
const validKeysDisplay = chalk.green(logtoConfigKeys.join(', '));
|
||||||
|
|
||||||
|
type ValidateKeysFunction = {
|
||||||
|
(keys: string[]): asserts keys is LogtoConfigKey[];
|
||||||
|
(key: string): asserts key is LogtoConfigKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateKeys: ValidateKeysFunction = (keys) => {
|
||||||
|
const invalidKey = (Array.isArray(keys) ? keys : [keys]).find(
|
||||||
|
// Using `.includes()` will result a type error
|
||||||
|
// eslint-disable-next-line unicorn/prefer-includes
|
||||||
|
(key) => !logtoConfigKeys.some((element) => element === key)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (invalidKey) {
|
||||||
|
log.error(
|
||||||
|
`Invalid config key ${chalk.red(invalidKey)} found, expected one of ${validKeysDisplay}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getKey: CommandModule<unknown, { key: string; keys: string[] }> = {
|
||||||
|
command: 'get-key <key> [keys...]',
|
||||||
|
describe: 'Get config value(s) of the given key(s) in Logto database',
|
||||||
|
builder: (yargs) =>
|
||||||
|
yargs
|
||||||
|
.positional('key', {
|
||||||
|
describe: `The key to get from database, one of ${validKeysDisplay}`,
|
||||||
|
type: 'string',
|
||||||
|
demandOption: true,
|
||||||
|
})
|
||||||
|
.positional('keys', {
|
||||||
|
describe: 'The additional keys to get from database',
|
||||||
|
type: 'string',
|
||||||
|
array: true,
|
||||||
|
default: [],
|
||||||
|
}),
|
||||||
|
handler: async ({ key, keys }) => {
|
||||||
|
const queryKeys = deduplicate([key, ...keys]);
|
||||||
|
validateKeys(queryKeys);
|
||||||
|
|
||||||
|
const pool = await createPoolFromConfig();
|
||||||
|
const { rows } = await getRowsByKeys(pool, queryKeys);
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
queryKeys
|
||||||
|
.map((currentKey) => {
|
||||||
|
const value = rows.find(({ key }) => currentKey === key)?.value;
|
||||||
|
|
||||||
|
return (
|
||||||
|
chalk.magenta(currentKey) +
|
||||||
|
'=' +
|
||||||
|
(value === undefined ? chalk.gray(value) : chalk.green(JSON.stringify(value)))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.join('\n')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setKey: CommandModule<unknown, { key: string; value: string }> = {
|
||||||
|
command: 'set-key <key> <value>',
|
||||||
|
describe: 'Set config value of the given key in Logto database',
|
||||||
|
builder: (yargs) =>
|
||||||
|
yargs
|
||||||
|
.positional('key', {
|
||||||
|
describe: `The key to get from database, one of ${validKeysDisplay}`,
|
||||||
|
type: 'string',
|
||||||
|
demandOption: true,
|
||||||
|
})
|
||||||
|
.positional('value', {
|
||||||
|
describe: 'The value to set, should be a valid JSON string',
|
||||||
|
type: 'string',
|
||||||
|
demandOption: true,
|
||||||
|
}),
|
||||||
|
handler: async ({ key, value }) => {
|
||||||
|
validateKeys(key);
|
||||||
|
|
||||||
|
const guarded = logtoConfigGuards[key].parse(JSON.parse(value));
|
||||||
|
|
||||||
|
const pool = await createPoolFromConfig();
|
||||||
|
await updateValueByKey(pool, key, guarded);
|
||||||
|
await pool.end();
|
||||||
|
|
||||||
|
log.info(`Update ${chalk.green(key)} succeeded`);
|
||||||
|
},
|
||||||
|
};
|
|
@ -11,7 +11,7 @@ export const getUrl: CommandModule = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setUrl: CommandModule<Record<string, unknown>, { url: string }> = {
|
export const setUrl: CommandModule<unknown, { url: string }> = {
|
||||||
command: 'set-url <url>',
|
command: 'set-url <url>',
|
||||||
describe: 'Set database URL and save to config file',
|
describe: 'Set database URL and save to config file',
|
||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
|
|
|
@ -123,7 +123,7 @@ const installLogto = async ({ path: pathArgument = defaultPath, silent = false }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const install: CommandModule<Record<string, unknown>, { path?: string; silent?: boolean }> = {
|
const install: CommandModule<unknown, { path?: string; silent?: boolean }> = {
|
||||||
command: ['init', 'i', 'install'],
|
command: ['init', 'i', 'install'],
|
||||||
describe: 'Download and run the latest Logto release',
|
describe: 'Download and run the latest Logto release',
|
||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
|
|
39
packages/cli/src/database.ts
Normal file
39
packages/cli/src/database.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import { createPool, IdentifierSqlToken, sql } from 'slonik';
|
||||||
|
import { createInterceptors } from 'slonik-interceptor-preset';
|
||||||
|
|
||||||
|
import { getConfig } from './config';
|
||||||
|
import { log } from './utilities';
|
||||||
|
|
||||||
|
export const createPoolFromConfig = async () => {
|
||||||
|
const { databaseUrl } = await getConfig();
|
||||||
|
|
||||||
|
if (!databaseUrl) {
|
||||||
|
log.error(
|
||||||
|
`No database URL configured. Set one via ${chalk.green('database set-url')} command first.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPool(databaseUrl, {
|
||||||
|
interceptors: createInterceptors(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Move database utils to `core-kit`
|
||||||
|
export type Table = { table: string; fields: Record<string, string> };
|
||||||
|
export type FieldIdentifiers<Key extends string | number | symbol> = {
|
||||||
|
[key in Key]: IdentifierSqlToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertToIdentifiers = <T extends Table>({ table, fields }: T, withPrefix = false) => {
|
||||||
|
const fieldsIdentifiers = Object.entries<string>(fields).map<
|
||||||
|
[keyof T['fields'], IdentifierSqlToken]
|
||||||
|
>(([key, value]) => [key, sql.identifier(withPrefix ? [table, value] : [value])]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
table: sql.identifier([table]),
|
||||||
|
// Key value inferred from the original fields directly
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
fields: Object.fromEntries(fieldsIdentifiers) as FieldIdentifiers<keyof T['fields']>,
|
||||||
|
};
|
||||||
|
};
|
10
packages/cli/src/include.d/slonik-interceptor-preset.d.ts
vendored
Normal file
10
packages/cli/src/include.d/slonik-interceptor-preset.d.ts
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
declare module 'slonik-interceptor-preset' {
|
||||||
|
import { Interceptor } from 'slonik';
|
||||||
|
|
||||||
|
export const createInterceptors: (config?: {
|
||||||
|
benchmarkQueries: boolean;
|
||||||
|
logQueries: boolean;
|
||||||
|
normaliseQueries: boolean;
|
||||||
|
transformFieldNames: boolean;
|
||||||
|
}) => readonly Interceptor[];
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ void yargs(hideBin(process.argv))
|
||||||
.command(install)
|
.command(install)
|
||||||
.command(database)
|
.command(database)
|
||||||
.demandCommand(1)
|
.demandCommand(1)
|
||||||
.showHelpOnFail(true)
|
.showHelpOnFail(false)
|
||||||
.strict()
|
.strict()
|
||||||
.parserConfiguration({
|
.parserConfiguration({
|
||||||
'dot-notation': false,
|
'dot-notation': false,
|
||||||
|
|
26
packages/cli/src/queries/logto-config.ts
Normal file
26
packages/cli/src/queries/logto-config.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { LogtoConfig, logtoConfigGuards, LogtoConfigKey, LogtoConfigs } from '@logto/schemas';
|
||||||
|
import { DatabasePool, sql } from 'slonik';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { convertToIdentifiers } from '../database';
|
||||||
|
|
||||||
|
const { table, fields } = convertToIdentifiers(LogtoConfigs);
|
||||||
|
|
||||||
|
export const getRowsByKeys = async (pool: DatabasePool, keys: LogtoConfigKey[]) =>
|
||||||
|
pool.query<LogtoConfig>(sql`
|
||||||
|
select ${sql.join([fields.key, fields.value], sql`,`)} from ${table}
|
||||||
|
where ${fields.key} in (${sql.join(keys, sql`,`)})
|
||||||
|
`);
|
||||||
|
|
||||||
|
export const updateValueByKey = async <T extends LogtoConfigKey>(
|
||||||
|
pool: DatabasePool,
|
||||||
|
key: T,
|
||||||
|
value: z.infer<typeof logtoConfigGuards[T]>
|
||||||
|
) =>
|
||||||
|
pool.query(
|
||||||
|
sql`
|
||||||
|
insert into ${table} (${fields.key}, ${fields.value})
|
||||||
|
values (${key}, ${sql.jsonb(value)})
|
||||||
|
on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
|
||||||
|
`
|
||||||
|
);
|
|
@ -15,7 +15,7 @@ export const safeExecSync = (command: string) => {
|
||||||
type Log = Readonly<{
|
type Log = Readonly<{
|
||||||
info: typeof console.log;
|
info: typeof console.log;
|
||||||
warn: typeof console.log;
|
warn: typeof console.log;
|
||||||
error: typeof console.log;
|
error: (...args: Parameters<typeof console.log>) => never;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export const log: Log = Object.freeze({
|
export const log: Log = Object.freeze({
|
||||||
|
@ -72,3 +72,5 @@ export const downloadFile = async (url: string, destination: string) => {
|
||||||
// Intended
|
// Intended
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
export const noop = () => {};
|
export const noop = () => {};
|
||||||
|
|
||||||
|
export const deduplicate = <T>(array: T[]) => [...new Set(array)];
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
export const alterationStateKey = 'alterationState';
|
import { LogtoConfigKey } from '@logto/schemas';
|
||||||
|
|
||||||
|
export const alterationStateKey: LogtoConfigKey = 'alterationState';
|
||||||
export const logtoConfigsTableFilePath = 'node_modules/@logto/schemas/tables/logto_configs.sql';
|
export const logtoConfigsTableFilePath = 'node_modules/@logto/schemas/tables/logto_configs.sql';
|
||||||
export const alterationFilesDirectorySource = 'node_modules/@logto/schemas/alterations';
|
export const alterationFilesDirectorySource = 'node_modules/@logto/schemas/alterations';
|
||||||
export const alterationFilesDirectory = 'alterations/';
|
export const alterationFilesDirectory = 'alterations/';
|
||||||
|
|
|
@ -115,7 +115,7 @@ describe('createLogtoConfigsTable()', () => {
|
||||||
describe('updateDatabaseTimestamp()', () => {
|
describe('updateDatabaseTimestamp()', () => {
|
||||||
const expectSql = sql`
|
const expectSql = sql`
|
||||||
insert into ${table} (${fields.key}, ${fields.value})
|
insert into ${table} (${fields.key}, ${fields.value})
|
||||||
values ($1, $2)
|
values ($1, $2::jsonb)
|
||||||
on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
|
on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
|
||||||
`;
|
`;
|
||||||
const updatedAt = '2022-09-21T06:32:46.583Z';
|
const updatedAt = '2022-09-21T06:32:46.583Z';
|
||||||
|
|
|
@ -2,12 +2,8 @@ import { existsSync } from 'fs';
|
||||||
import { readdir, readFile } from 'fs/promises';
|
import { readdir, readFile } from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { LogtoConfig, LogtoConfigs } from '@logto/schemas';
|
import { LogtoConfig, LogtoConfigs, AlterationState, alterationStateGuard } from '@logto/schemas';
|
||||||
import {
|
import { AlterationScript } from '@logto/schemas/lib/types/alteration';
|
||||||
AlterationScript,
|
|
||||||
AlterationState,
|
|
||||||
alterationStateGuard,
|
|
||||||
} from '@logto/schemas/lib/types/alteration';
|
|
||||||
import { conditionalString } from '@silverhand/essentials';
|
import { conditionalString } from '@silverhand/essentials';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { copy, remove } from 'fs-extra';
|
import { copy, remove } from 'fs-extra';
|
||||||
|
@ -70,7 +66,7 @@ export const updateDatabaseTimestamp = async (pool: DatabasePool, timestamp?: nu
|
||||||
await pool.query(
|
await pool.query(
|
||||||
sql`
|
sql`
|
||||||
insert into ${table} (${fields.key}, ${fields.value})
|
insert into ${table} (${fields.key}, ${fields.value})
|
||||||
values (${alterationStateKey}, ${JSON.stringify(value)})
|
values (${alterationStateKey}, ${sql.jsonb(value)})
|
||||||
on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
|
on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
import type { DatabaseTransactionConnection } from 'slonik';
|
import type { DatabaseTransactionConnection } from 'slonik';
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
export const alterationStateGuard = z.object({
|
|
||||||
timestamp: z.number(),
|
|
||||||
updatedAt: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type AlterationState = z.infer<typeof alterationStateGuard>;
|
|
||||||
|
|
||||||
export type AlterationScript = {
|
export type AlterationScript = {
|
||||||
up: (connection: DatabaseTransactionConnection) => Promise<void>;
|
up: (connection: DatabaseTransactionConnection) => Promise<void>;
|
||||||
|
|
|
@ -2,3 +2,4 @@ export * from './connector';
|
||||||
export * from './log';
|
export * from './log';
|
||||||
export * from './oidc-config';
|
export * from './oidc-config';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
|
export * from './logto-config';
|
||||||
|
|
30
packages/schemas/src/types/logto-config.ts
Normal file
30
packages/schemas/src/types/logto-config.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
// Alteration state
|
||||||
|
export const alterationStateGuard = z.object({
|
||||||
|
timestamp: z.number(),
|
||||||
|
updatedAt: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AlterationState = z.infer<typeof alterationStateGuard>;
|
||||||
|
|
||||||
|
// Logto OIDC config
|
||||||
|
export const logtoOidcConfigGuard = z.object({
|
||||||
|
privateKeys: z.string().array().optional(),
|
||||||
|
cookieKeys: z.string().array().optional(),
|
||||||
|
refreshTokenReuseInterval: z.number().gte(3).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type LogtoOidcConfig = z.infer<typeof logtoOidcConfigGuard>;
|
||||||
|
|
||||||
|
// Summary
|
||||||
|
export const logtoConfigGuards = Object.freeze({
|
||||||
|
alterationState: alterationStateGuard,
|
||||||
|
oidcConfig: logtoOidcConfigGuard,
|
||||||
|
} as const);
|
||||||
|
|
||||||
|
export type LogtoConfigKey = keyof typeof logtoConfigGuards;
|
||||||
|
|
||||||
|
// `as` is intended since we'd like to keep `logtoConfigGuards` as the SSOT of keys
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export const logtoConfigKeys = Object.keys(logtoConfigGuards) as LogtoConfigKey[];
|
|
@ -20,6 +20,7 @@ importers:
|
||||||
|
|
||||||
packages/cli:
|
packages/cli:
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@logto/schemas': ^1.0.0-beta.10
|
||||||
'@silverhand/eslint-config': 1.0.0
|
'@silverhand/eslint-config': 1.0.0
|
||||||
'@silverhand/ts-config': 1.0.0
|
'@silverhand/ts-config': 1.0.0
|
||||||
'@types/decompress': ^4.2.4
|
'@types/decompress': ^4.2.4
|
||||||
|
@ -39,12 +40,15 @@ importers:
|
||||||
prettier: ^2.7.1
|
prettier: ^2.7.1
|
||||||
rimraf: ^3.0.2
|
rimraf: ^3.0.2
|
||||||
semver: ^7.3.7
|
semver: ^7.3.7
|
||||||
|
slonik: ^30.0.0
|
||||||
|
slonik-interceptor-preset: ^1.2.10
|
||||||
tar: ^6.1.11
|
tar: ^6.1.11
|
||||||
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
|
zod: ^3.18.0
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@logto/schemas': link:../schemas
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
find-up: 5.0.0
|
find-up: 5.0.0
|
||||||
got: 11.8.3
|
got: 11.8.3
|
||||||
|
@ -52,6 +56,8 @@ importers:
|
||||||
inquirer: 8.2.2
|
inquirer: 8.2.2
|
||||||
ora: 5.4.1
|
ora: 5.4.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
|
slonik: 30.1.2
|
||||||
|
slonik-interceptor-preset: 1.2.10
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
yargs: 17.6.0
|
yargs: 17.6.0
|
||||||
zod: 3.18.0
|
zod: 3.18.0
|
||||||
|
@ -1730,6 +1736,7 @@ packages:
|
||||||
pacote: 13.4.1
|
pacote: 13.4.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -1760,6 +1767,7 @@ packages:
|
||||||
p-waterfall: 2.1.1
|
p-waterfall: 2.1.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -1900,6 +1908,7 @@ packages:
|
||||||
whatwg-url: 8.7.0
|
whatwg-url: 8.7.0
|
||||||
yargs-parser: 20.2.4
|
yargs-parser: 20.2.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2097,6 +2106,7 @@ packages:
|
||||||
npm-registry-fetch: 9.0.0
|
npm-registry-fetch: 9.0.0
|
||||||
npmlog: 4.1.2
|
npmlog: 4.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2126,6 +2136,7 @@ packages:
|
||||||
pify: 5.0.0
|
pify: 5.0.0
|
||||||
read-package-json: 3.0.1
|
read-package-json: 3.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2164,6 +2175,7 @@ packages:
|
||||||
npmlog: 4.1.2
|
npmlog: 4.1.2
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2262,6 +2274,7 @@ packages:
|
||||||
pacote: 13.4.1
|
pacote: 13.4.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -2307,6 +2320,7 @@ packages:
|
||||||
'@npmcli/run-script': 3.0.2
|
'@npmcli/run-script': 3.0.2
|
||||||
npmlog: 4.1.2
|
npmlog: 4.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2408,6 +2422,7 @@ packages:
|
||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
write-json-file: 4.3.0
|
write-json-file: 4.3.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -2663,6 +2678,7 @@ packages:
|
||||||
treeverse: 2.0.0
|
treeverse: 2.0.0
|
||||||
walk-up-path: 1.0.0
|
walk-up-path: 1.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2698,6 +2714,8 @@ packages:
|
||||||
promise-retry: 2.0.1
|
promise-retry: 2.0.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@npmcli/installed-package-contents/1.0.7:
|
/@npmcli/installed-package-contents/1.0.7:
|
||||||
|
@ -2728,6 +2746,7 @@ packages:
|
||||||
pacote: 13.4.1
|
pacote: 13.4.1
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -2779,6 +2798,7 @@ packages:
|
||||||
node-gyp: 9.0.0
|
node-gyp: 9.0.0
|
||||||
read-package-json-fast: 2.0.3
|
read-package-json-fast: 2.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -3831,6 +3851,7 @@ packages:
|
||||||
stylelint-config-xo-scss: 0.15.0_eqpuutlgonckfyjzwkrpusdvaa
|
stylelint-config-xo-scss: 0.15.0_eqpuutlgonckfyjzwkrpusdvaa
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- eslint
|
- eslint
|
||||||
|
- eslint-import-resolver-webpack
|
||||||
- postcss
|
- postcss
|
||||||
- prettier
|
- prettier
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -3851,6 +3872,7 @@ packages:
|
||||||
stylelint-config-xo-scss: 0.15.0_uyk3cwxn3favstz4untq233szu
|
stylelint-config-xo-scss: 0.15.0_uyk3cwxn3favstz4untq233szu
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- eslint
|
- eslint
|
||||||
|
- eslint-import-resolver-webpack
|
||||||
- postcss
|
- postcss
|
||||||
- prettier
|
- prettier
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -5463,6 +5485,8 @@ packages:
|
||||||
ssri: 8.0.1
|
ssri: 8.0.1
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
unique-filename: 1.1.1
|
unique-filename: 1.1.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/cacache/16.1.0:
|
/cacache/16.1.0:
|
||||||
|
@ -5487,6 +5511,8 @@ packages:
|
||||||
ssri: 9.0.1
|
ssri: 9.0.1
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
unique-filename: 1.1.1
|
unique-filename: 1.1.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/cache-content-type/1.0.1:
|
/cache-content-type/1.0.1:
|
||||||
|
@ -6319,6 +6345,18 @@ packages:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/debug/3.2.7_supports-color@5.5.0:
|
||||||
|
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
supports-color: 5.5.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/debug/4.3.3:
|
/debug/4.3.3:
|
||||||
resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
|
resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
|
@ -10126,6 +10164,7 @@ packages:
|
||||||
import-local: 3.1.0
|
import-local: 3.1.0
|
||||||
npmlog: 4.1.2
|
npmlog: 4.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -10160,6 +10199,7 @@ packages:
|
||||||
npm-package-arg: 8.1.5
|
npm-package-arg: 8.1.5
|
||||||
npm-registry-fetch: 11.0.0
|
npm-registry-fetch: 11.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -10173,6 +10213,7 @@ packages:
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
ssri: 8.0.1
|
ssri: 8.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -10474,6 +10515,7 @@ packages:
|
||||||
socks-proxy-agent: 6.1.1
|
socks-proxy-agent: 6.1.1
|
||||||
ssri: 9.0.1
|
ssri: 9.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -10497,6 +10539,7 @@ packages:
|
||||||
socks-proxy-agent: 5.0.1
|
socks-proxy-agent: 5.0.1
|
||||||
ssri: 8.0.1
|
ssri: 8.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -10521,6 +10564,7 @@ packages:
|
||||||
socks-proxy-agent: 6.1.1
|
socks-proxy-agent: 6.1.1
|
||||||
ssri: 8.0.1
|
ssri: 8.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -11421,6 +11465,7 @@ packages:
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -11455,7 +11500,7 @@ packages:
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
debug: 3.2.7
|
debug: 3.2.7_supports-color@5.5.0
|
||||||
ignore-by-default: 1.0.1
|
ignore-by-default: 1.0.1
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
pstree.remy: 1.1.8
|
pstree.remy: 1.1.8
|
||||||
|
@ -11604,6 +11649,7 @@ packages:
|
||||||
minizlib: 2.1.2
|
minizlib: 2.1.2
|
||||||
npm-package-arg: 8.1.5
|
npm-package-arg: 8.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -11619,6 +11665,7 @@ packages:
|
||||||
npm-package-arg: 9.0.2
|
npm-package-arg: 9.0.2
|
||||||
proc-log: 2.0.1
|
proc-log: 2.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -11635,6 +11682,7 @@ packages:
|
||||||
minizlib: 2.1.2
|
minizlib: 2.1.2
|
||||||
npm-package-arg: 8.1.5
|
npm-package-arg: 8.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -12035,6 +12083,7 @@ packages:
|
||||||
ssri: 9.0.1
|
ssri: 9.0.1
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- bluebird
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -12736,6 +12785,11 @@ packages:
|
||||||
|
|
||||||
/promise-inflight/1.0.1:
|
/promise-inflight/1.0.1:
|
||||||
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
||||||
|
peerDependencies:
|
||||||
|
bluebird: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bluebird:
|
||||||
|
optional: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/promise-retry/2.0.1:
|
/promise-retry/2.0.1:
|
||||||
|
|
Loading…
Reference in a new issue