From dc7d75a1eaaac12a06b4dcffd0cfd370c5432648 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Wed, 28 Aug 2024 08:57:11 +0200 Subject: [PATCH 01/21] Update npm scripts (#1190) --- .github/workflows/ci.yaml | 4 +- Makefile | 40 ------ package.json | 7 ++ packages/connect-conformance/package.json | 3 +- .../conformance/v1/client_compat_pb.ts | 2 +- .../connectrpc/conformance/v1/config_pb.ts | 2 +- .../conformance/v1/server_compat_pb.ts | 2 +- .../conformance/v1/service_connect.ts | 2 +- .../connectrpc/conformance/v1/service_pb.ts | 2 +- .../gen/connectrpc/conformance/v1/suite_pb.ts | 2 +- packages/connect-express/package.json | 2 +- packages/connect-fastify/package.json | 2 +- packages/connect-migrate/package.json | 2 +- packages/connect-next/package.json | 2 +- packages/connect-node/package.json | 2 +- packages/connect-web-bench/package.json | 2 +- packages/connect-web/package.json | 3 +- packages/connect/package.json | 3 +- .../src/protocol-connect/transport.spec.ts | 3 + packages/protoc-gen-connect-es/package.json | 2 +- scripts/gh-diffcheck.js | 36 ++++++ scripts/release.js | 118 ++++++++++++++++++ 22 files changed, 186 insertions(+), 57 deletions(-) create mode 100644 scripts/gh-diffcheck.js create mode 100644 scripts/release.js diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0917c0e8e..eb06b5eab 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,4 +24,6 @@ jobs: restore-keys: | ${{ runner.os }}-connect-es-ci- - name: make - run: make ci && make checkdiff + run: make ci + - name: Check changed files + run: node scripts/gh-diffcheck.js diff --git a/Makefile b/Makefile index a8a525dc6..dbbcb0207 100644 --- a/Makefile +++ b/Makefile @@ -59,49 +59,41 @@ $(BIN)/node16: Makefile @touch $(@) $(BUILD)/protoc-gen-connect-es: node_modules tsconfig.base.json packages/protoc-gen-connect-es/tsconfig.json $(shell find packages/protoc-gen-connect-es/src -name '*.ts') - npm run -w packages/protoc-gen-connect-es clean npm run -w packages/protoc-gen-connect-es build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect: $(GEN)/connect node_modules packages/connect/package.json packages/connect/scripts/* tsconfig.base.json packages/connect/tsconfig.json $(shell find packages/connect/src -name '*.ts') packages/connect/*.js - npm run -w packages/connect clean npm run -w packages/connect build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-node: $(BUILD)/connect $(BUILD)/connect-conformance packages/connect-node/tsconfig.json $(shell find packages/connect-node/src -name '*.ts') - npm run -w packages/connect-node clean npm run -w packages/connect-node build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-fastify: $(BUILD)/connect $(BUILD)/connect-node packages/connect-fastify/tsconfig.json $(shell find packages/connect-fastify/src -name '*.ts') - npm run -w packages/connect-fastify clean npm run -w packages/connect-fastify build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-express: $(BUILD)/connect $(BUILD)/connect-node packages/connect-express/tsconfig.json $(shell find packages/connect-express/src -name '*.ts') - npm run -w packages/connect-express clean npm run -w packages/connect-express build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-next: $(BUILD)/connect $(BUILD)/connect-node packages/connect-next/tsconfig.json $(shell find packages/connect-next/src -name '*.ts') - npm run -w packages/connect-next clean npm run -w packages/connect-next build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-web: $(GEN)/connect-web $(BUILD)/connect $(BUILD)/connect-conformance packages/connect-web/tsconfig.json $(shell find packages/connect-web/src -name '*.ts') - npm run -w packages/connect-web clean npm run -w packages/connect-web build @mkdir -p $(@D) @touch $(@) $(BUILD)/connect-conformance: $(GEN)/connect-conformance $(BUILD)/connect packages/connect-conformance/tsconfig.json $(shell find packages/connect-conformance/src -name '*.ts') - npm run -w packages/connect-conformance clean npm run -w packages/connect-conformance build @mkdir -p $(@D) @touch $(@) @@ -112,7 +104,6 @@ $(BUILD)/example: $(GEN)/example $(BUILD)/connect-web packages/example/tsconfig. @touch $(@) $(BUILD)/connect-migrate: packages/connect-migrate/package.json packages/connect-migrate/tsconfig.json $(shell find packages/connect-migrate/src -name '*.ts') - npm run -w packages/connect-migrate clean npm run -w packages/connect-migrate build @mkdir -p $(@D) @touch $(@) @@ -257,34 +248,3 @@ format: node_modules ## Format all files, adding license headers .PHONY: bench bench: node_modules $(GEN)/connect-web-bench $(BUILD)/connect-web ## Benchmark code size npm run -w packages/connect-web-bench bundle-size - -.PHONY: setversion -setversion: ## Set a new version in for the project, i.e. make setversion SET_VERSION=1.2.3 - node scripts/set-workspace-version.js $(SET_VERSION) - npm ci - $(MAKE) all - -# Recommended procedure: -# 1. Set a new version with the target `setversion` -# 2. Commit and push all changes -# 3. Login with `npm login` -# 4. Run this target, publishing to npmjs.com -# 5. Tag the release -.PHONY: release -release: all ## Release npm packages - @[ -z "$(shell git status --short)" ] || (echo "Uncommitted changes found." && exit 1); - npm publish \ - --workspace packages/connect \ - --workspace packages/connect-web \ - --workspace packages/connect-node \ - --workspace packages/connect-fastify \ - --workspace packages/connect-express \ - --workspace packages/connect-next \ - --workspace packages/protoc-gen-connect-es \ - --workspace packages/connect-migrate \ - -.PHONY: checkdiff -checkdiff: - @# Used in CI to verify that `make` does not produce a diff - test -z "$$(git status --porcelain | tee /dev/stderr)" - diff --git a/package.json b/package.json index 96153e107..ebbd5673c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,13 @@ "./packages/connect-conformance", "./packages/connect-cloudflare" ], + "scripts": { + "clean": "git clean -Xdf", + "setversion": "node scripts/set-workspace-version.js", + "postsetversion": "npm run all", + "all": "make", + "release": "npm run all && node scripts/release.js" + }, "type": "module", "engineStrict": true, "engines": { diff --git a/packages/connect-conformance/package.json b/packages/connect-conformance/package.json index c4a62177a..0dd7e14ed 100644 --- a/packages/connect-conformance/package.json +++ b/packages/connect-conformance/package.json @@ -15,7 +15,8 @@ }, "scripts": { "generate": "buf generate buf.build/connectrpc/conformance:v1.0.2", - "clean": "rm -rf ./dist/*", + "postgenerate": "license-header src/gen", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "postbuild": "connectconformance --version", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/src/package.json '{\"type\":\"commonjs\"}'", diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts index 66fcbbb48..52a020e15 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts index 7df98b1cb..fdc518fcb 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/server_compat_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/server_compat_pb.ts index 3c5035cb1..e56188206 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/server_compat_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/server_compat_pb.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts index 9c46f51b4..dddad87c3 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_pb.ts index 6d5b3513d..2968d6332 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_pb.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/suite_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/suite_pb.ts index bef304b4d..923376e0f 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/suite_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/suite_pb.ts @@ -1,4 +1,4 @@ -// Copyright 2023-2024 The Connect Authors +// Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/packages/connect-express/package.json b/packages/connect-express/package.json index 639c02b3f..c11f937f1 100644 --- a/packages/connect-express/package.json +++ b/packages/connect-express/package.json @@ -8,7 +8,7 @@ "directory": "packages/connect-express" }, "scripts": { - "clean": "rm -rf ./dist/*", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", diff --git a/packages/connect-fastify/package.json b/packages/connect-fastify/package.json index faa83e7ae..a788db74d 100644 --- a/packages/connect-fastify/package.json +++ b/packages/connect-fastify/package.json @@ -8,7 +8,7 @@ "directory": "packages/connect-fastify" }, "scripts": { - "clean": "rm -rf ./dist/*", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", diff --git a/packages/connect-migrate/package.json b/packages/connect-migrate/package.json index c681b8602..22607e251 100644 --- a/packages/connect-migrate/package.json +++ b/packages/connect-migrate/package.json @@ -13,7 +13,7 @@ "connect-migrate": "bin/connect-migrate" }, "scripts": { - "clean": "rm -rf ./dist/cjs/*", + "prebuild": "rm -rf ./dist/*", "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs", "test": "jasmine --config=jasmine.json", "build+test": "npm run build && npm run test" diff --git a/packages/connect-next/package.json b/packages/connect-next/package.json index 209fa1011..3d7ea8dea 100644 --- a/packages/connect-next/package.json +++ b/packages/connect-next/package.json @@ -8,7 +8,7 @@ "directory": "packages/connect-next" }, "scripts": { - "clean": "rm -rf ./dist/*", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", diff --git a/packages/connect-node/package.json b/packages/connect-node/package.json index 1433e5805..9dad50d8b 100644 --- a/packages/connect-node/package.json +++ b/packages/connect-node/package.json @@ -8,7 +8,7 @@ "directory": "packages/connect-node" }, "scripts": { - "clean": "rm -rf ./dist/*", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --moduleResolution node10 --verbatimModuleSyntax false --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", diff --git a/packages/connect-web-bench/package.json b/packages/connect-web-bench/package.json index 54dde5559..9ccde1a86 100644 --- a/packages/connect-web-bench/package.json +++ b/packages/connect-web-bench/package.json @@ -4,7 +4,7 @@ "scripts": { "bundle-size": "tsx src/report.ts", "generate": "buf generate", - "postgenerate": "license-header ." + "postgenerate": "license-header src/gen" }, "dependencies": { "@bufbuild/buf": "^1.36.0", diff --git a/packages/connect-web/package.json b/packages/connect-web/package.json index da38d954c..79da10b60 100644 --- a/packages/connect-web/package.json +++ b/packages/connect-web/package.json @@ -8,7 +8,7 @@ "directory": "packages/connect-web" }, "scripts": { - "clean": "rm -rf ./dist/*", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", @@ -23,6 +23,7 @@ "conformance:client:node:callback": "connectconformance --mode client --conf ./conformance/conformance-web-node.yaml -v --known-failing @./conformance/known-failing-callback-client.txt -- ./conformance/client.ts --browser node --useCallbackClient", "jasmine": "jasmine --config=jasmine.json", "generate": "buf generate --template browserstack/buf.gen.yaml", + "postgenerate": "license-header browserstack/gen", "karma:browserstack": "karma start browserstack/karma.browserstack.conf.cjs" }, "type": "module", diff --git a/packages/connect/package.json b/packages/connect/package.json index 1506a9786..a5003e6e3 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -9,8 +9,9 @@ "directory": "packages/connect" }, "scripts": { - "clean": "rm -rf ./dist/*", "generate": "buf generate", + "postgenerate": "license-header src/protocol-grpc/gen", + "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm && node scripts/update-user-agent.mjs", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", diff --git a/packages/connect/src/protocol-connect/transport.spec.ts b/packages/connect/src/protocol-connect/transport.spec.ts index 47069cbd1..1da286a82 100644 --- a/packages/connect/src/protocol-connect/transport.spec.ts +++ b/packages/connect/src/protocol-connect/transport.spec.ts @@ -384,6 +384,9 @@ describe("Connect transport", function () { } }); }); + // Special handling of set-cookie is available since Node.js v20.0.0, + // v18.14.1, v16.19.1, but not in headers-polyfill 3.1.2. + // Also see https://github.com/nodejs/undici/releases/tag/v5.19.0 if ("getSetCookie" in new Headers()) { describe("when there is support for set-cookie", function () { // eslint-disable-next-line @typescript-eslint/require-await diff --git a/packages/protoc-gen-connect-es/package.json b/packages/protoc-gen-connect-es/package.json index c71f012a6..f8d0d1e05 100644 --- a/packages/protoc-gen-connect-es/package.json +++ b/packages/protoc-gen-connect-es/package.json @@ -15,7 +15,7 @@ "node": ">=16.0.0" }, "scripts": { - "clean": "rm -rf ./dist/cjs/*", + "prebuild": "rm -rf ./dist/*", "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs" }, "preferUnplugged": true, diff --git a/scripts/gh-diffcheck.js b/scripts/gh-diffcheck.js new file mode 100644 index 000000000..03123c418 --- /dev/null +++ b/scripts/gh-diffcheck.js @@ -0,0 +1,36 @@ +// Copyright 2021-2024 The Connect Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { execSync } from "node:child_process"; + +if (gitUncommitted()) { + process.stdout.write( + "::error::Uncommitted changes found. Please make sure this branch is up to date, and run the command locally (for example `npx turbo format`). " + + "Verify the changes are what you want and commit them.\n", + ); + execSync("git --no-pager diff", { + stdio: "inherit", + }); + process.exit(1); +} + +/** + * @returns {boolean} + */ +function gitUncommitted() { + const out = execSync("git status --porcelain", { + encoding: "utf-8", + }); + return out.trim().length > 0; +} diff --git a/scripts/release.js b/scripts/release.js new file mode 100644 index 000000000..44ddbbb84 --- /dev/null +++ b/scripts/release.js @@ -0,0 +1,118 @@ +// Copyright 2021-2024 The Connect Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { readdirSync, readFileSync } from "fs"; +import { join } from "path"; +import { existsSync } from "node:fs"; +import { execSync } from "node:child_process"; + +/* + * Publish connect-es + * + * Recommended procedure: + * 1. Set a new version with `npm run setversion 1.2.3` + * 2. Commit and push all changes to a PR, wait for approval. + * 3. Login with `npm login` + * 4. Publish to npmjs.com with `npm run release` + * 5. Merge PR and create a release on GitHub + */ + +const tag = determinePublishTag(findWorkspaceVersion("packages")); +const uncommitted = gitUncommitted(); +if (uncommitted.length > 0) { + throw new Error("Uncommitted changes found: \n" + uncommitted); +} +npmPublish(); + +/** + * + */ +function npmPublish() { + const command = + `npm publish --tag ${tag}` + + " --workspace packages/connect" + + " --workspace packages/connect-web" + + " --workspace packages/connect-node" + + " --workspace packages/connect-fastify" + + " --workspace packages/connect-express" + + " --workspace packages/connect-next" + + " --workspace packages/connect-migrate" + + " --workspace packages/protoc-gen-connect-es"; + execSync(command, { + stdio: "inherit", + }); +} + +/** + * @returns {string} + */ +function gitUncommitted() { + const out = execSync("git status --short", { + encoding: "utf-8", + }); + if (out.trim().length === 0) { + return ""; + } + return out; +} + +/** + * @param {string} version + * @returns {string} + */ +function determinePublishTag(version) { + if (/^\d+\.\d+\.\d+$/.test(version)) { + return "latest"; + } else if (/^\d+\.\d+\.\d+-alpha.*$/.test(version)) { + return "alpha"; + } else if (/^\d+\.\d+\.\d+-beta.*$/.test(version)) { + return "beta"; + } else if (/^\d+\.\d+\.\d+-rc.*$/.test(version)) { + return "rc"; + } else { + throw new Error(`Unable to determine publish tag from version ${version}`); + } +} + +/** + * @param {string} packagesDir + * @returns {string} + */ +function findWorkspaceVersion(packagesDir) { + let version = undefined; + for (const entry of readdirSync(packagesDir, { withFileTypes: true })) { + if (!entry.isDirectory()) { + continue; + } + const path = join(packagesDir, entry.name, "package.json"); + if (existsSync(path)) { + const pkg = JSON.parse(readFileSync(path, "utf-8")); + if (pkg.private === true) { + continue; + } + if (!pkg.version) { + throw new Error(`${path} is missing "version"`); + } + if (version === undefined) { + version = pkg.version; + } else if (version !== pkg.version) { + throw new Error(`${path} has unexpected version ${pkg.version}`); + } + } + } + if (version === undefined) { + throw new Error(`unable to find workspace version`); + } + return version; +} From 1a3bb2f57d032a1230e31070a04fcfcc25ead0b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:03:10 +0200 Subject: [PATCH 02/21] Bump tsx from 4.16.5 to 4.19.0 in the build group (#1197) --- package-lock.json | 1114 +++++++++++++++++++++- packages/connect-cloudflare/package.json | 2 +- packages/connect-express/package.json | 2 +- packages/example/package.json | 2 +- 4 files changed, 1067 insertions(+), 53 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ec8248d3..ac6c71fa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1168,6 +1168,66 @@ "esbuild": "*" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.19.12", "cpu": [ @@ -1182,6 +1242,291 @@ "node": ">=12" } }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "dev": true, @@ -4088,23 +4433,353 @@ "@esbuild/win32-x64": "0.19.12" } }, - "node_modules/escalade": { - "version": "3.1.2", - "license": "MIT", + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { "node": ">=10" }, "funding": { @@ -9344,11 +10019,11 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.16.5", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.16.5.tgz", - "integrity": "sha512-ArsiAQHEW2iGaqZ8fTA1nX0a+lN5mNTyuGRRO6OW3H/Yno1y9/t1f9YOI1Cfoqz63VAthn++ZYcbDP7jPflc+A==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", + "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", "dependencies": { - "esbuild": "~0.21.5", + "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -9362,53 +10037,56 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.21.5", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" } }, "node_modules/type-check": { @@ -9982,6 +10660,54 @@ } } }, + "node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { "version": "0.17.19", "cpu": [ @@ -9997,6 +10723,294 @@ "node": ">=12" } }, + "node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/wrangler/node_modules/esbuild": { "version": "0.17.19", "dev": true, @@ -10246,7 +11260,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20240725.0", "@connectrpc/connect-conformance": "^1.4.0", - "tsx": "^4.16.5", + "tsx": "^4.19.0", "wrangler": "^3.68.0" } }, @@ -10278,7 +11292,7 @@ "@connectrpc/connect-conformance": "^1.4.0", "@types/express": "^4.17.18", "express": "^4.19.2", - "tsx": "^4.16.5" + "tsx": "^4.19.0" }, "engines": { "node": ">=16.0.0" @@ -10402,7 +11416,7 @@ "@bufbuild/protobuf": "^1.10.0", "@connectrpc/connect-node": "^1.4.0", "@connectrpc/connect-web": "^1.4.0", - "tsx": "^4.16.5" + "tsx": "^4.19.0" }, "devDependencies": { "@bufbuild/buf": "^1.36.0", diff --git a/packages/connect-cloudflare/package.json b/packages/connect-cloudflare/package.json index 244d830a4..3607d4cf8 100644 --- a/packages/connect-cloudflare/package.json +++ b/packages/connect-cloudflare/package.json @@ -15,7 +15,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20240725.0", "wrangler": "^3.68.0", - "tsx": "^4.16.5", + "tsx": "^4.19.0", "@connectrpc/connect-conformance": "^1.4.0" } } diff --git a/packages/connect-express/package.json b/packages/connect-express/package.json index c11f937f1..aadec8ecc 100644 --- a/packages/connect-express/package.json +++ b/packages/connect-express/package.json @@ -32,7 +32,7 @@ "@connectrpc/connect-conformance": "^1.4.0", "@types/express": "^4.17.18", "express": "^4.19.2", - "tsx": "^4.16.5" + "tsx": "^4.19.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", diff --git a/packages/example/package.json b/packages/example/package.json index 049f13896..8ada3e6eb 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -15,7 +15,7 @@ "@bufbuild/protobuf": "^1.10.0", "@connectrpc/connect-node": "^1.4.0", "@connectrpc/connect-web": "^1.4.0", - "tsx": "^4.16.5" + "tsx": "^4.19.0" }, "devDependencies": { "@bufbuild/buf": "^1.36.0", From edf87005de8c378125d2b0bb2357b25204849a48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:16:13 +0200 Subject: [PATCH 03/21] Bump @bufbuild/buf from 1.38.0 to 1.39.0 (#1201) --- package-lock.json | 64 +++++++++++------------ packages/connect-conformance/package.json | 2 +- packages/connect-web-bench/package.json | 2 +- packages/connect-web/package.json | 2 +- packages/connect/package.json | 2 +- packages/example/package.json | 2 +- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac6c71fa6..e4a9fed44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -792,9 +792,9 @@ } }, "node_modules/@bufbuild/buf": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.38.0.tgz", - "integrity": "sha512-5I4pTI3kQl36OBBV5+ggxROt6AoukCQB4NG366wSkQN14eguthdLBGvC73LGC6hmVvwjo+nadwodIpGs2nbOvQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.39.0.tgz", + "integrity": "sha512-lm7xb9pc7X04rRjCQ69o9byAAZ7/dsUQGoH+iJ9uBSXQWiwQ1Ts8gneBnuUVsAH2vdW73NFBpmNQGE9XtFauVQ==", "hasInstallScript": true, "bin": { "buf": "bin/buf", @@ -805,18 +805,18 @@ "node": ">=12" }, "optionalDependencies": { - "@bufbuild/buf-darwin-arm64": "1.38.0", - "@bufbuild/buf-darwin-x64": "1.38.0", - "@bufbuild/buf-linux-aarch64": "1.38.0", - "@bufbuild/buf-linux-x64": "1.38.0", - "@bufbuild/buf-win32-arm64": "1.38.0", - "@bufbuild/buf-win32-x64": "1.38.0" + "@bufbuild/buf-darwin-arm64": "1.39.0", + "@bufbuild/buf-darwin-x64": "1.39.0", + "@bufbuild/buf-linux-aarch64": "1.39.0", + "@bufbuild/buf-linux-x64": "1.39.0", + "@bufbuild/buf-win32-arm64": "1.39.0", + "@bufbuild/buf-win32-x64": "1.39.0" } }, "node_modules/@bufbuild/buf-darwin-arm64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.38.0.tgz", - "integrity": "sha512-4qGrNMUNboPyWHtWhdo9XzCGn+1/BeNlw963hhr8tGkmmc36oDGzacyw/oj7m43533TGMiLmVTqPuOAyYao+Sw==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.39.0.tgz", + "integrity": "sha512-Ptl0uAGssLxQTzoZhGwv1FFTbzUfcstIpEwMhN+XrwiuqsSxOg9eq/n3yXoci5VJsHokjDUHnWkR3y+j5P/5KA==", "cpu": [ "arm64" ], @@ -829,9 +829,9 @@ } }, "node_modules/@bufbuild/buf-darwin-x64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.38.0.tgz", - "integrity": "sha512-6yADcSHJayTjviy0i/32DOik4nneDvDjsN0vb1UejHL/g1/0YM8dzo4n677uHaxUe4yKr2ivYkBvKpRnMMsgDQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.39.0.tgz", + "integrity": "sha512-XNCuy9sjQwVJ4NIZqxaTIyzUtlyquSkp/Uuoh5W5thJ3nzZ5RSgvXKF5iXHhZmesrfRGApktwoCx5Am8runsfQ==", "cpu": [ "x64" ], @@ -844,9 +844,9 @@ } }, "node_modules/@bufbuild/buf-linux-aarch64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.38.0.tgz", - "integrity": "sha512-Lo8d6QbZp8o11x4vkRV1Mm3wzrcXdORMYumd7Wd64UPz4l/0R11xu1wgv/gFRuse4djOAwWNNzXp4FEOq4oJwQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.39.0.tgz", + "integrity": "sha512-Am+hrw94awp/eY027ROXwRQBuwAzOpQ/4zI4dgmgsyhzeWZ8w1LWC8z2SSr8T2cqd0cm52KxtoWMW+B3b2qzbw==", "cpu": [ "arm64" ], @@ -859,9 +859,9 @@ } }, "node_modules/@bufbuild/buf-linux-x64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.38.0.tgz", - "integrity": "sha512-YHkYkb0e72waDcLthK8C0ns7vMdecg+AcQugwLq6TLjvwJRyEet97tGfK1QUTGzKgN+874MmqOBCuKKfWc40YQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.39.0.tgz", + "integrity": "sha512-JXVkHoMrTvmpseqdoQPJJ6MRV7/vlloYtvXHHACEzVytYjljOYCNoVET/E5gLBco/edeXFMNc40cCi1KgL3rSw==", "cpu": [ "x64" ], @@ -874,9 +874,9 @@ } }, "node_modules/@bufbuild/buf-win32-arm64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.38.0.tgz", - "integrity": "sha512-Tgj/inG+CAhRRHK/7Ku8DufVN/iG7yJs3y2U/A+pYjzdreu/egj0/2JFq9I6wjJKaPELp4+Br659qar6tABxiQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.39.0.tgz", + "integrity": "sha512-akdGW02mo04wbLfjNMBQqxC4mPQ/L/vTU8/o79I67GSxyFYt7bKifvYIYhAA39C2gibHyB7ZLmoeRPbaU8wbYA==", "cpu": [ "arm64" ], @@ -889,9 +889,9 @@ } }, "node_modules/@bufbuild/buf-win32-x64": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.38.0.tgz", - "integrity": "sha512-Br32Xgp/tPInxMx/qNMhrsZQuef3CLeDOTqqSiPf6e2PegrWDQCJsF9jGUQTIy1na11nCAkbShnXm0EJK9bA6g==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.39.0.tgz", + "integrity": "sha512-jos08UMg9iUZsGjPrNpLXP+FNk6q6GizO+bjee/GcI0kSijIzXYMg14goQr0TKlvqs/+IRAM5vZIokQBYlAENQ==", "cpu": [ "x64" ], @@ -11240,7 +11240,7 @@ "version": "1.4.0", "license": "Apache-2.0", "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@types/jasmine": "^5.0.0", "jasmine": "^5.2.0", @@ -11278,7 +11278,7 @@ "connectconformance": "bin/connectconformance.cjs" }, "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@types/debug": "^4.1.12", "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3" @@ -11379,7 +11379,7 @@ "version": "1.4.0", "license": "Apache-2.0", "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/connect-conformance": "^1.4.0", "@connectrpc/protoc-gen-connect-es": "^1.4.0", @@ -11399,7 +11399,7 @@ "packages/connect-web-bench": { "name": "@connectrpc/connect-web-bench", "dependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protobuf": "^1.10.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/connect-web": "1.4.0", @@ -11419,7 +11419,7 @@ "tsx": "^4.19.0" }, "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/protoc-gen-connect-es": "^1.4.0", "@types/express": "^4.17.18", diff --git a/packages/connect-conformance/package.json b/packages/connect-conformance/package.json index 0dd7e14ed..0607b8c8d 100644 --- a/packages/connect-conformance/package.json +++ b/packages/connect-conformance/package.json @@ -30,7 +30,7 @@ "undici": "^5.28.4" }, "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3", "@types/debug": "^4.1.12" diff --git a/packages/connect-web-bench/package.json b/packages/connect-web-bench/package.json index 9ccde1a86..81014703a 100644 --- a/packages/connect-web-bench/package.json +++ b/packages/connect-web-bench/package.json @@ -7,7 +7,7 @@ "postgenerate": "license-header src/gen" }, "dependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protobuf": "^1.10.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/connect-web": "1.4.0", diff --git a/packages/connect-web/package.json b/packages/connect-web/package.json index 79da10b60..651668a60 100644 --- a/packages/connect-web/package.json +++ b/packages/connect-web/package.json @@ -37,7 +37,7 @@ }, "devDependencies": { "webdriverio": "^8.39.1", - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/protoc-gen-connect-es": "^1.4.0", "@connectrpc/connect-conformance": "^1.4.0", diff --git a/packages/connect/package.json b/packages/connect/package.json index a5003e6e3..798876eeb 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -63,7 +63,7 @@ "@bufbuild/protobuf": "^1.10.0" }, "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@types/jasmine": "^5.0.0", "jasmine": "^5.2.0", diff --git a/packages/example/package.json b/packages/example/package.json index 8ada3e6eb..e33b91d81 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -18,7 +18,7 @@ "tsx": "^4.19.0" }, "devDependencies": { - "@bufbuild/buf": "^1.36.0", + "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", "@connectrpc/protoc-gen-connect-es": "^1.4.0", "@types/express": "^4.17.18", From ab54a6c394102a90d8fac6579ab75b160250ecac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:24:09 +0200 Subject: [PATCH 04/21] Bump jscodeshift from 0.16.1 to 17.0.0 (#1203) --- package-lock.json | 48 ++++++++------------------- packages/connect-migrate/package.json | 2 +- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4a9fed44..6a68f23ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2806,6 +2806,7 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3465,6 +3466,7 @@ }, "node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3576,6 +3578,7 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3586,6 +3589,7 @@ }, "node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/commander": { @@ -6213,6 +6217,7 @@ }, "node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6887,9 +6892,9 @@ "license": "MIT" }, "node_modules/jscodeshift": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.16.1.tgz", - "integrity": "sha512-oMQXySazy63awNBzMpXbbVv73u3irdxTeX2L5ueRyFRxi32qb9uzdZdOY5fTBYADBG19l5M/wnGknZSV1dzCdA==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-17.0.0.tgz", + "integrity": "sha512-Af+MFsNwLSVO+t4kKjJdJKh6iNbNHfDfFGdyltJ2wUFN3furgbvHguJmB85iou+fY7wbHgI8eiEKpp6doGgtKg==", "dependencies": { "@babel/core": "^7.24.7", "@babel/parser": "^7.24.7", @@ -6901,12 +6906,11 @@ "@babel/preset-flow": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@babel/register": "^7.24.6", - "chalk": "^4.1.2", "flow-parser": "0.*", "graceful-fs": "^4.2.4", "micromatch": "^4.0.7", "neo-async": "^2.5.0", - "node-dir": "^0.1.17", + "picocolors": "^1.0.1", "recast": "^0.23.9", "temp": "^0.9.4", "write-file-atomic": "^5.0.1" @@ -6914,6 +6918,9 @@ "bin": { "jscodeshift": "bin/jscodeshift.js" }, + "engines": { + "node": ">=16" + }, "peerDependencies": { "@babel/preset-env": "^7.1.6" }, @@ -7785,34 +7792,6 @@ } } }, - "node_modules/node-dir": { - "version": "0.1.17", - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.2" - }, - "engines": { - "node": ">= 0.10.5" - } - }, - "node_modules/node-dir/node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/node-dir/node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -9807,6 +9786,7 @@ }, "node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11326,7 +11306,7 @@ "license": "Apache-2.0", "dependencies": { "fast-glob": "3.3.2", - "jscodeshift": "0.16.1", + "jscodeshift": "17.0.0", "semver": "^7.6.3" }, "bin": { diff --git a/packages/connect-migrate/package.json b/packages/connect-migrate/package.json index 22607e251..569507886 100644 --- a/packages/connect-migrate/package.json +++ b/packages/connect-migrate/package.json @@ -23,7 +23,7 @@ }, "dependencies": { "fast-glob": "3.3.2", - "jscodeshift": "0.16.1", + "jscodeshift": "17.0.0", "semver": "^7.6.3" }, "devDependencies": { From ef6911dc9bdcfa0e65f61d0ae8dd719f6a1ce243 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:51:18 +0530 Subject: [PATCH 05/21] Bump @cloudflare/workers-types from 4.20240725.0 to 4.20240821.1 (#1199) --- package-lock.json | 8 ++++---- packages/connect-cloudflare/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a68f23ec..c776875ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1065,9 +1065,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240725.0.tgz", - "integrity": "sha512-L6T/Bg50zm9IIACQVQ0CdVcQL+2nLkRXdPz6BsXF3SlzgjyWR5ndVctAbfr/HLV7aKYxWnnEZsIORsTWb+FssA==", + "version": "4.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240821.1.tgz", + "integrity": "sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==", "dev": true }, "node_modules/@colors/colors": { @@ -11238,7 +11238,7 @@ "@connectrpc/connect-node": "1.4.0" }, "devDependencies": { - "@cloudflare/workers-types": "^4.20240725.0", + "@cloudflare/workers-types": "^4.20240821.1", "@connectrpc/connect-conformance": "^1.4.0", "tsx": "^4.19.0", "wrangler": "^3.68.0" diff --git a/packages/connect-cloudflare/package.json b/packages/connect-cloudflare/package.json index 3607d4cf8..fd43e9297 100644 --- a/packages/connect-cloudflare/package.json +++ b/packages/connect-cloudflare/package.json @@ -13,7 +13,7 @@ "@connectrpc/connect-node": "1.4.0" }, "devDependencies": { - "@cloudflare/workers-types": "^4.20240725.0", + "@cloudflare/workers-types": "^4.20240821.1", "wrangler": "^3.68.0", "tsx": "^4.19.0", "@connectrpc/connect-conformance": "^1.4.0" From 56f07b65e666f6d7a92ccf22b9e258ca9f1778f5 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Tue, 3 Sep 2024 09:11:19 +0200 Subject: [PATCH 06/21] Replace Makefile with turborepo (#1194) --- .eslintrc.cjs | 102 +++---- .github/CONTRIBUTING.md | 23 +- .github/ISSUE_TEMPLATE/bug_report.md | 14 +- .github/ISSUE_TEMPLATE/feature_request.md | 5 +- .github/RELEASING.md | 26 +- .github/workflows/browserstack.yaml | 42 +-- .github/workflows/ci.yaml | 100 +++++-- .github/workflows/cloudflare.yaml | 36 --- .github/workflows/conformance-cloudflare.yaml | 50 ++++ .github/workflows/conformance-express.yaml | 39 +++ .github/workflows/conformance-fastify.yaml | 39 +++ .github/workflows/conformance-node.yaml | 40 +++ .github/workflows/conformance-web.yaml | 66 +++++ .github/workflows/node-conformance.yaml | 77 ------ .github/workflows/web-conformance.yaml | 78 ------ .gitignore | 7 +- .nvmrc | 2 +- .prettierignore | 6 - MAINTAINERS.md | 12 +- Makefile | 250 ------------------ README.md | 24 +- SECURITY.md | 3 +- package-lock.json | 139 +++++++++- package.json | 39 +-- packages/connect-cloudflare/README.md | 33 ++- .../connect-cloudflare/conformance/client.ts | 2 - .../connect-cloudflare/conformance/server.ts | 2 - packages/connect-cloudflare/package.json | 8 +- packages/connect-cloudflare/turbo.json | 8 + packages/connect-conformance/README.md | 6 +- packages/connect-conformance/package.json | 9 +- packages/connect-conformance/turbo.json | 9 + packages/connect-express/README.md | 5 +- .../connect-express/conformance/server.ts | 17 +- packages/connect-express/package.json | 11 +- packages/connect-fastify/README.md | 5 +- .../connect-fastify/conformance/server.ts | 17 +- packages/connect-fastify/package.json | 11 +- packages/connect-migrate/README.md | 18 +- packages/connect-migrate/bin/connect-migrate | 2 +- packages/connect-migrate/package.json | 5 +- .../src/lib/replace-dependencies.ts | 8 +- packages/connect-migrate/tsconfig.json | 7 +- packages/connect-migrate/turbo.json | 9 + packages/connect-next/README.md | 17 +- packages/connect-next/package.json | 7 + packages/connect-node/README.md | 7 +- packages/connect-node/conformance/README.md | 13 +- packages/connect-node/conformance/client.ts | 2 - packages/connect-node/conformance/server.ts | 12 +- .../connect-node/conformance/transport.ts | 2 +- packages/connect-node/package.json | 12 +- packages/connect-node/turbo.json | 11 + packages/connect-web-bench/package.json | 5 +- packages/connect-web-bench/turbo.json | 9 + packages/connect-web/README.md | 4 +- packages/connect-web/browserstack/README.md | 4 +- packages/connect-web/conformance/README.md | 19 +- packages/connect-web/conformance/client.ts | 2 - packages/connect-web/conformance/transport.ts | 2 +- packages/connect-web/package.json | 26 +- packages/connect-web/tsconfig.json | 2 +- packages/connect-web/turbo.json | 53 ++++ packages/connect/README.md | 5 +- packages/connect/package.json | 5 +- packages/connect/turbo.json | 9 + packages/example/README.md | 4 +- packages/example/index.html | 12 +- packages/example/package.json | 7 +- packages/example/src/client.ts | 2 +- packages/example/www/index.html | 14 +- packages/protoc-gen-connect-es/README.md | 18 +- .../bin/protoc-gen-connect-es | 6 +- packages/protoc-gen-connect-es/package.json | 5 +- packages/protoc-gen-connect-es/tsconfig.json | 7 +- packages/protoc-gen-connect-es/turbo.json | 9 + turbo.json | 41 +++ 77 files changed, 954 insertions(+), 810 deletions(-) delete mode 100644 .github/workflows/cloudflare.yaml create mode 100644 .github/workflows/conformance-cloudflare.yaml create mode 100644 .github/workflows/conformance-express.yaml create mode 100644 .github/workflows/conformance-fastify.yaml create mode 100644 .github/workflows/conformance-node.yaml create mode 100644 .github/workflows/conformance-web.yaml delete mode 100644 .github/workflows/node-conformance.yaml delete mode 100644 .github/workflows/web-conformance.yaml delete mode 100644 .prettierignore delete mode 100644 Makefile create mode 100644 packages/connect-cloudflare/turbo.json create mode 100644 packages/connect-conformance/turbo.json create mode 100644 packages/connect-migrate/turbo.json create mode 100644 packages/connect-node/turbo.json create mode 100644 packages/connect-web-bench/turbo.json create mode 100644 packages/connect-web/turbo.json create mode 100644 packages/connect/turbo.json create mode 100644 packages/protoc-gen-connect-es/turbo.json create mode 100644 turbo.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 30472d82e..758fc03fb 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -12,77 +12,62 @@ // See the License for the specific language governing permissions and // limitations under the License. -const { readdirSync, existsSync } = require("fs"); -const { join } = require("path"); - module.exports = { env: { browser: true, es2021: true, node: true, }, + root: true, ignorePatterns: [ - "packages/connect-web-bench/src/gen/grpcweb/**/*", - "packages/connect/src/protocol-grpc/gen/**/*", - "packages/connect-node-test/connect-node-h1-server.mjs", // https://github.com/eslint/eslint/issues/14156 - "packages/example/www/webclient.js", "packages/*/dist/**", - "node_modules/**", + // Our ESLint setup assumes all `.js` files are ESM, however these particular assets are CommonJS. + // Since for these files we cannot use `.cjs`, instead we override here to avoid having to override in each file + "packages/connect/*.js", + // + "packages/connect-web-bench/src/gen/grpcweb/**/*", ], plugins: ["@typescript-eslint", "n", "import"], // Rules and settings that do not require a non-default parser extends: ["eslint:recommended"], rules: { "no-console": "error", + "import/no-cycle": "error", + "import/no-duplicates": "error", }, - settings: {}, overrides: [ - ...readdirSync("packages", { withFileTypes: true }) - .filter((entry) => entry.isDirectory()) - .map((entry) => join("packages", entry.name)) - .filter((dir) => existsSync(join(dir, "tsconfig.json"))) - .map((dir) => { - return { - files: [join(dir, "src/**/*.ts"), join(dir, "conformance/**/*.ts")], - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: dir, - }, - settings: { - "import/resolver": { - typescript: { - project: "packages/*/tsconfig.json", - }, - }, - }, - extends: [ - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:import/recommended", - "plugin:import/typescript", - ], - rules: { - "@typescript-eslint/strict-boolean-expressions": "error", - "@typescript-eslint/no-unnecessary-condition": "error", - // we use complex typings, where Array is actually more readable than T[] - "@typescript-eslint/array-type": "off", - "@typescript-eslint/switch-exhaustiveness-check": "error", - "@typescript-eslint/prefer-nullish-coalescing": "error", - "@typescript-eslint/no-unnecessary-boolean-literal-compare": - "error", - "@typescript-eslint/no-invalid-void-type": "error", - "@typescript-eslint/no-base-to-string": "error", - "import/no-cycle": "error", - "import/no-duplicates": "error", - // TS 4.5 adds type modifiers on import names, but we want to support lower versions - "import/consistent-type-specifier-style": [ - "error", - "prefer-top-level", - ], + { + files: ["**/*.{ts,tsx,cts,mts}"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, + settings: { + "import/resolver": { + typescript: { + project: "tsconfig.json", }, - }; - }), + }, + }, + extends: [ + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:import/recommended", + "plugin:import/typescript", + ], + rules: { + "@typescript-eslint/strict-boolean-expressions": "error", + "@typescript-eslint/no-unnecessary-condition": "error", + "@typescript-eslint/array-type": "off", // we use complex typings, where Array is actually more readable than T[] + "@typescript-eslint/switch-exhaustiveness-check": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", + "@typescript-eslint/no-invalid-void-type": "error", + "@typescript-eslint/no-base-to-string": "error", + "import/no-cycle": "error", + "import/no-duplicates": "error", + }, + }, // For scripts and configurations, use Node.js rules { files: ["**/*.{js,mjs,cjs}"], @@ -106,14 +91,5 @@ module.exports = { "n/no-unsupported-features/es-syntax": "error", }, }, - { - // Our ESLint setup assumes all `.js` files are ESM, however these particular assets are CommonJS. - // Since for these files we cannot use `.cjs`, instead we override here to avoid having to override in each file - files: ["packages/connect/*.js"], - globals: { - module: "readonly", - require: "readonly", - }, - }, ], }; diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 052275684..594be9495 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -25,13 +25,22 @@ git remote add upstream https://github.com/connectrpc/connect-es.git git fetch upstream ``` -Make sure that the tests and the linters pass (you'll need Node.js in the -version specified in .nvmrc, `make`, `bash` and Docker installed): +Install dependencies (you'll need Node.js in the version specified in `.nvmrc`, +and `npm` in the version specified in `package.json`): +```bash +npm ci ``` -make + +Make sure that the tests, linters, and other checks pass: + +```bash +npm run all ``` +We're using `turborepo` to run tasks. If you haven't used it yet, take a look at +[filtering and package scoping](https://turbo.build/repo/docs/crafting-your-repository/running-tasks). + ## Making Changes Start by creating a new branch for your changes: @@ -53,16 +62,16 @@ git push origin cool_new_feature Then use the GitHub UI to open a pull request. -At this point, you're waiting on us to review your changes. We *try* to respond +At this point, you're waiting on us to review your changes. We _try_ to respond to issues and pull requests within a few business days, and we may suggest some improvements or alternatives. Once your changes are approved, one of the project maintainers will merge them. We're much more likely to approve your changes if you: -* Add tests for new functionality. -* Write a [good commit message][commit-message]. -* Maintain backward compatibility. +- Add tests for new functionality. +- Write a [good commit message][commit-message]. +- Maintain backward compatibility. [fork]: https://github.com/connectrpc/connect-es/fork [open-issue]: https://github.com/connectrpc/connect-es/issues/new diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 36cc00c8c..6163721a4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,40 +1,38 @@ --- name: Bug report about: Let us know about a bug -title: '' +title: "" labels: bug -assignees: '' - +assignees: "" --- **Describe the bug** As clearly as you can, please tell us what the bug is. - **To Reproduce** If you encountered an error message, please copy and paste it verbatim. If the bug is specific to an RPC or payload, please provide a reduced example. - **Environment (please complete the following information):** + - @connectrpc/connect-web version: (for example, `0.1.0`) - @connectrpc/connect-node version: (for example, `0.1.0`) - Frontend framework and version: (for example, `react@18.2.0`) - Node.js version: (for example, `18.0.0`) - Browser and version: (for example, `Google Chrome 103.0.5060.134`) -If your problem is specific to bundling, please also provide the following information: +If your problem is specific to bundling, please also provide the following information: - Bundler and version: (for example, `webpack@5.74.0`) - Bundler plugins and version: (for example `compression-webpack-plugin@10.0.0`) -- Bundler configuration file: +- Bundler configuration file: + ```js ``` - **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ef92c7050..ca4cd5e2e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,9 @@ --- name: Feature request about: Suggest a new feature or improvement -title: '' +title: "" labels: enhancement -assignees: '' - +assignees: "" --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/RELEASING.md b/.github/RELEASING.md index 2d2c1e75c..7c1775611 100644 --- a/.github/RELEASING.md +++ b/.github/RELEASING.md @@ -3,22 +3,22 @@ ## Prerequisites - See the setup and tools required in CONTRIBUTING.md -- A granular access token for npmjs.com with read and write permissions, scoped - to the `connectrpc` organization. -- Make sure that the repository is in a good state, without PRs close to merge +- A granular access token for npmjs.com with read and write permissions, scoped + to the `connectrpc` organization. +- Make sure that the repository is in a good state, without PRs close to merge that would ideally be part of the release. ## Steps -1. Choose a new version (e.g. 1.2.3), making sure to follow semver. Note that all +1. Choose a new version (e.g. 1.2.3), making sure to follow semver. Note that all packages in this repository use the same version number. 2. Make sure you are on the latest main, and create a new git branch. -3. Set the new version across all packages within the monorepo with the following - command: `make setversion SET_VERSION=1.2.3` +3. Set the new version across all packages within the monorepo with the following + command: `npm run setversion 1.2.3` 4. Commit, push, and open a pull request with the title "Release 1.2.3". The PR title must start with "Release" to trigger the conformance tests in CI. See the conformance tests [README](/packages/connect-conformance/README.md) for more details. 5. Edit the PR description with release notes. See the section below for details. 6. Make sure CI passed on your PR and ask a maintainer for review. -7. After approval, run the following command to publish to npmjs.com: `make release`. +7. After approval, run the following command to publish to npmjs.com: `npm run release`. 8. Merge your PR. 9. Create a new release in the GitHub UI - Choose "v1.2.3" as a tag and as the release title. @@ -27,19 +27,19 @@ ## Release notes -- We generate release notes with the GitHub feature, see +- We generate release notes with the GitHub feature, see https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes -- Only changes that impact users should be listed. No need to list things like +- Only changes that impact users should be listed. No need to list things like doc changes (unless it’s something major), dependency version bumps, or similar. Remove them from the generated release notes. -- If the release introduces a major new feature or change, add a section at the +- If the release introduces a major new feature or change, add a section at the top that explains it for users. A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.10.0 - It lists a major new feature and a major change with dedicated sections, and + It lists a major new feature and a major change with dedicated sections, and moves the changelist with PR links to a separate "Enhancement" section below. -- If the release includes a very long list of changes, consider breaking the +- If the release includes a very long list of changes, consider breaking the changelist up with the sections "Enhancements", "Bugfixes", "Breaking changes". A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.9.0 -- If the release includes changes specific to a npm package, group and explain +- If the release includes changes specific to a npm package, group and explain the changelist in according separate sections. A good example is https://github.com/connectrpc/connect-es/releases/tag/v0.8.0 Note that we are not using full package names with scope - a more user-friendly name like "Connect for Node.js" or "Connect for Fastify" is preferable. diff --git a/.github/workflows/browserstack.yaml b/.github/workflows/browserstack.yaml index 145bd857c..8ef001f33 100644 --- a/.github/workflows/browserstack.yaml +++ b/.github/workflows/browserstack.yaml @@ -1,31 +1,39 @@ -name: browserstack +name: "Browserstack" + on: push: - branches: [main] - tags: ['v*'] + branches: [main, "v*"] + tags: ["v*"] pull_request: - branches: [main] + branches: [main, "v*"] workflow_dispatch: + permissions: contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + jobs: browserstack: + name: "Test @connectrpc/connect-web" runs-on: ubuntu-22.04 + timeout-minutes: 10 steps: - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + - uses: actions/cache@v4 with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-web-browserstack-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-web-browserstack- - - name: browserstack + path: .turbo + key: ${{ runner.os }}/browserstack/${{ github.sha }} + restore-keys: ${{ runner.os }}/browserstack + - name: NPM Install + run: npm ci + - name: Browserstack env: BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - run: make testwebbrowserstack - + run: npx turbo run test-browserstack --output-logs new-only --log-order stream diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index eb06b5eab..32191db28 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,29 +1,97 @@ name: ci + on: push: - branches: [main] - tags: ['v*'] + branches: [main, "v*"] + tags: ["v*"] pull_request: - branches: [main] + branches: [main, "v*"] workflow_dispatch: + permissions: contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + jobs: - ci: + tasks: runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + task: + - format + - license-header + - lint + - attw + - bundle-size + - build + include: + - task: format + diff-check: true + - task: license-header + diff-check: true + - task: bundle-size + diff-check: true + name: ${{ matrix.task }} steps: - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-es-ci-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-es-ci- - - name: make - run: make ci + node-version-file: .nvmrc + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/${{ matrix.task }}/${{ github.sha }} + restore-keys: ${{ runner.os }}/${{ matrix.task }} + - run: npm ci + - run: npx turbo run ${{ matrix.task }} - name: Check changed files + if: ${{ matrix.diff-check }} run: node scripts/gh-diffcheck.js + test: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + # Node.js v16 does not provide all necessary fetch types by default, so + # we cannot run tests for @connectrpc/connect-web. + # v16 is tested in a separate job below. + node-version: [21.1.0, 20.9.0, 18.16.0] + name: "test on Node.js ${{ matrix.node-version }}" + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/test/${{ github.sha }} + restore-keys: ${{ runner.os }}/test + - run: npm ci + - run: npx turbo run test + test16: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + node-version: [16.20.0] + name: "test on Node.js ${{ matrix.node-version }}" + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/test/${{ github.sha }} + restore-keys: ${{ runner.os }}/test + - run: npm ci + - run: npx turbo run test --filter '!@connectrpc/connect-web' diff --git a/.github/workflows/cloudflare.yaml b/.github/workflows/cloudflare.yaml deleted file mode 100644 index 8df7a6d9b..000000000 --- a/.github/workflows/cloudflare.yaml +++ /dev/null @@ -1,36 +0,0 @@ -name: Cloudflare Conformance Tests -on: - schedule: - - cron: "0 0 * * *" - push: - tags: ["v*"] - pull_request: - branches: [main] - workflow_dispatch: -jobs: - test: - if: github.event_name != 'pull_request' || startsWith(github.event.pull_request.title, 'Release ') - runs-on: conformance - steps: - - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-conformance-ci-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-conformance-ci- - - name: build - run: make .tmp/build/connect-conformance - - name: test - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CLOUDFLARE_WORKERS_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_SERVER_HOST}} - CLOUDFLARE_WORKERS_CLIENT_HOST: ${{ vars.CLOUDFLARE_WORKERS_CLIENT_HOST}} - CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST}} - CLOUDFLARE_WORKERS_REFERENCE_SERVER_KEY: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_KEY }} - CLOUDFLARE_WORKERS_REFERENCE_SERVER_CERT: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_CERT }} - TEMP: .tmp/build - run: make testcloudflareconformance diff --git a/.github/workflows/conformance-cloudflare.yaml b/.github/workflows/conformance-cloudflare.yaml new file mode 100644 index 000000000..08387e502 --- /dev/null +++ b/.github/workflows/conformance-cloudflare.yaml @@ -0,0 +1,50 @@ +name: "Cloudflare Conformance" + +on: + schedule: + - cron: "0 0 * * *" + push: + tags: ["v*"] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + +jobs: + test: + name: "Test @connectrpc/connect-cloudflare" + if: github.event_name != 'pull_request' || startsWith(github.event.pull_request.title, 'Release ') + runs-on: conformance + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/cloudflare-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/cloudflare-conformance + - run: npm ci + - name: conformance:server + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_WORKERS_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_SERVER_HOST}} + CLOUDFLARE_WORKERS_CLIENT_HOST: ${{ vars.CLOUDFLARE_WORKERS_CLIENT_HOST}} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST}} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_KEY: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_KEY }} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_CERT: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_CERT }} + run: npx turbo run conformance:server --filter '@connectrpc/connect-cloudflare' --output-logs new-only --log-order stream + - name: conformance:client + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_WORKERS_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_SERVER_HOST}} + CLOUDFLARE_WORKERS_CLIENT_HOST: ${{ vars.CLOUDFLARE_WORKERS_CLIENT_HOST}} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST: ${{ vars.CLOUDFLARE_WORKERS_REFERENCE_SERVER_HOST}} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_KEY: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_KEY }} + CLOUDFLARE_WORKERS_REFERENCE_SERVER_CERT: ${{ vars.CLOUDFALRE_WORKERS_REFERENCE_SERVER_CERT }} + run: npx turbo run conformance:client --filter '@connectrpc/connect-cloudflare' --output-logs new-only --log-order stream diff --git a/.github/workflows/conformance-express.yaml b/.github/workflows/conformance-express.yaml new file mode 100644 index 000000000..77533b0b0 --- /dev/null +++ b/.github/workflows/conformance-express.yaml @@ -0,0 +1,39 @@ +name: "Express Conformance" + +on: + push: + branches: [main, "v*"] + tags: ["v*"] + pull_request: + branches: [main, "v*"] + workflow_dispatch: + +permissions: + contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + +jobs: + node: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + node-version: [21.1.0, 20.9.0, 18.16.0] + name: "Node.js ${{ matrix.node-version }}" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/express-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/express-conformance + - run: npm ci + - run: npx turbo run conformance --filter '@connectrpc/connect-express' --output-logs new-only --log-order stream diff --git a/.github/workflows/conformance-fastify.yaml b/.github/workflows/conformance-fastify.yaml new file mode 100644 index 000000000..cd903cb56 --- /dev/null +++ b/.github/workflows/conformance-fastify.yaml @@ -0,0 +1,39 @@ +name: "Fastify Conformance" + +on: + push: + branches: [main, "v*"] + tags: ["v*"] + pull_request: + branches: [main, "v*"] + workflow_dispatch: + +permissions: + contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + +jobs: + node: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + node-version: [21.1.0, 20.9.0, 18.16.0] + name: "Node.js ${{ matrix.node-version }}" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/fastify-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/fastify-conformance + - run: npm ci + - run: npx turbo run conformance --filter '@connectrpc/connect-fastify' --output-logs new-only --log-order stream diff --git a/.github/workflows/conformance-node.yaml b/.github/workflows/conformance-node.yaml new file mode 100644 index 000000000..bcec39217 --- /dev/null +++ b/.github/workflows/conformance-node.yaml @@ -0,0 +1,40 @@ +name: "Node.js Conformance" + +on: + push: + branches: [main, "v*"] + tags: ["v*"] + pull_request: + branches: [main, "v*"] + workflow_dispatch: + +permissions: + contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + +jobs: + node: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + node-version: [21.1.0, 20.9.0, 18.16.0] + side: [client, server] + name: "Node.js ${{ matrix.node-version }} ${{ matrix.side }}" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/node-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/node-conformance + - run: npm ci + - run: npx turbo run conformance:${{matrix.side}} --filter '@connectrpc/connect-node' --output-logs new-only --log-order stream diff --git a/.github/workflows/conformance-web.yaml b/.github/workflows/conformance-web.yaml new file mode 100644 index 000000000..a0a1afa23 --- /dev/null +++ b/.github/workflows/conformance-web.yaml @@ -0,0 +1,66 @@ +name: "Web Conformance" + +on: + push: + branches: [main, "v*"] + tags: ["v*"] + pull_request: + branches: [main, "v*"] + workflow_dispatch: + +permissions: + contents: read + +env: + # https://consoledonottrack.com/ + DO_NOT_TRACK: 1 + +jobs: + browser: + strategy: + fail-fast: false + matrix: + browser: [chrome, safari, firefox] + client: [promise, callback] + include: + - os: ubuntu-22.04 + - browser: safari + os: macos-12 + runs-on: ${{ matrix.os }} + name: "${{ matrix.browser }} ${{ matrix.client }}" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/web-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/web-conformance + - run: npm ci + - run: npx turbo run conformance:${{matrix.browser}}:${{matrix.client}} --filter '@connectrpc/connect-web' --output-logs new-only --log-order stream + node: + runs-on: ubuntu-22.04 + strategy: + matrix: + # Node.js v16 does not provide all necessary fetch types by default + node-version: [21.1.0, 20.9.0, 18.16.0] + client: [promise, callback] + name: "Node.js ${{ matrix.node-version }} ${{ matrix.client }}" + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - uses: actions/cache@v4 + with: + path: .turbo + key: ${{ runner.os }}/web-conformance/${{ github.sha }} + restore-keys: ${{ runner.os }}/web-conformance + - run: npm ci + - run: npx turbo run conformance:node:${{matrix.client}} --filter '@connectrpc/connect-web' --output-logs new-only --log-order stream diff --git a/.github/workflows/node-conformance.yaml b/.github/workflows/node-conformance.yaml deleted file mode 100644 index 44eefbacb..000000000 --- a/.github/workflows/node-conformance.yaml +++ /dev/null @@ -1,77 +0,0 @@ -name: Node Conformance -on: - push: - branches: [main] - tags: ['v*'] - pull_request: - branches: [main] - workflow_dispatch: -permissions: - contents: read -jobs: - node: - runs-on: ubuntu-22.04 - strategy: - matrix: - node-version: [18, 20, 21] - steps: - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-node-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-node-conformance- - - name: testconnectnodeconformance - run: make testconnectnodeconformance - fastify: - runs-on: ubuntu-22.04 - strategy: - matrix: - node-version: [18, 20, 21] - steps: - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-fastify-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-fastify-conformance- - - name: testconnectfastifyconformance - run: make testconnectfastifyconformance - express: - runs-on: ubuntu-22.04 - strategy: - matrix: - node-version: [18, 20, 21] - steps: - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-express-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-express-conformance- - - name: testconnectexpressconformance - run: make testconnectexpressconformance diff --git a/.github/workflows/web-conformance.yaml b/.github/workflows/web-conformance.yaml deleted file mode 100644 index 0dd28b076..000000000 --- a/.github/workflows/web-conformance.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: Web Conformance -on: - push: - branches: [main] - tags: ['v*'] - pull_request: - branches: [main] - workflow_dispatch: -permissions: - contents: read -jobs: - chrome: - runs-on: ubuntu-22.04 - steps: - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-web-chrome-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-web-chrome-conformance- - - name: testwebchromeconformance - run: make testwebchromeconformance - firefox: - runs-on: ubuntu-22.04 - steps: - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-web-firefox-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-web-firefox-conformance- - - name: testwebfirefoxconformance - run: make testwebfirefoxconformance - safari: - runs-on: macos-12 - steps: - - name: checkout - uses: actions/checkout@v4 - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-web-safari-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-web-safari-conformance- - - name: testwebsafariconformance - run: make testwebsafariconformance - node: - runs-on: ubuntu-22.04 - steps: - - name: checkout - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version-file: .nvmrc - - name: cache - uses: actions/cache@v4 - with: - path: | - ~/.tmp - .tmp - key: ${{ runner.os }}-connect-web-node-conformance-${{ hashFiles('Makefile') }} - restore-keys: | - ${{ runner.os }}-connect-web-node-conformance- - - name: testwebnodeconformance - run: make testwebnodeconformance diff --git a/.gitignore b/.gitignore index 2892551d5..98f977560 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -/.tmp +.turbo +.wrangler +node_modules /packages/*/dist /packages/connect-web/conformance/logs/* -node_modules -.wrangler +packages/connect-web/local.log diff --git a/.nvmrc b/.nvmrc index 209e3ef4b..f3f52b42d 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +20.9.0 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 42ae16adc..000000000 --- a/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules -/packages/connect/src/protocol-grpc/gen/*.ts -/packages/connect-web/browserstack/gen/**/*.ts -/packages/*/dist -/packages/*/src/gen -/.tmp diff --git a/MAINTAINERS.md b/MAINTAINERS.md index bd8aa43c8..92fa3480b 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,8 +1,8 @@ -Maintainers -=========== +# Maintainers ## Current -* [Peter Edge](https://github.com/bufdev), [Buf](https://buf.build) -* [Timo Stamm](https://github.com/timostamm), [Buf](https://buf.build) -* [Steve Ayers](https://github.com/smaye81), [Buf](https://buf.build) -* [Sri Krishna Paritala](https://github.com/srikrsna-buf), [Buf](https://buf.build) + +- [Peter Edge](https://github.com/bufdev), [Buf](https://buf.build) +- [Timo Stamm](https://github.com/timostamm), [Buf](https://buf.build) +- [Steve Ayers](https://github.com/smaye81), [Buf](https://buf.build) +- [Sri Krishna Paritala](https://github.com/srikrsna-buf), [Buf](https://buf.build) diff --git a/Makefile b/Makefile deleted file mode 100644 index dbbcb0207..000000000 --- a/Makefile +++ /dev/null @@ -1,250 +0,0 @@ -# See https://tech.davis-hansson.com/p/make/ -SHELL := bash -.DELETE_ON_ERROR: -.SHELLFLAGS := -eu -o pipefail -c -.DEFAULT_GOAL := all -MAKEFLAGS += --warn-undefined-variables -MAKEFLAGS += --no-builtin-rules -MAKEFLAGS += --no-print-directory -TMP = .tmp -BIN = .tmp/bin -BUILD = .tmp/build -GEN = .tmp/gen -NODE21_VERSION ?= v21.1.0 -NODE20_VERSION ?= v20.9.0 -NODE18_VERSION ?= v18.16.0 -NODE16_VERSION ?= v16.20.0 -NODE_OS = $(subst Linux,linux,$(subst Darwin,darwin,$(shell uname -s))) -NODE_ARCH = $(subst x86_64,x64,$(subst aarch64,arm64,$(shell uname -m))) - -node_modules: package-lock.json - npm ci - -node_modules/.bin/protoc-gen-es: node_modules - -$(BIN)/node21: Makefile - @mkdir -p $(@D) - curl --retry 5 --retry-all-errors --http1.1 -sSL -o $(TMP)/$(NODE21_VERSION).tar.xz https://nodejs.org/dist/$(NODE21_VERSION)/node-$(NODE21_VERSION)-$(NODE_OS)-$(NODE_ARCH).tar.xz - tar xJf $(TMP)/$(NODE21_VERSION).tar.xz -C $(TMP) node-$(NODE21_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node - @mv $(TMP)/node-$(NODE21_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node $(@) - @rm -r $(TMP)/node-$(NODE21_VERSION)-$(NODE_OS)-$(NODE_ARCH) - @rm -r $(TMP)/$(NODE21_VERSION).tar.xz - @touch $(@) - -$(BIN)/node20: Makefile - @mkdir -p $(@D) - curl --retry 5 --retry-all-errors --http1.1 -sSL -o $(TMP)/$(NODE20_VERSION).tar.xz https://nodejs.org/dist/$(NODE20_VERSION)/node-$(NODE20_VERSION)-$(NODE_OS)-$(NODE_ARCH).tar.xz - tar xJf $(TMP)/$(NODE20_VERSION).tar.xz -C $(TMP) node-$(NODE20_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node - @mv $(TMP)/node-$(NODE20_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node $(@) - @rm -r $(TMP)/node-$(NODE20_VERSION)-$(NODE_OS)-$(NODE_ARCH) - @rm -r $(TMP)/$(NODE20_VERSION).tar.xz - @touch $(@) - -$(BIN)/node18: Makefile - @mkdir -p $(@D) - curl --retry 5 --retry-all-errors --http1.1 -sSL -o $(TMP)/$(NODE18_VERSION).tar.xz https://nodejs.org/dist/$(NODE18_VERSION)/node-$(NODE18_VERSION)-$(NODE_OS)-$(NODE_ARCH).tar.xz - tar xJf $(TMP)/$(NODE18_VERSION).tar.xz -C $(TMP) node-$(NODE18_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node - @mv $(TMP)/node-$(NODE18_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node $(@) - @rm -r $(TMP)/node-$(NODE18_VERSION)-$(NODE_OS)-$(NODE_ARCH) - @rm -r $(TMP)/$(NODE18_VERSION).tar.xz - @touch $(@) - -$(BIN)/node16: Makefile - @mkdir -p $(@D) - curl --retry 5 --retry-all-errors --http1.1 -sSL -o $(TMP)/$(NODE16_VERSION).tar.xz https://nodejs.org/dist/$(NODE16_VERSION)/node-$(NODE16_VERSION)-$(NODE_OS)-$(NODE_ARCH).tar.xz - tar xJf $(TMP)/$(NODE16_VERSION).tar.xz -C $(TMP) node-$(NODE16_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node - @mv $(TMP)/node-$(NODE16_VERSION)-$(NODE_OS)-$(NODE_ARCH)/bin/node $(@) - @rm -r $(TMP)/node-$(NODE16_VERSION)-$(NODE_OS)-$(NODE_ARCH) - @rm -r $(TMP)/$(NODE16_VERSION).tar.xz - @touch $(@) - -$(BUILD)/protoc-gen-connect-es: node_modules tsconfig.base.json packages/protoc-gen-connect-es/tsconfig.json $(shell find packages/protoc-gen-connect-es/src -name '*.ts') - npm run -w packages/protoc-gen-connect-es build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect: $(GEN)/connect node_modules packages/connect/package.json packages/connect/scripts/* tsconfig.base.json packages/connect/tsconfig.json $(shell find packages/connect/src -name '*.ts') packages/connect/*.js - npm run -w packages/connect build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-node: $(BUILD)/connect $(BUILD)/connect-conformance packages/connect-node/tsconfig.json $(shell find packages/connect-node/src -name '*.ts') - npm run -w packages/connect-node build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-fastify: $(BUILD)/connect $(BUILD)/connect-node packages/connect-fastify/tsconfig.json $(shell find packages/connect-fastify/src -name '*.ts') - npm run -w packages/connect-fastify build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-express: $(BUILD)/connect $(BUILD)/connect-node packages/connect-express/tsconfig.json $(shell find packages/connect-express/src -name '*.ts') - npm run -w packages/connect-express build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-next: $(BUILD)/connect $(BUILD)/connect-node packages/connect-next/tsconfig.json $(shell find packages/connect-next/src -name '*.ts') - npm run -w packages/connect-next build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-web: $(GEN)/connect-web $(BUILD)/connect $(BUILD)/connect-conformance packages/connect-web/tsconfig.json $(shell find packages/connect-web/src -name '*.ts') - npm run -w packages/connect-web build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-conformance: $(GEN)/connect-conformance $(BUILD)/connect packages/connect-conformance/tsconfig.json $(shell find packages/connect-conformance/src -name '*.ts') - npm run -w packages/connect-conformance build - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/example: $(GEN)/example $(BUILD)/connect-web packages/example/tsconfig.json $(shell find packages/example/src -name '*.ts') - npm run -w packages/example lint - @mkdir -p $(@D) - @touch $(@) - -$(BUILD)/connect-migrate: packages/connect-migrate/package.json packages/connect-migrate/tsconfig.json $(shell find packages/connect-migrate/src -name '*.ts') - npm run -w packages/connect-migrate build - @mkdir -p $(@D) - @touch $(@) - -$(GEN)/connect: node_modules/.bin/protoc-gen-es packages/connect/buf.gen.yaml $(shell find packages/connect/src -name '*.proto') Makefile - npm run -w packages/connect generate - @mkdir -p $(@D) - @touch $(@) - -$(GEN)/connect-conformance: node_modules/.bin/protoc-gen-es $(BUILD)/protoc-gen-connect-es packages/connect-conformance/buf.gen.yaml packages/connect-conformance/package.json Makefile - npm run -w packages/connect-conformance generate - @mkdir -p $(@D) - @touch $(@) - -$(GEN)/connect-web: node_modules/.bin/protoc-gen-es $(BUILD)/protoc-gen-connect-es packages/connect-web/browserstack/buf.gen.yaml Makefile - npm run -w packages/connect-web generate - @mkdir -p $(@D) - @touch $(@) - -$(GEN)/connect-web-bench: node_modules/.bin/protoc-gen-es $(BUILD)/protoc-gen-connect-es packages/connect-web-bench/buf.gen.yaml - npm run -w packages/connect-web-bench generate - @mkdir -p $(@D) - @touch $(@) - -$(GEN)/example: node_modules/.bin/protoc-gen-es $(BUILD)/protoc-gen-connect-es packages/example/buf.gen.yaml $(shell find packages/example -name '*.proto') - npm run -w packages/example generate - @mkdir -p $(@D) - @touch $(@) - - -.PHONY: help -help: ## Describe useful make targets - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-30s %s\n", $$1, $$2}' - -.PHONY: all -all: build test testconformance format lint bench ## build, test, testconformance, format, lint, and bench (default) - -.PHONY: ci -ci: build test format lint bench ## build, test, format, lint, and bench (default) - -.PHONY: clean -clean: ## Delete build artifacts and installed dependencies - @# -X only removes untracked files, -d recurses into directories, -f actually removes files/dirs - git clean -Xdf - -.PHONY: build -build: $(BUILD)/connect $(BUILD)/connect-web $(BUILD)/connect-node $(BUILD)/connect-fastify $(BUILD)/connect-express $(BUILD)/connect-next $(BUILD)/protoc-gen-connect-es $(BUILD)/example $(BUILD)/connect-migrate ## Build - -.PHONY: test -test: testconnectpackage testconnectnodepackage testconnectwebpackage testconnectexpresspackage testconnectmigrate ## Run all tests, except browserstack - -.PHONY: testconnectpackage -testconnectpackage: $(BUILD)/connect - npm run -w packages/connect jasmine - -.PHONY: testconnectnodepackage -testconnectnodepackage: $(BIN)/node16 $(BIN)/node18 $(BIN)/node20 $(BIN)/node21 $(BUILD)/connect-node - cd packages/connect-node && PATH="$(abspath $(BIN)):$(PATH)" node16 --trace-warnings ../../node_modules/.bin/jasmine --config=jasmine.json - cd packages/connect-node && PATH="$(abspath $(BIN)):$(PATH)" node18 --trace-warnings ../../node_modules/.bin/jasmine --config=jasmine.json - cd packages/connect-node && PATH="$(abspath $(BIN)):$(PATH)" node20 --trace-warnings ../../node_modules/.bin/jasmine --config=jasmine.json - cd packages/connect-node && PATH="$(abspath $(BIN)):$(PATH)" node21 --trace-warnings ../../node_modules/.bin/jasmine --config=jasmine.json - -.PHONY: testconnectwebpackage -testconnectwebpackage: $(BIN)/node18 $(BIN)/node20 $(BIN)/node21 $(BUILD)/connect-web - cd packages/connect-web && PATH="$(abspath $(BIN)):$(PATH)" NODE_TLS_REJECT_UNAUTHORIZED=0 node18 ../../node_modules/.bin/jasmine --config=jasmine.json - cd packages/connect-web && PATH="$(abspath $(BIN)):$(PATH)" NODE_TLS_REJECT_UNAUTHORIZED=0 node20 ../../node_modules/.bin/jasmine --config=jasmine.json - cd packages/connect-web && PATH="$(abspath $(BIN)):$(PATH)" NODE_TLS_REJECT_UNAUTHORIZED=0 node21 ../../node_modules/.bin/jasmine --config=jasmine.json - -.PHONY: testconnectexpresspackage -testconnectexpresspackage: $(BUILD)/connect-express - npm run -w packages/connect-express jasmine - -.PHONY: testconformance -testconformance: testconnectnodeconformance testconnectfastifyconformance testconnectexpressconformance testwebconformance - -.PHONY: testconnectnodeconformance -testconnectnodeconformance: $(BUILD)/connect-node - # Vanilla Node Server and Client - npm run -w packages/connect-node conformance - -.PHONY: testconnectexpressconformance -testconnectexpressconformance: $(BUILD)/connect-express - # Express Server - npm run -w packages/connect-express conformance - -.PHONY: testconnectfastifyconformance -testconnectfastifyconformance: $(BUILD)/connect-fastify - # Fastify Server - npm run -w packages/connect-fastify conformance - -.PHONY: testwebconformance -testwebconformance: testwebchromeconformance testwebfirefoxconformance testwebsafariconformance testwebnodeconformance - -.PHONY: testwebchromeconformance -testwebchromeconformance: $(BUILD)/connect-web - npm run -w packages/connect-web conformance:client:chrome:promise - npm run -w packages/connect-web conformance:client:chrome:callback - -.PHONY: testwebfirefoxconformance -testwebfirefoxconformance: $(BUILD)/connect-web - npm run -w packages/connect-web conformance:client:firefox:promise - npm run -w packages/connect-web conformance:client:firefox:callback - -.PHONY: testwebsafariconformance -testwebsafariconformance: $(BUILD)/connect-web - npm run -w packages/connect-web conformance:client:safari:promise - npm run -w packages/connect-web conformance:client:safari:callback - -.PHONY: testwebnodeconformance -testwebnodeconformance: $(BUILD)/connect-web - npm run -w packages/connect-web conformance:client:node:promise - npm run -w packages/connect-web conformance:client:node:callback - -.PHONY: testcloudflareconformance -testcloudflareconformance: $(BUILD)/connect-conformance $(BUILD)/connect-node - npm run -w packages/connect-cloudflare conformance - -.PHONY: testwebbrowserstack -testwebbrowserstack: $(BUILD)/connect-web - npm run -w packages/connect-web karma:browserstack - -.PHONY: testconnectmigrate -testconnectmigrate: $(BUILD)/connect-migrate - npm run -w packages/connect-migrate test - -.PHONY: lint -lint: node_modules $(BUILD)/connect $(BUILD)/connect-express $(BUILD)/connect-fastify $(BUILD)/connect-next $(BUILD)/connect-node $(BUILD)/connect-web $(GEN)/connect-web-bench ## Lint all files - npx eslint --max-warnings 0 . - @# Check type exports on npm packages to verify they're correct - npm run -w packages/connect attw - npm run -w packages/connect-express attw - npm run -w packages/connect-fastify attw - npm run -w packages/connect-next attw - npm run -w packages/connect-node attw - npm run -w packages/connect-web attw - -.PHONY: format -format: node_modules ## Format all files, adding license headers - npx prettier --write '**/*.{json,js,jsx,ts,tsx,css,mjs,cjs}' --log-level error - npx license-header --ignore 'packages/*/src/gen/**/*' - -.PHONY: bench -bench: node_modules $(GEN)/connect-web-bench $(BUILD)/connect-web ## Benchmark code size - npm run -w packages/connect-web-bench bundle-size diff --git a/README.md b/README.md index 20a2008e7..7487521ee 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ service ElizaService { And with the magic of code generation, this schema produces servers and clients: ```ts -const answer = await eliza.say({sentence: "I feel happy."}); +const answer = await eliza.say({ sentence: "I feel happy." }); console.log(answer); // {sentence: 'When you feel happy, what do you do?'} ``` @@ -43,7 +43,6 @@ gRPC-web protocols, and Connect's [own protocol](https://connectrpc.com/docs/pro optimized for the web. This gives you unparalleled interoperability across many platforms and languages, with type-safety end-to-end. - ## Get started on the web Follow our [10 minute tutorial](https://connectrpc.com/docs/web/getting-started) where @@ -56,7 +55,6 @@ We support all modern web browsers that implement the widely available [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and the [Encoding API](https://developer.mozilla.org/en-US/docs/Web/API/Encoding_API). - ## Get started on Node.js Follow our [10 minute tutorial](https://connectrpc.com/docs/node/getting-started) @@ -67,7 +65,6 @@ You can serve your Connect RPCs with vanilla Node.js, or use our [server plugins for **Fastify**, **Next.js**, and **Express**. We support Node.js v16 and later with the builtin `http` and `http2` modules. - ## Other platforms Would you like to use Connect on other platforms like Bun, Deno, Vercel’s Edge Runtime, @@ -76,7 +73,6 @@ with Connect. You can reach us either through the [Buf Slack](https://buf.build/ or by filing a [GitHub issue](https://github.com/connectrpc/connect-es/issues) and we’d be more than happy to chat! - ## Packages - [@connectrpc/connect](https://www.npmjs.com/package/@connectrpc/connect): @@ -96,25 +92,23 @@ be more than happy to chat! The libraries and the generated code are compatible with ES2017 and TypeScript 4.1. - ## Ecosystem -* [examples-es](https://github.com/connectrpc/examples-es): +- [examples-es](https://github.com/connectrpc/examples-es): Examples for using Connect with various TypeScript web frameworks and tooling -* [connect-query-es](https://github.com/connectrpc/connect-query-es): +- [connect-query-es](https://github.com/connectrpc/connect-query-es): TypeScript-first expansion pack for TanStack Query that gives you Protobuf superpowers -* [connect-playwright-es](https://github.com/connectrpc/connect-playwright-es): +- [connect-playwright-es](https://github.com/connectrpc/connect-playwright-es): Playwright tests for your Connect application -* [connect-swift](https://github.com/connectrpc/connect-swift): +- [connect-swift](https://github.com/connectrpc/connect-swift): Idiomatic gRPC & Connect RPCs for Swift -* [connect-go](https://github.com/connectrpc/connect-go): +- [connect-go](https://github.com/connectrpc/connect-go): Go implementation of gRPC, gRPC-Web, and Connect -* [examples-go](https://github.com/connectrpc/examples-go): +- [examples-go](https://github.com/connectrpc/examples-go): Example RPC service powering https://demo.connectrpc.com and built with connect-go -* [conformance](https://github.com/connectrpc/conformance): +- [conformance](https://github.com/connectrpc/conformance): gRPC-Web and Connect interoperability tests -* [Buf Studio](https://buf.build/studio): web UI for ad-hoc RPCs - +- [Buf Studio](https://buf.build/studio): web UI for ad-hoc RPCs ## Status: Stable diff --git a/SECURITY.md b/SECURITY.md index 04dcde521..e15bc1420 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,4 @@ -Security Policy -=============== +# Security Policy This project follows the [Connect security policy and reporting process](https://connectrpc.com/docs/governance/security). diff --git a/package-lock.json b/package-lock.json index c776875ee..8beed2294 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,19 +4,20 @@ "requires": true, "packages": { "": { + "name": "connect-es", "workspaces": [ - "./packages/connect", - "./packages/protoc-gen-connect-es", - "./packages/connect-web", - "./packages/connect-node", - "./packages/connect-fastify", - "./packages/connect-next", - "./packages/connect-express", - "./packages/connect-web-bench", - "./packages/example", - "./packages/connect-migrate", - "./packages/connect-conformance", - "./packages/connect-cloudflare" + "packages/connect", + "packages/protoc-gen-connect-es", + "packages/connect-web", + "packages/connect-node", + "packages/connect-fastify", + "packages/connect-next", + "packages/connect-express", + "packages/connect-web-bench", + "packages/example", + "packages/connect-migrate", + "packages/connect-conformance", + "packages/connect-cloudflare" ], "devDependencies": { "@arethetypeswrong/cli": "^0.15.3", @@ -28,6 +29,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^17.10.1", "prettier": "^3.3.3", + "turbo": "^2.1.0", "typescript": "5.5.4" }, "engines": { @@ -10069,6 +10071,108 @@ "@esbuild/win32-x64": "0.23.1" } }, + "node_modules/turbo": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.1.0.tgz", + "integrity": "sha512-A969/LO/sPHKlapIarY2VVzqQ5JnnW2/1kksZlnMEpsRD6gwOELvVL+ozfMiO7av9RILt3UeN02L17efr6HUCA==", + "dev": true, + "license": "MIT", + "bin": { + "turbo": "bin/turbo" + }, + "optionalDependencies": { + "turbo-darwin-64": "2.1.0", + "turbo-darwin-arm64": "2.1.0", + "turbo-linux-64": "2.1.0", + "turbo-linux-arm64": "2.1.0", + "turbo-windows-64": "2.1.0", + "turbo-windows-arm64": "2.1.0" + } + }, + "node_modules/turbo-darwin-64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.1.0.tgz", + "integrity": "sha512-gHwpDk2gyB7qZ57gUUwDIS/IkglqEjjVtPZCTxmCRg28Tiwjui0azsLVKrnHP9UZHllozwbi28x8HXLXLEFF1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/turbo-darwin-arm64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.1.0.tgz", + "integrity": "sha512-GLaqGetNC6eS4eqXgsheLOHic/OcnGCGDi5boVf+TFZTXYH6YE15L4ugZha4xHXCr1KouCLILHh+f8EHEmWylg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/turbo-linux-64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.1.0.tgz", + "integrity": "sha512-VzBOsj7JyGoZtiNZZ6brjnY7UehRnClluw7pwznuLPzClkqOOPMd2jOcgkWxnP/xW4NBmOoFANXXrtvKBD4f2w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/turbo-linux-arm64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.1.0.tgz", + "integrity": "sha512-St7svJnOO5g4F6R7Z32e10I/0M3e6qpNjEYybXwPNul9NSfnUXeky4WoKaALwqNhyJ7nYemoFpZ1d+i8hFQTHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/turbo-windows-64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.1.0.tgz", + "integrity": "sha512-iSobNud2MrJ1SZ1upVPlErT8xexsr0MQtKapdfq6z0M0rBnrDGEq5bUCSScWyGu+O4+glB4br9xkTAkGFqaxqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/turbo-windows-arm64": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.1.0.tgz", + "integrity": "sha512-d61jN4rjE5PnUfF66GKrKoj8S8Ql4FGXzFFzZz4kjsHpZZzCTtqlzPZBmd1byzGYhDPTorTqG3G1USohbdyohA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -11259,6 +11363,7 @@ }, "devDependencies": { "@bufbuild/buf": "^1.39.0", + "@connectrpc/protoc-gen-connect-es": "1.4.0", "@types/debug": "^4.1.12", "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3" @@ -11269,7 +11374,9 @@ "version": "1.4.0", "license": "Apache-2.0", "devDependencies": { + "@connectrpc/connect": "1.4.0", "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect-node": "1.4.0", "@types/express": "^4.17.18", "express": "^4.19.2", "tsx": "^4.19.0" @@ -11288,7 +11395,9 @@ "version": "1.4.0", "license": "Apache-2.0", "devDependencies": { - "@connectrpc/connect-conformance": "^1.4.0" + "@connectrpc/connect": "1.4.0", + "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect-node": "1.4.0" }, "engines": { "node": ">=16.0.0" @@ -11324,6 +11433,10 @@ "name": "@connectrpc/connect-next", "version": "1.4.0", "license": "Apache-2.0", + "devDependencies": { + "@connectrpc/connect": "1.4.0", + "@connectrpc/connect-node": "1.4.0" + }, "engines": { "node": ">=16.0.0" }, diff --git a/package.json b/package.json index ebbd5673c..d99881895 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,30 @@ { + "name": "connect-es", "private": true, "workspaces": [ - "./packages/connect", - "./packages/protoc-gen-connect-es", - "./packages/connect-web", - "./packages/connect-node", - "./packages/connect-fastify", - "./packages/connect-next", - "./packages/connect-express", - "./packages/connect-web-bench", - "./packages/example", - "./packages/connect-migrate", - "./packages/connect-conformance", - "./packages/connect-cloudflare" + "packages/connect", + "packages/protoc-gen-connect-es", + "packages/connect-web", + "packages/connect-node", + "packages/connect-fastify", + "packages/connect-next", + "packages/connect-express", + "packages/connect-web-bench", + "packages/example", + "packages/connect-migrate", + "packages/connect-conformance", + "packages/connect-cloudflare" ], "scripts": { + "all": "turbo run --ui tui build format test conformance bundle-size lint attw license-header", "clean": "git clean -Xdf", "setversion": "node scripts/set-workspace-version.js", "postsetversion": "npm run all", - "all": "make", - "release": "npm run all && node scripts/release.js" + "release": "node scripts/release.js", + "prerelease": "npm run all", + "format": "prettier --write --ignore-unknown '.' '!packages' '!.turbo' '!node_modules'", + "license-header": "license-header --ignore 'packages/**'", + "lint": "eslint --max-warnings 0 . --ignore-pattern 'packages/**'" }, "type": "module", "engineStrict": true, @@ -27,6 +32,7 @@ "node": ">=16", "npm": ">=8" }, + "packageManager": "npm@10.1.0", "licenseHeader": { "licenseType": "apache", "yearRange": "2021-2024", @@ -35,13 +41,14 @@ "devDependencies": { "@arethetypeswrong/cli": "^0.15.3", "@bufbuild/license-header": "^0.0.4", + "@typescript-eslint/eslint-plugin": "^7.14.0", "@typescript-eslint/parser": "^7.14.0", "eslint": "^8.56.0", - "@typescript-eslint/eslint-plugin": "^7.14.0", "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-n": "^17.10.1", "eslint-plugin-import": "^2.29.1", + "eslint-plugin-n": "^17.10.1", "prettier": "^3.3.3", + "turbo": "^2.1.0", "typescript": "5.5.4" } } diff --git a/packages/connect-cloudflare/README.md b/packages/connect-cloudflare/README.md index 3a9c18476..b18aca8ec 100644 --- a/packages/connect-cloudflare/README.md +++ b/packages/connect-cloudflare/README.md @@ -4,32 +4,31 @@ This package provides conformance test coverage for Connect-ES on Cloudflare for It uses the [conformance runner](https://github.com/connectrpc/conformance/releases) to run the tests. -Cloudflare worker tests are run once every 24 hours and on a release PR. This is because the tests are run on a live +Cloudflare worker tests are run once every 24 hours and on a release PR. This is because the tests are run on a live Cloudflare worker, and deploying a new version of the worker is a slow process. ## Running conformance tests -Run `make testcloudflareconformance` to run all Cloudflare conformance tests for both server and client. The above command -is also available as an npm script: `npm run conformance`. +Cloudflare conformance tests can be run with the tasks `conformance:client` and `conformance:server` for the package +`@connectrpc/connect-cloudflare`. You can run both with the following command: -The individual tests for server and client can also be run via npm: - -`npm run conformance:server` -`npm run conformance:client` +```bash +npx turbo run --filter @connectrpc/connect-cloudflare conformance:client conformance:server +``` ### Client tests on Cloudflare -Client tests on Cloudflare require a live server with valid TLS. To run the tests, we set up a -[self hosted GitHub action runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) +Client tests on Cloudflare require a live server with valid TLS. To run the tests, we set up a +[self hosted GitHub action runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) that runs the conformance runner and exposes the reference server on port 443 over the public internet. #### Steps to setup the action runner -* Provision a VM with a static public IP address. -* Reserve a domain (can be a subdomain) and point it to the public IP address from the previous step. -* Use [certbot](https://certbot.eff.org/) to setup automatic certificate renewal for the domain. -* Using iptables, redirect traffic from port 443 to a non-privileged port say 8181. -* Create a dedicated user to run the action runner. -* Make sure the user has the necessary permissions to run the conformance runner, read the cert and key that certbot maintains. -* Follow the steps [here](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners) to add a self-hosted runner to the repository. -* Configure the runner app to [run as a service](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service) with the created user. +- Provision a VM with a static public IP address. +- Reserve a domain (can be a subdomain) and point it to the public IP address from the previous step. +- Use [certbot](https://certbot.eff.org/) to setup automatic certificate renewal for the domain. +- Using iptables, redirect traffic from port 443 to a non-privileged port say 8181. +- Create a dedicated user to run the action runner. +- Make sure the user has the necessary permissions to run the conformance runner, read the cert and key that certbot maintains. +- Follow the steps [here](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners) to add a self-hosted runner to the repository. +- Configure the runner app to [run as a service](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service) with the created user. diff --git a/packages/connect-cloudflare/conformance/client.ts b/packages/connect-cloudflare/conformance/client.ts index 1f54b8ffd..c1d64c585 100755 --- a/packages/connect-cloudflare/conformance/client.ts +++ b/packages/connect-cloudflare/conformance/client.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/connect-cloudflare/conformance/server.ts b/packages/connect-cloudflare/conformance/server.ts index e56926b8e..4a6f6ece0 100755 --- a/packages/connect-cloudflare/conformance/server.ts +++ b/packages/connect-cloudflare/conformance/server.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/connect-cloudflare/package.json b/packages/connect-cloudflare/package.json index fd43e9297..b9b14c7a2 100644 --- a/packages/connect-cloudflare/package.json +++ b/packages/connect-cloudflare/package.json @@ -3,9 +3,11 @@ "private": true, "type": "module", "scripts": { - "conformance": "tsc --noEmit && npm run conformance:server && npm run conformance:client", - "conformance:server": "npx wrangler deploy -c ./conformance/wrangler-server.toml && connectconformance --mode server --conf ./conformance/conformance-cloudflare-server.yaml -v ./conformance/server.ts", - "conformance:client": "npx wrangler deploy -c ./conformance/wrangler-client.toml && connectconformance --mode client --conf ./conformance/conformance-cloudflare-client.yaml -v --known-failing @./conformance/known-failing-client.txt --bind 0.0.0.0 --port 8181 --cert $CLOUDFLARE_WORKERS_REFERENCE_SERVER_CERT --key $CLOUDFLARE_WORKERS_REFERENCE_SERVER_KEY -- ./conformance/client.ts" + "conformance:server": "npx wrangler deploy -c ./conformance/wrangler-server.toml && connectconformance --mode server --conf ./conformance/conformance-cloudflare-server.yaml -v tsx ./conformance/server.ts", + "conformance:client": "npx wrangler deploy -c ./conformance/wrangler-client.toml && connectconformance --mode client --conf ./conformance/conformance-cloudflare-client.yaml -v --known-failing @./conformance/known-failing-client.txt --bind 0.0.0.0 --port 8181 --cert $CLOUDFLARE_WORKERS_REFERENCE_SERVER_CERT --key $CLOUDFLARE_WORKERS_REFERENCE_SERVER_KEY -- tsx ./conformance/client.ts", + "format": "prettier --write --ignore-unknown '.'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 ." }, "dependencies": { "@bufbuild/protobuf": "^1.10.0", diff --git a/packages/connect-cloudflare/turbo.json b/packages/connect-cloudflare/turbo.json new file mode 100644 index 000000000..0c8092c4b --- /dev/null +++ b/packages/connect-cloudflare/turbo.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "conformance:client": { "cache": false, "dependsOn": ["^build"] }, + "conformance:server": { "cache": false, "dependsOn": ["^build"] } + } +} diff --git a/packages/connect-conformance/README.md b/packages/connect-conformance/README.md index ab4f861f5..5d6948633 100644 --- a/packages/connect-conformance/README.md +++ b/packages/connect-conformance/README.md @@ -6,11 +6,11 @@ this repository. For documentation on the conformance tests, see the repository [here](https://github.com/connectrpc/conformance?tab=readme-ov-file#documentation). Note that this package does not run any conformance tests itself, but instead exports functionality to be used by other -packages, such as `connect-node`, `connect-web`, etc. +packages, such as `@connectprc/connect-node`, `@connectprc/connect-web`, etc. ## Updating the conformance version To update the version of the conformance runner and protos, change the version in the following places: -* The `generate` command of this package's `package.json` file. -* The `version` constant inside `node/conformance.ts`. +- The `generate` command of this package's `package.json` file. +- The `version` constant inside `node/conformance.ts`. diff --git a/packages/connect-conformance/package.json b/packages/connect-conformance/package.json index 0607b8c8d..cd39b6e41 100644 --- a/packages/connect-conformance/package.json +++ b/packages/connect-conformance/package.json @@ -20,7 +20,11 @@ "build": "npm run build:cjs && npm run build:esm", "postbuild": "connectconformance --version", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/src/package.json '{\"type\":\"commonjs\"}'", - "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm" + "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", + "format": "prettier --write --ignore-unknown '.' '!dist' '!src/gen'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", + "attw": "attw --pack" }, "dependencies": { "@bufbuild/protobuf": "^1.10.0", @@ -33,6 +37,7 @@ "@bufbuild/buf": "^1.39.0", "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3", - "@types/debug": "^4.1.12" + "@types/debug": "^4.1.12", + "@connectrpc/protoc-gen-connect-es": "1.4.0" } } diff --git a/packages/connect-conformance/turbo.json b/packages/connect-conformance/turbo.json new file mode 100644 index 000000000..fd0ee0db3 --- /dev/null +++ b/packages/connect-conformance/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "lint": { + "dependsOn": ["format", "^build", "generate", "build"] + } + } +} diff --git a/packages/connect-express/README.md b/packages/connect-express/README.md index 33b3a839b..c6ec96bac 100644 --- a/packages/connect-express/README.md +++ b/packages/connect-express/README.md @@ -15,7 +15,7 @@ Adds your Connect RPCs to an Express server. // connect.ts import { ConnectRouter } from "@connectrpc/connect"; -export default function(router: ConnectRouter) { +export default function (router: ConnectRouter) { // implement rpc Say(SayRequest) returns (SayResponse) router.rpc(ElizaService, ElizaService.methods.say, async (req) => ({ sentence: `you said: ${req.sentence}`, @@ -64,7 +64,7 @@ const transport = createGrpcWebTransport({ const client = createPromiseClient(ElizaService, transport); const { sentence } = await client.say({ sentence: "I feel happy." }); -console.log(sentence) // you said: I feel happy. +console.log(sentence); // you said: I feel happy. ``` A client for the web browser actually looks identical to this example - it would @@ -74,7 +74,6 @@ instead. Note that support for gRPC is limited, since many gRPC clients require HTTP/2, and Express does not support the Node.js `http2` module. - ## Getting started To get started with Connect, head over to the [docs](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect-express/conformance/server.ts b/packages/connect-express/conformance/server.ts index 04da05b98..cf1ae2f7c 100755 --- a/packages/connect-express/conformance/server.ts +++ b/packages/connect-express/conformance/server.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,9 +29,10 @@ import { ServerCompatResponse, ServerStreamRequest, UnaryRequest, + writeSizeDelimitedBuffer, } from "@connectrpc/connect-conformance"; import express from "express"; -import { expressConnectMiddleware } from "@connectrpc/connect-express"; +import { expressConnectMiddleware } from "../src/index.js"; main(); @@ -104,8 +103,12 @@ function main() { } process.on("SIGTERM", () => { - server.close(); + // Gracefully shutting down a http2 server is complicated. + // We trust the conformance test runner to only send the signal if it's done, + // so we simply shut down hard. + process.exit(); }); + server.listen(undefined, "127.0.0.1", () => { const addrInfo = server.address() as net.AddressInfo; const res = new ServerCompatResponse({ @@ -116,10 +119,6 @@ function main() { host: addrInfo.address, port: addrInfo.port, }); - const data = res.toBinary(); - const size = Buffer.alloc(4); - size.writeUInt32BE(data.byteLength); - process.stdout.write(size); - process.stdout.write(data); + process.stdout.write(writeSizeDelimitedBuffer(res.toBinary())); }); } diff --git a/packages/connect-express/package.json b/packages/connect-express/package.json index aadec8ecc..7801ec796 100644 --- a/packages/connect-express/package.json +++ b/packages/connect-express/package.json @@ -12,9 +12,12 @@ "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", - "attw": "attw --pack", - "jasmine": "jasmine --config=jasmine.json", - "conformance": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-express.yaml -v ./conformance/server.ts" + "test": "jasmine --config=jasmine.json", + "conformance": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-express.yaml -v -- tsx ./conformance/server.ts", + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", + "attw": "attw --pack" }, "type": "module", "sideEffects": false, @@ -30,6 +33,8 @@ }, "devDependencies": { "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect": "1.4.0", + "@connectrpc/connect-node": "1.4.0", "@types/express": "^4.17.18", "express": "^4.19.2", "tsx": "^4.19.0" diff --git a/packages/connect-fastify/README.md b/packages/connect-fastify/README.md index 627b41508..bbde6bab5 100644 --- a/packages/connect-fastify/README.md +++ b/packages/connect-fastify/README.md @@ -15,7 +15,7 @@ Plug your Connect RPCs into a fastify server. // connect.ts import { ConnectRouter } from "@connectrpc/connect"; -export default function(router: ConnectRouter) { +export default function (router: ConnectRouter) { // implement rpc Say(SayRequest) returns (SayResponse) router.rpc(ElizaService, ElizaService.methods.say, async (req) => ({ sentence: `you said: ${req.sentence}`, @@ -78,14 +78,13 @@ const transport = createGrpcTransport({ const client = createPromiseClient(ElizaService, transport); const { sentence } = await client.say({ sentence: "I feel happy." }); -console.log(sentence) // you said: I feel happy. +console.log(sentence); // you said: I feel happy. ``` A client for the web browser actually looks identical to this example - it would simply use `createConnectTransport` from [@connectrpc/connect-web](https://www.npmjs.com/package/@connectrpc/connect-web) instead. - ## Getting started To get started with Connect, head over to the [docs](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect-fastify/conformance/server.ts b/packages/connect-fastify/conformance/server.ts index 516aaec8e..7e985b3ad 100755 --- a/packages/connect-fastify/conformance/server.ts +++ b/packages/connect-fastify/conformance/server.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +28,7 @@ import { ServerCompatResponse, ServerStreamRequest, UnaryRequest, + writeSizeDelimitedBuffer, } from "@connectrpc/connect-conformance"; import { fastify } from "fastify"; import type { @@ -39,7 +38,7 @@ import type { FastifyHttp2SecureOptions, FastifyInstance, } from "fastify"; -import { fastifyConnectPlugin } from "@connectrpc/connect-fastify"; +import { fastifyConnectPlugin } from "../src/index.js"; main(); @@ -136,8 +135,12 @@ function main() { } process.on("SIGTERM", () => { - void server.close(); + // Gracefully shutting down a http2 server is complicated. + // We trust the conformance test runner to only send the signal if it's done, + // so we simply shut down hard. + process.exit(); }); + server.listen({ host: "127.0.0.1", port: 0 }, () => { const addrInfo = server.addresses()[0]; const res = new ServerCompatResponse({ @@ -148,10 +151,6 @@ function main() { host: addrInfo.address, port: addrInfo.port, }); - const data = res.toBinary(); - const size = Buffer.alloc(4); - size.writeUInt32BE(data.byteLength); - process.stdout.write(size); - process.stdout.write(data); + process.stdout.write(writeSizeDelimitedBuffer(res.toBinary())); }); } diff --git a/packages/connect-fastify/package.json b/packages/connect-fastify/package.json index a788db74d..f7f8e21ba 100644 --- a/packages/connect-fastify/package.json +++ b/packages/connect-fastify/package.json @@ -12,8 +12,11 @@ "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", - "attw": "attw --pack", - "conformance": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-fastify.yaml -v ./conformance/server.ts" + "conformance": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-fastify.yaml -v -- tsx ./conformance/server.ts", + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", + "attw": "attw --pack" }, "type": "module", "sideEffects": false, @@ -28,7 +31,9 @@ "node": ">=16.0.0" }, "devDependencies": { - "@connectrpc/connect-conformance": "^1.4.0" + "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect": "1.4.0", + "@connectrpc/connect-node": "1.4.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", diff --git a/packages/connect-migrate/README.md b/packages/connect-migrate/README.md index 15d8fa6de..4d4345a49 100644 --- a/packages/connect-migrate/README.md +++ b/packages/connect-migrate/README.md @@ -2,7 +2,6 @@ This tool updates your Connect project to use the new `@connectrpc` packages. - ## Usage To migrate, run the following command in your project root directory: @@ -13,7 +12,6 @@ npx @connectrpc/connect-migrate Add the `--help` flag to the command to learn more about the available flags. - ## What it does This package is made up of a few migration steps @@ -24,29 +22,27 @@ This package is made up of a few migration steps ## What files are changed -We ignore all files within `node_modules` but will update any other files that +We ignore all files within `node_modules` but will update any other files that end with the following extensions: `.ts`, `.tsx`, `.js`, `.jsx`, `.cjs`, `.mjs`. - ## Prerequisites -- Commit any unstaged changes to your project, so that you can revert in case the +- Commit any unstaged changes to your project, so that you can revert in case the migration fails. - After migration, run your generate scripts to re-generate code with the latest plugin versions. - ## Alternative running methods -This tool leverages `jscodeshift` in order to find all references to packages and -update them. As a result, we've assumed a parser to parse your JavaScript/TypeScript -files. If you see errors due to parsing, you may be using a custom babel config -or another custom parser. You can work around this while leveraging our +This tool leverages `jscodeshift` in order to find all references to packages and +update them. As a result, we've assumed a parser to parse your JavaScript/TypeScript +files. If you see errors due to parsing, you may be using a custom babel config +or another custom parser. You can work around this while leveraging our transforms by calling `jscodeshift` directly. ```shell npx jscodeshift -t ./node_modules/@connectrpc/connect-migrate/dist/cjs/migrations/v0.13.1-transform.js . ``` -And add any additional params you feel are necessary. You can find more +And add any additional params you feel are necessary. You can find more information about `jscodeshift` [here](https://github.com/facebook/jscodeshift/blob/main/README.md#usage-cli). diff --git a/packages/connect-migrate/bin/connect-migrate b/packages/connect-migrate/bin/connect-migrate index 8705279e2..ae12b1f82 100755 --- a/packages/connect-migrate/bin/connect-migrate +++ b/packages/connect-migrate/bin/connect-migrate @@ -1,3 +1,3 @@ #!/usr/bin/env node -require("../dist/cjs/cli.js"); \ No newline at end of file +require("../dist/cjs/cli.js"); diff --git a/packages/connect-migrate/package.json b/packages/connect-migrate/package.json index 569507886..c8dfc30ea 100644 --- a/packages/connect-migrate/package.json +++ b/packages/connect-migrate/package.json @@ -8,7 +8,6 @@ "url": "https://github.com/connectrpc/connect-es.git", "directory": "packages/connect-migrate" }, - "sideEffects": true, "bin": { "connect-migrate": "bin/connect-migrate" }, @@ -16,7 +15,9 @@ "prebuild": "rm -rf ./dist/*", "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs", "test": "jasmine --config=jasmine.json", - "build+test": "npm run build && npm run test" + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 ." }, "engines": { "node": ">=16.0.0" diff --git a/packages/connect-migrate/src/lib/replace-dependencies.ts b/packages/connect-migrate/src/lib/replace-dependencies.ts index 23b947050..b638f156c 100644 --- a/packages/connect-migrate/src/lib/replace-dependencies.ts +++ b/packages/connect-migrate/src/lib/replace-dependencies.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { PackageJson } from "./package-json"; +import type { PackageJson } from "./package-json"; import { intersects as semverIntersects, satisfies as semverSatisfies, @@ -32,7 +32,7 @@ export function replaceDependencies( ): PackageJson | null { const modifiedPackageNames = new Set(); const replacedPackageNames = new Map(); - const copy = structuredClone(pkg) as PackageJson; + const copy = clonePackageJson(pkg); // replace dependencies for (const replacement of replacements) { for (const p of [ @@ -92,3 +92,7 @@ export function replaceDependencies( } return modifiedPackageNames.size > 0 ? copy : null; } + +function clonePackageJson(pkg: PackageJson): PackageJson { + return JSON.parse(JSON.stringify(pkg)) as PackageJson; +} diff --git a/packages/connect-migrate/tsconfig.json b/packages/connect-migrate/tsconfig.json index 2e85139ed..aecaa31d3 100644 --- a/packages/connect-migrate/tsconfig.json +++ b/packages/connect-migrate/tsconfig.json @@ -2,6 +2,11 @@ "include": ["src/**/*.ts"], "extends": "../../tsconfig.base.json", "compilerOptions": { - "esModuleInterop": true // required for jscodeshift + // required for jscodeshift + "esModuleInterop": true, + // This package is CommonJS + "verbatimModuleSyntax": false, + "module": "CommonJS", + "moduleResolution": "Node10" } } diff --git a/packages/connect-migrate/turbo.json b/packages/connect-migrate/turbo.json new file mode 100644 index 000000000..fd0ee0db3 --- /dev/null +++ b/packages/connect-migrate/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "lint": { + "dependsOn": ["format", "^build", "generate", "build"] + } + } +} diff --git a/packages/connect-next/README.md b/packages/connect-next/README.md index 90264b321..c337941cd 100644 --- a/packages/connect-next/README.md +++ b/packages/connect-next/README.md @@ -7,10 +7,9 @@ TypeScript. `@connectrpc/connect-next` provides a plugin for [Next.js](https://nextjs.org/), the React Framework for the Web. - ### nextJsApiRouter() -Provide your Connect RPCs via Next.js API routes. To enable Connect in Next.js, +Provide your Connect RPCs via Next.js API routes. To enable Connect in Next.js, add two files to your project: ```diff @@ -21,8 +20,8 @@ add two files to your project:         └── [[...connect]].ts ``` -> **Note:** Next.js 13 introduced the new App Router. Your Connect API routes -> need to be placed in `pages/`, but you can use the `app/` directory for the +> **Note:** Next.js 13 introduced the new App Router. Your Connect API routes +> need to be placed in `pages/`, but you can use the `app/` directory for the > App Router at the same time. The new file `connect.ts` is where you register your RPCs: @@ -31,7 +30,7 @@ The new file `connect.ts` is where you register your RPCs: // connect.ts import { ConnectRouter } from "@connectrpc/connect"; -export default function(router: ConnectRouter) { +export default function (router: ConnectRouter) { // implement rpc Say(SayRequest) returns (SayResponse) router.rpc(ElizaService, ElizaService.methods.say, async (req) => ({ sentence: `you said: ${req.sentence}`, @@ -46,8 +45,8 @@ export default function(router: ConnectRouter) { import { nextJsApiRouter } from "@connectrpc/connect-next"; import routes from "../../connect"; -const {handler, config} = nextJsApiRouter({ routes }); -export {handler as default, config}; +const { handler, config } = nextJsApiRouter({ routes }); +export { handler as default, config }; ``` With that server running, you can make requests with any Connect or gRPC-Web client. @@ -77,7 +76,7 @@ const transport = createGrpcWebTransport({ const client = createPromiseClient(ElizaService, transport); const { sentence } = await client.say({ sentence: "I feel happy." }); -console.log(sentence) // you said: I feel happy. +console.log(sentence); // you said: I feel happy. ``` A client for the web browser actually looks identical to this example - it would @@ -87,14 +86,12 @@ instead. Note that support for gRPC is limited, since many gRPC clients require HTTP/2, and Express does not support the Node.js `http2` module. - ### Deploying to Vercel Currently, `@connectrpc/connect-next` does not support the Vercel Edge runtime. It requires the Node.js server runtime, which is used by default when deploying to Vercel. - ## Getting started To get started with Connect, head over to the [docs](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect-next/package.json b/packages/connect-next/package.json index 3d7ea8dea..18d7e6aa5 100644 --- a/packages/connect-next/package.json +++ b/packages/connect-next/package.json @@ -12,6 +12,9 @@ "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", "attw": "attw --pack" }, "type": "module", @@ -31,5 +34,9 @@ "next": "^13.2.4 || ^14.2.5", "@connectrpc/connect": "1.4.0", "@connectrpc/connect-node": "1.4.0" + }, + "devDependencies": { + "@connectrpc/connect": "1.4.0", + "@connectrpc/connect-node": "1.4.0" } } diff --git a/packages/connect-node/README.md b/packages/connect-node/README.md index 004b30e40..ff94f35db 100644 --- a/packages/connect-node/README.md +++ b/packages/connect-node/README.md @@ -66,7 +66,6 @@ const { sentence } = await client.say({ sentence: "I feel happy." }); console.log(sentence) // you said: I feel happy. ``` - ### connectNodeAdapter() Run your Connect RPCs on the Node.js `http`, `https`, or `http2` modules. @@ -75,7 +74,7 @@ Run your Connect RPCs on the Node.js `http`, `https`, or `http2` modules. // connect.ts import { ConnectRouter } from "@connectrpc/connect"; -export default function(router: ConnectRouter) { +export default function (router: ConnectRouter) { // implement rpc Say(SayRequest) returns (SayResponse) router.rpc(ElizaService, ElizaService.methods.say, async (req) => ({ sentence: `you said: ${req.sentence}`, @@ -94,7 +93,6 @@ http2.createServer( ).listen(8080); ``` - With that server running, you can make requests with any gRPC, gRPC-Web, or Connect client. `buf curl` with the gRPC protocol: @@ -130,14 +128,13 @@ const transport = createGrpcTransport({ const client = createPromiseClient(ElizaService, transport); const { sentence } = await client.say({ sentence: "I feel happy." }); -console.log(sentence) // you said: I feel happy. +console.log(sentence); // you said: I feel happy. ``` A client for the web browser actually looks identical to this example - it would simply use `createConnectTransport` from [@connectrpc/connect-web](https://www.npmjs.com/package/@connectrpc/connect-web) instead. - ## Getting started To get started with Connect, head over to the [docs](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect-node/conformance/README.md b/packages/connect-node/conformance/README.md index b5e3d266b..9b854e49b 100644 --- a/packages/connect-node/conformance/README.md +++ b/packages/connect-node/conformance/README.md @@ -1,15 +1,12 @@ # Connect-Node Conformance Tests -This directory provides conformance test coverage for @connectrpc/connect-node for both clients and servers. +This directory provides conformance test coverage for @connectrpc/connect-node for both clients and servers. It uses the [conformance runner](https://github.com/connectrpc/conformance/releases) to run the tests. ## Running conformance tests -Run `make testnodeconformance` to run all Node conformance tests for both server and client. -The above command is also available as an npm script: `npm run conformance`. - -The individual tests for server and client can also be run via npm: - -`npm run conformance:server` -`npm run conformance:client` +```bash +cd packages/connect-node +npx turbo run conformance:server conformance:client +``` diff --git a/packages/connect-node/conformance/client.ts b/packages/connect-node/conformance/client.ts index 8a8a32893..35091a05b 100755 --- a/packages/connect-node/conformance/client.ts +++ b/packages/connect-node/conformance/client.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/connect-node/conformance/server.ts b/packages/connect-node/conformance/server.ts index a341c7203..c2c0b5a36 100755 --- a/packages/connect-node/conformance/server.ts +++ b/packages/connect-node/conformance/server.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +17,7 @@ import { compressionBrotli, compressionGzip, connectNodeAdapter, -} from "@connectrpc/connect-node"; +} from "../src/index.js"; import * as http from "node:http"; import * as http2 from "node:http2"; import * as https from "node:https"; @@ -107,9 +105,13 @@ function main() { } process.on("SIGTERM", () => { - server.close(); + // Gracefully shutting down a http2 server is complicated. + // We trust the conformance test runner to only send the signal if it's done, + // so we simply shut down hard. + process.exit(); }); - server.listen(undefined, "127.0.0.1", () => { + + server.listen(0, "127.0.0.1", () => { const addrInfo = server.address() as net.AddressInfo; const res = new ServerCompatResponse({ pemCert: diff --git a/packages/connect-node/conformance/transport.ts b/packages/connect-node/conformance/transport.ts index 5926e7c9e..827ef2a46 100644 --- a/packages/connect-node/conformance/transport.ts +++ b/packages/connect-node/conformance/transport.ts @@ -31,7 +31,7 @@ import { compressionGzip, compressionBrotli, createGrpcWebTransport, -} from "@connectrpc/connect-node"; +} from "../src/index.js"; import type { Compression } from "@connectrpc/connect/protocol"; import * as http2 from "node:http2"; diff --git a/packages/connect-node/package.json b/packages/connect-node/package.json index 9dad50d8b..7307cb860 100644 --- a/packages/connect-node/package.json +++ b/packages/connect-node/package.json @@ -12,11 +12,13 @@ "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --moduleResolution node10 --verbatimModuleSyntax false --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", - "attw": "attw --pack", - "jasmine": "jasmine --config=jasmine.json", - "conformance": "npm run conformance:server && npm run conformance:client", - "conformance:server": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-node.yaml -v ./conformance/server.ts", - "conformance:client": "tsc --noEmit && connectconformance --mode client --conf ./conformance/conformance-node.yaml -v ./conformance/client.ts" + "test": "jasmine --config=jasmine.json", + "conformance:server": "tsc --noEmit && connectconformance --mode server --conf ./conformance/conformance-node.yaml -v -- tsx ./conformance/server.ts", + "conformance:client": "tsc --noEmit && connectconformance --mode client --conf ./conformance/conformance-node.yaml -v -- tsx ./conformance/client.ts", + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", + "attw": "attw --pack" }, "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/connect-node/turbo.json b/packages/connect-node/turbo.json new file mode 100644 index 000000000..b57bb0aa8 --- /dev/null +++ b/packages/connect-node/turbo.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "conformance": { + "dependsOn": ["conformance:client", "conformance:server"] + }, + "conformance:client": { "cache": false, "dependsOn": ["^build"] }, + "conformance:server": { "cache": false, "dependsOn": ["^build"] } + } +} diff --git a/packages/connect-web-bench/package.json b/packages/connect-web-bench/package.json index 81014703a..4f87f2a79 100644 --- a/packages/connect-web-bench/package.json +++ b/packages/connect-web-bench/package.json @@ -4,7 +4,10 @@ "scripts": { "bundle-size": "tsx src/report.ts", "generate": "buf generate", - "postgenerate": "license-header src/gen" + "postgenerate": "license-header src/gen", + "format": "prettier --write --ignore-unknown '.' '!src/gen'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 ." }, "dependencies": { "@bufbuild/buf": "^1.39.0", diff --git a/packages/connect-web-bench/turbo.json b/packages/connect-web-bench/turbo.json new file mode 100644 index 000000000..d271cff70 --- /dev/null +++ b/packages/connect-web-bench/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "bundle-size": { + "dependsOn": ["^build", "generate"] + } + } +} diff --git a/packages/connect-web/README.md b/packages/connect-web/README.md index 41b1f0cad..418c3ce0e 100644 --- a/packages/connect-web/README.md +++ b/packages/connect-web/README.md @@ -7,7 +7,6 @@ TypeScript. `@connectrpc/connect-web` provides the following adapters for web browsers, and any other platform that has the fetch API on board: - ### createConnectTransport() Lets your clients running in the web browser talk to a server with the Connect protocol: @@ -29,7 +28,7 @@ console.log(sentence) // you said: I feel happy. ### createGrpcWebTransport() -Lets your clients running in the web browser talk to a server with the gRPC-web protocol: +Lets your clients running in the web browser talk to a server with the gRPC-web protocol: ```diff import { createPromiseClient } from "@connectrpc/connect"; @@ -46,7 +45,6 @@ const { sentence } = await client.say({ sentence: "I feel happy." }); console.log(sentence) // you said: I feel happy. ``` - ## Getting started To get started with Connect, head over to the [docs](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect-web/browserstack/README.md b/packages/connect-web/browserstack/README.md index 9fa187959..9fa49d6c9 100644 --- a/packages/connect-web/browserstack/README.md +++ b/packages/connect-web/browserstack/README.md @@ -1,11 +1,11 @@ # Connect-Web Browserstack Tests -This directory provides cross-browser test coverage for @connectrpc/connect-web with Browserstack +This directory provides cross-browser test coverage for @connectrpc/connect-web with Browserstack by running a few select tests on old browsers. Thanks to Browserstack for the sponsorship! To run these tests locally, you need to sign up on [Browserstack](https://www.browserstack.com/) and provide your username and access key: ```bash -BROWSERSTACK_USERNAME= BROWSERSTACK_ACCESS_KEY= make testwebbrowserstack +BROWSERSTACK_USERNAME= BROWSERSTACK_ACCESS_KEY= npx turbo run test-browserstack ``` diff --git a/packages/connect-web/conformance/README.md b/packages/connect-web/conformance/README.md index 311a72da4..4997b59f9 100644 --- a/packages/connect-web/conformance/README.md +++ b/packages/connect-web/conformance/README.md @@ -8,25 +8,24 @@ It uses the [conformance runner](https://github.com/connectrpc/conformance/relea Tests run in the following environments: -* Chrome -* Firefox -* Safari (only if running in OSX. Safari requires users to enable the "Allow Remote Automation" option in Safari's Develop menu) -* Node.js +- Chrome +- Firefox +- Safari (only if running in OSX. Safari requires users to enable the "Allow Remote Automation" option in Safari's Develop menu) +- Node.js For every environment, two client flavors are available: -* Promise (using `createPromiseClient`) -* Callback (using `createCallbackClient`) -For every combination, an npm script is available: +- Promise (using `createPromiseClient`) +- Callback (using `createCallbackClient`) -`npm run conformance:client::` +For every combination, a task is available: -Before you run npm scripts, make sure to build dependencies with `make .tmp/build/connect-web`. +`npx turbo run conformance::` ## Using a local browser To launch a browser window with access to the browser's network inspector, append the `--openBrowser` flag to the npm script: ``` -npm run conformance:client:chrome:promise -- --openBrowser +npx turbo run conformance:chrome:promise -- --openBrowser ``` diff --git a/packages/connect-web/conformance/client.ts b/packages/connect-web/conformance/client.ts index 92a1d834e..b39c28250 100755 --- a/packages/connect-web/conformance/client.ts +++ b/packages/connect-web/conformance/client.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env -S npx tsx - // Copyright 2021-2024 The Connect Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/connect-web/conformance/transport.ts b/packages/connect-web/conformance/transport.ts index 97fcc7d07..0a57b0b21 100644 --- a/packages/connect-web/conformance/transport.ts +++ b/packages/connect-web/conformance/transport.ts @@ -16,7 +16,7 @@ import { createRegistry } from "@bufbuild/protobuf"; import { createConnectTransport, createGrpcWebTransport, -} from "@connectrpc/connect-web"; +} from "../src/index.js"; import { BidiStreamRequest, ClientCompatRequest, diff --git a/packages/connect-web/package.json b/packages/connect-web/package.json index 651668a60..8d49a71be 100644 --- a/packages/connect-web/package.json +++ b/packages/connect-web/package.json @@ -12,19 +12,23 @@ "build": "npm run build:cjs && npm run build:esm", "build:cjs": "tsc --project tsconfig.build.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", - "attw": "attw --pack", - "conformance:client:chrome:promise": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v -- ./conformance/client.ts --browser chrome", - "conformance:client:chrome:callback": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v --known-failing @./conformance/known-failing-callback-client.txt -- ./conformance/client.ts --browser chrome --useCallbackClient", - "conformance:client:firefox:promise": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v -- ./conformance/client.ts --browser firefox", - "conformance:client:firefox:callback": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v --known-failing @./conformance/known-failing-callback-client.txt -- ./conformance/client.ts --browser firefox --useCallbackClient", - "conformance:client:safari:promise": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v -- ./conformance/client.ts --browser safari", - "conformance:client:safari:callback": "connectconformance --mode client --conf ./conformance/conformance-web.yaml -v --known-failing @./conformance/known-failing-callback-client.txt -- ./conformance/client.ts --browser safari --useCallbackClient", - "conformance:client:node:promise": "connectconformance --mode client --conf ./conformance/conformance-web-node.yaml -v -- ./conformance/client.ts --browser node", - "conformance:client:node:callback": "connectconformance --mode client --conf ./conformance/conformance-web-node.yaml -v --known-failing @./conformance/known-failing-callback-client.txt -- ./conformance/client.ts --browser node --useCallbackClient", - "jasmine": "jasmine --config=jasmine.json", + "conformance:safari": "npm run conformance:safari:promise && npm run conformance:client:safari:callback", + "conformance:safari:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser safari", + "conformance:safari:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser safari --useCallbackClient", + "conformance:chrome:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser chrome", + "conformance:chrome:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser chrome --useCallbackClient", + "conformance:firefox:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser firefox", + "conformance:firefox:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser firefox --useCallbackClient", + "conformance:node:promise": "connectconformance --mode client --conf conformance/conformance-web-node.yaml -- tsx conformance/client.ts --browser node", + "conformance:node:callback": "connectconformance --mode client --conf conformance/conformance-web-node.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser node --useCallbackClient", + "test": "jasmine --config=jasmine.json", "generate": "buf generate --template browserstack/buf.gen.yaml", "postgenerate": "license-header browserstack/gen", - "karma:browserstack": "karma start browserstack/karma.browserstack.conf.cjs" + "test-browserstack": "karma start browserstack/karma.browserstack.conf.cjs", + "format": "prettier --write --ignore-unknown '.' '!dist' '!browserstack/gen'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", + "attw": "attw --pack" }, "type": "module", "sideEffects": false, diff --git a/packages/connect-web/tsconfig.json b/packages/connect-web/tsconfig.json index 1725882fe..6fc737680 100644 --- a/packages/connect-web/tsconfig.json +++ b/packages/connect-web/tsconfig.json @@ -1,4 +1,4 @@ { - "include": ["src/**/*.ts", "conformance/**/*.ts"], + "include": ["src/**/*.ts", "conformance/**/*.ts", "browserstack/**/*.ts"], "extends": "../../tsconfig.base.json" } diff --git a/packages/connect-web/turbo.json b/packages/connect-web/turbo.json new file mode 100644 index 000000000..c9bd0c466 --- /dev/null +++ b/packages/connect-web/turbo.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "generate": { + "outputs": ["browserstack/gen/**"] + }, + "test-browserstack": { + "cache": false, + "env": ["BROWSERSTACK_USERNAME", "BROWSERSTACK_ACCESS_KEY"], + "dependsOn": ["generate", "^build"] + }, + "conformance": { + "dependsOn": ["conformance:node:promise", "conformance:node:callback"] + }, + "conformance:safari": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:safari:promise": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:safari:callback": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:chrome:promise": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:chrome:callback": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:firefox:promise": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:firefox:callback": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:node:promise": { + "cache": false, + "dependsOn": ["^build"] + }, + "conformance:node:callback": { + "cache": false, + "dependsOn": ["^build"] + } + } +} diff --git a/packages/connect/README.md b/packages/connect/README.md index f60c32a77..e0e305435 100644 --- a/packages/connect/README.md +++ b/packages/connect/README.md @@ -4,7 +4,6 @@ Connect is a family of libraries for building type-safe APIs with different lang [@connectrpc/connect](https://www.npmjs.com/package/@connectrpc/connect) brings them to TypeScript, the web browser, and to Node.js. - With Connect, you define your schema first: ``` @@ -16,7 +15,7 @@ service ElizaService { And with the magic of code generation, this schema produces servers and clients: ```ts -const answer = await eliza.say({sentence: "I feel happy."}); +const answer = await eliza.say({ sentence: "I feel happy." }); console.log(answer); // {sentence: 'When you feel happy, what do you do?'} ``` @@ -40,7 +39,6 @@ gRPC and gRPC-web, and Connect's [own protocol](https://connectrpc.com/docs/prot optimized for the web. This gives you unparalleled interoperability with full-stack type-safety. - ## Get started on the web Follow our [10 minute tutorial](https://connectrpc.com/docs/web/getting-started) where @@ -53,7 +51,6 @@ We support all modern web browsers that implement the widely available [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and the [Encoding API](https://developer.mozilla.org/en-US/docs/Web/API/Encoding_API). - ## Get started on Node.js Follow our [10 minute tutorial](https://connectrpc.com/docs/node/getting-started) diff --git a/packages/connect/package.json b/packages/connect/package.json index 798876eeb..299fccbe4 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -15,7 +15,10 @@ "build": "npm run build:cjs && npm run build:esm && node scripts/update-user-agent.mjs", "build:cjs": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", "build:esm": "tsc --project tsconfig.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", - "jasmine": "jasmine --config=jasmine.json", + "test": "jasmine --config=jasmine.json", + "format": "prettier --write --ignore-unknown '.' '!dist' '!src/protocol-grpc/gen'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 .", "attw": "attw --pack" }, "type": "module", diff --git a/packages/connect/turbo.json b/packages/connect/turbo.json new file mode 100644 index 000000000..1f59c7cad --- /dev/null +++ b/packages/connect/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "generate": { + "outputs": ["src/protocol-grpc/gen/**"] + } + } +} diff --git a/packages/example/README.md b/packages/example/README.md index d066939d8..b839187ed 100644 --- a/packages/example/README.md +++ b/packages/example/README.md @@ -44,12 +44,11 @@ Once we have that out of the way, let's start the Connect server: npm start ``` -That's it! You should now be able to open a web browser to https://localhost:8443 and see the +That's it! You should now be able to open a web browser to https://localhost:8443 and see the example running locally. ![Screenshot](README.png) - ## Using Node.js as a client The file `src/client.ts` implements a CLI client that you can run in Node.js. @@ -87,7 +86,6 @@ npx buf curl --protocol grpc --schema . -d '{"name": "John"}' \ https://localhost:8443/connectrpc.eliza.v1.ElizaService/Introduce ``` - ## Generate code If you make changes to `eliza.proto`, make sure to re-generate the code. For example, you could rename a field, or diff --git a/packages/example/index.html b/packages/example/index.html index 9cd481ccd..58ac61af5 100644 --- a/packages/example/index.html +++ b/packages/example/index.html @@ -1,4 +1,4 @@ - + @@ -6,10 +6,10 @@ Connect-Web example -
-

Eliza

-
-
- +
+

Eliza

+
+
+ diff --git a/packages/example/package.json b/packages/example/package.json index e33b91d81..a3edc9446 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -3,10 +3,13 @@ "private": true, "type": "module", "scripts": { - "lint": "tsc --noEmit", + "build": "tsc --noEmit", "start": "tsx src/server.ts", "client": "tsx src/client.ts", - "generate": "buf generate" + "generate": "buf generate", + "format": "prettier --write --ignore-unknown '.' '!src/gen'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 ." }, "engines": { "node": ">=16" diff --git a/packages/example/src/client.ts b/packages/example/src/client.ts index 02172f7d1..a95fafbb0 100644 --- a/packages/example/src/client.ts +++ b/packages/example/src/client.ts @@ -15,7 +15,7 @@ import { createPromiseClient } from "@connectrpc/connect"; import { createConnectTransport } from "@connectrpc/connect-node"; import { ElizaService } from "./gen/eliza_connect.js"; -import { stdin, stdout, env } from "process"; +import { stdin, stdout, env } from "node:process"; import * as readline from "node:readline/promises"; const rl = readline.createInterface(stdin, stdout); diff --git a/packages/example/www/index.html b/packages/example/www/index.html index e358323a4..0b6ca3409 100644 --- a/packages/example/www/index.html +++ b/packages/example/www/index.html @@ -1,16 +1,16 @@ - + Connect-Web example - + -
-

Eliza

-
-
- +
+

Eliza

+
+
+ diff --git a/packages/protoc-gen-connect-es/README.md b/packages/protoc-gen-connect-es/README.md index b4db1e187..1d0019957 100644 --- a/packages/protoc-gen-connect-es/README.md +++ b/packages/protoc-gen-connect-es/README.md @@ -1,7 +1,7 @@ # @connectrpc/protoc-gen-connect-es The code generator for Connect, a simple library to work with servers and clients -in ECMAScript with the type-safety of TypeScript. It generates code that is compatible with +in ECMAScript with the type-safety of TypeScript. It generates code that is compatible with browsers and Node.js. Learn more about Connect at [github.com/connectrpc/connect-es](https://github.com/connectrpc/connect-es). @@ -33,7 +33,6 @@ We use peer dependencies to ensure that code generator and runtime library are compatible with each other. Note that npm installs them automatically, but yarn and pnpm do not. - ## Generating code ### With buf @@ -68,7 +67,6 @@ not just local protobuf files. For example, `npx buf generate buf.build/connectr generates code for the module [connectrpc/eliza](https://buf.build/connectrpc/eliza) on the Buf Schema Registry. - ### With protoc ```bash @@ -91,7 +89,6 @@ change the variable a bit: PATH=$(dirname $(yarn bin protoc-gen-es)):$(dirname $(yarn bin protoc-gen-connect-es)):$PATH ``` - ## Plugin options ### `target` @@ -100,6 +97,7 @@ This option controls whether the plugin generates JavaScript, TypeScript, or TypeScript declaration files. Possible values: + - `target=js` - generates a `_connect.js` file for every `.proto` input file. - `target=ts` - generates a `_connect.ts` file for every `.proto` input file. - `target=dts` - generates a `_connect.d.ts` file for every `.proto` input file. @@ -134,6 +132,7 @@ CommonJS is difficult to avoid, this option can be used to generate CommonJS `require()` calls. Possible values: + - `js_import_style=module` generate ECMAScript `import` / `export` statements - the default behavior. - `js_import_style=legacy_commonjs` generate CommonJS `require()` calls. @@ -153,10 +152,10 @@ By default, [protoc-gen-connect-es](https://www.npmjs.com/package/@connectrpc/pr (and all other plugins based on [@bufbuild/protoplugin](https://www.npmjs.com/package/@bufbuild/protoplugin)) generate an annotation at the top of each file: `// @ts-nocheck`. -We generate the annotation to support a wide range of compiler configurations -and future changes to the language. But there can be situations where the -annotation shadows an underlying problem, for example an unresolvable import. -To remove the annotation and to enable type checks, set the plugin option +We generate the annotation to support a wide range of compiler configurations +and future changes to the language. But there can be situations where the +annotation shadows an underlying problem, for example an unresolvable import. +To remove the annotation and to enable type checks, set the plugin option `ts_nocheck=false`. ## Example generated code @@ -191,6 +190,7 @@ message SayResponse { ``` `eliza_connect.ts` + ```ts /** * ElizaService provides a way to talk to Eliza, a port of the DOCTOR script @@ -216,6 +216,6 @@ export const ElizaService = { O: SayResponse, kind: MethodKind.Unary, }, - } + }, } as const; ``` diff --git a/packages/protoc-gen-connect-es/bin/protoc-gen-connect-es b/packages/protoc-gen-connect-es/bin/protoc-gen-connect-es index 1087fd8b8..9a6324f64 100755 --- a/packages/protoc-gen-connect-es/bin/protoc-gen-connect-es +++ b/packages/protoc-gen-connect-es/bin/protoc-gen-connect-es @@ -1,6 +1,8 @@ #!/usr/bin/env node -const {runNodeJs} = require("@bufbuild/protoplugin"); -const {protocGenConnectEs} = require("../dist/cjs/src/protoc-gen-connect-es-plugin.js"); +const { runNodeJs } = require("@bufbuild/protoplugin"); +const { + protocGenConnectEs, +} = require("../dist/cjs/src/protoc-gen-connect-es-plugin.js"); runNodeJs(protocGenConnectEs); diff --git a/packages/protoc-gen-connect-es/package.json b/packages/protoc-gen-connect-es/package.json index f8d0d1e05..92277f7ae 100644 --- a/packages/protoc-gen-connect-es/package.json +++ b/packages/protoc-gen-connect-es/package.json @@ -16,7 +16,10 @@ }, "scripts": { "prebuild": "rm -rf ./dist/*", - "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs" + "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs", + "format": "prettier --write --ignore-unknown '.' '!dist'", + "license-header": "license-header", + "lint": "eslint --max-warnings 0 ." }, "preferUnplugged": true, "dependencies": { diff --git a/packages/protoc-gen-connect-es/tsconfig.json b/packages/protoc-gen-connect-es/tsconfig.json index 85cbbc9df..3086186a0 100644 --- a/packages/protoc-gen-connect-es/tsconfig.json +++ b/packages/protoc-gen-connect-es/tsconfig.json @@ -2,6 +2,11 @@ "files": ["src/protoc-gen-connect-es-plugin.ts"], "extends": "../../tsconfig.base.json", "compilerOptions": { - "resolveJsonModule": true + // We import the plugin's version number from package.json + "resolveJsonModule": true, + // This package is CommonJS + "verbatimModuleSyntax": false, + "module": "CommonJS", + "moduleResolution": "Node10" } } diff --git a/packages/protoc-gen-connect-es/turbo.json b/packages/protoc-gen-connect-es/turbo.json new file mode 100644 index 000000000..fd0ee0db3 --- /dev/null +++ b/packages/protoc-gen-connect-es/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "lint": { + "dependsOn": ["format", "^build", "generate", "build"] + } + } +} diff --git a/turbo.json b/turbo.json new file mode 100644 index 000000000..1e315ea13 --- /dev/null +++ b/turbo.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build", "generate"], + "outputs": ["dist/**"] + }, + "generate": { + "dependsOn": ["^build"], + "outputs": ["src/gen/**"] + }, + "test": { + "dependsOn": ["build"], + "cache": false + }, + "conformance": { + "cache": false, + "dependsOn": ["^build"] + }, + "format": {}, + "license-header": { + "dependsOn": ["generate"] + }, + "lint": { + "dependsOn": ["format", "^build", "generate"] + }, + "attw": { + "dependsOn": ["build"] + }, + "//#format": { + "inputs": ["$TURBO_DEFAULT$", "!packages/**", "package-lock.json"] + }, + "//#license-header": { + "inputs": ["$TURBO_DEFAULT$", "!packages/**"] + }, + "//#lint": { + "dependsOn": ["format"], + "inputs": ["$TURBO_DEFAULT$", "!packages/**", "package-lock.json"] + } + } +} From 4422dda00743076ebb336112a9cb530254c841e5 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Tue, 3 Sep 2024 09:12:41 +0200 Subject: [PATCH 07/21] Fix flaky decompression error code (#1204) --- packages/connect-node/src/compression.ts | 37 ++++++++++-------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/packages/connect-node/src/compression.ts b/packages/connect-node/src/compression.ts index 242b26565..d30ddc64f 100644 --- a/packages/connect-node/src/compression.ts +++ b/packages/connect-node/src/compression.ts @@ -76,35 +76,30 @@ function wrapZLibErrors( readMaxBytes: number, ): Promise { return promise.catch((e) => { - const { code } = getNodeErrorProps(e); + const props = getNodeErrorProps(e); + let code = Code.Internal; + let message = "decompression failed"; // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check - switch (code) { + switch (props.code) { case "ERR_BUFFER_TOO_LARGE": - e = new ConnectError( - `message is larger than configured readMaxBytes ${readMaxBytes} after decompression`, - Code.ResourceExhausted, - ); + code = Code.ResourceExhausted; + message = `message is larger than configured readMaxBytes ${readMaxBytes} after decompression`; break; case "Z_DATA_ERROR": case "ERR_PADDING_2": - e = new ConnectError( - "decompression failed", - Code.InvalidArgument, - undefined, - undefined, - e, - ); + code = Code.InvalidArgument; break; default: - e = new ConnectError( - "decompression failed", - Code.Internal, - undefined, - undefined, - e, - ); + if ( + props.code !== undefined && + props.code.startsWith("ERR__ERROR_FORMAT_") + ) { + code = Code.InvalidArgument; + } break; } - return Promise.reject(e); + return Promise.reject( + new ConnectError(message, code, undefined, undefined, e), + ); }); } From e4422790f2b249403aef1d937282f99fc95a2ebc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:44:03 +0530 Subject: [PATCH 08/21] Bump wrangler from 3.68.0 to 3.73.0 (#1202) --- package-lock.json | 131 ++++++++++------------- packages/connect-cloudflare/package.json | 2 +- 2 files changed, 60 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8beed2294..28bf9d5f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -987,9 +987,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240725.0.tgz", - "integrity": "sha512-KpE7eycdZ9ON+tKBuTyqZh8SdFWHGrh2Ru9LcbpeFwb7O9gDQv9ceSdoV/T598qlT0a0yVKM62R6xa5ec0UOWA==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240821.1.tgz", + "integrity": "sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==", "cpu": [ "x64" ], @@ -1003,9 +1003,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240725.0.tgz", - "integrity": "sha512-/UQlI04FdXLpPlDzzsWGz8TuKrMZKLowTo+8PkxgEiWIaBhE4DIDM5bwj3jM4Bs8yOLiL2ovQNpld5CnAKqA8g==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240821.1.tgz", + "integrity": "sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==", "cpu": [ "arm64" ], @@ -1019,9 +1019,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240725.0.tgz", - "integrity": "sha512-Z5t12qYLvHz0b3ZRBBm2HQ93RiHrAnjFfdhtjMcgJypAGkiWpOCEn2xar/WqDhMfqnk0sa8aYiYAbMAlP1WN6w==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240821.1.tgz", + "integrity": "sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==", "cpu": [ "x64" ], @@ -1035,9 +1035,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240725.0.tgz", - "integrity": "sha512-j9gYXLOwOyNehLMzP7KxQ+Y6/nxcL9i6LTDJC6RChoaxLRbm0Y/9Otu+hfyzeNeRpt31ip6vqXZ1QQk6ygzI8A==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240821.1.tgz", + "integrity": "sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==", "cpu": [ "arm64" ], @@ -1051,9 +1051,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240725.0.tgz", - "integrity": "sha512-fkrJLWNN6rrPjZ0eKJx328NVMo4BsainKxAfqaPMEd6uRwjOM8uN8V4sSLsXXP8GQMAx6hAG2hU86givS4GItg==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240821.1.tgz", + "integrity": "sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==", "cpu": [ "x64" ], @@ -1066,6 +1066,15 @@ "node": ">=16" } }, + "node_modules/@cloudflare/workers-shared": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.4.1.tgz", + "integrity": "sha512-nYh4r8JwOOjYIdH2zub++CmIKlkYFlpxI1nBHimoiHcytJXD/b7ldJ21TtfzUZMCgI78mxVlymMHA/ReaOxKlA==", + "dev": true, + "engines": { + "node": ">=16.7.0" + } + }, "node_modules/@cloudflare/workers-types": { "version": "4.20240821.1", "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240821.1.tgz", @@ -3688,15 +3697,6 @@ "node": ">= 0.6" } }, - "node_modules/consola": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", - "dev": true, - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, "node_modules/content-disposition": { "version": "0.5.4", "dev": true, @@ -7594,9 +7594,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240725.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240725.0.tgz", - "integrity": "sha512-n9NTLI8J9Xt0Cls6dRpqoIPkVFnxD9gMnU/qDkDX9diKfN16HyxpAdA5mto/hKuRpjW19TxnTMcxBo90vZXemw==", + "version": "3.20240821.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240821.0.tgz", + "integrity": "sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -7607,7 +7607,7 @@ "glob-to-regexp": "^0.4.1", "stoppable": "^1.1.0", "undici": "^5.28.4", - "workerd": "1.20240725.0", + "workerd": "1.20240821.1", "ws": "^8.17.1", "youch": "^3.2.2", "zod": "^3.22.3" @@ -7845,12 +7845,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/node-fetch-native": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", - "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", - "dev": true - }, "node_modules/node-forge": { "version": "1.3.1", "dev": true, @@ -7971,6 +7965,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ohash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", + "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", + "dev": true + }, "node_modules/on-exit-leak-free": { "version": "2.1.2", "license": "MIT", @@ -10312,9 +10312,9 @@ } }, "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", "dev": true }, "node_modules/unbox-primitive": { @@ -10379,29 +10379,15 @@ }, "node_modules/unenv": { "name": "unenv-nightly", - "version": "1.10.0-1717606461.a117952", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-1.10.0-1717606461.a117952.tgz", - "integrity": "sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==", + "version": "2.0.0-1724863496.70db6f1", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-1724863496.70db6f1.tgz", + "integrity": "sha512-r+VIl1gnsI4WQxluruSQhy8alpAf1AsLRLm4sEKp3otCyTIVD6I6wHEYzeQnwsyWgaD4+3BD4A/eqrgOpdTzhw==", "dev": true, "dependencies": { - "consola": "^3.2.3", "defu": "^6.1.4", - "mime": "^3.0.0", - "node-fetch-native": "^1.6.4", + "ohash": "^1.1.3", "pathe": "^1.1.2", - "ufo": "^1.5.3" - } - }, - "node_modules/unenv/node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" + "ufo": "^1.5.4" } }, "node_modules/unicode-emoji-modifier-base": { @@ -10682,9 +10668,9 @@ } }, "node_modules/workerd": { - "version": "1.20240725.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240725.0.tgz", - "integrity": "sha512-VZwgejRcHsQ9FEPtc7v25ebINLAR+stL3q1hC1xByE+quskdoWpTXHkZwZ3IdSgvm9vPVbCbJw9p5mGnDByW2A==", + "version": "1.20240821.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240821.1.tgz", + "integrity": "sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==", "dev": true, "hasInstallScript": true, "bin": { @@ -10694,35 +10680,36 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20240725.0", - "@cloudflare/workerd-darwin-arm64": "1.20240725.0", - "@cloudflare/workerd-linux-64": "1.20240725.0", - "@cloudflare/workerd-linux-arm64": "1.20240725.0", - "@cloudflare/workerd-windows-64": "1.20240725.0" + "@cloudflare/workerd-darwin-64": "1.20240821.1", + "@cloudflare/workerd-darwin-arm64": "1.20240821.1", + "@cloudflare/workerd-linux-64": "1.20240821.1", + "@cloudflare/workerd-linux-arm64": "1.20240821.1", + "@cloudflare/workerd-windows-64": "1.20240821.1" } }, "node_modules/wrangler": { - "version": "3.68.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.68.0.tgz", - "integrity": "sha512-gsIeglkh5nOn1mHJs0bf1pOq/DvIt+umjO/5a867IYYXaN4j/ar5cRR1+F5ue3S7uEjYCLIZZjs8ESiPTSEt+Q==", + "version": "3.73.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.73.0.tgz", + "integrity": "sha512-VrdDR2OpvsCQp+r5Of3rDP1W64cNN/LHLVx1roULOlPS8PZiv7rUYgkwhdCQ61+HICAaeSxWYIzkL5+B9+8W3g==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", + "@cloudflare/workers-shared": "0.4.1", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "blake3-wasm": "^2.1.5", "chokidar": "^3.5.3", "date-fns": "^3.6.0", "esbuild": "0.17.19", - "miniflare": "3.20240725.0", + "miniflare": "3.20240821.0", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@1.10.0-1717606461.a117952", - "workerd": "1.20240725.0", + "unenv": "npm:unenv-nightly@2.0.0-1724863496.70db6f1", + "workerd": "1.20240821.1", "xxhash-wasm": "^1.0.1" }, "bin": { @@ -10736,7 +10723,7 @@ "fsevents": "~2.3.2" }, "peerDependencies": { - "@cloudflare/workers-types": "^4.20240725.0" + "@cloudflare/workers-types": "^4.20240821.1" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { @@ -11345,7 +11332,7 @@ "@cloudflare/workers-types": "^4.20240821.1", "@connectrpc/connect-conformance": "^1.4.0", "tsx": "^4.19.0", - "wrangler": "^3.68.0" + "wrangler": "^3.73.0" } }, "packages/connect-conformance": { diff --git a/packages/connect-cloudflare/package.json b/packages/connect-cloudflare/package.json index b9b14c7a2..0338f317f 100644 --- a/packages/connect-cloudflare/package.json +++ b/packages/connect-cloudflare/package.json @@ -16,7 +16,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20240821.1", - "wrangler": "^3.68.0", + "wrangler": "^3.73.0", "tsx": "^4.19.0", "@connectrpc/connect-conformance": "^1.4.0" } From d42cff57ee0c20bfbef2f279186bdcc235a2e348 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Tue, 3 Sep 2024 17:07:58 +0200 Subject: [PATCH 09/21] Fix Node.js v16 error responses on HTTP1.1 (#1206) Signed-off-by: Timo Stamm --- .github/workflows/conformance-express.yaml | 2 +- .github/workflows/conformance-fastify.yaml | 2 +- .github/workflows/conformance-node.yaml | 2 +- packages/connect-node/src/node-universal-handler.ts | 11 ++++++++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/conformance-express.yaml b/.github/workflows/conformance-express.yaml index 77533b0b0..ac331b543 100644 --- a/.github/workflows/conformance-express.yaml +++ b/.github/workflows/conformance-express.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0] + node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] name: "Node.js ${{ matrix.node-version }}" timeout-minutes: 10 steps: diff --git a/.github/workflows/conformance-fastify.yaml b/.github/workflows/conformance-fastify.yaml index cd903cb56..94e175429 100644 --- a/.github/workflows/conformance-fastify.yaml +++ b/.github/workflows/conformance-fastify.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0] + node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] name: "Node.js ${{ matrix.node-version }}" timeout-minutes: 10 steps: diff --git a/.github/workflows/conformance-node.yaml b/.github/workflows/conformance-node.yaml index bcec39217..110c6e5ca 100644 --- a/.github/workflows/conformance-node.yaml +++ b/.github/workflows/conformance-node.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0] + node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] side: [client, server] name: "Node.js ${{ matrix.node-version }} ${{ matrix.side }}" timeout-minutes: 10 diff --git a/packages/connect-node/src/node-universal-handler.ts b/packages/connect-node/src/node-universal-handler.ts index 2eb7230d4..15d9e027e 100644 --- a/packages/connect-node/src/node-universal-handler.ts +++ b/packages/connect-node/src/node-universal-handler.ts @@ -207,7 +207,16 @@ export async function universalResponseToNodeResponse( async function* asyncIterableFromNodeServerRequest( request: NodeServerRequest, ): AsyncIterable { - for await (const chunk of request) { + const it = request.iterator({ + // Node.js v16 closes request and response when this option isn't disabled. + // When one of our handlers receives invalid data (such as an unexpected + // compression flag in a streaming request), we're unable to write the error + // response. + // Later major versions have a more sensible behavior - we can revert this + // workaround once we stop supporting v16. + destroyOnReturn: false, + }); + for await (const chunk of it) { yield chunk; } } From e1e56133181db2a3e9c58b6ac117587ddad52283 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Wed, 4 Sep 2024 12:15:20 +0200 Subject: [PATCH 10/21] Update Node.js versions (#1207) --- .github/workflows/ci.yaml | 4 ++-- .github/workflows/conformance-express.yaml | 2 +- .github/workflows/conformance-fastify.yaml | 2 +- .github/workflows/conformance-node.yaml | 2 +- .github/workflows/conformance-web.yaml | 2 +- .nvmrc | 2 +- packages/connect-node/src/compression.spec.ts | 14 -------------- 7 files changed, 7 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 32191db28..1cb788112 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -60,7 +60,7 @@ jobs: # Node.js v16 does not provide all necessary fetch types by default, so # we cannot run tests for @connectrpc/connect-web. # v16 is tested in a separate job below. - node-version: [21.1.0, 20.9.0, 18.16.0] + node-version: [22.7.0, 20.17.0, 18.20.4] name: "test on Node.js ${{ matrix.node-version }}" steps: - uses: actions/checkout@v4 @@ -80,7 +80,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [16.20.0] + node-version: [16.20.2] name: "test on Node.js ${{ matrix.node-version }}" steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/conformance-express.yaml b/.github/workflows/conformance-express.yaml index ac331b543..1ffd8f0f8 100644 --- a/.github/workflows/conformance-express.yaml +++ b/.github/workflows/conformance-express.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] + node-version: [22.7.0, 20.17.0, 18.20.4, 16.20.2] name: "Node.js ${{ matrix.node-version }}" timeout-minutes: 10 steps: diff --git a/.github/workflows/conformance-fastify.yaml b/.github/workflows/conformance-fastify.yaml index 94e175429..7c4ae2fae 100644 --- a/.github/workflows/conformance-fastify.yaml +++ b/.github/workflows/conformance-fastify.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] + node-version: [22.7.0, 20.17.0, 18.20.4, 16.20.2] name: "Node.js ${{ matrix.node-version }}" timeout-minutes: 10 steps: diff --git a/.github/workflows/conformance-node.yaml b/.github/workflows/conformance-node.yaml index 110c6e5ca..90d32c286 100644 --- a/.github/workflows/conformance-node.yaml +++ b/.github/workflows/conformance-node.yaml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [21.1.0, 20.9.0, 18.16.0, 16.20.0] + node-version: [22.7.0, 20.17.0, 18.20.4, 16.20.2] side: [client, server] name: "Node.js ${{ matrix.node-version }} ${{ matrix.side }}" timeout-minutes: 10 diff --git a/.github/workflows/conformance-web.yaml b/.github/workflows/conformance-web.yaml index a0a1afa23..2d1562c45 100644 --- a/.github/workflows/conformance-web.yaml +++ b/.github/workflows/conformance-web.yaml @@ -47,7 +47,7 @@ jobs: strategy: matrix: # Node.js v16 does not provide all necessary fetch types by default - node-version: [21.1.0, 20.9.0, 18.16.0] + node-version: [22.7.0, 20.17.0, 18.20.4, 18.16.0] client: [promise, callback] name: "Node.js ${{ matrix.node-version }} ${{ matrix.client }}" timeout-minutes: 10 diff --git a/.nvmrc b/.nvmrc index f3f52b42d..3516580bb 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.9.0 +20.17.0 diff --git a/packages/connect-node/src/compression.spec.ts b/packages/connect-node/src/compression.spec.ts index 4aeaf65fd..618d7653b 100644 --- a/packages/connect-node/src/compression.spec.ts +++ b/packages/connect-node/src/compression.spec.ts @@ -69,20 +69,6 @@ describe("compression", () => { ); } }); - it("should raise internal error on excessive readMaxBytes", async () => { - try { - await compression.decompress( - new Uint8Array([0xde, 0xad, 0xbe, 0xef]), - Number.MAX_SAFE_INTEGER, - ); - fail("excepted an error"); - } catch (e) { - expect(e).toBeInstanceOf(ConnectError); - expect(ConnectError.from(e).message).toBe( - "[internal] decompression failed", - ); - } - }); }); } }); From 8eee2fa69a72c1ab3e94199817f8346ef889102c Mon Sep 17 00:00:00 2001 From: Sri Krishna <93153132+srikrsna-buf@users.noreply.github.com> Date: Wed, 4 Sep 2024 23:45:36 +0530 Subject: [PATCH 11/21] Fix gRPC trailers only response (#1209) Signed-off-by: Sri Krishna Paritala --- packages/connect/src/protocol-grpc/transport.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/connect/src/protocol-grpc/transport.ts b/packages/connect/src/protocol-grpc/transport.ts index 689bdf5c8..57d1662f1 100644 --- a/packages/connect/src/protocol-grpc/transport.ts +++ b/packages/connect/src/protocol-grpc/transport.ts @@ -147,6 +147,10 @@ export function createTransport(opt: CommonTransportOptions): Transport { ); validateTrailer(uRes.trailer, uRes.header); if (message === undefined) { + // Trailers only response + if (headerError) { + throw headerError; + } throw new ConnectError( "protocol error: missing output message for unary method", uRes.trailer.has(headerGrpcStatus) From 3a291fd4b2051298ca89d5b6b8bddadfef9e0265 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Thu, 5 Sep 2024 17:02:27 +0200 Subject: [PATCH 12/21] Rename argument for the sessionProvider option for the Node HTTP client (#1210) --- packages/connect-node/src/http2-session-manager.ts | 4 ++-- packages/connect-node/src/node-universal-client.ts | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/connect-node/src/http2-session-manager.ts b/packages/connect-node/src/http2-session-manager.ts index 258e42ca1..4341097f2 100644 --- a/packages/connect-node/src/http2-session-manager.ts +++ b/packages/connect-node/src/http2-session-manager.ts @@ -156,13 +156,13 @@ export class Http2SessionManager { private verifying: Promise | undefined; public constructor( - authority: URL | string, + url: URL | string, pingOptions?: Http2SessionOptions, http2SessionOptions?: | http2.ClientSessionOptions | http2.SecureClientSessionOptions, ) { - this.authority = new URL(authority).origin; + this.authority = new URL(url).origin; this.http2SessionOptions = http2SessionOptions; this.options = { pingIntervalMs: pingOptions?.pingIntervalMs ?? Number.POSITIVE_INFINITY, diff --git a/packages/connect-node/src/node-universal-client.ts b/packages/connect-node/src/node-universal-client.ts index 9df5260f6..0902de6a7 100644 --- a/packages/connect-node/src/node-universal-client.ts +++ b/packages/connect-node/src/node-universal-client.ts @@ -62,11 +62,11 @@ export type NodeHttpClientOptions = httpVersion: "2"; /** - * A function that must return a session manager for the given authority. + * A function that must return a session manager for the given URL. * The session manager may be taken from a pool. * By default, a new Http2SessionManager is created for every request. */ - sessionProvider?: (authority: string) => NodeHttp2ClientSessionManager; + sessionProvider?: (url: string) => NodeHttp2ClientSessionManager; }; /** @@ -80,8 +80,7 @@ export function createNodeHttpClient(options: NodeHttpClientOptions) { return createNodeHttp1Client(options.nodeOptions); } const sessionProvider = - options.sessionProvider ?? - ((authority: string) => new Http2SessionManager(authority)); + options.sessionProvider ?? ((url: string) => new Http2SessionManager(url)); return createNodeHttp2Client(sessionProvider); } @@ -169,7 +168,7 @@ function createNodeHttp1Client( * an UniversalClientResponse. */ function createNodeHttp2Client( - sessionProvider: (authority: string) => NodeHttp2ClientSessionManager, + sessionProvider: (url: string) => NodeHttp2ClientSessionManager, ): UniversalClientFn { return function request( req: UniversalClientRequest, From 32d7ada91cd31e63ffe26690431923a51ef39721 Mon Sep 17 00:00:00 2001 From: Sri Krishna <93153132+srikrsna-buf@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:42:17 +0530 Subject: [PATCH 13/21] Upgrade conformance tests to v1.0.3 (#1208) --- packages/connect-conformance/package.json | 2 +- .../src/callback-client.ts | 221 +++++------- .../connect-conformance/src/conformance.ts | 30 +- .../conformance/v1/client_compat_pb.ts | 36 +- .../connectrpc/conformance/v1/config_pb.ts | 5 +- .../connect-conformance/src/promise-client.ts | 323 ++++++------------ packages/connect-conformance/src/protocol.ts | 101 +++++- packages/connect-web-bench/README.md | 8 +- packages/connect-web-bench/chart.svg | 10 +- .../known-failing-callback-client.txt | 4 - packages/connect-web/package.json | 8 +- packages/connect-web/src/connect-transport.ts | 18 +- .../connect-web/src/grpc-web-transport.ts | 12 + 13 files changed, 370 insertions(+), 408 deletions(-) delete mode 100644 packages/connect-web/conformance/known-failing-callback-client.txt diff --git a/packages/connect-conformance/package.json b/packages/connect-conformance/package.json index cd39b6e41..8ef29c829 100644 --- a/packages/connect-conformance/package.json +++ b/packages/connect-conformance/package.json @@ -14,7 +14,7 @@ "connectconformance": "bin/connectconformance.cjs" }, "scripts": { - "generate": "buf generate buf.build/connectrpc/conformance:v1.0.2", + "generate": "buf generate buf.build/connectrpc/conformance:v1.0.3", "postgenerate": "license-header src/gen", "prebuild": "rm -rf ./dist/*", "build": "npm run build:cjs && npm run build:esm", diff --git a/packages/connect-conformance/src/callback-client.ts b/packages/connect-conformance/src/callback-client.ts index 92e09cdb0..25c3066ee 100644 --- a/packages/connect-conformance/src/callback-client.ts +++ b/packages/connect-conformance/src/callback-client.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createCallbackClient, ConnectError } from "@connectrpc/connect"; +import { createCallbackClient, ConnectError, Code } from "@connectrpc/connect"; import type { CallbackClient, Transport } from "@connectrpc/connect"; import { ClientCompatRequest, @@ -20,18 +20,18 @@ import { } from "./gen/connectrpc/conformance/v1/client_compat_pb.js"; import { UnaryRequest, - Header as ConformanceHeader, ServerStreamRequest, - ConformancePayload, UnimplementedRequest, IdempotentUnaryRequest, } from "./gen/connectrpc/conformance/v1/service_pb.js"; import { convertToProtoError, convertToProtoHeaders, - appendProtoHeaders, wait, getCancelTiming, + getRequestHeaders, + getSingleRequestMessage, + setClientErrorResult, } from "./protocol.js"; import { ConformanceService } from "./gen/connectrpc/conformance/v1/service_connect.js"; @@ -59,189 +59,138 @@ export function invokeWithCallbackClient( async function unary( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, idempotent: boolean = false, ) { - if (req.requestMessages.length !== 1) { - throw new Error("Unary method requires exactly one request message"); - } - const msg = req.requestMessages[0]; - const uReq = idempotent ? new IdempotentUnaryRequest() : new UnaryRequest(); - if (!msg.unpackTo(uReq)) { - throw new Error("Could not unpack request message to unary request"); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; - - let call = client.unary; - if (idempotent) { - call = client.idempotentUnary; - } - - await wait(req.requestDelayMs); + await wait(compatRequest.requestDelayMs); + const result = new ClientResponseResult(); return new Promise((resolve) => { - call( - uReq, - (err, uRes) => { + const call = idempotent ? client.idempotentUnary : client.unary; + let clientCancelled = false; + const clientCancelFn = call( + getSingleRequestMessage( + compatRequest, + idempotent ? IdempotentUnaryRequest : UnaryRequest, + ), + (err, response) => { + // Callback clients swallow client triggered cancellations and never + // call the callback. This will trigger the global error handler and + // fail the process. + if (clientCancelled) { + throw new Error("Aborted requests should not trigger the callback"); + } if (err !== undefined) { - error = ConnectError.from(err); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, err); } else { - payloads.push(uRes.payload!); + result.payloads.push(response.payload!); } - resolve( - new ClientResponseResult({ - payloads: payloads, - responseHeaders: resHeaders, - responseTrailers: resTrailers, - error: convertToProtoError(error), - }), - ); + resolve(result); }, { - headers: reqHeader, + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }, ); + const { afterCloseSendMs } = getCancelTiming(compatRequest); + if (afterCloseSendMs >= 0) { + setTimeout(() => { + clientCancelled = true; + clientCancelFn(); + // Callback clients swallow client triggered cancellations and never + // call the callback. We report a fake error to the test runner to let + // it know that the call was cancelled. + result.error = convertToProtoError( + new ConnectError("client cancelled", Code.Canceled), + ); + resolve(result); + }, afterCloseSendMs); + } }); } async function serverStream( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { - if (req.requestMessages.length !== 1) { - throw new Error("ServerStream method requires exactly one request message"); - } - const msg = req.requestMessages[0]; - const uReq = new ServerStreamRequest(); - if (!msg.unpackTo(uReq)) { - throw new Error( - "Could not unpack request message to server stream request", - ); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; - const cancelTiming = getCancelTiming(req); - let count = 0; - - await wait(req.requestDelayMs); + const cancelTiming = getCancelTiming(compatRequest); + await wait(compatRequest.requestDelayMs); + const result = new ClientResponseResult(); return new Promise((resolve) => { - const cancelFn = client.serverStream( - uReq, - (uResp) => { - if (cancelTiming.afterNumResponses === 0) { - cancelFn(); - } - payloads.push(uResp.payload!); - count++; - if (count === cancelTiming.afterNumResponses) { - cancelFn(); + let clientCancelled = false; + const clientCancelFn = client.serverStream( + getSingleRequestMessage(compatRequest, ServerStreamRequest), + (response) => { + result.payloads.push(response.payload!); + if (result.payloads.length === cancelTiming.afterNumResponses) { + clientCancelled = true; + clientCancelFn(); } }, (err) => { + // Callback clients call the closeCallback without an error for client + // triggered cancellation. We report a fake error to the test runner to let + // it know that the call was cancelled. + if (clientCancelled) { + if (err !== undefined) { + throw new Error( + "Aborted requests should not trigger the closeCallback with an error", + ); + } + result.error = convertToProtoError( + new ConnectError("client cancelled", Code.Canceled), + ); + } if (err !== undefined) { - error = ConnectError.from(err); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, err); } - resolve( - new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - payloads: payloads, - error: convertToProtoError(error), - }), - ); + resolve(result); }, { - headers: reqHeader, + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }, ); + if (cancelTiming.afterCloseSendMs >= 0) { + setTimeout(() => { + clientCancelled = true; + clientCancelFn(); + }, cancelTiming.afterCloseSendMs); + } }); } async function unimplemented( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { - const msg = req.requestMessages[0]; - const unReq = new UnimplementedRequest(); - if (!msg.unpackTo(unReq)) { - throw new Error("Could not unpack request message to unary request"); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - + const result = new ClientResponseResult(); return new Promise((resolve) => { client.unimplemented( - unReq, + getSingleRequestMessage(compatRequest, UnimplementedRequest), // eslint-disable-next-line @typescript-eslint/no-unused-vars (err, _) => { if (err !== undefined) { - error = ConnectError.from(err); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, err); } - resolve( - new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - error: convertToProtoError(error), - }), - ); + resolve(result); }, { - headers: reqHeader, + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }, ); diff --git a/packages/connect-conformance/src/conformance.ts b/packages/connect-conformance/src/conformance.ts index 4df4ce74a..6854c7300 100644 --- a/packages/connect-conformance/src/conformance.ts +++ b/packages/connect-conformance/src/conformance.ts @@ -29,20 +29,18 @@ import { execFileSync } from "node:child_process"; import { fetch } from "undici"; import { scripts } from "../package.json"; -// Extract conformance runner version from the `generate` script -const [, version] = /conformance:(v\d+\.\d+\.\d+)/.exec(scripts.generate) ?? [ - "?", -]; - -const downloadUrl = `https://github.com/connectrpc/conformance/releases/download/${version}`; - export async function run() { - const { archive, bin } = getArtifactNameForEnv(); - const tempDir = getTempDir(); + // Extract conformance runner version from the `generate` script + const [, version] = /conformance:(v\d+\.\d+\.\d+)/.exec(scripts.generate) ?? [ + "?", + ]; + const { archive, bin } = getArtifactNameForEnv(version); + const tempDir = getTempDir(version); const binPath = joinPath(tempDir, bin); if (!existsSync(binPath)) { + const downloadUrl = `https://github.com/connectrpc/conformance/releases/download/${version}/${archive}`; const archivePath = joinPath(tempDir, archive); - await download(`${downloadUrl}/${archive}`, archivePath); + await download(downloadUrl, archivePath); await extractBin(archivePath, binPath); } execFileSync(binPath, process.argv.slice(2), { @@ -101,15 +99,21 @@ async function extractBin(archivePath: string, binPath: string) { ); } -function getTempDir() { - const tempDir = joinPath(process.env["TEMP"] ?? os.tmpdir(), "conformance"); +function getTempDir(version: string) { + const tempDir = joinPath( + process.env["TEMP"] ?? os.tmpdir(), + `conformance-${version}`, + ); if (!existsSync(tempDir)) { mkdirSync(tempDir, { recursive: true }); } return tempDir; } -function getArtifactNameForEnv(): { archive: string; bin: string } { +function getArtifactNameForEnv(version: string): { + archive: string; + bin: string; +} { let build = ""; let ext = ".tar.gz"; let bin = "connectconformance"; diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts index 52a020e15..cbf06a717 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/client_compat_pb.ts @@ -131,7 +131,8 @@ export class ClientCompatRequest extends Message { method?: string; /** - * The stream type of `method` (i.e. Unary, Client-Streaming, Server-Streaming, Full Duplex Bidi, or Half Duplex Bidi). + * The stream type of `method` (i.e. unary, client stream, server stream, full-duplex bidi + * stream, or half-duplex bidi stream). * When writing test cases, this is a required field. * * @generated from field: connectrpc.conformance.v1.StreamType stream_type = 13; @@ -161,9 +162,9 @@ export class ClientCompatRequest extends Message { * The actual request messages that will sent to the server. * The type URL for all entries should be equal to the request type of the * method. - * There must be exactly one for unary and server-stream methods but - * can be zero or more for client- and bidi-stream methods. - * For client- and bidi-stream methods, all entries will have the + * There must be exactly one for unary and server stream methods but + * can be zero or more for client and bidi stream methods. + * For client and bidi stream methods, all entries will have the * same type URL. * * @generated from field: repeated google.protobuf.Any request_messages = 16; @@ -180,7 +181,7 @@ export class ClientCompatRequest extends Message { /** * Wait this many milliseconds before sending a request message. - * For client- or bidi-streaming requests, this delay should be + * For client or bidi stream methods, this delay should be * applied before each request sent. * * @generated from field: uint32 request_delay_ms = 18; @@ -274,8 +275,9 @@ export class ClientCompatRequest_Cancel extends Message { /** * Servers should echo back payloads that they received as part of the request. * This field should contain all the payloads the server echoed back. Note that - * There will be zero-to-one for unary and client-stream methods and - * zero-to-many for server- and bidi-stream methods. + * There will be zero-to-one for unary and client stream methods and + * zero-to-many for server and bidi stream methods. * * @generated from field: repeated connectrpc.conformance.v1.ConformancePayload payloads = 2; */ diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts index fdc518fcb..8373d0234 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/config_pb.ts @@ -107,7 +107,10 @@ export enum Codec { JSON = 2, /** - * @generated from enum value: CODEC_TEXT = 3; + * not used; will be ignored + * + * @generated from enum value: CODEC_TEXT = 3 [deprecated = true]; + * @deprecated */ TEXT = 3, } diff --git a/packages/connect-conformance/src/promise-client.ts b/packages/connect-conformance/src/promise-client.ts index d437b8378..81f5a280d 100644 --- a/packages/connect-conformance/src/promise-client.ts +++ b/packages/connect-conformance/src/promise-client.ts @@ -12,28 +12,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createPromiseClient, ConnectError } from "@connectrpc/connect"; import type { PromiseClient, Transport } from "@connectrpc/connect"; +import { createPromiseClient } from "@connectrpc/connect"; import { ClientCompatRequest, ClientResponseResult, } from "./gen/connectrpc/conformance/v1/client_compat_pb.js"; import { - UnaryRequest, - Header as ConformanceHeader, + BidiStreamRequest, ClientStreamRequest, + IdempotentUnaryRequest, ServerStreamRequest, - ConformancePayload, - BidiStreamRequest, + UnaryRequest, UnimplementedRequest, - IdempotentUnaryRequest, } from "./gen/connectrpc/conformance/v1/service_pb.js"; import { - convertToProtoError, convertToProtoHeaders, - appendProtoHeaders, - wait, getCancelTiming, + getRequestHeaders, + getRequestMessages, + getSingleRequestMessage, + setClientErrorResult, + wait, } from "./protocol.js"; import { ConformanceService } from "./gen/connectrpc/conformance/v1/service_connect.js"; import { createWritableIterable } from "@connectrpc/connect/protocol"; @@ -43,172 +43,115 @@ type ConformanceClient = PromiseClient; export function invokeWithPromiseClient( transport: Transport, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { const client = createPromiseClient(ConformanceService, transport); - switch (req.method) { + switch (compatRequest.method) { case ConformanceService.methods.unary.name: - return unary(client, req); + return unary(client, compatRequest); case ConformanceService.methods.idempotentUnary.name: - return unary(client, req, true); + return unary(client, compatRequest, true); case ConformanceService.methods.serverStream.name: - return serverStream(client, req); + return serverStream(client, compatRequest); case ConformanceService.methods.clientStream.name: - return clientStream(client, req); + return clientStream(client, compatRequest); case ConformanceService.methods.bidiStream.name: - return bidiStream(client, req); + return bidiStream(client, compatRequest); case ConformanceService.methods.unimplemented.name: - return unimplemented(client, req); + return unimplemented(client, compatRequest); default: - throw new Error(`Unknown method: ${req.method}`); + throw new Error(`Unknown method: ${compatRequest.method}`); } } async function unary( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, idempotent: boolean = false, ) { - if (req.requestMessages.length !== 1) { - throw new Error("Unary method requires exactly one request message"); - } - const msg = req.requestMessages[0]; - const uReq = idempotent ? new IdempotentUnaryRequest() : new UnaryRequest(); - if (!msg.unpackTo(uReq)) { - throw new Error("Could not unpack request message to unary request"); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; + await wait(compatRequest.requestDelayMs); + const result = new ClientResponseResult(); try { - let call = client.unary; - if (idempotent) { - call = client.idempotentUnary; + const controller = new AbortController(); + const { afterCloseSendMs } = getCancelTiming(compatRequest); + if (afterCloseSendMs >= 0) { + void wait(afterCloseSendMs).then(() => controller.abort()); } - await wait(req.requestDelayMs); - const uRes = await call(uReq, { - headers: reqHeader, + const request = getSingleRequestMessage( + compatRequest, + idempotent ? IdempotentUnaryRequest : UnaryRequest, + ); + const call = idempotent ? client.idempotentUnary : client.unary; + const response = await call(request, { + headers: getRequestHeaders(compatRequest), + signal: controller.signal, onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }); - payloads.push(uRes.payload!); + result.payloads.push(response.payload!); } catch (e) { - error = ConnectError.from(e); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, e); } - return new ClientResponseResult({ - payloads: payloads, - responseHeaders: resHeaders, - responseTrailers: resTrailers, - error: convertToProtoError(error), - }); + return result; } async function serverStream( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { - if (req.requestMessages.length !== 1) { - throw new Error("ServerStream method requires exactly one request message"); - } - const msg = req.requestMessages[0]; - const uReq = new ServerStreamRequest(); - if (!msg.unpackTo(uReq)) { - throw new Error( - "Could not unpack request message to server stream request", - ); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; - const cancelTiming = getCancelTiming(req); + const cancelTiming = getCancelTiming(compatRequest); const controller = new AbortController(); + await wait(compatRequest.requestDelayMs); + const result = new ClientResponseResult(); + const request = getSingleRequestMessage(compatRequest, ServerStreamRequest); try { - await wait(req.requestDelayMs); - const res = client.serverStream(uReq, { - headers: reqHeader, + const res = client.serverStream(request, { + headers: getRequestHeaders(compatRequest), signal: controller.signal, onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }); - if (cancelTiming.afterNumResponses == 0) { + if (cancelTiming.afterCloseSendMs >= 0) { + await wait(cancelTiming.afterCloseSendMs); controller.abort(); } - let count = 0; for await (const msg of res) { - payloads.push(msg.payload!); - count++; - if (count === cancelTiming.afterNumResponses) { + result.payloads.push(msg.payload!); + if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } } } catch (e) { - error = ConnectError.from(e); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, e); } - return new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - payloads: payloads, - error: convertToProtoError(error), - }); + return result; } async function clientStream( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { - const reqHeaders = new Headers(); - appendProtoHeaders(reqHeaders, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; - const cancelTiming = getCancelTiming(req); + const cancelTiming = getCancelTiming(compatRequest); const controller = new AbortController(); + const result = new ClientResponseResult(); try { - const csRes = await client.clientStream( + const response = await client.clientStream( (async function* () { - for (const msg of req.requestMessages) { - const csReq = new ClientStreamRequest(); - if (!msg.unpackTo(csReq)) { - throw new Error( - "Could not unpack request message to client stream request", - ); - } - await wait(req.requestDelayMs); - yield csReq; + for (const msg of getRequestMessages( + compatRequest, + ClientStreamRequest, + )) { + await wait(compatRequest.requestDelayMs); + yield msg; } if (cancelTiming.beforeCloseSend !== undefined) { controller.abort(); @@ -220,87 +163,63 @@ async function clientStream( })(), { signal: controller.signal, - headers: reqHeaders, + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }, ); - payloads.push(csRes.payload!); + result.payloads.push(response.payload!); } catch (e) { - error = ConnectError.from(e); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, e); } - return new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - payloads: payloads, - error: convertToProtoError(error), - }); + return result; } -async function bidiStream(client: ConformanceClient, req: ClientCompatRequest) { - const reqHeaders = new Headers(); - appendProtoHeaders(reqHeaders, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; - const payloads: ConformancePayload[] = []; - const cancelTiming = getCancelTiming(req); +async function bidiStream( + client: ConformanceClient, + compatRequest: ClientCompatRequest, +) { + const cancelTiming = getCancelTiming(compatRequest); const controller = new AbortController(); - let recvCount = 0; + const result = new ClientResponseResult(); try { - const reqIt = createWritableIterable(); - const sRes = client.bidiStream(reqIt, { + const request = createWritableIterable(); + const responses = client.bidiStream(request, { signal: controller.signal, - headers: reqHeaders, + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }); - const resIt = sRes[Symbol.asyncIterator](); - for (const msg of req.requestMessages) { - const bdReq = new BidiStreamRequest(); - if (!msg.unpackTo(bdReq)) { - throw new Error( - "Could not unpack request message to client stream request", - ); - } - await wait(req.requestDelayMs); - await reqIt.write(bdReq); - if (req.streamType === StreamType.FULL_DUPLEX_BIDI_STREAM) { + const responseIterator = responses[Symbol.asyncIterator](); + for (const msg of getRequestMessages(compatRequest, BidiStreamRequest)) { + await wait(compatRequest.requestDelayMs); + await request.write(msg); + if (compatRequest.streamType === StreamType.FULL_DUPLEX_BIDI_STREAM) { if (cancelTiming.afterNumResponses === 0) { controller.abort(); } - const next = await resIt.next(); + const next = await responseIterator.next(); if (next.done === true) { continue; } - recvCount++; - if (cancelTiming.afterNumResponses === recvCount) { + result.payloads.push(next.value.payload!); + if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } - payloads.push(next.value.payload!); } } if (cancelTiming.beforeCloseSend !== undefined) { controller.abort(); } - reqIt.close(); + request.close(); if (cancelTiming.afterCloseSendMs >= 0) { setTimeout(() => { controller.abort(); @@ -311,75 +230,39 @@ async function bidiStream(client: ConformanceClient, req: ClientCompatRequest) { } // Drain the response iterator for (;;) { - const next = await resIt.next(); + const next = await responseIterator.next(); if (next.done === true) { break; } - recvCount++; - if (cancelTiming.afterNumResponses === recvCount) { + result.payloads.push(next.value.payload!); + if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } - payloads.push(next.value.payload!); } } catch (e) { - error = ConnectError.from(e); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, e); } - return new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - payloads: payloads, - error: convertToProtoError(error), - }); + return result; } async function unimplemented( client: ConformanceClient, - req: ClientCompatRequest, + compatRequest: ClientCompatRequest, ) { - const msg = req.requestMessages[0]; - const unReq = new UnimplementedRequest(); - if (!msg.unpackTo(unReq)) { - throw new Error("Could not unpack request message to unary request"); - } - const reqHeader = new Headers(); - appendProtoHeaders(reqHeader, req.requestHeaders); - let error: ConnectError | undefined = undefined; - let resHeaders: ConformanceHeader[] = []; - let resTrailers: ConformanceHeader[] = []; + const request = getSingleRequestMessage(compatRequest, UnimplementedRequest); + const result = new ClientResponseResult(); try { - await client.unimplemented(unReq, { - headers: reqHeader, + await client.unimplemented(request, { + headers: getRequestHeaders(compatRequest), onHeader(headers) { - resHeaders = convertToProtoHeaders(headers); + result.responseHeaders = convertToProtoHeaders(headers); }, onTrailer(trailers) { - resTrailers = convertToProtoHeaders(trailers); + result.responseTrailers = convertToProtoHeaders(trailers); }, }); } catch (e) { - error = ConnectError.from(e); - // We can't distinguish between headers and trailers here, so we just - // add the metadata to both. - // - // But if the headers are already set, we don't need to overwrite them. - resHeaders = - resHeaders.length === 0 - ? convertToProtoHeaders(error.metadata) - : resHeaders; - resTrailers = convertToProtoHeaders(error.metadata); + setClientErrorResult(result, e); } - return new ClientResponseResult({ - responseHeaders: resHeaders, - responseTrailers: resTrailers, - error: convertToProtoError(error), - }); + return result; } diff --git a/packages/connect-conformance/src/protocol.ts b/packages/connect-conformance/src/protocol.ts index 92e479943..64cec6eac 100644 --- a/packages/connect-conformance/src/protocol.ts +++ b/packages/connect-conformance/src/protocol.ts @@ -12,39 +12,120 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { ConnectError, Code } from "@connectrpc/connect"; -import { createRegistry, Any, Message } from "@bufbuild/protobuf"; +import { Code, ConnectError } from "@connectrpc/connect"; import { + Any, + createRegistry, + Message, + type MessageType, +} from "@bufbuild/protobuf"; +import { + ConformancePayload_RequestInfo, Error as ConformanceError, Header as ConformanceHeader, - ConformancePayload_RequestInfo, } from "./gen/connectrpc/conformance/v1/service_pb.js"; import { Code as ConformanceCode } from "./gen/connectrpc/conformance/v1/config_pb.js"; -import { ClientCompatRequest } from "./gen/connectrpc/conformance/v1/client_compat_pb.js"; +import { + ClientCompatRequest, + ClientResponseResult, +} from "./gen/connectrpc/conformance/v1/client_compat_pb.js"; -const detailsRegitry = createRegistry(ConformancePayload_RequestInfo); +const detailsRegistry = createRegistry(ConformancePayload_RequestInfo); -export function getCancelTiming(req: ClientCompatRequest) { +export function getCancelTiming(compatRequest: ClientCompatRequest) { const def = { beforeCloseSend: undefined, afterCloseSendMs: -1, afterNumResponses: -1, }; - switch (req.cancel?.cancelTiming.case) { + switch (compatRequest.cancel?.cancelTiming.case) { case "beforeCloseSend": return { ...def, beforeCloseSend: {} }; case "afterCloseSendMs": return { ...def, - afterCloseSendMs: req.cancel.cancelTiming.value, + afterCloseSendMs: compatRequest.cancel.cancelTiming.value, }; case "afterNumResponses": - return { ...def, afterNumResponses: req.cancel.cancelTiming.value }; + return { + ...def, + afterNumResponses: compatRequest.cancel.cancelTiming.value, + }; case undefined: return def; } } +/** + * Get the headers for a conformance client request. + */ +export function getRequestHeaders( + compatRequest: ClientCompatRequest, +): HeadersInit { + const headers = new Headers(); + appendProtoHeaders(headers, compatRequest.requestHeaders); + return headers; +} + +/** + * Get a single request message for a conformance client call. + */ +export function getSingleRequestMessage>( + compatRequest: ClientCompatRequest, + type: MessageType, +): T { + if (compatRequest.requestMessages.length !== 1) { + throw new Error( + `Expected exactly one request_message in ClientCompatRequest, found ${compatRequest.requestMessages.length}`, + ); + } + const any = compatRequest.requestMessages[0]; + const target = new type(); + if (!any.unpackTo(target)) { + throw new Error( + `Could not unpack request_message from ClientCompatRequest into ${type.typeName}`, + ); + } + return target; +} + +/** + * Get a request messages for a conformance client call. + */ +export function* getRequestMessages>( + compatRequest: ClientCompatRequest, + type: MessageType, +): Iterable { + for (const any of compatRequest.requestMessages) { + const target = new type(); + if (!any.unpackTo(target)) { + throw new Error( + `Could not unpack request_message from ClientCompatRequest into ${type.typeName}`, + ); + } + yield target; + } +} + +/** + * Record an error from a failed conformance client call in the result message. + */ +export function setClientErrorResult( + result: ClientResponseResult, + error: unknown, +): void { + const connectError = ConnectError.from(error); + result.error = convertToProtoError(connectError); + // We can't distinguish between headers and trailers here, so we just + // add the metadata to both. + // + // But if the headers are already set, we don't need to overwrite them. + if (result.responseHeaders.length === 0) { + result.responseHeaders = convertToProtoHeaders(connectError.metadata); + } + result.responseTrailers = convertToProtoHeaders(connectError.metadata); +} + export function connectErrorFromProto(err: ConformanceError) { // The ConnectError constructor accepts messages for details. // The conformance error details are the raw google.protobuf.Any messages. @@ -54,7 +135,7 @@ export function connectErrorFromProto(err: ConformanceError) { err.code as unknown as Code, undefined, err.details.map((d) => { - const m = d.unpack(detailsRegitry); + const m = d.unpack(detailsRegistry); if (m === undefined) { throw new Error(`Cannot unpack ${d.typeUrl}`); } diff --git a/packages/connect-web-bench/README.md b/packages/connect-web-bench/README.md index 2b5ddebfb..e340f0cd1 100644 --- a/packages/connect-web-bench/README.md +++ b/packages/connect-web-bench/README.md @@ -15,10 +15,10 @@ usually do. We repeat this for an increasing number of RPCs. | code generator | RPCs | bundle size | minified | compressed | | -------------- | ---: | ----------: | --------: | ---------: | -| Connect-ES | 1 | 152,643 b | 66,478 b | 16,380 b | -| Connect-ES | 4 | 168,085 b | 72,418 b | 16,852 b | -| Connect-ES | 8 | 193,398 b | 82,142 b | 17,475 b | -| Connect-ES | 16 | 227,037 b | 96,408 b | 18,237 b | +| Connect-ES | 1 | 152,759 b | 66,533 b | 16,438 b | +| Connect-ES | 4 | 168,201 b | 72,473 b | 16,896 b | +| Connect-ES | 8 | 193,514 b | 82,198 b | 17,477 b | +| Connect-ES | 16 | 227,153 b | 96,461 b | 18,226 b | | gRPC-Web | 1 | 876,563 b | 548,495 b | 52,300 b | | gRPC-Web | 4 | 928,964 b | 580,477 b | 54,673 b | | gRPC-Web | 8 | 1,004,833 b | 628,223 b | 57,118 b | diff --git a/packages/connect-web-bench/chart.svg b/packages/connect-web-bench/chart.svg index 287b9d8aa..7b6c13018 100644 --- a/packages/connect-web-bench/chart.svg +++ b/packages/connect-web-bench/chart.svg @@ -42,13 +42,13 @@ 0 KiB - + Connect-ES -Connect-ES 16 KiB for 1 RPCs -Connect-ES 16.46 KiB for 4 RPCs -Connect-ES 17.07 KiB for 8 RPCs -Connect-ES 17.81 KiB for 16 RPCs +Connect-ES 16.05 KiB for 1 RPCs +Connect-ES 16.5 KiB for 4 RPCs +Connect-ES 17.07 KiB for 8 RPCs +Connect-ES 17.8 KiB for 16 RPCs diff --git a/packages/connect-web/conformance/known-failing-callback-client.txt b/packages/connect-web/conformance/known-failing-callback-client.txt deleted file mode 100644 index 032ad2d5d..000000000 --- a/packages/connect-web/conformance/known-failing-callback-client.txt +++ /dev/null @@ -1,4 +0,0 @@ -# The callback client does not pass a cancelled error to the end-of-stream callback for cancellations. This is intentional behavior as it is the user's -# responsibility to handle this on the client side. -**/server-stream/cancel-after-zero-responses -**/server-stream/cancel-after-responses diff --git a/packages/connect-web/package.json b/packages/connect-web/package.json index 8d49a71be..c92e5f07b 100644 --- a/packages/connect-web/package.json +++ b/packages/connect-web/package.json @@ -14,13 +14,13 @@ "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationDir ./dist/esm", "conformance:safari": "npm run conformance:safari:promise && npm run conformance:client:safari:callback", "conformance:safari:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser safari", - "conformance:safari:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser safari --useCallbackClient", + "conformance:safari:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser safari --useCallbackClient", "conformance:chrome:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser chrome", - "conformance:chrome:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser chrome --useCallbackClient", + "conformance:chrome:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser chrome --useCallbackClient", "conformance:firefox:promise": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser firefox", - "conformance:firefox:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser firefox --useCallbackClient", + "conformance:firefox:callback": "connectconformance --mode client --conf conformance/conformance-web.yaml -- tsx conformance/client.ts --browser firefox --useCallbackClient", "conformance:node:promise": "connectconformance --mode client --conf conformance/conformance-web-node.yaml -- tsx conformance/client.ts --browser node", - "conformance:node:callback": "connectconformance --mode client --conf conformance/conformance-web-node.yaml --known-failing @conformance/known-failing-callback-client.txt -- tsx conformance/client.ts --browser node --useCallbackClient", + "conformance:node:callback": "connectconformance --mode client --conf conformance/conformance-web-node.yaml -- tsx conformance/client.ts --browser node --useCallbackClient", "test": "jasmine --config=jasmine.json", "generate": "buf generate --template browserstack/buf.gen.yaml", "postgenerate": "license-header browserstack/gen", diff --git a/packages/connect-web/src/connect-transport.ts b/packages/connect-web/src/connect-transport.ts index 3e27ce6ec..2d097cac9 100644 --- a/packages/connect-web/src/connect-transport.ts +++ b/packages/connect-web/src/connect-transport.ts @@ -266,6 +266,7 @@ export function createConnectTransport( body: ReadableStream, trailerTarget: Headers, header: Headers, + signal: AbortSignal, ) { const reader = createEnvelopeReadableStream(body).getReader(); let endStreamReceived = false; @@ -298,6 +299,16 @@ export function createConnectTransport( } yield parse(data); } + // Node wil not throw an AbortError on `read` if the + // signal is aborted before `getReader` is called. + // As a work around we check at the end and throw. + // + // Ref: https://github.com/nodejs/undici/issues/1940 + if ("throwIfAborted" in signal) { + // We assume that implementations without `throwIfAborted` (old + // browsers) do honor aborted signals on `read`. + signal.throwIfAborted(); + } if (!endStreamReceived) { throw "missing EndStreamResponse"; } @@ -369,7 +380,12 @@ export function createConnectTransport( ...req, header: fRes.headers, trailer, - message: parseResponseBody(fRes.body, trailer, fRes.headers), + message: parseResponseBody( + fRes.body, + trailer, + fRes.headers, + req.signal, + ), }; return res; }, diff --git a/packages/connect-web/src/grpc-web-transport.ts b/packages/connect-web/src/grpc-web-transport.ts index 350961603..cfec08940 100644 --- a/packages/connect-web/src/grpc-web-transport.ts +++ b/packages/connect-web/src/grpc-web-transport.ts @@ -275,6 +275,7 @@ export function createGrpcWebTransport( trailerTarget: Headers, header: Headers, headerError: ConnectError | undefined, + signal: AbortSignal, ) { const reader = createEnvelopeReadableStream(body).getReader(); if (foundStatus) { @@ -314,6 +315,16 @@ export function createGrpcWebTransport( yield parse(data); continue; } + // Node wil not throw an AbortError on `read` if the + // signal is aborted before `getReader` is called. + // As a work around we check at the end and throw. + // + // Ref: https://github.com/nodejs/undici/issues/1940 + if ("throwIfAborted" in signal) { + // We assume that implementations without `throwIfAborted` (old + // browsers) do honor aborted signals on `read`. + signal.throwIfAborted(); + } if (!trailerReceived) { if (headerError) { throw headerError; @@ -388,6 +399,7 @@ export function createGrpcWebTransport( trailer, fRes.headers, headerError, + req.signal, ), }; return res; From 575bd8508b2d0ed5f4ecabdc82bacd284478b07e Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Mon, 9 Sep 2024 08:06:15 +0200 Subject: [PATCH 14/21] Allow cloudflare environment variables in CI (#1214) Signed-off-by: Timo Stamm --- packages/connect-cloudflare/turbo.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/connect-cloudflare/turbo.json b/packages/connect-cloudflare/turbo.json index 0c8092c4b..d18ba31c8 100644 --- a/packages/connect-cloudflare/turbo.json +++ b/packages/connect-cloudflare/turbo.json @@ -2,7 +2,15 @@ "$schema": "https://turbo.build/schema.json", "extends": ["//"], "tasks": { - "conformance:client": { "cache": false, "dependsOn": ["^build"] }, - "conformance:server": { "cache": false, "dependsOn": ["^build"] } + "conformance:client": { + "cache": false, + "dependsOn": ["^build"], + "env": ["CLOUDFLARE_*"] + }, + "conformance:server": { + "cache": false, + "dependsOn": ["^build"], + "env": ["CLOUDFLARE_*"] + } } } From 3a67300c2089ef47c7d5bc266f24a957f2e1e9c3 Mon Sep 17 00:00:00 2001 From: Sri Krishna <93153132+srikrsna-buf@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:31:51 +0530 Subject: [PATCH 15/21] Fix signal in handler always aborted in HTTP/1.1 (#1218) Signed-off-by: Sri Krishna Paritala --- .../src/express-connect-middleware.ts | 1 + .../src/fastify-connect-plugin.ts | 1 + .../src/connect-nextjs-adapter.ts | 1 + .../connect-node/src/connect-node-adapter.ts | 1 + .../src/node-universal-handler.spec.ts | 54 +++++++++++++++++-- .../src/node-universal-handler.ts | 48 +++++++++++++++-- 6 files changed, 98 insertions(+), 8 deletions(-) diff --git a/packages/connect-express/src/express-connect-middleware.ts b/packages/connect-express/src/express-connect-middleware.ts index f01c5dbe3..df05dfb18 100644 --- a/packages/connect-express/src/express-connect-middleware.ts +++ b/packages/connect-express/src/express-connect-middleware.ts @@ -87,6 +87,7 @@ export function expressConnectMiddleware( } const uReq = universalRequestFromNodeRequest( req, + res, getPreparsedBody(req), options.contextValues?.(req), ); diff --git a/packages/connect-fastify/src/fastify-connect-plugin.ts b/packages/connect-fastify/src/fastify-connect-plugin.ts index c75b2763d..a2c45acfc 100644 --- a/packages/connect-fastify/src/fastify-connect-plugin.ts +++ b/packages/connect-fastify/src/fastify-connect-plugin.ts @@ -115,6 +115,7 @@ export function fastifyConnectPlugin( const uRes = await uHandler( universalRequestFromNodeRequest( req.raw, + reply.raw, req.body as JsonValue | undefined, opts.contextValues?.(req), ), diff --git a/packages/connect-next/src/connect-nextjs-adapter.ts b/packages/connect-next/src/connect-nextjs-adapter.ts index d5618225a..2fe6d1463 100644 --- a/packages/connect-next/src/connect-nextjs-adapter.ts +++ b/packages/connect-next/src/connect-nextjs-adapter.ts @@ -95,6 +95,7 @@ export function nextJsApiRouter(options: NextJsApiRouterOptions): ApiRoute { const uRes = await uHandler( universalRequestFromNodeRequest( req, + res, req.body as JsonValue | undefined, options.contextValues?.(req), ), diff --git a/packages/connect-node/src/connect-node-adapter.ts b/packages/connect-node/src/connect-node-adapter.ts index 68a389bff..ec2394b17 100644 --- a/packages/connect-node/src/connect-node-adapter.ts +++ b/packages/connect-node/src/connect-node-adapter.ts @@ -96,6 +96,7 @@ export function connectNodeAdapter( } const uReq = universalRequestFromNodeRequest( req, + res, undefined, options.contextValues?.(req), ); diff --git a/packages/connect-node/src/node-universal-handler.spec.ts b/packages/connect-node/src/node-universal-handler.spec.ts index 47f35de7d..510fa8d3a 100644 --- a/packages/connect-node/src/node-universal-handler.spec.ts +++ b/packages/connect-node/src/node-universal-handler.spec.ts @@ -27,14 +27,15 @@ import type { UniversalServerRequest } from "@connectrpc/connect/protocol"; // Polyfill the Headers API for Node versions < 18 import "./node-headers-polyfill.js"; -describe("universalRequestFromNodeRequest()", function () { +describe("universalRequestFromNodeResponse()", function () { describe("with HTTP/2 stream closed with an RST code", function () { let serverRequest: UniversalServerRequest | undefined; const server = useNodeServer(() => { serverRequest = undefined; - return http2.createServer(function (request) { + return http2.createServer(function (request, response) { serverRequest = universalRequestFromNodeRequest( request, + response, undefined, undefined, ); @@ -176,9 +177,10 @@ describe("universalRequestFromNodeRequest()", function () { connectionsCheckingInterval: 1, requestTimeout: 0, }, - function (request) { + function (request, response) { serverRequest = universalRequestFromNodeRequest( request, + response, undefined, undefined, ); @@ -269,6 +271,7 @@ describe("universalRequestFromNodeRequest()", function () { function (request, response) { serverRequest = universalRequestFromNodeRequest( request, + response, undefined, undefined, ); @@ -322,4 +325,49 @@ describe("universalRequestFromNodeRequest()", function () { } }); }); + describe("with HTTP/1.1", function () { + let serverRequest: UniversalServerRequest | undefined; + let serverNodeResponse: + | http.ServerResponse + | undefined; + const server = useNodeServer(() => + http.createServer(function (request, response) { + serverRequest = universalRequestFromNodeRequest( + request, + response, + undefined, + undefined, + ); + response.on("error", fail); + serverNodeResponse = response; + void readAllBytes( + serverRequest.body as AsyncIterable, + Number.MAX_SAFE_INTEGER, + ).then(() => { + response.writeHead(200); + response.flushHeaders(); + }); + }), + ); + it("signal should not be aborted on start", async function () { + await new Promise((resolve) => { + const request = http.request(server.getUrl(), { + method: "POST", + // close TCP connection after we're done so that the server shuts down cleanly + agent: new http.Agent({ keepAlive: false }), + }); + request.on("error", fail); + request.flushHeaders(); + request.end(); + request.on("response", (response) => { + expect(serverRequest).toBeDefined(); + expect(serverRequest?.signal.aborted).toBeFalse(); + serverNodeResponse?.end(); + void readAllBytes(response, Number.MAX_SAFE_INTEGER).then(() => + resolve(), + ); + }); + }); + }); + }); }); diff --git a/packages/connect-node/src/node-universal-handler.ts b/packages/connect-node/src/node-universal-handler.ts index 15d9e027e..997f8779f 100644 --- a/packages/connect-node/src/node-universal-handler.ts +++ b/packages/connect-node/src/node-universal-handler.ts @@ -66,16 +66,44 @@ export type NodeServerResponse = ( }; /** - * Converts a UniversalServerRequest to a Node.js server request. + * Converts a Node.js server request to a UniversalServerRequest. * This function helps to implement adapters to server frameworks running * on Node.js. Please be careful using this function in your own code, as we * may have to make changes to it in the future. */ +export function universalRequestFromNodeRequest( + nodeRequest: NodeServerRequest, + nodeResponse: NodeServerResponse, + parsedJsonBody: JsonValue | undefined, + contextValues: ContextValues | undefined, +): UniversalServerRequest; +/** + * @deprecated + */ export function universalRequestFromNodeRequest( nodeRequest: NodeServerRequest, parsedJsonBody: JsonValue | undefined, contextValues: ContextValues | undefined, +): UniversalServerRequest; +export function universalRequestFromNodeRequest( + nodeRequest: NodeServerRequest, + ...rest: + | [ + nodeResponse: NodeServerResponse, + parsedJsonBody: JsonValue | undefined, + contextValues: ContextValues | undefined, + ] + | [ + parsedJsonBody: JsonValue | undefined, + contextValues: ContextValues | undefined, + ] ): UniversalServerRequest { + const nodeResponse: NodeServerResponse | undefined = + rest.length === 3 ? rest[0] : undefined; + const parsedJsonBody: JsonValue | undefined = + rest.length === 3 ? rest[1] : rest[0]; + const contextValues: ContextValues | undefined = + rest.length === 3 ? rest[2] : rest[1]; const encrypted = "encrypted" in nodeRequest.socket && nodeRequest.socket.encrypted; const protocol = encrypted ? "https" : "http"; @@ -107,18 +135,28 @@ export function universalRequestFromNodeRequest( }); } else { // HTTP/1.1 does not have error codes, but Node.js has ECONNRESET + const nodeResponsOrRequest = nodeResponse ?? nodeRequest; const onH1Error = (e: Error) => { nodeRequest.off("error", onH1Error); - nodeRequest.off("close", onH1Close); + nodeResponsOrRequest.off("close", onH1Close); abortController.abort(connectErrorFromNodeReason(e)); }; const onH1Close = () => { nodeRequest.off("error", onH1Error); - nodeRequest.off("close", onH1Close); - abortController.abort(); + nodeResponsOrRequest.off("close", onH1Close); + // When subscribed to the response, this can get called before "error" + abortController.abort( + nodeRequest.errored + ? connectErrorFromNodeReason(nodeRequest.errored) + : undefined, + ); }; nodeRequest.once("error", onH1Error); - nodeRequest.once("close", onH1Close); + // Node emits close on the request as soon as all data is read. + // We instead subscribe to the response (if available) + // + // Ref: https://github.com/nodejs/node/issues/40775 + nodeResponsOrRequest.once("close", onH1Close); } return { httpVersion: nodeRequest.httpVersion, From 6d375c1e05fb566108b5c82391ba400172359c8b Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Mon, 9 Sep 2024 17:14:03 +0200 Subject: [PATCH 16/21] Fix baseUrl without // mangling request URL on Node.js with HTTP/2 (#1220) --- packages/connect-node/src/node-universal-client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/connect-node/src/node-universal-client.ts b/packages/connect-node/src/node-universal-client.ts index 0902de6a7..10a64631d 100644 --- a/packages/connect-node/src/node-universal-client.ts +++ b/packages/connect-node/src/node-universal-client.ts @@ -280,7 +280,7 @@ function h2Request( options: Omit, onStream: (stream: http2.ClientHttp2Stream) => void, ): void { - const requestUrl = new URL(url, sm.authority); + const requestUrl = new URL(url); if (requestUrl.origin !== sm.authority) { const message = `cannot make a request to ${requestUrl.origin}: the http2 session is connected to ${sm.authority}`; sentinel.reject(new ConnectError(message, Code.Internal)); From ed63ceecfbf0188e709946b54e1ba3afdaba4972 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Mon, 9 Sep 2024 17:15:04 +0200 Subject: [PATCH 17/21] Respect headers from transport option `nodeOptions.headers` (#1219) --- .../connect-node/src/node-universal-client.ts | 3 +- .../src/node-universal-header.spec.ts | 21 ++++++ .../connect-node/src/node-universal-header.ts | 69 ++++++++++++------- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/packages/connect-node/src/node-universal-client.ts b/packages/connect-node/src/node-universal-client.ts index 10a64631d..46c754254 100644 --- a/packages/connect-node/src/node-universal-client.ts +++ b/packages/connect-node/src/node-universal-client.ts @@ -130,13 +130,12 @@ function createNodeHttp1Client( sentinel.catch((e) => { reject(e); }); - h1Request( sentinel, req.url, { ...httpOptions, - headers: webHeaderToNodeHeaders(req.header), + headers: webHeaderToNodeHeaders(req.header, httpOptions?.headers), method: req.method, }, (request) => { diff --git a/packages/connect-node/src/node-universal-header.spec.ts b/packages/connect-node/src/node-universal-header.spec.ts index 97829ee4f..b7c5a61ac 100644 --- a/packages/connect-node/src/node-universal-header.spec.ts +++ b/packages/connect-node/src/node-universal-header.spec.ts @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import * as http from "http"; import { nodeHeaderToWebHeader, webHeaderToNodeHeaders, @@ -124,4 +125,24 @@ describe("webHeaderToNodeHeaders()", function () { }); }); } + it("should accept default node headers", function () { + const nodeDefaults: http.OutgoingHttpHeaders = { + a: "a", + b: ["b1", "b2"], + c: 123, + }; + const webHeaders: HeadersInit = [ + ["b", "web"], + ["c", "456"], + ["d", "d1"], + ["d", "d2"], + ]; + const h = webHeaderToNodeHeaders(webHeaders, nodeDefaults); + expect(h).toEqual({ + a: "a", + b: ["b1", "b2", "web"], + c: ["123", "456"], + d: ["d1", "d2"], + }); + }); }); diff --git a/packages/connect-node/src/node-universal-header.ts b/packages/connect-node/src/node-universal-header.ts index a1deda65e..1f4ddf320 100644 --- a/packages/connect-node/src/node-universal-header.ts +++ b/packages/connect-node/src/node-universal-header.ts @@ -53,45 +53,66 @@ export function nodeHeaderToWebHeader( /** * Convert a fetch API Headers object to a Node.js headers object. + * + * Optionally accepts default Node.js headers. If provided, fetch API headers + * are appended to the defaults. The original defaults headers are not modified. */ export function webHeaderToNodeHeaders( headersInit: HeadersInit, + defaultNodeHeaders?: http.OutgoingHttpHeaders, ): http.OutgoingHttpHeaders; export function webHeaderToNodeHeaders( headersInit: HeadersInit | undefined, ): http.OutgoingHttpHeaders | undefined; export function webHeaderToNodeHeaders( headersInit: HeadersInit | undefined, + defaultNodeHeaders?: http.OutgoingHttpHeaders, ): http.OutgoingHttpHeaders | undefined { - if (headersInit === undefined) { + if (headersInit === undefined && defaultNodeHeaders === undefined) { return undefined; } const o = Object.create(null) as http.OutgoingHttpHeaders; - const append = (key: string, value: string): void => { - key = key.toLowerCase(); - const existing = o[key]; - if (typeof existing == "string") { - o[key] = [existing, value]; - } else if (Array.isArray(existing)) { - existing.push(value); - } else { - o[key] = value; - } - }; - if (Array.isArray(headersInit)) { - for (const [key, value] of headersInit) { - append(key, value); - } - } else if ("forEach" in headersInit) { - if (typeof headersInit.forEach == "function") { - headersInit.forEach((value, key) => { - append(key, value); - }); + if (defaultNodeHeaders !== undefined) { + for (const [key, value] of Object.entries(defaultNodeHeaders)) { + if (Array.isArray(value)) { + o[key] = value.concat(); + } else if (value !== undefined) { + o[key] = value; + } } - } else { - for (const [key, value] of Object.entries(headersInit)) { - append(key, value); + } + if (headersInit !== undefined) { + if (Array.isArray(headersInit)) { + for (const [key, value] of headersInit) { + appendWebHeader(o, key, value); + } + } else if ("forEach" in headersInit) { + if (typeof headersInit.forEach == "function") { + headersInit.forEach((value, key) => { + appendWebHeader(o, key, value); + }); + } + } else { + for (const [key, value] of Object.entries(headersInit)) { + appendWebHeader(o, key, value); + } } } return o; } + +function appendWebHeader( + o: http.OutgoingHttpHeaders, + key: string, + value: string, +) { + key = key.toLowerCase(); + const existing = o[key]; + if (Array.isArray(existing)) { + existing.push(value); + } else if (existing === undefined) { + o[key] = value; + } else { + o[key] = [existing.toString(), value]; + } +} From 552d40bc52cf3c1aba38111075a0957899b2df33 Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Tue, 10 Sep 2024 17:53:25 +0200 Subject: [PATCH 18/21] Fix error detail debug property (#1221) --- packages/connect-conformance/src/callback-client.ts | 7 +++++-- packages/connect-conformance/src/promise-client.ts | 13 ++++++++----- packages/connect-web-bench/README.md | 8 ++++---- packages/connect-web-bench/chart.svg | 10 +++++----- packages/connect/src/protocol-connect/error-json.ts | 3 +-- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/connect-conformance/src/callback-client.ts b/packages/connect-conformance/src/callback-client.ts index 25c3066ee..32aed77e8 100644 --- a/packages/connect-conformance/src/callback-client.ts +++ b/packages/connect-conformance/src/callback-client.ts @@ -23,6 +23,7 @@ import { ServerStreamRequest, UnimplementedRequest, IdempotentUnaryRequest, + ConformancePayload, } from "./gen/connectrpc/conformance/v1/service_pb.js"; import { convertToProtoError, @@ -37,6 +38,8 @@ import { ConformanceService } from "./gen/connectrpc/conformance/v1/service_conn type ConformanceClient = CallbackClient; +const emptyPayload = new ConformancePayload(); + export function invokeWithCallbackClient( transport: Transport, req: ClientCompatRequest, @@ -82,7 +85,7 @@ async function unary( if (err !== undefined) { setClientErrorResult(result, err); } else { - result.payloads.push(response.payload!); + result.payloads.push(response.payload ?? emptyPayload); } resolve(result); }, @@ -125,7 +128,7 @@ async function serverStream( const clientCancelFn = client.serverStream( getSingleRequestMessage(compatRequest, ServerStreamRequest), (response) => { - result.payloads.push(response.payload!); + result.payloads.push(response.payload ?? emptyPayload); if (result.payloads.length === cancelTiming.afterNumResponses) { clientCancelled = true; clientCancelFn(); diff --git a/packages/connect-conformance/src/promise-client.ts b/packages/connect-conformance/src/promise-client.ts index 81f5a280d..7c72afaed 100644 --- a/packages/connect-conformance/src/promise-client.ts +++ b/packages/connect-conformance/src/promise-client.ts @@ -21,6 +21,7 @@ import { import { BidiStreamRequest, ClientStreamRequest, + ConformancePayload, IdempotentUnaryRequest, ServerStreamRequest, UnaryRequest, @@ -41,6 +42,8 @@ import { StreamType } from "./gen/connectrpc/conformance/v1/config_pb.js"; type ConformanceClient = PromiseClient; +const emptyPayload = new ConformancePayload(); + export function invokeWithPromiseClient( transport: Transport, compatRequest: ClientCompatRequest, @@ -93,7 +96,7 @@ async function unary( result.responseTrailers = convertToProtoHeaders(trailers); }, }); - result.payloads.push(response.payload!); + result.payloads.push(response.payload ?? emptyPayload); } catch (e) { setClientErrorResult(result, e); } @@ -125,7 +128,7 @@ async function serverStream( controller.abort(); } for await (const msg of res) { - result.payloads.push(msg.payload!); + result.payloads.push(msg.payload ?? emptyPayload); if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } @@ -172,7 +175,7 @@ async function clientStream( }, }, ); - result.payloads.push(response.payload!); + result.payloads.push(response.payload ?? emptyPayload); } catch (e) { setClientErrorResult(result, e); } @@ -210,7 +213,7 @@ async function bidiStream( if (next.done === true) { continue; } - result.payloads.push(next.value.payload!); + result.payloads.push(next.value.payload ?? emptyPayload); if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } @@ -234,7 +237,7 @@ async function bidiStream( if (next.done === true) { break; } - result.payloads.push(next.value.payload!); + result.payloads.push(next.value.payload ?? emptyPayload); if (result.payloads.length === cancelTiming.afterNumResponses) { controller.abort(); } diff --git a/packages/connect-web-bench/README.md b/packages/connect-web-bench/README.md index e340f0cd1..ecc96388d 100644 --- a/packages/connect-web-bench/README.md +++ b/packages/connect-web-bench/README.md @@ -15,10 +15,10 @@ usually do. We repeat this for an increasing number of RPCs. | code generator | RPCs | bundle size | minified | compressed | | -------------- | ---: | ----------: | --------: | ---------: | -| Connect-ES | 1 | 152,759 b | 66,533 b | 16,438 b | -| Connect-ES | 4 | 168,201 b | 72,473 b | 16,896 b | -| Connect-ES | 8 | 193,514 b | 82,198 b | 17,477 b | -| Connect-ES | 16 | 227,153 b | 96,461 b | 18,226 b | +| Connect-ES | 1 | 152,703 b | 66,494 b | 16,400 b | +| Connect-ES | 4 | 168,145 b | 72,434 b | 16,865 b | +| Connect-ES | 8 | 193,458 b | 82,159 b | 17,484 b | +| Connect-ES | 16 | 227,097 b | 96,422 b | 18,224 b | | gRPC-Web | 1 | 876,563 b | 548,495 b | 52,300 b | | gRPC-Web | 4 | 928,964 b | 580,477 b | 54,673 b | | gRPC-Web | 8 | 1,004,833 b | 628,223 b | 57,118 b | diff --git a/packages/connect-web-bench/chart.svg b/packages/connect-web-bench/chart.svg index 7b6c13018..4e6f0cdd4 100644 --- a/packages/connect-web-bench/chart.svg +++ b/packages/connect-web-bench/chart.svg @@ -42,13 +42,13 @@ 0 KiB - + Connect-ES -Connect-ES 16.05 KiB for 1 RPCs -Connect-ES 16.5 KiB for 4 RPCs -Connect-ES 17.07 KiB for 8 RPCs -Connect-ES 17.8 KiB for 16 RPCs +Connect-ES 16.02 KiB for 1 RPCs +Connect-ES 16.47 KiB for 4 RPCs +Connect-ES 17.07 KiB for 8 RPCs +Connect-ES 17.8 KiB for 16 RPCs diff --git a/packages/connect/src/protocol-connect/error-json.ts b/packages/connect/src/protocol-connect/error-json.ts index 7e5930f33..425bebb8f 100644 --- a/packages/connect/src/protocol-connect/error-json.ts +++ b/packages/connect/src/protocol-connect/error-json.ts @@ -61,8 +61,7 @@ export function errorFromJson( typeof detail != "object" || Array.isArray(detail) || typeof detail.type != "string" || - typeof detail.value != "string" || - ("debug" in detail && typeof detail.debug != "object") + typeof detail.value != "string" ) { throw fallback; } From 837b6ce399e2951b5295fecface70fc7f85061e7 Mon Sep 17 00:00:00 2001 From: Sri Krishna <93153132+srikrsna-buf@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:49:00 +0530 Subject: [PATCH 19/21] Throw an error on missing status in gRPC and gRPC-Web transports (#1205) Signed-off-by: Sri Krishna Paritala Co-authored-by: Timo Stamm --- packages/connect-node/src/transport.spec.ts | 113 ++++++++++++++++++ .../src/use-node-server-helper.spec.ts | 2 +- packages/connect-web-bench/README.md | 8 +- packages/connect-web-bench/chart.svg | 10 +- .../src/protocol-connect/validate-response.ts | 8 +- .../protocol-grpc/validate-response.spec.ts | 22 +++- .../src/protocol-grpc/validate-response.ts | 15 ++- .../src/protocol-grpc/validate-trailer.ts | 14 ++- 8 files changed, 174 insertions(+), 18 deletions(-) create mode 100644 packages/connect-node/src/transport.spec.ts diff --git a/packages/connect-node/src/transport.spec.ts b/packages/connect-node/src/transport.spec.ts new file mode 100644 index 000000000..3b2a77aea --- /dev/null +++ b/packages/connect-node/src/transport.spec.ts @@ -0,0 +1,113 @@ +// Copyright 2021-2024 The Connect Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* eslint-disable @typescript-eslint/no-invalid-void-type */ +import { Int32Value, StringValue, MethodKind } from "@bufbuild/protobuf"; +import { useNodeServer } from "./use-node-server-helper.spec.js"; +import * as http2 from "node:http2"; +import { connectNodeAdapter } from "./connect-node-adapter.js"; +import { createPromiseClient } from "@connectrpc/connect"; +import type { Transport } from "@connectrpc/connect"; +import { createTransport as createGrpcTransport } from "@connectrpc/connect/protocol-grpc"; +import { createTransport as createGrpcWebTransport } from "@connectrpc/connect/protocol-grpc-web"; +import { validateNodeTransportOptions } from "./node-transport-options.js"; + +const TestService = { + typeName: "TestService", + methods: { + server: { + name: "Server", + I: Int32Value, + O: StringValue, + kind: MethodKind.ServerStreaming, + }, + }, +} as const; + +describe("Calls should fail with code internal on RST_STREAM no_error before trailers are received", function () { + let firstMessage: ReturnType>; + let rstStream: ReturnType>; + beforeEach(function () { + firstMessage = createCompleter(); + rstStream = createCompleter(); + }); + const adaptor = connectNodeAdapter({ + routes({ rpc }) { + rpc(TestService, TestService.methods.server, async function* () { + yield { value: "foo" }; + // Notify to send rst stream after a message. + firstMessage.resolve(); + // Wait for rst stream to be sent before returning. + // If we return early it will create a race. + await rstStream.promise; + }); + }, + }); + const server = useNodeServer(() => + http2.createServer((request, response) => { + adaptor(request, response); + firstMessage.promise + .then(() => { + response.stream.close(0, () => rstStream.resolve()); + }) + .catch(fail); + }), + ); + async function testRstStream(transport: Transport) { + const client = createPromiseClient(TestService, transport); + const it = client.server({ value: 1 })[Symbol.asyncIterator](); + const first = await it.next(); + expect(first.done).toBeFalse(); + expect(first.value).toEqual(new StringValue({ value: "foo" })); + await expectAsync(it.next()).toBeRejected(); + } + it("for gRPC Transport", async function () { + await testRstStream( + createGrpcTransport({ + ...validateNodeTransportOptions({ + httpVersion: "2", + baseUrl: server.getUrl(), + }), + baseUrl: server.getUrl(), + httpClient: server.getClient(), + }), + ); + }); + it("for gRPC Transport", async function () { + await testRstStream( + createGrpcWebTransport({ + ...validateNodeTransportOptions({ + httpVersion: "2", + baseUrl: server.getUrl(), + }), + baseUrl: server.getUrl(), + httpClient: server.getClient(), + }), + ); + }); +}); + +function createCompleter() { + let resolve: (_: T | PromiseLike) => void; + let reject: (reason?: unknown) => void; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { + promise, + resolve: resolve!, + reject: reject!, + }; +} diff --git a/packages/connect-node/src/use-node-server-helper.spec.ts b/packages/connect-node/src/use-node-server-helper.spec.ts index 3330a2ad8..8e9e2c3f3 100644 --- a/packages/connect-node/src/use-node-server-helper.spec.ts +++ b/packages/connect-node/src/use-node-server-helper.spec.ts @@ -99,7 +99,7 @@ export function useNodeServer( client = createNodeHttpClient({ httpVersion: "2", sessionProvider: (authority) => { - if (authority !== this.getUrl()) { + if (new URL(this.getUrl()).origin != new URL(authority).origin) { throw new Error( "client from useNodeServer() can only be used for requests against the server URL", ); diff --git a/packages/connect-web-bench/README.md b/packages/connect-web-bench/README.md index ecc96388d..311c4113e 100644 --- a/packages/connect-web-bench/README.md +++ b/packages/connect-web-bench/README.md @@ -15,10 +15,10 @@ usually do. We repeat this for an increasing number of RPCs. | code generator | RPCs | bundle size | minified | compressed | | -------------- | ---: | ----------: | --------: | ---------: | -| Connect-ES | 1 | 152,703 b | 66,494 b | 16,400 b | -| Connect-ES | 4 | 168,145 b | 72,434 b | 16,865 b | -| Connect-ES | 8 | 193,458 b | 82,159 b | 17,484 b | -| Connect-ES | 16 | 227,097 b | 96,422 b | 18,224 b | +| Connect-ES | 1 | 152,706 b | 66,483 b | 16,386 b | +| Connect-ES | 4 | 168,148 b | 72,422 b | 16,890 b | +| Connect-ES | 8 | 193,461 b | 82,145 b | 17,461 b | +| Connect-ES | 16 | 227,100 b | 96,411 b | 18,214 b | | gRPC-Web | 1 | 876,563 b | 548,495 b | 52,300 b | | gRPC-Web | 4 | 928,964 b | 580,477 b | 54,673 b | | gRPC-Web | 8 | 1,004,833 b | 628,223 b | 57,118 b | diff --git a/packages/connect-web-bench/chart.svg b/packages/connect-web-bench/chart.svg index 4e6f0cdd4..390216865 100644 --- a/packages/connect-web-bench/chart.svg +++ b/packages/connect-web-bench/chart.svg @@ -42,13 +42,13 @@ 0 KiB - + Connect-ES -Connect-ES 16.02 KiB for 1 RPCs -Connect-ES 16.47 KiB for 4 RPCs -Connect-ES 17.07 KiB for 8 RPCs -Connect-ES 17.8 KiB for 16 RPCs +Connect-ES 16 KiB for 1 RPCs +Connect-ES 16.49 KiB for 4 RPCs +Connect-ES 17.05 KiB for 8 RPCs +Connect-ES 17.79 KiB for 16 RPCs diff --git a/packages/connect/src/protocol-connect/validate-response.ts b/packages/connect/src/protocol-connect/validate-response.ts index 8e878d3f1..c556c66be 100644 --- a/packages/connect/src/protocol-connect/validate-response.ts +++ b/packages/connect/src/protocol-connect/validate-response.ts @@ -17,7 +17,11 @@ import { Code } from "../code.js"; import { codeFromHttpStatus } from "./http-status.js"; import { ConnectError } from "../connect-error.js"; import { parseContentType } from "./content-type.js"; -import { headerStreamEncoding, headerUnaryEncoding } from "./headers.js"; +import { + headerContentType, + headerStreamEncoding, + headerUnaryEncoding, +} from "./headers.js"; import type { Compression } from "../protocol/compression.js"; /** @@ -38,7 +42,7 @@ export function validateResponse( ): | { isUnaryError: false; unaryError?: undefined } | { isUnaryError: true; unaryError: ConnectError } { - const mimeType = headers.get("Content-Type"); + const mimeType = headers.get(headerContentType); const parsedType = parseContentType(mimeType); if (status !== 200) { const errorFromStatus = new ConnectError( diff --git a/packages/connect/src/protocol-grpc/validate-response.spec.ts b/packages/connect/src/protocol-grpc/validate-response.spec.ts index d46ca0497..8bde24133 100644 --- a/packages/connect/src/protocol-grpc/validate-response.spec.ts +++ b/packages/connect/src/protocol-grpc/validate-response.spec.ts @@ -38,17 +38,28 @@ describe("gRPC validateResponse()", function () { } it("should honor grpc-status field", function () { - const e = v(200, { "grpc-status": "8" }); + const e = v(200, { + "grpc-status": "8", + "content-type": "application/grpc+proto", + }); expect(e?.message).toBe("[resource_exhausted]"); }); it("should honor grpc-message field", function () { - const e = v(200, { "grpc-status": "8", "grpc-message": "out of space" }); + const e = v(200, { + "grpc-status": "8", + "grpc-message": "out of space", + "content-type": "application/grpc+proto", + }); expect(e?.message).toBe("[resource_exhausted] out of space"); }); it("should include headers as error metadata with grpc-status", function () { - const e = v(200, { "grpc-status": "8", Foo: "Bar" }); + const e = v(200, { + "grpc-status": "8", + Foo: "Bar", + "content-type": "application/grpc+proto", + }); expect(e?.metadata.get("Foo")).toBe("Bar"); }); @@ -80,7 +91,10 @@ describe("gRPC validateResponse()", function () { it("should return foundStatus for grpc-status OK", function () { const { foundStatus } = validateResponse( 200, - new Headers({ "grpc-status": "0" }), + new Headers({ + "grpc-status": "0", + "content-type": "application/grpc+proto", + }), ); expect(foundStatus).toBeTrue(); }); diff --git a/packages/connect/src/protocol-grpc/validate-response.ts b/packages/connect/src/protocol-grpc/validate-response.ts index 2245f43c1..cc574dd89 100644 --- a/packages/connect/src/protocol-grpc/validate-response.ts +++ b/packages/connect/src/protocol-grpc/validate-response.ts @@ -16,8 +16,13 @@ import { codeFromHttpStatus } from "./http-status.js"; import { ConnectError } from "../connect-error.js"; import { findTrailerError } from "./trailer-status.js"; import { Code } from "../code.js"; -import { headerEncoding, headerGrpcStatus } from "./headers.js"; +import { + headerContentType, + headerEncoding, + headerGrpcStatus, +} from "./headers.js"; import type { Compression } from "../protocol/compression.js"; +import { parseContentType } from "./content-type.js"; /** * Validates response status and header for the gRPC protocol. @@ -41,6 +46,14 @@ export function validateResponse( headers, ); } + const mimeType = headers.get(headerContentType); + const parsedType = parseContentType(mimeType); + if (parsedType == undefined) { + throw new ConnectError( + `unsupported content type ${mimeType}`, + Code.Unknown, + ); + } return { foundStatus: headers.has(headerGrpcStatus), headerError: findTrailerError(headers), diff --git a/packages/connect/src/protocol-grpc/validate-trailer.ts b/packages/connect/src/protocol-grpc/validate-trailer.ts index 59fc78af2..d045ac3a8 100644 --- a/packages/connect/src/protocol-grpc/validate-trailer.ts +++ b/packages/connect/src/protocol-grpc/validate-trailer.ts @@ -12,11 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { Code } from "../code.js"; +import { ConnectError } from "../connect-error.js"; +import { headerGrpcStatus } from "./headers.js"; import { findTrailerError } from "./trailer-status.js"; /** * Validates a trailer for the gRPC and the gRPC-web protocol. - * Throws a ConnectError if the trailer contains an error status. + * + * If the trailer contains an error status, a ConnectError is + * thrown. It will include trailer and header in the error's + * "metadata" property. + * + * Throws a ConnectError with code "internal" if neither the trailer + * nor the header contain the Grpc-Status field. * * @private Internal code, does not follow semantic versioning. */ @@ -28,4 +37,7 @@ export function validateTrailer(trailer: Headers, header: Headers): void { }); throw err; } + if (!header.has(headerGrpcStatus) && !trailer.has(headerGrpcStatus)) { + throw new ConnectError("protocol error: missing status", Code.Internal); + } } From 6575fc157d96b1df0c004c7653bb64ddd78a564c Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Wed, 11 Sep 2024 15:24:35 +0200 Subject: [PATCH 20/21] Release 1.5.0 (#1222) --- package-lock.json | 76 +++++++++---------- packages/connect-cloudflare/package.json | 6 +- packages/connect-conformance/package.json | 6 +- .../conformance/v1/service_connect.ts | 2 +- packages/connect-express/package.json | 12 +-- packages/connect-fastify/package.json | 12 +-- packages/connect-migrate/package.json | 2 +- packages/connect-next/package.json | 10 +-- packages/connect-node/package.json | 6 +- packages/connect-web-bench/README.md | 8 +- packages/connect-web-bench/chart.svg | 10 +-- packages/connect-web-bench/package.json | 2 +- .../module/v1/commit_service_connect.ts | 2 +- .../module/v1/download_service_connect.ts | 2 +- .../module/v1/graph_service_connect.ts | 2 +- .../module/v1/label_service_connect.ts | 2 +- .../module/v1/module_service_connect.ts | 2 +- .../module/v1/resource_service_connect.ts | 2 +- .../module/v1/upload_service_connect.ts | 2 +- .../module/v1beta1/commit_service_connect.ts | 2 +- .../v1beta1/download_service_connect.ts | 2 +- .../module/v1beta1/graph_service_connect.ts | 2 +- .../module/v1beta1/label_service_connect.ts | 2 +- .../module/v1beta1/module_service_connect.ts | 2 +- .../v1beta1/resource_service_connect.ts | 2 +- .../module/v1beta1/upload_service_connect.ts | 2 +- .../owner/v1/organization_service_connect.ts | 2 +- .../owner/v1/owner_service_connect.ts | 2 +- .../registry/owner/v1/user_service_connect.ts | 2 +- .../gen/connectrpc/eliza/v1/eliza_connect.ts | 2 +- packages/connect-web/package.json | 8 +- packages/connect/package.json | 2 +- packages/example/package.json | 6 +- packages/example/src/gen/eliza_connect.ts | 2 +- packages/protoc-gen-connect-es/package.json | 4 +- 35 files changed, 105 insertions(+), 105 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28bf9d5f0..9a0c79933 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11308,7 +11308,7 @@ }, "packages/connect": { "name": "@connectrpc/connect", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "devDependencies": { "@bufbuild/buf": "^1.39.0", @@ -11325,22 +11325,22 @@ "name": "@connectrpc/connect-cloudflare", "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240821.1", - "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect-conformance": "^1.5.0", "tsx": "^4.19.0", "wrangler": "^3.73.0" } }, "packages/connect-conformance": { "name": "@connectrpc/connect-conformance", - "version": "1.4.0", + "version": "1.5.0", "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", + "@connectrpc/connect": "1.5.0", "fflate": "^0.8.1", "tar-stream": "^3.1.7", "undici": "^5.28.4" @@ -11350,7 +11350,7 @@ }, "devDependencies": { "@bufbuild/buf": "^1.39.0", - "@connectrpc/protoc-gen-connect-es": "1.4.0", + "@connectrpc/protoc-gen-connect-es": "1.5.0", "@types/debug": "^4.1.12", "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3" @@ -11358,12 +11358,12 @@ }, "packages/connect-express": { "name": "@connectrpc/connect-express", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "devDependencies": { - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-conformance": "^1.4.0", - "@connectrpc/connect-node": "1.4.0", + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-conformance": "^1.5.0", + "@connectrpc/connect-node": "1.5.0", "@types/express": "^4.17.18", "express": "^4.19.2", "tsx": "^4.19.0" @@ -11373,32 +11373,32 @@ }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" } }, "packages/connect-fastify": { "name": "@connectrpc/connect-fastify", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "devDependencies": { - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-conformance": "^1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-conformance": "^1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0", + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0", "fastify": "^4.22.1" } }, "packages/connect-migrate": { "name": "@connectrpc/connect-migrate", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "dependencies": { "fast-glob": "3.3.2", @@ -11418,31 +11418,31 @@ }, "packages/connect-next": { "name": "@connectrpc/connect-next", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "devDependencies": { - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0", + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0", "next": "^13.2.4 || ^14.2.5" } }, "packages/connect-node": { "name": "@connectrpc/connect-node", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "dependencies": { "undici": "^5.28.4" }, "devDependencies": { - "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/connect-conformance": "^1.5.0", "@types/jasmine": "^5.0.0", "jasmine": "^5.2.0" }, @@ -11451,18 +11451,18 @@ }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0" + "@connectrpc/connect": "1.5.0" } }, "packages/connect-web": { "name": "@connectrpc/connect-web", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "devDependencies": { "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/connect-conformance": "^1.4.0", - "@connectrpc/protoc-gen-connect-es": "^1.4.0", + "@connectrpc/connect-conformance": "^1.5.0", + "@connectrpc/protoc-gen-connect-es": "^1.5.0", "jasmine": "^5.2.0", "karma": "^6.4.4", "karma-browserstack-launcher": "^1.6.0", @@ -11473,7 +11473,7 @@ }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0" + "@connectrpc/connect": "1.5.0" } }, "packages/connect-web-bench": { @@ -11482,7 +11482,7 @@ "@bufbuild/buf": "^1.39.0", "@bufbuild/protobuf": "^1.10.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/connect-web": "1.4.0", + "@connectrpc/connect-web": "1.5.0", "@types/brotli": "^1.3.4", "brotli": "^1.3.3", "esbuild": "^0.19.8", @@ -11494,14 +11494,14 @@ "name": "@connectrpc/example", "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect-node": "^1.4.0", - "@connectrpc/connect-web": "^1.4.0", + "@connectrpc/connect-node": "^1.5.0", + "@connectrpc/connect-web": "^1.5.0", "tsx": "^4.19.0" }, "devDependencies": { "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/protoc-gen-connect-es": "^1.4.0", + "@connectrpc/protoc-gen-connect-es": "^1.5.0", "@types/express": "^4.17.18", "esbuild": "^0.19.8", "typescript": "^5.5.4" @@ -11512,7 +11512,7 @@ }, "packages/protoc-gen-connect-es": { "name": "@connectrpc/protoc-gen-connect-es", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "dependencies": { "@bufbuild/protobuf": "^1.10.0", @@ -11526,7 +11526,7 @@ }, "peerDependencies": { "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/connect": "1.4.0" + "@connectrpc/connect": "1.5.0" }, "peerDependenciesMeta": { "@bufbuild/protoc-gen-es": { diff --git a/packages/connect-cloudflare/package.json b/packages/connect-cloudflare/package.json index 0338f317f..5526be819 100644 --- a/packages/connect-cloudflare/package.json +++ b/packages/connect-cloudflare/package.json @@ -11,13 +11,13 @@ }, "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240821.1", "wrangler": "^3.73.0", "tsx": "^4.19.0", - "@connectrpc/connect-conformance": "^1.4.0" + "@connectrpc/connect-conformance": "^1.5.0" } } diff --git a/packages/connect-conformance/package.json b/packages/connect-conformance/package.json index 8ef29c829..20bd72e14 100644 --- a/packages/connect-conformance/package.json +++ b/packages/connect-conformance/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-conformance", - "version": "1.4.0", + "version": "1.5.0", "private": true, "type": "module", "main": "./dist/cjs/src/index.js", @@ -28,7 +28,7 @@ }, "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", + "@connectrpc/connect": "1.5.0", "fflate": "^0.8.1", "tar-stream": "^3.1.7", "undici": "^5.28.4" @@ -38,6 +38,6 @@ "@types/node-forge": "^1.3.9", "@types/tar-stream": "^3.1.3", "@types/debug": "^4.1.12", - "@connectrpc/protoc-gen-connect-es": "1.4.0" + "@connectrpc/protoc-gen-connect-es": "1.5.0" } } diff --git a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts index dddad87c3..210b89def 100644 --- a/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts +++ b/packages/connect-conformance/src/gen/connectrpc/conformance/v1/service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file connectrpc/conformance/v1/service.proto (package connectrpc.conformance.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-express/package.json b/packages/connect-express/package.json index 7801ec796..24ff7a038 100644 --- a/packages/connect-express/package.json +++ b/packages/connect-express/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-express", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -32,16 +32,16 @@ "node": ">=16.0.0" }, "devDependencies": { - "@connectrpc/connect-conformance": "^1.4.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0", + "@connectrpc/connect-conformance": "^1.5.0", + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0", "@types/express": "^4.17.18", "express": "^4.19.2", "tsx": "^4.19.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" } } diff --git a/packages/connect-fastify/package.json b/packages/connect-fastify/package.json index f7f8e21ba..5d459c177 100644 --- a/packages/connect-fastify/package.json +++ b/packages/connect-fastify/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-fastify", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -31,14 +31,14 @@ "node": ">=16.0.0" }, "devDependencies": { - "@connectrpc/connect-conformance": "^1.4.0", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect-conformance": "^1.5.0", + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", "fastify": "^4.22.1", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" } } diff --git a/packages/connect-migrate/package.json b/packages/connect-migrate/package.json index c8dfc30ea..8d54ca8c9 100644 --- a/packages/connect-migrate/package.json +++ b/packages/connect-migrate/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-migrate", - "version": "1.4.0", + "version": "1.5.0", "description": "This tool updates your Connect project to use the new @connectrpc packages.", "license": "Apache-2.0", "repository": { diff --git a/packages/connect-next/package.json b/packages/connect-next/package.json index 18d7e6aa5..8ded4eadb 100644 --- a/packages/connect-next/package.json +++ b/packages/connect-next/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-next", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -32,11 +32,11 @@ "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", "next": "^13.2.4 || ^14.2.5", - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" }, "devDependencies": { - "@connectrpc/connect": "1.4.0", - "@connectrpc/connect-node": "1.4.0" + "@connectrpc/connect": "1.5.0", + "@connectrpc/connect-node": "1.5.0" } } diff --git a/packages/connect-node/package.json b/packages/connect-node/package.json index 7307cb860..171391791 100644 --- a/packages/connect-node/package.json +++ b/packages/connect-node/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-node", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -36,11 +36,11 @@ }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0" + "@connectrpc/connect": "1.5.0" }, "devDependencies": { "@types/jasmine": "^5.0.0", "jasmine": "^5.2.0", - "@connectrpc/connect-conformance": "^1.4.0" + "@connectrpc/connect-conformance": "^1.5.0" } } diff --git a/packages/connect-web-bench/README.md b/packages/connect-web-bench/README.md index 311c4113e..c0917491f 100644 --- a/packages/connect-web-bench/README.md +++ b/packages/connect-web-bench/README.md @@ -15,10 +15,10 @@ usually do. We repeat this for an increasing number of RPCs. | code generator | RPCs | bundle size | minified | compressed | | -------------- | ---: | ----------: | --------: | ---------: | -| Connect-ES | 1 | 152,706 b | 66,483 b | 16,386 b | -| Connect-ES | 4 | 168,148 b | 72,422 b | 16,890 b | -| Connect-ES | 8 | 193,461 b | 82,145 b | 17,461 b | -| Connect-ES | 16 | 227,100 b | 96,411 b | 18,214 b | +| Connect-ES | 1 | 152,706 b | 66,483 b | 16,394 b | +| Connect-ES | 4 | 168,148 b | 72,422 b | 16,888 b | +| Connect-ES | 8 | 193,461 b | 82,145 b | 17,496 b | +| Connect-ES | 16 | 227,100 b | 96,411 b | 18,258 b | | gRPC-Web | 1 | 876,563 b | 548,495 b | 52,300 b | | gRPC-Web | 4 | 928,964 b | 580,477 b | 54,673 b | | gRPC-Web | 8 | 1,004,833 b | 628,223 b | 57,118 b | diff --git a/packages/connect-web-bench/chart.svg b/packages/connect-web-bench/chart.svg index 390216865..9a39fc5f9 100644 --- a/packages/connect-web-bench/chart.svg +++ b/packages/connect-web-bench/chart.svg @@ -42,13 +42,13 @@ 0 KiB - + Connect-ES -Connect-ES 16 KiB for 1 RPCs -Connect-ES 16.49 KiB for 4 RPCs -Connect-ES 17.05 KiB for 8 RPCs -Connect-ES 17.79 KiB for 16 RPCs +Connect-ES 16.01 KiB for 1 RPCs +Connect-ES 16.49 KiB for 4 RPCs +Connect-ES 17.09 KiB for 8 RPCs +Connect-ES 17.83 KiB for 16 RPCs diff --git a/packages/connect-web-bench/package.json b/packages/connect-web-bench/package.json index 4f87f2a79..6f137733d 100644 --- a/packages/connect-web-bench/package.json +++ b/packages/connect-web-bench/package.json @@ -13,7 +13,7 @@ "@bufbuild/buf": "^1.39.0", "@bufbuild/protobuf": "^1.10.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/connect-web": "1.4.0", + "@connectrpc/connect-web": "1.5.0", "@types/brotli": "^1.3.4", "brotli": "^1.3.3", "esbuild": "^0.19.8", diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/commit_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/commit_service_connect.ts index 89f530fb3..98f8327c1 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/commit_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/commit_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/commit_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/download_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/download_service_connect.ts index 3bd0130d5..01a250f98 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/download_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/download_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/download_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/graph_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/graph_service_connect.ts index 1588dd2c9..9cd00ff24 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/graph_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/graph_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/graph_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/label_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/label_service_connect.ts index f41593e13..53fe1123a 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/label_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/label_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/label_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/module_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/module_service_connect.ts index 42f372914..8a71ff952 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/module_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/module_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/module_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/resource_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/resource_service_connect.ts index fd858d7af..0e8555818 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/resource_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/resource_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/resource_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/upload_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/upload_service_connect.ts index 68abb46dd..a261fa87e 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/upload_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1/upload_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1/upload_service.proto (package buf.registry.module.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/commit_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/commit_service_connect.ts index 794f707b6..35140b298 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/commit_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/commit_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/commit_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/download_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/download_service_connect.ts index 2b40e157b..387e21cfe 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/download_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/download_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/download_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/graph_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/graph_service_connect.ts index edf11b489..a9ac1be23 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/graph_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/graph_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/graph_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/label_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/label_service_connect.ts index a692edeaf..b6e6c7976 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/label_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/label_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/label_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/module_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/module_service_connect.ts index 37d03d6f4..c8b352fb6 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/module_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/module_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/module_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/resource_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/resource_service_connect.ts index bded5b937..a4339cb51 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/resource_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/resource_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/resource_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/upload_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/upload_service_connect.ts index 939f824ef..a0026d59a 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/upload_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/module/v1beta1/upload_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/module/v1beta1/upload_service.proto (package buf.registry.module.v1beta1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/organization_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/organization_service_connect.ts index c615a0f29..c05d35bee 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/organization_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/organization_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/owner/v1/organization_service.proto (package buf.registry.owner.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/owner_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/owner_service_connect.ts index 8ab395423..051687c05 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/owner_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/owner_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/owner/v1/owner_service.proto (package buf.registry.owner.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/user_service_connect.ts b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/user_service_connect.ts index 3475473ae..e0382b976 100644 --- a/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/user_service_connect.ts +++ b/packages/connect-web-bench/src/gen/connectweb/buf/registry/owner/v1/user_service_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "ts_nocheck=false,target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "ts_nocheck=false,target=ts" // @generated from file buf/registry/owner/v1/user_service.proto (package buf.registry.owner.v1, syntax proto3) /* eslint-disable */ diff --git a/packages/connect-web/browserstack/gen/connectrpc/eliza/v1/eliza_connect.ts b/packages/connect-web/browserstack/gen/connectrpc/eliza/v1/eliza_connect.ts index e67c054a1..2928c8147 100644 --- a/packages/connect-web/browserstack/gen/connectrpc/eliza/v1/eliza_connect.ts +++ b/packages/connect-web/browserstack/gen/connectrpc/eliza/v1/eliza_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "target=ts" // @generated from file connectrpc/eliza/v1/eliza.proto (package connectrpc.eliza.v1, syntax proto3) /* eslint-disable */ // @ts-nocheck diff --git a/packages/connect-web/package.json b/packages/connect-web/package.json index c92e5f07b..887eb0912 100644 --- a/packages/connect-web/package.json +++ b/packages/connect-web/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect-web", - "version": "1.4.0", + "version": "1.5.0", "license": "Apache-2.0", "repository": { "type": "git", @@ -43,8 +43,8 @@ "webdriverio": "^8.39.1", "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/protoc-gen-connect-es": "^1.4.0", - "@connectrpc/connect-conformance": "^1.4.0", + "@connectrpc/protoc-gen-connect-es": "^1.5.0", + "@connectrpc/connect-conformance": "^1.5.0", "jasmine": "^5.2.0", "karma": "^6.4.4", "karma-browserstack-launcher": "^1.6.0", @@ -54,6 +54,6 @@ }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect": "1.4.0" + "@connectrpc/connect": "1.5.0" } } diff --git a/packages/connect/package.json b/packages/connect/package.json index 299fccbe4..4e66f920c 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/connect", - "version": "1.4.0", + "version": "1.5.0", "description": "Type-safe APIs with Protobuf and TypeScript.", "license": "Apache-2.0", "repository": { diff --git a/packages/example/package.json b/packages/example/package.json index a3edc9446..52df36cbc 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -16,14 +16,14 @@ }, "dependencies": { "@bufbuild/protobuf": "^1.10.0", - "@connectrpc/connect-node": "^1.4.0", - "@connectrpc/connect-web": "^1.4.0", + "@connectrpc/connect-node": "^1.5.0", + "@connectrpc/connect-web": "^1.5.0", "tsx": "^4.19.0" }, "devDependencies": { "@bufbuild/buf": "^1.39.0", "@bufbuild/protoc-gen-es": "^1.10.0", - "@connectrpc/protoc-gen-connect-es": "^1.4.0", + "@connectrpc/protoc-gen-connect-es": "^1.5.0", "@types/express": "^4.17.18", "esbuild": "^0.19.8", "typescript": "^5.5.4" diff --git a/packages/example/src/gen/eliza_connect.ts b/packages/example/src/gen/eliza_connect.ts index 14459b926..54f123daa 100644 --- a/packages/example/src/gen/eliza_connect.ts +++ b/packages/example/src/gen/eliza_connect.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-connect-es v1.4.0 with parameter "target=ts" +// @generated by protoc-gen-connect-es v1.5.0 with parameter "target=ts" // @generated from file eliza.proto (package connectrpc.eliza.v1, syntax proto3) /* eslint-disable */ // @ts-nocheck diff --git a/packages/protoc-gen-connect-es/package.json b/packages/protoc-gen-connect-es/package.json index 92277f7ae..d817b3130 100644 --- a/packages/protoc-gen-connect-es/package.json +++ b/packages/protoc-gen-connect-es/package.json @@ -1,6 +1,6 @@ { "name": "@connectrpc/protoc-gen-connect-es", - "version": "1.4.0", + "version": "1.5.0", "description": "Code generator for Connect", "license": "Apache-2.0", "repository": { @@ -27,7 +27,7 @@ "@bufbuild/protoplugin": "^1.10.0" }, "peerDependencies": { - "@connectrpc/connect": "1.4.0", + "@connectrpc/connect": "1.5.0", "@bufbuild/protoc-gen-es": "^1.10.0" }, "peerDependenciesMeta": { From 15296baf152dd1fc87850e90a7a6497681acb2a0 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Wed, 11 Sep 2024 22:07:34 +0530 Subject: [PATCH 21/21] Revert changes to Migrate package.json Signed-off-by: Sri Krishna Paritala --- packages/connect-migrate/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/connect-migrate/package.json b/packages/connect-migrate/package.json index 01630e04d..ee99ca0e1 100644 --- a/packages/connect-migrate/package.json +++ b/packages/connect-migrate/package.json @@ -13,7 +13,7 @@ }, "scripts": { "prebuild": "rm -rf ./dist/*", - "build": "tsc --project tsconfig.json --module commonjs --verbatimModuleSyntax false --moduleResolution node10 --outDir ./dist/cjs", + "build": "tsc --project tsconfig.json --outDir ./dist/cjs", "test": "jasmine --config=jasmine.json", "format": "prettier --write --ignore-unknown '.' '!dist'", "license-header": "license-header",