perf: remove find-up dependency, upgrade file-type dependency (#8195)

Fixes https://github.com/payloadcms/payload/issues/8111 and
https://github.com/payloadcms/payload/issues/8113

Before: 132 dependencies
After: 123 dependencies

This PR also contains a small performance optimization during telemetry
startup: By using the async `fs.promises.readFile` instead of
`readFileSync` we're not blocking the entire thread anymore and are
allowing other stuff to happen while the file is being read.
Also, in our dependency checker, this moves some variables out of loops,
to the module scope, as they only need to be calculated once.

We have to pin file-type to 19.3.0 and cannot upgrade it further (latest
is 19.5.0). See reasoning in
https://github.com/payloadcms/payload/issues/8111#issuecomment-2348119533
This commit is contained in:
Alessio Gravili
2024-09-15 09:53:53 -07:00
committed by GitHub
parent bb2dd5f4d2
commit 6d1a287dd1
11 changed files with 265 additions and 128 deletions

View File

@@ -5,7 +5,6 @@ const esModules = [
'readable-web-to-node-stream',
'token-types',
'peek-readable',
'find-up',
'locate-path',
'p-locate',
'p-limit',
@@ -13,6 +12,7 @@ const esModules = [
'unicorn-magic',
'path-exists',
'qs-esm',
'uint8array-extras',
].join('|')
/** @type {import('jest').Config} */

View File

@@ -70,7 +70,7 @@
"@payloadcms/translations": "workspace:*",
"@payloadcms/ui": "workspace:*",
"busboy": "^1.6.0",
"file-type": "17.1.6",
"file-type": "19.3.0",
"graphql-http": "^1.22.0",
"graphql-playground-html": "1.6.30",
"http-status": "1.6.2",

View File

@@ -94,8 +94,7 @@
"console-table-printer": "2.11.2",
"dataloader": "2.2.2",
"deepmerge": "4.3.1",
"file-type": "17.1.6",
"find-up": "7.0.0",
"file-type": "19.3.0",
"get-tsconfig": "^4.7.2",
"http-status": "1.6.2",
"image-size": "^1.1.1",

View File

@@ -1,6 +1,7 @@
import nextEnvImport from '@next/env'
import { findUpSync } from '../utilities/findUp.js'
const { loadEnvConfig } = nextEnvImport
import { findUpStop, findUpSync } from 'find-up'
/**
* Try to find user's env files and load it. Uses the same algorithm next.js uses to parse env files, meaning this also supports .env.local, .env.development, .env.production, etc.
@@ -15,11 +16,14 @@ export function loadEnv(path?: string) {
if (!loadedEnvFiles?.length) {
// use findUp to find the env file. So, run loadEnvConfig for every directory upwards
findUpSync((dir) => {
const { loadedEnvFiles } = loadEnvConfig(dir, true)
if (loadedEnvFiles?.length) {
return findUpStop
}
findUpSync({
condition: (dir) => {
const { loadedEnvFiles } = loadEnvConfig(dir, true)
if (loadedEnvFiles?.length) {
return true
}
},
dir: process.cwd(),
})
}
}

View File

@@ -1,7 +1,13 @@
import { findUpSync, pathExistsSync } from 'find-up'
import { getTsconfig } from 'get-tsconfig'
import path from 'path'
import { findUpSync } from '../utilities/findUp.js'
/**
* List of all filenames to detect as a Payload configuration file.
*/
export const payloadConfigFileNames = ['payload.config.js', 'payload.config.ts']
/**
* Returns the source and output paths from the nearest tsconfig.json file.
* If no tsconfig.json file is found, returns the current working directory.
@@ -75,26 +81,10 @@ export const findConfig = (): string => {
continue
}
const configPath = findUpSync(
(dir) => {
const tsPath = path.join(dir, 'payload.config.ts')
const hasTS = pathExistsSync(tsPath)
if (hasTS) {
return tsPath
}
const jsPath = path.join(dir, 'payload.config.js')
const hasJS = pathExistsSync(jsPath)
if (hasJS) {
return jsPath
}
return undefined
},
{ cwd: searchPath },
)
const configPath = findUpSync({
dir: searchPath,
fileNames: payloadConfigFileNames,
})
if (configPath) {
return configPath
@@ -104,16 +94,18 @@ export const findConfig = (): string => {
// If no config file is found in the directories defined by tsconfig.json,
// try searching in the 'src' and 'dist' directory as a last resort, as they are most commonly used
if (process.env.NODE_ENV === 'production') {
const distConfigPath = findUpSync(['payload.config.js', 'payload.config.ts'], {
cwd: path.resolve(process.cwd(), 'dist'),
const distConfigPath = findUpSync({
dir: path.resolve(process.cwd(), 'dist'),
fileNames: ['payload.config.js'],
})
if (distConfigPath) {
return distConfigPath
}
} else {
const srcConfigPath = findUpSync(['payload.config.js', 'payload.config.ts'], {
cwd: path.resolve(process.cwd(), 'src'),
const srcConfigPath = findUpSync({
dir: path.resolve(process.cwd(), 'src'),
fileNames: payloadConfigFileNames,
})
if (srcConfigPath) {

View File

@@ -1005,6 +1005,12 @@ export {
deepMergeWithSourceArrays,
} from './utilities/deepMerge.js'
export { getDependencies } from './utilities/dependencies/getDependencies.js'
export {
findUp,
findUpSync,
pathExistsAndIsAccessible,
pathExistsAndIsAccessibleSync,
} from './utilities/findUp.js'
export { default as flattenTopLevelFields } from './utilities/flattenTopLevelFields.js'
export { formatLabels, formatNames, toWords } from './utilities/formatLabels.js'
export { getCollectionIDFieldTypes } from './utilities/getCollectionIDFieldTypes.js'

View File

@@ -14,16 +14,23 @@
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { findUp } from 'find-up'
import { existsSync, promises as fs } from 'fs'
import { promises as fs } from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { findUp } from '../findUp.js'
import { resolveFrom } from './resolveFrom.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const payloadPkgDirname = path.resolve(dirname, '../../../') // pkg dir (outside src)
// if node_modules is in payloadPkgDirname, go to parent dir which contains node_modules
if (payloadPkgDirname.includes('node_modules')) {
payloadPkgDirname.split('node_modules').slice(0, -1)
}
const resolvedCwd = path.resolve(process.cwd())
export type NecessaryDependencies = {
missing: string[]
resolved: Map<
@@ -52,35 +59,29 @@ export async function getDependencies(
requiredPackages.map(async (pkg) => {
try {
const pkgPath = await fs.realpath(resolveFrom(baseDir, pkg))
const pkgDir = path.dirname(pkgPath)
let packageJsonFilePath = null
const processCwd = process.cwd()
const payloadPkgDirname = path.resolve(dirname, '../../../') // pkg dir (outside src)
// if node_modules is in payloadPkgDirname, go to parent dir which contains node_modules
if (payloadPkgDirname.includes('node_modules')) {
payloadPkgDirname.split('node_modules').slice(0, -1)
}
await findUp('package.json', { type: 'file', cwd: pkgDir }).then((foundPath) => {
if (foundPath) {
const resolvedFoundPath = path.resolve(foundPath)
const resolvedCwd = path.resolve(processCwd)
if (
resolvedFoundPath.startsWith(resolvedCwd) ||
resolvedFoundPath.startsWith(payloadPkgDirname)
) {
// We don't want to match node modules outside the user's project. Checking for both process.cwd and dirname is a reliable way to do this.
packageJsonFilePath = foundPath
}
}
const foundPackageJsonDir = await findUp({
dir: pkgDir,
fileNames: ['package.json'],
})
if (packageJsonFilePath && existsSync(packageJsonFilePath)) {
if (foundPackageJsonDir) {
const resolvedFoundPath = path.resolve(foundPackageJsonDir)
if (
resolvedFoundPath.startsWith(resolvedCwd) ||
resolvedFoundPath.startsWith(payloadPkgDirname)
) {
// We don't want to match node modules outside the user's project. Checking for both process.cwd and dirname is a reliable way to do this.
packageJsonFilePath = resolvedFoundPath
}
}
// No need to check if packageJsonFilePath exists - findUp checks that for us
if (packageJsonFilePath) {
// parse version
const packageJson = JSON.parse(await fs.readFile(packageJsonFilePath, 'utf8'))
const version = packageJson.version

View File

@@ -0,0 +1,118 @@
import fs from 'fs'
import path from 'path'
/**
* Synchronously walks up parent directories until a condition is met and/or one of the file names within the fileNames array is found.
*/
export function findUpSync({
condition,
dir,
fileNames,
}: {
condition?: (dir: string) => boolean | Promise<boolean | string> | string
dir: string
fileNames?: string[]
}): null | string {
const { root } = path.parse(dir)
while (true) {
if (fileNames?.length) {
let found = false
for (const fileName of fileNames) {
const filePath = path.join(dir, fileName)
const exists = pathExistsAndIsAccessibleSync(filePath)
if (exists) {
if (!condition) {
return filePath
}
found = true
break
}
}
if (!found) {
dir = path.dirname(dir) // Move up one directory level.
continue
}
}
const result = condition(dir)
if (result === true) {
return dir
}
if (typeof result === 'string' && result?.length) {
return result
}
if (dir === root) {
return null // Reached the root directory without a match.
}
dir = path.dirname(dir) // Move up one directory level.
}
}
/**
* Asynchronously walks up parent directories until a condition is met and/or one of the file names within the fileNames array is found.
*/
export async function findUp({
condition,
dir,
fileNames,
}: {
condition?: (dir: string) => boolean | Promise<boolean | string> | string
dir: string
fileNames?: string[]
}): Promise<null | string> {
const { root } = path.parse(dir)
while (true) {
if (fileNames?.length) {
let found = false
for (const fileName of fileNames) {
const filePath = path.resolve(dir, fileName)
const exists = await pathExistsAndIsAccessible(filePath)
if (exists) {
if (!condition) {
return filePath
}
found = true
break
}
}
if (!found) {
dir = path.dirname(dir) // Move up one directory level.
continue
}
}
const result = await condition(dir)
if (result === true) {
return dir
}
if (typeof result === 'string' && result?.length) {
return result
}
if (dir === root) {
return null // Reached the root directory without a match.
}
dir = path.dirname(dir) // Move up one directory level.
}
}
// From https://github.com/sindresorhus/path-exists/blob/main/index.js
// fs.accessSync is preferred over fs.existsSync as it's usually a good idea
// to check if the process has permission to read/write to a file before doing so.
// Also see https://github.com/nodejs/node/issues/39960
export function pathExistsAndIsAccessibleSync(path: string) {
try {
fs.accessSync(path)
return true
} catch {
return false
}
}
export async function pathExistsAndIsAccessible(path: string) {
try {
await fs.promises.access(path)
return true
} catch {
return false
}
}

View File

@@ -1,7 +1,6 @@
import { execSync } from 'child_process'
import ciInfo from 'ci-info'
import { randomBytes } from 'crypto'
import { findUp } from 'find-up'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
@@ -10,6 +9,7 @@ import type { Payload } from '../../types/index.js'
import type { AdminInitEvent } from './events/adminInit.js'
import type { ServerInitEvent } from './events/serverInit.js'
import { findUp } from '../findUp.js'
import { Conf } from './conf/index.js'
import { oneWayHash } from './oneWayHash.js'
@@ -136,13 +136,15 @@ const getPackageJSON = async (): Promise<{
// Old logic
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
packageJSONPath = await findUp('package.json', { cwd: dirname })
const jsonContent: PackageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf-8'))
return { packageJSON: jsonContent, packageJSONPath }
packageJSONPath = await findUp({
dir: dirname,
fileNames: ['package.json'],
})
}
const packageJSON: PackageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf-8'))
return { packageJSON, packageJSONPath }
const jsonContentString = await fs.promises.readFile(packageJSONPath, 'utf-8')
const jsonContent: PackageJSON = JSON.parse(jsonContentString)
return { packageJSON: jsonContent, packageJSONPath }
}
const getPackageJSONID = (payload: Payload, packageJSON: PackageJSON): string => {

137
pnpm-lock.yaml generated
View File

@@ -143,7 +143,7 @@ importers:
version: 9.4.1(@aws-sdk/credential-providers@3.630.0(@aws-sdk/client-sso-oidc@3.629.0(@aws-sdk/client-sts@3.629.0)))
next:
specifier: 15.0.0-canary.104
version: 15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
version: 15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
open:
specifier: ^10.1.0
version: 10.1.0
@@ -695,8 +695,8 @@ importers:
specifier: ^1.6.0
version: 1.6.0
file-type:
specifier: 17.1.6
version: 17.1.6
specifier: 19.3.0
version: 19.3.0
graphql:
specifier: ^16.8.1
version: 16.9.0
@@ -822,11 +822,8 @@ importers:
specifier: 4.3.1
version: 4.3.1
file-type:
specifier: 17.1.6
version: 17.1.6
find-up:
specifier: 7.0.0
version: 7.0.0
specifier: 19.3.0
version: 19.3.0
get-tsconfig:
specifier: ^4.7.2
version: 4.7.6
@@ -1467,7 +1464,7 @@ importers:
version: link:../plugin-cloud-storage
uploadthing:
specifier: ^6.10.1
version: 6.13.2(express@4.19.2)(next@15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4))
version: 6.13.2(express@4.19.2)(next@15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4))
devDependencies:
payload:
specifier: workspace:*
@@ -1785,8 +1782,8 @@ importers:
specifier: 5.1.1
version: 5.1.1
file-type:
specifier: 17.1.6
version: 17.1.6
specifier: 19.3.0
version: 19.3.0
http-status:
specifier: 1.6.2
version: 1.6.2
@@ -1798,7 +1795,7 @@ importers:
version: 0.17.0
next:
specifier: 15.0.0-canary.104
version: 15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
version: 15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
payload:
specifier: workspace:*
version: link:../packages/payload
@@ -1828,7 +1825,7 @@ importers:
version: 5.6.2
uploadthing:
specifier: ^6.10.1
version: 6.13.2(express@4.19.2)(next@15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4))
version: 6.13.2(express@4.19.2)(next@15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4))
uuid:
specifier: 10.0.0
version: 10.0.0
@@ -6107,6 +6104,10 @@ packages:
resolution: {integrity: sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
file-type@19.3.0:
resolution: {integrity: sha512-mROwiKLZf/Kwa/2Rol+OOZQn1eyTkPB3ZTwC0ExY6OLFCbgxHYZvBm7xI77NvfZFMKBsmuXfmLJnD4eEftEhrA==}
engines: {node: '>=18'}
filelist@1.0.4:
resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
@@ -6144,10 +6145,6 @@ packages:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
find-up@7.0.0:
resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==}
engines: {node: '>=18'}
find-versions@5.1.0:
resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==}
engines: {node: '>=12'}
@@ -7204,10 +7201,6 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
locate-path@7.2.0:
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
@@ -7729,10 +7722,6 @@ packages:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
p-limit@4.0.0:
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
p-limit@5.0.0:
resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==}
engines: {node: '>=18'}
@@ -7745,10 +7734,6 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
p-locate@6.0.0:
resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
p-map@4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
engines: {node: '>=10'}
@@ -7789,10 +7774,6 @@ packages:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
path-exists@5.0.0:
resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
@@ -8887,6 +8868,10 @@ packages:
resolution: {integrity: sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==}
engines: {node: '>=16'}
strtok3@8.1.0:
resolution: {integrity: sha512-ExzDvHYPj6F6QkSNe/JxSlBxTh3OrI6wrAIz53ulxo1c4hBJ1bT9C/JrAthEKHWG9riVH3Xzg7B03Oxty6S2Lw==}
engines: {node: '>=16'}
stubs@3.0.0:
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
@@ -9026,6 +9011,10 @@ packages:
resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==}
engines: {node: '>=14.16'}
token-types@6.0.0:
resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==}
engines: {node: '>=14.16'}
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
@@ -9217,6 +9206,10 @@ packages:
ufo@1.5.4:
resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
uint8array-extras@1.4.0:
resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==}
engines: {node: '>=18'}
unbox-primitive@1.0.2:
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
@@ -9249,10 +9242,6 @@ packages:
resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==}
engines: {node: '>=4'}
unicorn-magic@0.1.0:
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
engines: {node: '>=18'}
unique-string@2.0.0:
resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
engines: {node: '>=8'}
@@ -15124,6 +15113,12 @@ snapshots:
strtok3: 7.1.1
token-types: 5.0.1
file-type@19.3.0:
dependencies:
strtok3: 8.1.0
token-types: 6.0.0
uint8array-extras: 1.4.0
filelist@1.0.4:
dependencies:
minimatch: 5.1.6
@@ -15175,12 +15170,6 @@ snapshots:
locate-path: 6.0.0
path-exists: 4.0.0
find-up@7.0.0:
dependencies:
locate-path: 7.2.0
path-exists: 5.0.0
unicorn-magic: 0.1.0
find-versions@5.1.0:
dependencies:
semver-regex: 4.0.5
@@ -16484,10 +16473,6 @@ snapshots:
dependencies:
p-locate: 5.0.0
locate-path@7.2.0:
dependencies:
p-locate: 6.0.0
lodash.debounce@4.0.8: {}
lodash.deburr@4.1.0: {}
@@ -16807,6 +16792,36 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
next@15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4):
dependencies:
'@next/env': 15.0.0-canary.104
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.12
busboy: 1.6.0
caniuse-lite: 1.0.30001651
graceful-fs: 4.2.11
postcss: 8.4.31
react: 19.0.0-rc-06d0b89e-20240801
react-dom: 19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801)
styled-jsx: 5.1.6(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-06d0b89e-20240801)
optionalDependencies:
'@next/swc-darwin-arm64': 15.0.0-canary.104
'@next/swc-darwin-x64': 15.0.0-canary.104
'@next/swc-linux-arm64-gnu': 15.0.0-canary.104
'@next/swc-linux-arm64-musl': 15.0.0-canary.104
'@next/swc-linux-x64-gnu': 15.0.0-canary.104
'@next/swc-linux-x64-musl': 15.0.0-canary.104
'@next/swc-win32-arm64-msvc': 15.0.0-canary.104
'@next/swc-win32-ia32-msvc': 15.0.0-canary.104
'@next/swc-win32-x64-msvc': 15.0.0-canary.104
'@playwright/test': 1.46.0
babel-plugin-react-compiler: 0.0.0-experimental-48eb8f4-20240822
sass: 1.77.4
sharp: 0.33.4
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
nice-napi@1.0.2:
dependencies:
node-addon-api: 3.2.1
@@ -17013,10 +17028,6 @@ snapshots:
dependencies:
yocto-queue: 0.1.0
p-limit@4.0.0:
dependencies:
yocto-queue: 1.1.1
p-limit@5.0.0:
dependencies:
yocto-queue: 1.1.1
@@ -17029,10 +17040,6 @@ snapshots:
dependencies:
p-limit: 3.1.0
p-locate@6.0.0:
dependencies:
p-limit: 4.0.0
p-map@4.0.0:
dependencies:
aggregate-error: 3.1.0
@@ -17069,8 +17076,6 @@ snapshots:
path-exists@4.0.0: {}
path-exists@5.0.0: {}
path-is-absolute@1.0.1: {}
path-key@2.0.1: {}
@@ -18201,6 +18206,11 @@ snapshots:
'@tokenizer/token': 0.3.0
peek-readable: 5.1.4
strtok3@8.1.0:
dependencies:
'@tokenizer/token': 0.3.0
peek-readable: 5.1.4
stubs@3.0.0: {}
styled-jsx@5.1.6(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-06d0b89e-20240801):
@@ -18363,6 +18373,11 @@ snapshots:
'@tokenizer/token': 0.3.0
ieee754: 1.2.1
token-types@6.0.0:
dependencies:
'@tokenizer/token': 0.3.0
ieee754: 1.2.1
totalist@3.0.1: {}
touch@3.1.1: {}
@@ -18540,6 +18555,8 @@ snapshots:
ufo@1.5.4: {}
uint8array-extras@1.4.0: {}
unbox-primitive@1.0.2:
dependencies:
call-bind: 1.0.7
@@ -18568,8 +18585,6 @@ snapshots:
unicode-property-aliases-ecmascript@2.1.0: {}
unicorn-magic@0.1.0: {}
unique-string@2.0.0:
dependencies:
crypto-random-string: 2.0.0
@@ -18588,7 +18603,7 @@ snapshots:
escalade: 3.1.2
picocolors: 1.0.1
uploadthing@6.13.2(express@4.19.2)(next@15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)):
uploadthing@6.13.2(express@4.19.2)(next@15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)):
dependencies:
'@effect/schema': 0.68.12(effect@3.4.5)
'@uploadthing/mime-types': 0.2.10
@@ -18598,7 +18613,7 @@ snapshots:
std-env: 3.7.0
optionalDependencies:
express: 4.19.2
next: 15.0.0-canary.104(@babel/core@7.25.2)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
next: 15.0.0-canary.104(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-48eb8f4-20240822)(react-dom@19.0.0-rc-06d0b89e-20240801(react@19.0.0-rc-06d0b89e-20240801))(react@19.0.0-rc-06d0b89e-20240801)(sass@1.77.4)
uri-js@4.4.1:
dependencies:

View File

@@ -67,7 +67,7 @@
"drizzle-kit": "0.23.2-df9e596",
"eslint-plugin-playwright": "1.6.2",
"execa": "5.1.1",
"file-type": "17.1.6",
"file-type": "19.3.0",
"http-status": "1.6.2",
"jwt-decode": "4.0.0",
"lexical": "0.17.0",