From 6fc821ffb6fb06f39e20b8357320b157fdb25417 Mon Sep 17 00:00:00 2001 From: Jan Piotrowski Date: Wed, 23 Mar 2022 14:51:03 +0100 Subject: [PATCH] fix(deps): update undici to 4.x (#8842) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joël Galeran Co-authored-by: Pierre-Antoine Mills Co-authored-by: Michal Kvasničák --- helpers/compile/plugins/replaceWithPlugin.ts | 44 +++++++++++++++++-- packages/cli/helpers/build.ts | 8 ++-- packages/cli/package.json | 3 +- packages/client/helpers/build.ts | 20 +++------ packages/client/package.json | 1 + packages/engine-core/package.json | 4 +- packages/engine-core/src/binary/Connection.ts | 29 +++++++----- packages/sdk/src/resolveBinary.ts | 8 ++-- pnpm-lock.yaml | 37 +++++++--------- 9 files changed, 94 insertions(+), 60 deletions(-) diff --git a/helpers/compile/plugins/replaceWithPlugin.ts b/helpers/compile/plugins/replaceWithPlugin.ts index 45d34a2f9250..1f49cfcee4aa 100644 --- a/helpers/compile/plugins/replaceWithPlugin.ts +++ b/helpers/compile/plugins/replaceWithPlugin.ts @@ -1,9 +1,16 @@ import type * as esbuild from 'esbuild' import fs from 'fs' +import { builtinModules } from 'module' -function applyReplacements(contents: string, replacements: [RegExp, string][]) { +type Replacement = [RegExp, string | ((regex: RegExp, contents: string) => string | Promise)] + +async function applyReplacements(contents: string, replacements: Replacement[]) { for (const [regex, replacement] of replacements) { - contents = contents.replace(regex, replacement) + if (typeof replacement === 'string') { + contents = contents.replace(regex, replacement) + } else { + contents = await replacement(regex, contents) + } } return contents @@ -14,15 +21,44 @@ function applyReplacements(contents: string, replacements: [RegExp, string][]) { * @param replacements * @returns */ -export const replaceWithPlugin = (replacements: [RegExp, string][]): esbuild.Plugin => { +export const replaceWithPlugin = (replacements: Replacement[]): esbuild.Plugin => { return { name: 'replaceWithPlugin', setup(build) { build.onLoad({ filter: /.*/ }, async (args) => { + // we skip, don't attempt to edit files that aren't js + if (builtinModules.includes(args.path)) return {} + if (!/.*?(.js|.mjs)$/.exec(args.path)) return {} + const contents = await fs.promises.readFile(args.path, 'utf8') - return { contents: applyReplacements(contents, replacements) } + return { contents: await applyReplacements(contents, replacements) } }) }, } } + +/** + * Example + */ +// const inlineUndiciWasm = replaceWithPlugin([ +// [ +// /(await WebAssembly\.compile\().*?'(.*?)'\)\)\)/g, +// async (regex, contents) => { +// for (const match of contents.matchAll(regex)) { +// if (match[2].includes('simd') === false) { +// // we only bundle lhttp wasm files that are not simd compiled +// const engineCoreDir = resolve.sync('@prisma/engine-core') +// const undiciPackage = resolve.sync('undici/package.json', { basedir: engineCoreDir }) +// const lhttpWasmPath = path.join(path.dirname(undiciPackage), 'lib', match[2]) +// const wasmContents = (await fs.promises.readFile(lhttpWasmPath)).toString('base64') +// const inlineWasm = `${match[1]}(Buffer.from("${wasmContents}", "base64")))` + +// contents = contents.replace(match[0], inlineWasm) +// } +// } + +// return contents +// }, +// ], +// ]) diff --git a/packages/cli/helpers/build.ts b/packages/cli/helpers/build.ts index c6994911eb10..0377676ded42 100644 --- a/packages/cli/helpers/build.ts +++ b/packages/cli/helpers/build.ts @@ -1,6 +1,6 @@ import type * as esbuild from 'esbuild' import fs from 'fs' -import { copySync } from 'fs-extra' +import { copy } from 'fs-extra' import lineReplace from 'line-replace' import path from 'path' import { promisify } from 'util' @@ -37,7 +37,7 @@ const resolveHelperPlugin: esbuild.Plugin = { const cliLifecyclePlugin: esbuild.Plugin = { name: 'cliLifecyclePlugin', setup(build) { - // we only do this for the first oen of the builds + // we only do this for the first one of the builds if (build.initialOptions?.format === 'esm') return build.onStart(async () => { @@ -47,7 +47,7 @@ const cliLifecyclePlugin: esbuild.Plugin = { build.onEnd(async () => { // we copy the contents from @prisma/studio to build - copySync(path.join(require.resolve('@prisma/studio/package.json'), '../dist'), './build/public', { + await copy(path.join(require.resolve('@prisma/studio/package.json'), '../dist'), './build/public', { recursive: true, overwrite: true, }) @@ -72,7 +72,7 @@ const cliLifecyclePlugin: esbuild.Plugin = { const cliBuildConfig: BuildOptions = { entryPoints: ['src/bin.ts'], outfile: 'build/index', - external: ['@prisma/engines', '_http_common'], + external: ['@prisma/engines'], plugins: [resolveHelperPlugin, cliLifecyclePlugin], bundle: true, } diff --git a/packages/cli/package.json b/packages/cli/package.json index 933b3b5f0ec4..0840821af0a3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -46,6 +46,7 @@ "runtime/*.d.ts", "runtime/utils", "runtime/dist", + "runtime/llhttp", "prisma-client", "preinstall", "scripts/preinstall-entry.js", @@ -113,7 +114,7 @@ "build": "node -r esbuild-register helpers/build.ts", "test": "jest --maxConcurrency=1 --verbose", "install": "node scripts/install-entry.js", - "tsc": "tsc -d -p tsconfig.build.json && bash scripts/copy-runtime-dist.sh", + "tsc": "tsc -d -p tsconfig.build.json", "prepublishOnly": "pnpm run build", "preinstall": "node scripts/preinstall-entry.js" }, diff --git a/packages/client/helpers/build.ts b/packages/client/helpers/build.ts index 4cb4f22a7165..347ea0d30a68 100644 --- a/packages/client/helpers/build.ts +++ b/packages/client/helpers/build.ts @@ -5,22 +5,11 @@ import type { BuildOptions } from '../../../helpers/compile/build' import { build } from '../../../helpers/compile/build' import { fillPlugin } from '../../../helpers/compile/plugins/fill-plugin/fillPlugin' -const external = ['_http_common'] - -// we define the config for generator -const generatorBuildConfig: BuildOptions = { - entryPoints: ['src/generation/generator.ts'], - outfile: 'generator-build/index', - bundle: true, - external: external, -} - // we define the config for runtime const runtimeBuildConfig: BuildOptions = { entryPoints: ['src/runtime/index.ts'], outfile: 'runtime/index', bundle: true, - external: external, define: { 'globalThis.NOT_PRISMA_DATA_PROXY': 'true', // that fixes an issue with lz-string umd builds @@ -34,7 +23,6 @@ const browserBuildConfig: BuildOptions = { outfile: 'runtime/index-browser', target: ['chrome58', 'firefox57', 'safari11', 'edge16'], bundle: true, - external: external, } // we define the config for proxy @@ -44,7 +32,6 @@ const proxyBuildConfig: BuildOptions = { bundle: true, minify: true, legalComments: 'none', - external: external, define: { // that helps us to tree-shake unused things out 'globalThis.NOT_PRISMA_DATA_PROXY': 'false', @@ -70,6 +57,13 @@ const proxyBuildConfig: BuildOptions = { logLevel: 'error', } +// we define the config for generator +const generatorBuildConfig: BuildOptions = { + entryPoints: ['src/generation/generator.ts'], + outfile: 'generator-build/index', + bundle: true, +} + /** * Bundle all type definitions by using the API Extractor from RushStack * @param filename the source d.ts to bundle diff --git a/packages/client/package.json b/packages/client/package.json index d6f260455747..c5b2e5607d22 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -100,6 +100,7 @@ "pkg-up": "3.1.0", "pluralize": "8.0.0", "replace-string": "3.1.0", + "resolve": "1.22.0", "rimraf": "3.0.2", "sort-keys": "4.2.0", "source-map-support": "0.5.21", diff --git a/packages/engine-core/package.json b/packages/engine-core/package.json index 312b20dc43d6..21f4475af997 100644 --- a/packages/engine-core/package.json +++ b/packages/engine-core/package.json @@ -22,7 +22,7 @@ "@swc/core": "1.2.141", "@swc/jest": "0.2.17", "@types/jest": "27.4.1", - "@types/node": "12.20.47", + "@types/node": "16.6.2", "esbuild": "0.13.14", "jest": "27.5.1", "jest-junit": "13.0.0", @@ -47,7 +47,7 @@ "p-retry": "4.6.1", "strip-ansi": "6.0.1", "terminal-link": "2.1.1", - "undici": "3.3.6" + "undici": "4.16.0" }, "files": [ "README.md", diff --git a/packages/engine-core/src/binary/Connection.ts b/packages/engine-core/src/binary/Connection.ts index 12e177939038..5ca40acc586b 100644 --- a/packages/engine-core/src/binary/Connection.ts +++ b/packages/engine-core/src/binary/Connection.ts @@ -1,14 +1,17 @@ import getStream from 'get-stream' -import type { Client } from 'undici' -import { Pool } from 'undici' +import type { Dispatcher, Pool } from 'undici' import type { URL } from 'url' export type Result = { - statusCode: Client.ResponseData['statusCode'] - headers: Client.ResponseData['headers'] + statusCode: Dispatcher.ResponseData['statusCode'] + headers: Dispatcher.ResponseData['headers'] data: R } +// because undici lazily loads llhttp wasm which bloats the memory +// TODO: hopefully replace with `import` but that causes segfaults +const undici = () => require('undici') + /** * Assertion function to make sure that we have a pool * @param pool @@ -53,10 +56,11 @@ export class Connection { open(url: string | URL, options?: Pool.Options) { if (this._pool) return - this._pool = new Pool(url, { + this._pool = new (undici().Pool)(url, { connections: 1000, keepAliveMaxTimeout: 600e3, headersTimeout: 0, + bodyTimeout: 0, ...options, }) } @@ -72,8 +76,8 @@ export class Connection { async raw( method: 'POST' | 'GET', endpoint: string, - headers?: Client.DispatchOptions['headers'], - body?: Client.DispatchOptions['body'], + headers?: Dispatcher.DispatchOptions['headers'], + body?: Dispatcher.DispatchOptions['body'], ) { assertHasPool(this._pool) @@ -84,8 +88,7 @@ export class Connection { 'Content-Type': 'application/json', ...headers, }, - body, - bodyTimeout: 0, + body: body, }) const result: Result = { @@ -104,7 +107,11 @@ export class Connection { * @param headers * @returns */ - post(endpoint: string, body?: Client.DispatchOptions['body'], headers?: Client.DispatchOptions['headers']) { + post( + endpoint: string, + body?: Dispatcher.DispatchOptions['body'], + headers?: Dispatcher.DispatchOptions['headers'], + ) { return this.raw('POST', endpoint, headers, body) } @@ -115,7 +122,7 @@ export class Connection { * @param headers * @returns */ - get(path: string, headers?: Client.DispatchOptions['headers']) { + get(path: string, headers?: Dispatcher.DispatchOptions['headers']) { return this.raw('GET', path, headers) } diff --git a/packages/sdk/src/resolveBinary.ts b/packages/sdk/src/resolveBinary.ts index bd92dd387b16..c75ac375f3d4 100644 --- a/packages/sdk/src/resolveBinary.ts +++ b/packages/sdk/src/resolveBinary.ts @@ -52,7 +52,7 @@ export async function resolveBinary(name: BinaryType, proposedPath?: string): Pr if (fs.existsSync(prismaPath)) { return maybeCopyToTmp(prismaPath) } - + // for pkg (related: https://github.com/vercel/pkg#snapshot-filesystem) const prismaPath2 = path.join(__dirname, '..', binaryName) if (fs.existsSync(prismaPath2)) { @@ -83,7 +83,7 @@ export async function resolveBinary(name: BinaryType, proposedPath?: string): Pr export async function maybeCopyToTmp(file: string): Promise { const dir = eval('__dirname') - + if (dir.startsWith('/snapshot/')) { // in this case, we are in a "pkg" context with a virtual fs // to make this work, we need to copy the binary to /tmp and execute it from there @@ -93,13 +93,13 @@ export async function maybeCopyToTmp(file: string): Promise { const targetDir = path.join(tempDir, 'prisma-binaries') await makeDir(targetDir) const target = path.join(targetDir, path.basename(file)) - + // We have to read and write until https://github.com/zeit/pkg/issues/639 is resolved const data = await readFile(file) await writeFile(target, data) // TODO Undo when https://github.com/vercel/pkg/pull/1484 is released // await copyFile(file, target) - + plusX(target) return target } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 84ed95030914..a164f55367f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -247,6 +247,7 @@ importers: pkg-up: 3.1.0 pluralize: 8.0.0 replace-string: 3.1.0 + resolve: 1.22.0 rimraf: 3.0.2 sort-keys: 4.2.0 source-map-support: 0.5.21 @@ -302,6 +303,7 @@ importers: pkg-up: 3.1.0 pluralize: 8.0.0 replace-string: 3.1.0 + resolve: 1.22.0 rimraf: 3.0.2 sort-keys: 4.2.0 source-map-support: 0.5.21 @@ -348,7 +350,7 @@ importers: '@swc/core': 1.2.141 '@swc/jest': 0.2.17 '@types/jest': 27.4.1 - '@types/node': 12.20.47 + '@types/node': 16.6.2 chalk: 4.1.2 esbuild: 0.13.14 execa: 5.1.1 @@ -361,7 +363,7 @@ importers: strip-ansi: 6.0.1 terminal-link: 2.1.1 typescript: 4.5.4 - undici: 3.3.6 + undici: 4.16.0 dependencies: '@prisma/debug': link:../debug '@prisma/engines': 3.12.0-16.f2e63a76e8eed99d99f0eb65596c7677b70a1e77 @@ -375,12 +377,12 @@ importers: p-retry: 4.6.1 strip-ansi: 6.0.1 terminal-link: 2.1.1 - undici: 3.3.6 + undici: 4.16.0 devDependencies: '@swc/core': 1.2.141 '@swc/jest': 0.2.17_@swc+core@1.2.141 '@types/jest': 27.4.1 - '@types/node': 12.20.47 + '@types/node': 16.6.2 esbuild: 0.13.14 jest: 27.5.1_ts-node@10.4.0 jest-junit: 13.0.0 @@ -1571,7 +1573,6 @@ packages: express: 4.17.2 untildify: 4.0.0 transitivePeerDependencies: - - '@prisma/client' - supports-color dev: true @@ -2010,6 +2011,10 @@ packages: resolution: {integrity: sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==} dev: true + /@types/node/16.6.2: + resolution: {integrity: sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA==} + dev: true + /@types/node/17.0.18: resolution: {integrity: sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==} @@ -2354,7 +2359,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4 + debug: 4.3.3 transitivePeerDependencies: - supports-color @@ -3149,17 +3154,6 @@ packages: supports-color: 9.2.1 dev: true - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - /decamelize-keys/1.1.0: resolution: {integrity: sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=} engines: {node: '>=0.10.0'} @@ -4692,7 +4686,7 @@ packages: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.3 transitivePeerDependencies: - supports-color @@ -4711,7 +4705,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.3 transitivePeerDependencies: - supports-color @@ -8138,8 +8132,9 @@ packages: which-boxed-primitive: 1.0.2 dev: true - /undici/3.3.6: - resolution: {integrity: sha512-/j3YTZ5AobMB4ZrTY72mzM54uFUX32v0R/JRW9G2vOyF1uSKYAx+WT8dMsAcRS13TOFISv094TxIyWYk+WEPsA==} + /undici/4.16.0: + resolution: {integrity: sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==} + engines: {node: '>=12.18'} dev: false /unique-string/2.0.0: