feat(cpa): rework all prompts to use @clack/prompts

This commit is contained in:
Elliot DeNolf
2024-03-31 23:22:38 -04:00
parent db0fb30f7b
commit 3c54d32b6d
11 changed files with 193 additions and 216 deletions

View File

@@ -21,6 +21,7 @@
"bin"
],
"dependencies": {
"@clack/prompts": "^0.7.0",
"@sindresorhus/slugify": "^1.1.0",
"arg": "^5.0.0",
"chalk": "^4.1.0",
@@ -33,9 +34,6 @@
"figures": "^3.2.0",
"fs-extra": "^9.0.1",
"globby": "11.1.0",
"handlebars": "^4.7.7",
"ora": "^5.1.0",
"prompts": "^2.4.2",
"terminal-link": "^2.1.1"
},
"devDependencies": {
@@ -44,8 +42,7 @@
"@types/esprima": "^4.0.6",
"@types/fs-extra": "^9.0.12",
"@types/jest": "^27.0.3",
"@types/node": "^16.6.2",
"@types/prompts": "^2.4.1"
"@types/node": "^16.6.2"
},
"exports": {
"./commands": {

View File

@@ -1,15 +1,14 @@
import * as p from '@clack/prompts'
import chalk from 'chalk'
import degit from 'degit'
import execa from 'execa'
import fse from 'fs-extra'
import { fileURLToPath } from 'node:url'
import ora from 'ora'
import path from 'path'
import type { CliArgs, DbDetails, PackageManager, ProjectTemplate } from '../types.js'
import { log } from '../utils/log.js'
import { debug, error, success, warning } from '../utils/log.js'
import { debug, error, warning } from '../utils/log.js'
import { configurePayloadConfig } from './configure-payload-config.js'
const filename = fileURLToPath(import.meta.url)
@@ -61,14 +60,12 @@ export async function createProject(args: {
const { cliArgs, dbDetails, packageManager, projectDir, projectName, template } = args
if (cliArgs['--dry-run']) {
log(`\n Dry run: Creating project in ${chalk.green(projectDir)}\n`)
debug(`Dry run: Creating project in ${chalk.green(projectDir)}`)
return
}
await createOrFindProjectDir(projectDir)
log(`\n Creating project in ${chalk.green(projectDir)}\n`)
if (cliArgs['--local-template']) {
// Copy template from local path. For development purposes.
const localTemplate = path.resolve(
@@ -87,9 +84,11 @@ export async function createProject(args: {
await emitter.clone(projectDir)
}
const spinner = ora('Checking latest Payload version...').start()
const spinner = p.spinner()
spinner.start('Checking latest Payload version...')
await updatePackageJSON({ projectDir, projectName })
spinner.message('Configuring Payload...')
await configurePayloadConfig({ dbDetails, projectDirOrConfigPath: { projectDir } })
// Remove yarn.lock file. This is only desired in Payload Cloud.
@@ -99,18 +98,16 @@ export async function createProject(args: {
}
if (!cliArgs['--no-deps']) {
spinner.text = 'Installing dependencies...'
spinner.message('Installing dependencies...')
const result = await installDeps({ cliArgs, packageManager, projectDir })
spinner.stop()
spinner.clear()
if (result) {
success('Dependencies installed')
spinner.stop('Dependencies installed')
} else {
error('Error installing dependencies')
spinner.stop('Error installing dependencies', 1)
}
} else {
spinner.stop()
spinner.clear()
spinner.stop('Dependency installation skipped')
}
}

View File

@@ -1,5 +1,6 @@
import type { CompilerOptions } from 'typescript'
import * as p from '@clack/prompts'
import { parse, stringify } from 'comment-json'
import execa from 'execa'
import fs from 'fs'
@@ -7,7 +8,6 @@ import globby from 'globby'
import path from 'path'
import { promisify } from 'util'
import { log } from '../utils/log.js'
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
@@ -16,14 +16,15 @@ const dirname = path.dirname(filename)
import { fileURLToPath } from 'node:url'
import type { CliArgs, PackageManager } from '../types.js'
import type { CliArgs, DbType, PackageManager } from '../types.js'
import { copyRecursiveSync } from '../utils/copy-recursive-sync.js'
import { error, info, debug as origDebug, success, warning } from '../utils/log.js'
import { debug as origDebug, warning } from '../utils/log.js'
import { moveMessage } from '../utils/messages.js'
import { wrapNextConfig } from './wrap-next-config.js'
type InitNextArgs = Pick<CliArgs, '--debug'> & {
dbType: DbType
nextConfigPath: string
packageManager: PackageManager
projectDir: string
@@ -40,7 +41,7 @@ type InitNextResult =
| { isSrcDir: boolean; nextAppDir?: string; reason: string; success: false }
export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
const { packageManager, projectDir } = args
const { dbType: dbType, packageManager, projectDir } = args
const isSrcDir = fs.existsSync(path.resolve(projectDir, 'src'))
@@ -61,7 +62,7 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
const layoutPath = path.resolve(nextAppDir, 'layout.tsx')
if (fs.existsSync(layoutPath)) {
// Output directions for user to move all files from app to top-level directory named `(app)`
log(moveMessage({ nextAppDir, projectDir }))
p.log.warn(moveMessage({ nextAppDir, projectDir }))
return {
isSrcDir,
nextAppDir,
@@ -70,6 +71,9 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
}
}
const installSpinner = p.spinner()
installSpinner.start('Installing Payload and dependencies...')
const configurationResult = installAndConfigurePayload({
...args,
isSrcDir,
@@ -78,11 +82,13 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
})
if (configurationResult.success === false) {
installSpinner.stop(configurationResult.reason, 1)
return { ...configurationResult, isSrcDir, success: false }
}
const { success: installSuccess } = await installDeps(projectDir, packageManager)
const { success: installSuccess } = await installDeps(projectDir, packageManager, dbType)
if (!installSuccess) {
installSpinner.stop('Failed to install dependencies', 1)
return {
...configurationResult,
isSrcDir,
@@ -93,7 +99,7 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
// Add `@payload-config` to tsconfig.json `paths`
await addPayloadConfigToTsConfig(projectDir, isSrcDir)
installSpinner.stop('Successfully installed Payload and dependencies')
return { ...configurationResult, isSrcDir, nextAppDir, success: true }
}
@@ -119,14 +125,15 @@ async function addPayloadConfigToTsConfig(projectDir: string, isSrcDir: boolean)
}
function installAndConfigurePayload(
args: InitNextArgs & { isSrcDir: boolean; nextAppDir: string },
args: InitNextArgs & {
isSrcDir: boolean
nextAppDir: string
},
):
| { payloadConfigPath: string; success: true }
| { payloadConfigPath?: string; reason: string; success: false } {
const { '--debug': debug, isSrcDir, nextAppDir, nextConfigPath, projectDir, useDistFiles } = args
info('Initializing Payload app in Next.js project', 1)
const logDebug = (message: string) => {
if (debug) origDebug(message)
}
@@ -174,21 +181,18 @@ function installAndConfigurePayload(
// Wrap next.config.js with withPayload
wrapNextConfig({ nextConfigPath })
success('Successfully initialized.')
return {
payloadConfigPath: path.resolve(nextAppDir, '../payload.config.ts'),
success: true,
}
}
async function installDeps(projectDir: string, packageManager: PackageManager) {
info(`Installing dependencies with ${packageManager}`, 1)
const packagesToInstall = [
'payload',
'@payloadcms/db-mongodb',
'@payloadcms/next',
'@payloadcms/richtext-lexical',
].map((pkg) => `${pkg}@alpha`)
async function installDeps(projectDir: string, packageManager: PackageManager, dbType: DbType) {
const packagesToInstall = ['payload', '@payloadcms/next', '@payloadcms/richtext-lexical'].map(
(pkg) => `${pkg}@alpha`,
)
packagesToInstall.push(`@payloadcms/db-${dbType}@alpha`)
let exitCode = 0
switch (packageManager) {
@@ -212,10 +216,5 @@ async function installDeps(projectDir: string, packageManager: PackageManager) {
}
}
if (exitCode !== 0) {
error(`Failed to install dependencies with ${packageManager}`)
} else {
success(`Successfully installed dependencies`)
}
return { success: exitCode === 0 }
}

View File

@@ -1,4 +1,4 @@
import prompts from 'prompts'
import * as p from '@clack/prompts'
import type { CliArgs } from '../types.js'
@@ -6,19 +6,14 @@ export async function parseProjectName(args: CliArgs): Promise<string> {
if (args['--name']) return args['--name']
if (args._[0]) return args._[0]
const response = await prompts(
{
name: 'value',
type: 'text',
const projectName = await p.text({
message: 'Project name?',
validate: (value: string) => !!value.length,
validate: (value) => {
if (!value) return 'Please enter a project name.'
},
{
onCancel: () => {
})
if (p.isCancel(projectName)) {
process.exit(0)
},
},
)
return response.value
}
return projectName
}

View File

@@ -1,11 +1,11 @@
import prompts from 'prompts'
import * as p from '@clack/prompts'
import type { CliArgs, ProjectTemplate } from '../types.js'
export async function parseTemplate(
args: CliArgs,
validTemplates: ProjectTemplate[],
): Promise<ProjectTemplate> {
): Promise<ProjectTemplate | undefined> {
if (args['--template']) {
const templateName = args['--template']
const template = validTemplates.find((t) => t.name === templateName)
@@ -13,29 +13,20 @@ export async function parseTemplate(
return template
}
const response = await prompts(
{
name: 'value',
type: 'select',
choices: validTemplates.map((p) => {
const response = await p.select<{ label: string; value: string }[], string>({
message: 'Choose project template',
options: validTemplates.map((p) => {
return {
description: p.description,
title: p.name,
label: p.name,
value: p.name,
}
}),
message: 'Choose project template',
validate: (value: string) => !!value.length,
},
{
onCancel: () => {
})
if (p.isCancel(response)) {
process.exit(0)
},
},
)
}
const template = validTemplates.find((t) => t.name === response.value)
if (!template) throw new Error('Template is undefined')
const template = validTemplates.find((t) => t.name === response)
return template
}

View File

@@ -1,5 +1,5 @@
import * as p from '@clack/prompts'
import slugify from '@sindresorhus/slugify'
import prompts from 'prompts'
import type { CliArgs, DbDetails, DbType } from '../types.js'
@@ -23,7 +23,7 @@ const dbChoiceRecord: Record<DbType, DbChoice> = {
}
export async function selectDb(args: CliArgs, projectName: string): Promise<DbDetails> {
let dbType: DbType | undefined = undefined
let dbType: DbType | symbol | undefined = undefined
if (args['--db']) {
if (!Object.values(dbChoiceRecord).some((dbChoice) => dbChoice.value === args['--db'])) {
throw new Error(
@@ -34,31 +34,20 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
}
dbType = args['--db'] as DbType
} else {
const dbTypeRes = await prompts(
{
name: 'value',
type: 'select',
choices: Object.values(dbChoiceRecord).map((dbChoice) => {
return {
title: dbChoice.title,
value: dbChoice.value,
}
}),
message: 'Select a database',
validate: (value: string) => !!value.length,
},
{
onCancel: () => {
process.exit(0)
},
},
)
dbType = dbTypeRes.value
dbType = await p.select<{ label: string; value: DbType }[], DbType>({
initialValue: 'mongodb',
message: `Select a database`,
options: [
{ label: 'MongoDB', value: 'mongodb' },
{ label: 'Postgres', value: 'postgres' },
],
})
if (p.isCancel(dbType)) process.exit(0)
}
const dbChoice = dbChoiceRecord[dbType]
let dbUri: string | undefined = undefined
let dbUri: string | symbol | undefined = undefined
const initialDbUri = `${dbChoice.dbConnectionPrefix}${
projectName === '.' ? `payload-${getRandomDigitSuffix()}` : slugify(projectName)
}`
@@ -68,21 +57,11 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
} else if (args['--db-connection-string']) {
dbUri = args['--db-connection-string']
} else {
const dbUriRes = await prompts(
{
name: 'value',
type: 'text',
initial: initialDbUri,
dbUri = await p.text({
initialValue: initialDbUri,
message: `Enter ${dbChoice.title.split(' ')[0]} connection string`, // strip beta from title
validate: (value: string) => !!value.length,
},
{
onCancel: () => {
process.exit(0)
},
},
)
dbUri = dbUriRes.value
})
if (p.isCancel(dbUri)) process.exit(0)
}
return {

View File

@@ -1,10 +1,9 @@
import chalk from 'chalk'
import fs from 'fs-extra'
import path from 'path'
import type { CliArgs, ProjectTemplate } from '../types.js'
import { error, success } from '../utils/log.js'
import { debug, error } from '../utils/log.js'
/** Parse and swap .env.example values and write .env */
export async function writeEnvFile(args: {
@@ -17,7 +16,7 @@ export async function writeEnvFile(args: {
const { cliArgs, databaseUri, payloadSecret, projectDir, template } = args
if (cliArgs['--dry-run']) {
success(`DRY RUN: .env file created`)
debug(`DRY RUN: .env file created`)
return
}
@@ -51,8 +50,6 @@ export async function writeEnvFile(args: {
const content = `MONGODB_URI=${databaseUri}\nPAYLOAD_SECRET=${payloadSecret}`
await fs.outputFile(`${projectDir}/.env`, content)
}
success('.env file created')
} catch (err: unknown) {
error('Unable to write .env file')
if (err instanceof Error) {

View File

@@ -1,5 +1,7 @@
import * as p from '@clack/prompts'
import slugify from '@sindresorhus/slugify'
import arg from 'arg'
import chalk from 'chalk'
import { detect } from 'detect-package-manager'
import globby from 'globby'
import path from 'path'
@@ -15,13 +17,8 @@ import { parseTemplate } from './lib/parse-template.js'
import { selectDb } from './lib/select-db.js'
import { getValidTemplates, validateTemplate } from './lib/templates.js'
import { writeEnvFile } from './lib/write-env-file.js'
import { error, log, success } from './utils/log.js'
import {
helpMessage,
successMessage,
successfulNextInit,
welcomeMessage,
} from './utils/messages.js'
import { error, info } from './utils/log.js'
import { feedbackOutro, helpMessage, successMessage, successfulNextInit } from './utils/messages.js'
export class Main {
args: CliArgs
@@ -73,21 +70,20 @@ export class Main {
try {
if (this.args['--help']) {
log(helpMessage())
helpMessage()
process.exit(0)
}
log(welcomeMessage)
// Detect if inside Next.js project
// eslint-disable-next-line no-console
console.log('\n')
p.intro(chalk.bgCyan(chalk.black(' create-payload-app ')))
p.log.message("Welcome to Payload. Let's create a project!")
// Detect if inside Next.js projeckpt
const nextConfigPath = (
await globby('next.config.*js', { absolute: true, cwd: process.cwd() })
)?.[0]
initContext.nextConfigPath = nextConfigPath
success('Next.js app detected.')
// TODO: Prompt to continue
if (initContext.nextConfigPath) {
this.args['--name'] = slugify(path.basename(path.dirname(initContext.nextConfigPath)))
}
@@ -100,20 +96,30 @@ export class Main {
const packageManager = await getPackageManager(this.args, projectDir)
if (nextConfigPath) {
// p.note('Detected existing Next.js project.')
p.log.step(chalk.bold('Detected existing Next.js project.'))
const proceed = await p.confirm({
initialValue: true,
message: 'Install Payload in this project?',
})
if (p.isCancel(proceed) || !proceed) {
process.exit(0)
}
const dbDetails = await selectDb(this.args, projectName)
const result = await initNext({
...this.args,
dbType: dbDetails.type,
nextConfigPath,
packageManager,
projectDir,
})
if (result.success === false) {
error(result.reason)
process.exit(1)
} else {
success('Payload app successfully initialized in Next.js project')
}
const dbDetails = await selectDb(this.args, projectName)
await configurePayloadConfig({
dbDetails,
projectDirOrConfigPath: {
@@ -121,9 +127,9 @@ export class Main {
},
})
// TODO: This should continue the normal prompt flow
success('Payload project successfully created')
log(successfulNextInit())
info('Payload project successfully created!')
p.note(successfulNextInit(), chalk.bgGreen(chalk.black(' Documentation ')))
p.outro(feedbackOutro())
return
}
@@ -131,13 +137,17 @@ export class Main {
if (templateArg) {
const valid = validateTemplate(templateArg)
if (!valid) {
log(helpMessage())
helpMessage()
process.exit(1)
}
}
const validTemplates = getValidTemplates()
const template = await parseTemplate(this.args, validTemplates)
if (!template) {
p.log.error('Invalid template given')
process.exit(1)
}
switch (template.type) {
case 'starter': {
@@ -172,8 +182,9 @@ export class Main {
}
}
success('Payload project successfully created')
log(successMessage(projectDir, packageManager))
info('Payload project successfully created!')
p.note(successMessage(projectDir, packageManager), chalk.bgGreen(chalk.black(' Next Steps ')))
p.outro(feedbackOutro())
} catch (err: unknown) {
error(err instanceof Error ? err.message : 'An error occurred')
}

View File

@@ -1,34 +1,23 @@
/* eslint-disable no-console */
import * as p from '@clack/prompts'
import chalk from 'chalk'
import figures from 'figures'
export const success = (message: string): void => {
console.log(`${chalk.green(figures.tick)} ${chalk.bold(message)}`)
}
export const warning = (message: string): void => {
console.log(chalk.yellow('? ') + chalk.bold(message))
p.log.warn(chalk.yellow('? ') + chalk.bold(message))
}
export const info = (message: string, paddingTop?: number): void => {
console.log(
`${'\n'.repeat(paddingTop || 0)}${chalk.green(figures.pointerSmall)} ${chalk.bold(message)}`,
)
export const info = (message: string): void => {
p.log.step(chalk.bold(message))
}
export const error = (message: string): void => {
console.log(`${chalk.red(figures.cross)} ${chalk.bold(message)}`)
p.log.error(chalk.bold(message))
}
export const debug = (message: string): void => {
console.log(
`${chalk.gray(figures.pointerSmall)} ${chalk.bgGray('[DEBUG]')} ${chalk.gray(message)}`,
)
p.log.step(`${chalk.bgGray('[DEBUG]')} ${chalk.gray(message)}`)
}
/**
* console.log passthrough
*/
export const log = (message: string): void => {
console.log(message)
p.log.message(message)
}

View File

@@ -1,13 +1,14 @@
/* eslint-disable no-console */
import chalk from 'chalk'
import figures from 'figures'
import path from 'path'
import terminalLink from 'terminal-link'
import type { ProjectTemplate } from '../types.js'
import type { PackageManager } from '../types.js'
import { getValidTemplates } from '../lib/templates.js'
const header = (message: string): string => `${chalk.yellow(figures.star)} ${chalk.bold(message)}`
const header = (message: string): string => chalk.bold(message)
export const welcomeMessage = chalk`
{green Welcome to Payload. Let's create a project! }
@@ -15,14 +16,14 @@ export const welcomeMessage = chalk`
const spacer = ' '.repeat(8)
export function helpMessage(): string {
export function helpMessage(): void {
const validTemplates = getValidTemplates()
return chalk`
console.log(chalk`
{bold USAGE}
{dim $} {bold npx create-payload-app}
{dim $} {bold npx create-payload-app} my-project
{dim $} {bold npx create-payload-app} -n my-project -t blog
{dim $} {bold npx create-payload-app} -n my-project -t template-name
{bold OPTIONS}
@@ -36,7 +37,7 @@ export function helpMessage(): string {
--use-pnpm Use pnpm to install dependencies
--no-deps Do not install any dependencies
-h Show help
`
`)
}
function formatTemplates(templates: ProjectTemplate[]) {
@@ -45,19 +46,20 @@ function formatTemplates(templates: ProjectTemplate[]) {
.join(`\n${spacer}`)}`
}
export function successMessage(projectDir: string, packageManager: string): string {
export function successMessage(projectDir: string, packageManager: PackageManager): string {
const relativePath = path.relative(process.cwd(), projectDir)
return `
${header('Launch Application:')}
${header('Launch Application:')}
- cd ${projectDir}
- cd ./${relativePath}
- ${
packageManager === 'yarn' ? 'yarn' : 'npm run'
packageManager === 'npm' ? 'npm run' : packageManager
} dev or follow directions in ${createTerminalLink(
'README.md',
`file://${path.resolve(projectDir, 'README.md')}`,
)}
${header('Documentation:')}
${header('Documentation:')}
- ${createTerminalLink(
'Getting Started',
@@ -69,35 +71,33 @@ export function successMessage(projectDir: string, packageManager: string): stri
}
export function successfulNextInit(): string {
return `
${header('Successful Payload Installation!')}
${header('Documentation:')}
- ${createTerminalLink(
return `- ${createTerminalLink(
'Getting Started',
'https://payloadcms.com/docs/getting-started/what-is-payload',
)}
- ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}
- ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}
`
}
export function moveMessage(args: { nextAppDir: string; projectDir: string }): string {
const relativePath = path.relative(process.cwd(), args.nextAppDir)
return `
${header('Next Steps:')}
${header('Next Steps:')}
Payload does not support a top-level layout.tsx file in your Next.js app directory.
Payload does not support a top-level layout.tsx file in your Next.js app directory.
${chalk.bold('To continue:')}
${chalk.bold('To continue:')}
- Move all files from ${args.nextAppDir} to a top-level directory named ${chalk.bold(
'(app)',
)} or similar.
Move all files from ./${relativePath} to a named directory such as ${chalk.bold('(app)')}
Once moved, rerun the create-payload-app command again.
Once moved, rerun the create-payload-app command again.
`
}
export function feedbackOutro(): string {
return `${chalk.bgCyan(chalk.black(' Have feedback? '))} Visit ${createTerminalLink('GitHub', 'https://github.com/payloadcms/payload')}`
}
// Create terminalLink with fallback for unsupported terminals
function createTerminalLink(text: string, url: string) {
return terminalLink(text, url, {

46
pnpm-lock.yaml generated
View File

@@ -295,6 +295,9 @@ importers:
packages/create-payload-app:
dependencies:
'@clack/prompts':
specifier: ^0.7.0
version: 0.7.0
'@sindresorhus/slugify':
specifier: ^1.1.0
version: 1.1.2
@@ -331,15 +334,6 @@ importers:
globby:
specifier: 11.1.0
version: 11.1.0
handlebars:
specifier: ^4.7.7
version: 4.7.8
ora:
specifier: ^5.1.0
version: 5.4.1
prompts:
specifier: ^2.4.2
version: 2.4.2
terminal-link:
specifier: ^2.1.1
version: 2.1.1
@@ -362,9 +356,6 @@ importers:
'@types/node':
specifier: ^16.6.2
version: 16.18.85
'@types/prompts':
specifier: ^2.4.1
version: 2.4.9
packages/db-mongodb:
dependencies:
@@ -2745,6 +2736,23 @@ packages:
/@bcoe/v8-coverage@0.2.3:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
/@clack/core@0.3.4:
resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==}
dependencies:
picocolors: 1.0.0
sisteransi: 1.0.5
dev: false
/@clack/prompts@0.7.0:
resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==}
dependencies:
'@clack/core': 0.3.4
picocolors: 1.0.0
sisteransi: 1.0.5
dev: false
bundledDependencies:
- is-unicode-supported
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
@@ -7451,6 +7459,7 @@ packages:
buffer: 5.7.1
inherits: 2.0.4
readable-stream: 3.6.2
dev: true
/body-parser@1.20.1:
resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
@@ -7790,6 +7799,7 @@ packages:
engines: {node: '>=8'}
dependencies:
restore-cursor: 3.1.0
dev: true
/cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
@@ -7801,6 +7811,7 @@ packages:
/cli-spinners@2.9.2:
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
engines: {node: '>=6'}
dev: true
/cli-truncate@3.1.0:
resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
@@ -7852,6 +7863,7 @@ packages:
/clone@1.0.4:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
dev: true
/clsx@1.2.1:
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
@@ -8738,6 +8750,7 @@ packages:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
dependencies:
clone: 1.0.4
dev: true
/defer-to-connect@2.0.1:
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
@@ -10725,6 +10738,7 @@ packages:
wordwrap: 1.0.0
optionalDependencies:
uglify-js: 3.17.4
dev: true
/hanji@0.0.5:
resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==}
@@ -11234,6 +11248,7 @@ packages:
/is-interactive@1.0.0:
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
engines: {node: '>=8'}
dev: true
/is-interactive@2.0.0:
resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==}
@@ -11366,6 +11381,7 @@ packages:
/is-unicode-supported@0.1.0:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
dev: true
/is-unicode-supported@1.3.0:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
@@ -12595,6 +12611,7 @@ packages:
dependencies:
chalk: 4.1.2
is-unicode-supported: 0.1.0
dev: true
/log-symbols@6.0.0:
resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==}
@@ -13060,6 +13077,7 @@ packages:
/neo-async@2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
/netmask@2.0.2:
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
@@ -13489,6 +13507,7 @@ packages:
log-symbols: 4.1.0
strip-ansi: 6.0.1
wcwidth: 1.0.1
dev: true
/ora@8.0.1:
resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==}
@@ -15472,6 +15491,7 @@ packages:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
dev: true
/restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
@@ -17014,6 +17034,7 @@ packages:
engines: {node: '>=0.8.0'}
hasBin: true
requiresBuild: true
dev: true
optional: true
/unbox-primitive@1.0.2:
@@ -17242,6 +17263,7 @@ packages:
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
dependencies:
defaults: 1.0.4
dev: true
/web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}