refactor(cna): make create-next-app
even smaller and faster (#58030)
The PR further reduces the `create-next-app` installation size by another 80 KiB: - Replace the callback version of Node.js built-in `dns` API usage with `dns/promise` + async/await - Replace `got` w/ `fetch` since Next.js and `create-next-app` now target Node.js 18.17.0+ - Download and extract the tar.gz file in the memory (without creating temporary files). This improves the performance. - Some other minor refinements. Following these changes, the size of `dist/index.js` is now 536 KiB.
This commit is contained in:
parent
e6e6609674
commit
b8b104506d
11 changed files with 101 additions and 229 deletions
|
@ -11,7 +11,6 @@ import {
|
|||
existsInRepo,
|
||||
hasRepo,
|
||||
} from './helpers/examples'
|
||||
import { makeDir } from './helpers/make-dir'
|
||||
import { tryGitInit } from './helpers/git'
|
||||
import { install } from './helpers/install'
|
||||
import { isFolderEmpty } from './helpers/is-folder-empty'
|
||||
|
@ -133,7 +132,7 @@ export async function createApp({
|
|||
|
||||
const appName = path.basename(root)
|
||||
|
||||
await makeDir(root)
|
||||
fs.mkdirSync(root, { recursive: true })
|
||||
if (!isFolderEmpty(root, appName)) {
|
||||
process.exit(1)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import got from 'got'
|
||||
import tar from 'tar'
|
||||
import { Stream } from 'stream'
|
||||
import { promisify } from 'util'
|
||||
import { join } from 'path'
|
||||
import { tmpdir } from 'os'
|
||||
import { createWriteStream, promises as fs } from 'fs'
|
||||
|
||||
const pipeline = promisify(Stream.pipeline)
|
||||
import { Readable } from 'stream'
|
||||
import { pipeline } from 'stream/promises'
|
||||
|
||||
export type RepoInfo = {
|
||||
username: string
|
||||
|
@ -17,8 +11,12 @@ export type RepoInfo = {
|
|||
}
|
||||
|
||||
export async function isUrlOk(url: string): Promise<boolean> {
|
||||
const res = await got.head(url).catch((e) => e)
|
||||
return res.statusCode === 200
|
||||
try {
|
||||
const res = await fetch(url, { method: 'HEAD' })
|
||||
return res.status === 200
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRepoInfo(
|
||||
|
@ -37,14 +35,19 @@ export async function getRepoInfo(
|
|||
// In this case "t" will be an empty string while the next part "_branch" will be undefined
|
||||
(t === '' && _branch === undefined)
|
||||
) {
|
||||
const infoResponse = await got(
|
||||
`https://api.github.com/repos/${username}/${name}`
|
||||
).catch((e) => e)
|
||||
if (infoResponse.statusCode !== 200) {
|
||||
try {
|
||||
const infoResponse = await fetch(
|
||||
`https://api.github.com/repos/${username}/${name}`
|
||||
)
|
||||
if (infoResponse.status !== 200) {
|
||||
return
|
||||
}
|
||||
|
||||
const info = await infoResponse.json()
|
||||
return { username, name, branch: info['default_branch'], filePath }
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
const info = JSON.parse(infoResponse.body)
|
||||
return { username, name, branch: info['default_branch'], filePath }
|
||||
}
|
||||
|
||||
// If examplePath is available, the branch name takes the entire path
|
||||
|
@ -82,33 +85,35 @@ export function existsInRepo(nameOrUrl: string): Promise<boolean> {
|
|||
}
|
||||
}
|
||||
|
||||
async function downloadTar(url: string) {
|
||||
const tempFile = join(tmpdir(), `next.js-cna-example.temp-${Date.now()}`)
|
||||
await pipeline(got.stream(url), createWriteStream(tempFile))
|
||||
return tempFile
|
||||
async function downloadTarStream(url: string) {
|
||||
const res = await fetch(url)
|
||||
|
||||
if (!res.body) {
|
||||
throw new Error(`Failed to download: ${url}`)
|
||||
}
|
||||
|
||||
return Readable.fromWeb(res.body as import('stream/web').ReadableStream)
|
||||
}
|
||||
|
||||
export async function downloadAndExtractRepo(
|
||||
root: string,
|
||||
{ username, name, branch, filePath }: RepoInfo
|
||||
) {
|
||||
const tempFile = await downloadTar(
|
||||
`https://codeload.github.com/${username}/${name}/tar.gz/${branch}`
|
||||
await pipeline(
|
||||
await downloadTarStream(
|
||||
`https://codeload.github.com/${username}/${name}/tar.gz/${branch}`
|
||||
),
|
||||
tar.x({
|
||||
cwd: root,
|
||||
strip: filePath ? filePath.split('/').length + 1 : 1,
|
||||
filter: (p) =>
|
||||
p.startsWith(
|
||||
`${name}-${branch.replace(/\//g, '-')}${
|
||||
filePath ? `/${filePath}/` : '/'
|
||||
}`
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
await tar.x({
|
||||
file: tempFile,
|
||||
cwd: root,
|
||||
strip: filePath ? filePath.split('/').length + 1 : 1,
|
||||
filter: (p) =>
|
||||
p.startsWith(
|
||||
`${name}-${branch.replace(/\//g, '-')}${
|
||||
filePath ? `/${filePath}/` : '/'
|
||||
}`
|
||||
),
|
||||
})
|
||||
|
||||
await fs.unlink(tempFile)
|
||||
}
|
||||
|
||||
export async function downloadAndExtractExample(root: string, name: string) {
|
||||
|
@ -116,16 +121,14 @@ export async function downloadAndExtractExample(root: string, name: string) {
|
|||
throw new Error('This is an internal example for testing the CLI.')
|
||||
}
|
||||
|
||||
const tempFile = await downloadTar(
|
||||
'https://codeload.github.com/vercel/next.js/tar.gz/canary'
|
||||
await pipeline(
|
||||
await downloadTarStream(
|
||||
'https://codeload.github.com/vercel/next.js/tar.gz/canary'
|
||||
),
|
||||
tar.x({
|
||||
cwd: root,
|
||||
strip: 2 + name.split('/').length,
|
||||
filter: (p) => p.includes(`next.js-canary/examples/${name}/`),
|
||||
})
|
||||
)
|
||||
|
||||
await tar.x({
|
||||
file: tempFile,
|
||||
cwd: root,
|
||||
strip: 2 + name.split('/').length,
|
||||
filter: (p) => p.includes(`next.js-canary/examples/${name}/`),
|
||||
})
|
||||
|
||||
await fs.unlink(tempFile)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ export async function install(
|
|||
/** Indicate whether there is an active Internet connection.*/
|
||||
isOnline: boolean
|
||||
): Promise<void> {
|
||||
let args: string[] = ['install']
|
||||
const args: string[] = ['install']
|
||||
if (!isOnline) {
|
||||
console.log(
|
||||
yellow('You appear to be offline.\nFalling back to the local cache.')
|
||||
|
|
|
@ -27,11 +27,12 @@ export function isFolderEmpty(root: string, name: string): boolean {
|
|||
'.yarn',
|
||||
]
|
||||
|
||||
const conflicts = fs
|
||||
.readdirSync(root)
|
||||
.filter((file) => !validFiles.includes(file))
|
||||
// Support IntelliJ IDEA-based editors
|
||||
.filter((file) => !/\.iml$/.test(file))
|
||||
const conflicts = fs.readdirSync(root).filter(
|
||||
(file) =>
|
||||
!validFiles.includes(file) &&
|
||||
// Support IntelliJ IDEA-based editors
|
||||
!/\.iml$/.test(file)
|
||||
)
|
||||
|
||||
if (conflicts.length > 0) {
|
||||
console.log(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { execSync } from 'child_process'
|
||||
import dns from 'dns'
|
||||
import dns from 'dns/promises'
|
||||
import url from 'url'
|
||||
|
||||
function getProxy(): string | undefined {
|
||||
|
@ -15,26 +15,31 @@ function getProxy(): string | undefined {
|
|||
}
|
||||
}
|
||||
|
||||
export function getOnline(): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
dns.lookup('registry.yarnpkg.com', (registryErr) => {
|
||||
if (!registryErr) {
|
||||
return resolve(true)
|
||||
}
|
||||
export async function getOnline(): Promise<boolean> {
|
||||
try {
|
||||
await dns.lookup('registry.yarnpkg.com')
|
||||
// If DNS lookup succeeds, we are online
|
||||
return true
|
||||
} catch {
|
||||
// The DNS lookup failed, but we are still fine as long as a proxy has been set
|
||||
const proxy = getProxy()
|
||||
if (!proxy) {
|
||||
return false
|
||||
}
|
||||
|
||||
const proxy = getProxy()
|
||||
if (!proxy) {
|
||||
return resolve(false)
|
||||
}
|
||||
const { hostname } = url.parse(proxy)
|
||||
if (!hostname) {
|
||||
// Invalid proxy URL
|
||||
return false
|
||||
}
|
||||
|
||||
const { hostname } = url.parse(proxy)
|
||||
if (!hostname) {
|
||||
return resolve(false)
|
||||
}
|
||||
|
||||
dns.lookup(hostname, (proxyErr) => {
|
||||
resolve(proxyErr == null)
|
||||
})
|
||||
})
|
||||
})
|
||||
try {
|
||||
await dns.lookup(hostname)
|
||||
// If DNS lookup succeeds for the proxy server, we are online
|
||||
return true
|
||||
} catch {
|
||||
// The DNS lookup for the proxy server also failed, so we are offline
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import fs from 'fs'
|
||||
|
||||
export function makeDir(
|
||||
root: string,
|
||||
options = { recursive: true }
|
||||
): Promise<string | undefined> {
|
||||
return fs.promises.mkdir(root, options)
|
||||
}
|
|
@ -1,10 +1,16 @@
|
|||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import validateProjectName from 'validate-npm-package-name'
|
||||
|
||||
export function validateNpmName(name: string): {
|
||||
valid: boolean
|
||||
problems?: string[]
|
||||
} {
|
||||
type ValidateNpmNameResult =
|
||||
| {
|
||||
valid: true
|
||||
}
|
||||
| {
|
||||
valid: false
|
||||
problems: string[]
|
||||
}
|
||||
|
||||
export function validateNpmName(name: string): ValidateNpmNameResult {
|
||||
const nameValidation = validateProjectName(name)
|
||||
if (nameValidation.validForNewPackages) {
|
||||
return { valid: true }
|
||||
|
|
|
@ -184,7 +184,7 @@ async function run(): Promise<void> {
|
|||
if (validation.valid) {
|
||||
return true
|
||||
}
|
||||
return 'Invalid project name: ' + validation.problems![0]
|
||||
return 'Invalid project name: ' + validation.problems[0]
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -207,15 +207,17 @@ async function run(): Promise<void> {
|
|||
const resolvedProjectPath = path.resolve(projectPath)
|
||||
const projectName = path.basename(resolvedProjectPath)
|
||||
|
||||
const { valid, problems } = validateNpmName(projectName)
|
||||
if (!valid) {
|
||||
const validation = validateNpmName(projectName)
|
||||
if (!validation.valid) {
|
||||
console.error(
|
||||
`Could not create a project called ${red(
|
||||
`"${projectName}"`
|
||||
)} because of npm naming restrictions:`
|
||||
)
|
||||
|
||||
problems!.forEach((p) => console.error(` ${red(bold('*'))} ${p}`))
|
||||
validation.problems.forEach((p) =>
|
||||
console.error(` ${red(bold('*'))} ${p}`)
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
"conf": "10.2.0",
|
||||
"cross-spawn": "7.0.3",
|
||||
"fast-glob": "3.3.1",
|
||||
"got": "10.7.0",
|
||||
"picocolors": "1.0.0",
|
||||
"prettier-plugin-tailwindcss": "0.3.0",
|
||||
"prompts": "2.4.2",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { install } from '../helpers/install'
|
||||
import { makeDir } from '../helpers/make-dir'
|
||||
import { copy } from '../helpers/copy'
|
||||
|
||||
import { async as glob } from 'fast-glob'
|
||||
|
@ -118,7 +117,7 @@ export const installTemplate = async ({
|
|||
}
|
||||
|
||||
if (srcDir) {
|
||||
await makeDir(path.join(root, 'src'))
|
||||
await fs.mkdir(path.join(root, 'src'), { recursive: true })
|
||||
await Promise.all(
|
||||
SRC_DIR_NAMES.map(async (file) => {
|
||||
await fs
|
||||
|
|
134
pnpm-lock.yaml
134
pnpm-lock.yaml
|
@ -725,9 +725,6 @@ importers:
|
|||
fast-glob:
|
||||
specifier: 3.3.1
|
||||
version: 3.3.1
|
||||
got:
|
||||
specifier: 10.7.0
|
||||
version: 10.7.0
|
||||
picocolors:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
|
@ -6261,11 +6258,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/@sindresorhus/is@2.1.0:
|
||||
resolution: {integrity: sha512-lXKXfypKo644k4Da4yXkPCrwcvn6SlUW2X2zFbuflKHNjf0w9htru01bo26uMhleMXsDmnZ12eJLdrAZa9MANg==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/@sinonjs/commons@1.8.6:
|
||||
resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==}
|
||||
dependencies:
|
||||
|
@ -6552,13 +6544,6 @@ packages:
|
|||
defer-to-connect: 1.1.3
|
||||
dev: true
|
||||
|
||||
/@szmarczak/http-timer@4.0.5:
|
||||
resolution: {integrity: sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
defer-to-connect: 2.0.0
|
||||
dev: true
|
||||
|
||||
/@szmarczak/http-timer@5.0.1:
|
||||
resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
@ -6755,15 +6740,6 @@ packages:
|
|||
resolution: {integrity: sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==}
|
||||
dev: true
|
||||
|
||||
/@types/cacheable-request@6.0.1:
|
||||
resolution: {integrity: sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==}
|
||||
dependencies:
|
||||
'@types/http-cache-semantics': 4.0.0
|
||||
'@types/keyv': 3.1.1
|
||||
'@types/node': 20.2.5
|
||||
'@types/responselike': 1.0.0
|
||||
dev: true
|
||||
|
||||
/@types/cheerio@0.22.16:
|
||||
resolution: {integrity: sha512-bSbnU/D4yzFdzLpp3+rcDj0aQQMIRUBNJU7azPxdqMpnexjUSvGJyDuOBQBHeOZh1mMKgsJm6Dy+LLh80Ew4tQ==}
|
||||
dependencies:
|
||||
|
@ -6902,10 +6878,6 @@ packages:
|
|||
'@types/node': 20.2.5
|
||||
dev: true
|
||||
|
||||
/@types/http-cache-semantics@4.0.0:
|
||||
resolution: {integrity: sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==}
|
||||
dev: true
|
||||
|
||||
/@types/http-proxy@1.17.3:
|
||||
resolution: {integrity: sha512-wIPqXANye5BbORbuh74exbwNzj+UWCwWyeEFJzUQ7Fq3W2NSAy+7x7nX1fgbEypr2/TdKqpeuxLnXWgzN533/Q==}
|
||||
dependencies:
|
||||
|
@ -9059,14 +9031,6 @@ packages:
|
|||
unset-value: 1.0.0
|
||||
dev: false
|
||||
|
||||
/cacheable-lookup@2.0.1:
|
||||
resolution: {integrity: sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
'@types/keyv': 3.1.1
|
||||
keyv: 4.0.0
|
||||
dev: true
|
||||
|
||||
/cacheable-request@6.1.0:
|
||||
resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -9080,19 +9044,6 @@ packages:
|
|||
responselike: 1.0.2
|
||||
dev: true
|
||||
|
||||
/cacheable-request@7.0.1:
|
||||
resolution: {integrity: sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
clone-response: 1.0.2
|
||||
get-stream: 5.1.0
|
||||
http-cache-semantics: 4.1.0
|
||||
keyv: 4.0.0
|
||||
lowercase-keys: 2.0.0
|
||||
normalize-url: 4.5.0
|
||||
responselike: 2.0.0
|
||||
dev: true
|
||||
|
||||
/call-bind@1.0.2:
|
||||
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
|
||||
dependencies:
|
||||
|
@ -10782,13 +10733,6 @@ packages:
|
|||
mimic-response: 1.0.1
|
||||
dev: true
|
||||
|
||||
/decompress-response@5.0.0:
|
||||
resolution: {integrity: sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
mimic-response: 2.1.0
|
||||
dev: true
|
||||
|
||||
/dedent@0.7.0:
|
||||
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
|
||||
dev: true
|
||||
|
@ -10843,11 +10787,6 @@ packages:
|
|||
resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
|
||||
dev: true
|
||||
|
||||
/defer-to-connect@2.0.0:
|
||||
resolution: {integrity: sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/defer-to-connect@2.0.1:
|
||||
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -13460,29 +13399,6 @@ packages:
|
|||
dependencies:
|
||||
get-intrinsic: 1.2.1
|
||||
|
||||
/got@10.7.0:
|
||||
resolution: {integrity: sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
'@sindresorhus/is': 2.1.0
|
||||
'@szmarczak/http-timer': 4.0.5
|
||||
'@types/cacheable-request': 6.0.1
|
||||
'@types/keyv': 3.1.1
|
||||
'@types/responselike': 1.0.0
|
||||
cacheable-lookup: 2.0.1
|
||||
cacheable-request: 7.0.1
|
||||
decompress-response: 5.0.0
|
||||
duplexer3: 0.1.4
|
||||
get-stream: 5.1.0
|
||||
lowercase-keys: 2.0.0
|
||||
mimic-response: 2.1.0
|
||||
p-cancelable: 2.0.0
|
||||
p-event: 4.1.0
|
||||
responselike: 2.0.0
|
||||
to-readable-stream: 2.1.0
|
||||
type-fest: 0.10.0
|
||||
dev: true
|
||||
|
||||
/got@7.1.0:
|
||||
resolution: {integrity: sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -16118,10 +16034,6 @@ packages:
|
|||
resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=}
|
||||
dev: true
|
||||
|
||||
/json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
dev: true
|
||||
|
||||
/json-merge-patch@1.0.2:
|
||||
resolution: {integrity: sha512-M6Vp2GN9L7cfuMXiWOmHj9bEFbeC250iVtcKQbqVgEsDVYnIsrNsbU+h/Y/PkbBQCtEa4Bez+Ebv0zfbC8ObLg==}
|
||||
dependencies:
|
||||
|
@ -16287,12 +16199,6 @@ packages:
|
|||
json-buffer: 3.0.0
|
||||
dev: true
|
||||
|
||||
/keyv@4.0.0:
|
||||
resolution: {integrity: sha512-U7ioE8AimvRVLfw4LffyOIRhL2xVgmE8T22L6i0BucSnBUyv4w+I7VN/zVZwRKHOI6ZRUcdMdWHQ8KSUvGpEog==}
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
dev: true
|
||||
|
||||
/kind-of@3.2.2:
|
||||
resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -17792,11 +17698,6 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/mimic-response@2.1.0:
|
||||
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/min-indent@1.0.1:
|
||||
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -18859,18 +18760,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/p-cancelable@2.0.0:
|
||||
resolution: {integrity: sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/p-event@4.1.0:
|
||||
resolution: {integrity: sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-timeout: 2.0.1
|
||||
dev: true
|
||||
|
||||
/p-finally@1.0.0:
|
||||
resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -18975,13 +18864,6 @@ packages:
|
|||
p-finally: 1.0.0
|
||||
dev: true
|
||||
|
||||
/p-timeout@2.0.1:
|
||||
resolution: {integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
p-finally: 1.0.0
|
||||
dev: true
|
||||
|
||||
/p-timeout@3.2.0:
|
||||
resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -22026,12 +21908,6 @@ packages:
|
|||
lowercase-keys: 1.0.1
|
||||
dev: true
|
||||
|
||||
/responselike@2.0.0:
|
||||
resolution: {integrity: sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==}
|
||||
dependencies:
|
||||
lowercase-keys: 2.0.0
|
||||
dev: true
|
||||
|
||||
/restore-cursor@2.0.0:
|
||||
resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -23959,11 +23835,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/to-readable-stream@2.1.0:
|
||||
resolution: {integrity: sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/to-regex-range@2.1.1:
|
||||
resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -24275,11 +24146,6 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/type-fest@0.10.0:
|
||||
resolution: {integrity: sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/type-fest@0.13.1:
|
||||
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
Loading…
Reference in a new issue