├── .asf.yaml ├── .editorconfig ├── .eslintrc.cjs ├── .github └── workflows │ ├── go.yml │ └── node.js.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg └── pre-commit ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CHANGE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── NOTICE ├── README.md ├── commitlint.config.js ├── docs ├── .vitepress │ └── config.ts ├── api │ └── index.md ├── config │ └── index.md ├── guide │ ├── dubboForNode │ │ ├── GetRequestsAndCaching.md │ │ ├── GettingStarted.md │ │ ├── ImplementingServices.md │ │ ├── Interceptors.md │ │ ├── ServerPlugins.md │ │ ├── Testing.md │ │ └── UsingClients.md │ ├── dubboForWEB │ │ ├── CancellationandTimeouts.md │ │ ├── Choosingaprotocol.md │ │ ├── CommonErrors.md │ │ ├── ConnectForTanStackQuery.md │ │ ├── Errors.md │ │ ├── GeneratingCode.md │ │ ├── GetRequestsandCaching.md │ │ ├── GettingStarted.md │ │ ├── HeadersandTrailers.md │ │ ├── Interceptors.md │ │ ├── ServerSideRendering.md │ │ ├── SupportedBrowsersandFrameworks.md │ │ ├── Testing.md │ │ └── UsingClients.md │ └── index.md ├── imgs │ └── arc.png ├── index.md ├── package.json └── public │ ├── favicon.ico │ └── logo.png ├── example ├── dubbo-node-example │ ├── README.md │ ├── client.ts │ ├── dubbo.ts │ ├── gen │ │ ├── example_dubbo.ts │ │ └── example_pb.ts │ ├── package-lock.json │ ├── package.json │ ├── proto │ │ └── example.proto │ └── server.ts ├── dubbo-observable-example │ ├── README.md │ ├── buf.gen.yaml │ ├── client.ts │ ├── docker │ │ ├── README.md │ │ ├── docker-compose.yml │ │ └── prometheus.yml │ ├── dubbo.ts │ ├── gen │ │ ├── example_dubbo.ts │ │ └── example_pb.ts │ ├── package.json │ ├── proto │ │ └── example.proto │ └── server.ts └── dubbo-web-example │ ├── README.md │ ├── doc │ ├── arc.png │ └── web.png │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ └── vite.svg │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── index.css │ ├── main.tsx │ ├── util │ │ ├── gen │ │ │ ├── example_dubbo.ts │ │ │ └── example_pb.ts │ │ └── proto │ │ │ └── example.proto │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── internal └── proto │ ├── buf.yaml │ ├── grpc │ └── testing │ │ ├── empty.proto │ │ ├── messages.proto │ │ └── test.proto │ └── server │ └── v1 │ └── server.proto ├── lint ├── __license__ │ ├── .npmignore │ ├── Makefile │ ├── fix.go │ ├── fix.java │ ├── fix.js │ ├── fix.sh │ ├── fix.ts │ ├── fix.xml │ ├── fix.yml │ ├── fix_head.xml │ └── test.go ├── __notice__ │ ├── NOTICE │ └── NOTICE_1 ├── go.mod ├── lint.go ├── lint_color.go ├── lint_glob.go ├── lint_license.go ├── lint_license_comment.go ├── lint_license_test.go ├── lint_notice.go ├── lint_notice_test.go └── main.go ├── package.json ├── packages ├── dubbo-express │ ├── README.md │ ├── package.json │ ├── src │ │ ├── express-dubbo-middleware.ts │ │ └── index.ts │ └── tsconfig.json ├── dubbo-fastify │ ├── README.md │ ├── package.json │ ├── src │ │ ├── fastify-dubbo-plugin.ts │ │ └── index.ts │ └── tsconfig.json ├── dubbo-next │ ├── README.md │ ├── package.json │ ├── src │ │ ├── dubbo-nextjs-adapter.ts │ │ └── index.ts │ └── tsconfig.json ├── dubbo-node-test │ ├── README.md │ ├── buf.gen.yaml │ ├── dubbo-node-h1-server.mjs │ ├── jasmine.json │ ├── localhost-cert.pem │ ├── localhost-key.pem │ ├── package.json │ ├── src │ │ ├── badweather │ │ │ ├── broken-input.spec.ts │ │ │ ├── unsupported-content-encoding.spec.ts │ │ │ ├── unsupported-media-type.spec.ts │ │ │ └── unsupported-method.spec.ts │ │ ├── compression.spec.ts │ │ ├── crosstest │ │ │ ├── cacheable_unary.spec.ts │ │ │ ├── cancel_after_begin.spec.ts │ │ │ ├── cancel_after_first_response.spec.ts │ │ │ ├── client_streaming.spec.ts │ │ │ ├── custom_metadata.spec.ts │ │ │ ├── custom_metadata_server_streaming.spec.ts │ │ │ ├── empty_stream.spec.ts │ │ │ ├── empty_unary.spec.ts │ │ │ ├── empty_unary_with_timeout.spec.ts │ │ │ ├── fail_server_streaming.spec.ts │ │ │ ├── fail_server_streaming_after_response.spec.ts │ │ │ ├── fail_unary.spec.ts │ │ │ ├── large_unary.spec.ts │ │ │ ├── ping_pong.spec.ts │ │ │ ├── server_isolation.spec.ts │ │ │ ├── server_streaming.spec.ts │ │ │ ├── special_status.spec.ts │ │ │ ├── status_code_and_message.spec.ts │ │ │ ├── timeout_on_sleeping_server.spec.ts │ │ │ ├── unimplemented_method.spec.ts │ │ │ ├── unimplemented_server_streaming_method.spec.ts │ │ │ ├── unimplemented_server_streaming_service.spec.ts │ │ │ ├── unimplemented_service.spec.ts │ │ │ └── unresolvable_host.spec.ts │ │ ├── express-readme.spec.ts │ │ ├── extra │ │ │ ├── add-grpc-service.spec.ts │ │ │ ├── add-grpc-service.ts │ │ │ ├── create-grpc-client.spec.ts │ │ │ ├── create-grpc-client.ts │ │ │ ├── create-grpc-definition.ts │ │ │ └── protocol-name.spec.ts │ │ ├── gen │ │ │ ├── grpc │ │ │ │ └── testing │ │ │ │ │ ├── empty_pb.ts │ │ │ │ │ ├── messages_pb.ts │ │ │ │ │ └── test_dubbo.ts │ │ │ └── server │ │ │ │ └── v1 │ │ │ │ └── server_pb.ts │ │ ├── helpers │ │ │ ├── http2-request.ts │ │ │ ├── import-express.ts │ │ │ ├── interop.ts │ │ │ ├── test-routes.ts │ │ │ └── testserver.ts │ │ ├── node-readme.spec.ts │ │ └── transports.spec.ts │ └── tsconfig.json ├── dubbo-node │ ├── .npmignore │ ├── README.md │ ├── jasmine.json │ ├── package.json │ ├── src │ │ ├── compression.ts │ │ ├── dubbo-node-adapter.ts │ │ ├── dubbo-transport.ts │ │ ├── grpc-transport.ts │ │ ├── grpc-web-transport.ts │ │ ├── http2-session-manager.spec.ts │ │ ├── http2-session-manager.ts │ │ ├── index.ts │ │ ├── node-error.ts │ │ ├── node-headers-polyfill.ts │ │ ├── node-transport-options.ts │ │ ├── node-universal-client.spec.ts │ │ ├── node-universal-client.ts │ │ ├── node-universal-handler.spec.ts │ │ ├── node-universal-handler.ts │ │ ├── node-universal-header.spec.ts │ │ ├── node-universal-header.ts │ │ └── use-node-server-helper.spec.ts │ └── tsconfig.json ├── dubbo-observable │ ├── jasmine.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── meter-collector.ts │ │ ├── observable.ts │ │ ├── qps-counter.spec.ts │ │ └── qps-counter.ts │ └── tsconfig.json ├── dubbo-web-bench │ ├── README.md │ ├── buf.gen.yaml │ ├── package.json │ ├── report.mjs │ ├── src │ │ ├── entry-dubbo.ts │ │ ├── entry-grpcweb.ts │ │ └── gen │ │ │ ├── connectweb │ │ │ └── buf │ │ │ │ └── connect │ │ │ │ └── demo │ │ │ │ └── eliza │ │ │ │ └── v1 │ │ │ │ ├── eliza_dubbo.ts │ │ │ │ └── eliza_pb.ts │ │ │ └── grpcweb │ │ │ └── buf │ │ │ └── connect │ │ │ └── demo │ │ │ └── eliza │ │ │ └── v1 │ │ │ ├── eliza_grpc_web_pb.d.ts │ │ │ ├── eliza_grpc_web_pb.js │ │ │ ├── eliza_pb.d.ts │ │ │ └── eliza_pb.js │ └── tsconfig.json ├── dubbo-web-test │ ├── README.md │ ├── buf.gen.yaml │ ├── jasmine.json │ ├── karma-fixup-AbortController.js │ ├── karma-fixup-globalThis.js │ ├── karma-fixup-queueMicrotask.js │ ├── karma-fixup-symbolAsyncIterator.js │ ├── karma-fixup.cjs │ ├── karma.browserstack.conf.cjs │ ├── karma.conf.cjs │ ├── karma.serve.conf.cjs │ ├── package.json │ ├── src │ │ ├── browserstackonly │ │ │ ├── bigint.spec.ts │ │ │ ├── eliza.spec.ts │ │ │ └── headers.spec.ts │ │ ├── cancellation.spec.ts │ │ ├── crosstest │ │ │ ├── cacheable_unary.spec.ts │ │ │ ├── custom_metadata.spec.ts │ │ │ ├── custom_metadata_server_streaming.spec.ts │ │ │ ├── empty_stream.spec.ts │ │ │ ├── empty_unary.spec.ts │ │ │ ├── empty_unary_with_timeout.spec.ts │ │ │ ├── fail_server_streaming.spec.ts │ │ │ ├── fail_server_streaming_after_response.spec.ts │ │ │ ├── fail_unary.spec.ts │ │ │ ├── large_unary.spec.ts │ │ │ ├── server_streaming.spec.ts │ │ │ ├── special_status.spec.ts │ │ │ ├── status_code_and_message.spec.ts │ │ │ ├── timeout_on_sleeping_server.spec.ts │ │ │ ├── unimplemented_method.spec.ts │ │ │ ├── unimplemented_server_streaming_method.spec.ts │ │ │ ├── unimplemented_server_streaming_service.spec.ts │ │ │ └── unimplemented_service.spec.ts │ │ ├── fetch.spec.ts │ │ ├── gen │ │ │ ├── buf │ │ │ │ └── connect │ │ │ │ │ └── demo │ │ │ │ │ └── eliza │ │ │ │ │ └── v1 │ │ │ │ │ ├── eliza_dubbo.ts │ │ │ │ │ └── eliza_pb.ts │ │ │ ├── grpc │ │ │ │ └── testing │ │ │ │ │ ├── empty_pb.ts │ │ │ │ │ ├── messages_pb.ts │ │ │ │ │ └── test_dubbo.ts │ │ │ └── server │ │ │ │ └── v1 │ │ │ │ └── server_pb.ts │ │ ├── helpers │ │ │ ├── crosstestserver.ts │ │ │ ├── interop.ts │ │ │ └── test-routes.ts │ │ └── interceptor.spec.ts │ └── tsconfig.json ├── dubbo-web │ ├── README.md │ ├── package.json │ ├── src │ │ ├── assert-fetch-api.ts │ │ ├── dubbo-transport.ts │ │ ├── grpc-web-transport.ts │ │ └── index.ts │ └── tsconfig.json ├── dubbo │ ├── .npmignore │ ├── README.md │ ├── buf.gen.yaml │ ├── jasmine.json │ ├── package.json │ ├── protocol-dubbo.js │ ├── protocol-grpc-web.js │ ├── protocol-grpc.js │ ├── protocol.js │ ├── src │ │ ├── any-client.spec.ts │ │ ├── any-client.ts │ │ ├── call-options.ts │ │ ├── callback-client.ts │ │ ├── code.spec.ts │ │ ├── code.ts │ │ ├── cors.ts │ │ ├── dubbo-error.spec.ts │ │ ├── dubbo-error.ts │ │ ├── fetch-headers.spec.ts │ │ ├── http-headers.spec.ts │ │ ├── http-headers.ts │ │ ├── implementation.spec.ts │ │ ├── implementation.ts │ │ ├── index.ts │ │ ├── interceptor.spec.ts │ │ ├── interceptor.ts │ │ ├── legacy-interceptor.ts │ │ ├── node16-polyfill-helper.spec.ts │ │ ├── promise-client.spec.ts │ │ ├── promise-client.ts │ │ ├── protocol-grpc-web │ │ │ ├── content-type.spec.ts │ │ │ ├── content-type.ts │ │ │ ├── handler-factory.spec.ts │ │ │ ├── handler-factory.ts │ │ │ ├── headers.ts │ │ │ ├── index.ts │ │ │ ├── request-header.spec.ts │ │ │ ├── request-header.ts │ │ │ ├── trailer.spec.ts │ │ │ ├── trailer.ts │ │ │ ├── transport.spec.ts │ │ │ ├── transport.ts │ │ │ ├── validate-response.spec.ts │ │ │ └── validate-response.ts │ │ ├── protocol-grpc │ │ │ ├── content-type.spec.ts │ │ │ ├── content-type.ts │ │ │ ├── gen │ │ │ │ └── status_pb.ts │ │ │ ├── handler-factory.spec.ts │ │ │ ├── handler-factory.ts │ │ │ ├── headers.ts │ │ │ ├── http-status.ts │ │ │ ├── index.ts │ │ │ ├── parse-timeout.spec.ts │ │ │ ├── parse-timeout.ts │ │ │ ├── proto │ │ │ │ └── status.proto │ │ │ ├── request-header.spec.ts │ │ │ ├── request-header.ts │ │ │ ├── trailer-status.spec.ts │ │ │ ├── trailer-status.ts │ │ │ ├── transport.spec.ts │ │ │ ├── transport.ts │ │ │ ├── validate-response.spec.ts │ │ │ ├── validate-response.ts │ │ │ └── validate-trailer.ts │ │ ├── protocol-triple │ │ │ ├── client-service-options.ts │ │ │ ├── code-string.ts │ │ │ ├── content-type.spec.ts │ │ │ ├── content-type.ts │ │ │ ├── end-stream.spec.ts │ │ │ ├── end-stream.ts │ │ │ ├── error-json.spec.ts │ │ │ ├── error-json.ts │ │ │ ├── expand-handler.ts │ │ │ ├── get-request.ts │ │ │ ├── handler-factory.spec.ts │ │ │ ├── handler-factory.ts │ │ │ ├── headers.ts │ │ │ ├── http-status.ts │ │ │ ├── index.ts │ │ │ ├── parse-timeout.spec.ts │ │ │ ├── parse-timeout.ts │ │ │ ├── query-params.ts │ │ │ ├── request-header.spec.ts │ │ │ ├── request-header.ts │ │ │ ├── trailer-mux.spec.ts │ │ │ ├── trailer-mux.ts │ │ │ ├── transport.spec.ts │ │ │ ├── transport.ts │ │ │ ├── validate-response.spec.ts │ │ │ ├── validate-response.ts │ │ │ └── version.ts │ │ ├── protocol │ │ │ ├── async-iterable-helper.spec.ts │ │ │ ├── async-iterable-story.spec.ts │ │ │ ├── async-iterable.spec.ts │ │ │ ├── async-iterable.ts │ │ │ ├── compression.spec.ts │ │ │ ├── compression.ts │ │ │ ├── content-type-matcher.spec.ts │ │ │ ├── content-type-matcher.ts │ │ │ ├── create-method-url.spec.ts │ │ │ ├── create-method-url.ts │ │ │ ├── envelope.spec.ts │ │ │ ├── envelope.ts │ │ │ ├── index.ts │ │ │ ├── invoke-implementation.ts │ │ │ ├── limit-io.spec.ts │ │ │ ├── limit-io.ts │ │ │ ├── protocol-handler-factory.ts │ │ │ ├── run-call.spec.ts │ │ │ ├── run-call.ts │ │ │ ├── serialization.spec.ts │ │ │ ├── serialization.ts │ │ │ ├── signals.spec.ts │ │ │ ├── signals.ts │ │ │ ├── transport-options.ts │ │ │ ├── universal-fetch.ts │ │ │ ├── universal-handler-client.ts │ │ │ ├── universal-handler.spec.ts │ │ │ ├── universal-handler.ts │ │ │ └── universal.ts │ │ ├── router-transport.spec.ts │ │ ├── router-transport.ts │ │ ├── router.ts │ │ └── transport.ts │ └── tsconfig.json ├── protoc-gen-apache-dubbo-es │ ├── README.md │ ├── bin │ │ └── protoc-gen-apache-dubbo-es │ ├── package.json │ ├── src │ │ ├── declaration.ts │ │ ├── javascript.ts │ │ ├── protoc-gen-apache-dubbo-es-plugin.ts │ │ └── typescript.ts │ └── tsconfig.json └── protoc-gen-apache-dubbo-web │ ├── README.md │ ├── bin │ └── protoc-gen-apache-dubbo-web │ ├── package.json │ ├── src │ ├── declaration.ts │ ├── javascript.ts │ ├── protoc-gen-apache-dubbo-web-plugin.ts │ └── typescript.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── tsconfig.base.json /.asf.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # 19 | 20 | notifications: 21 | commits: commits@dubbo.apache.org 22 | issues: notifications@dubbo.apache.org 23 | pullrequests: notifications@dubbo.apache.org 24 | jira_options: link label link label 25 | 26 | github: 27 | homepage: https://dubbo.apache.org/ 28 | description: "The Typescript implementation of Apache Dubbo. An RPC and microservice framework for Node.js and Web development." 29 | labels: 30 | - rpc 31 | - nodejs 32 | - web 33 | - javascript 34 | - typescript 35 | - http 36 | - http2 37 | - microservices 38 | - service-mesh 39 | features: 40 | # Enable wiki for documentation 41 | wiki: true 42 | # Enable issue management 43 | issues: true 44 | # Enable projects for project management boards 45 | projects: true 46 | protected_branches: 47 | dubbo3: 48 | # only disable force push 49 | foo: bar 50 | dubbo2: 51 | # only disable force push 52 | foo: bar 53 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true 6 | }, 7 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], 8 | overrides: [], 9 | parser: '@typescript-eslint/parser', 10 | parserOptions: { 11 | ecmaVersion: 'latest', 12 | sourceType: 'module' 13 | }, 14 | plugins: ['@typescript-eslint'], 15 | rules: { 16 | indent: ['error', 2], 17 | 'linebreak-style': ['error', 'unix'], 18 | quotes: ['off'], 19 | semi: ['off'] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # This workflow will build a golang project 17 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 18 | 19 | name: Go 20 | 21 | on: 22 | push: 23 | branches: ['dubbo3'] 24 | pull_request: 25 | branches: ['dubbo3'] 26 | 27 | jobs: 28 | build: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - uses: actions/checkout@v3 32 | 33 | - name: Set up Go 34 | uses: actions/setup-go@v3 35 | with: 36 | go-version: 1.18 37 | 38 | - name: Build 39 | run: cd ./lint && go build -o ../dj_lint 40 | 41 | - name: Test 42 | run: ./dj_lint 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # compiled output 18 | dist 19 | lib 20 | /tmp 21 | /out-tsc 22 | .tmp/* 23 | .*.out 24 | 25 | # dependencies 26 | node_modules 27 | 28 | # IDEs and editors 29 | /.idea 30 | .project 31 | .classpath 32 | .c9/ 33 | *.launch 34 | .settings/ 35 | *.sublime-workspace 36 | *.iml 37 | 38 | # IDE - VSCode 39 | .vscode/* 40 | !.vscode/settings.json 41 | !.vscode/tasks.json 42 | !.vscode/launch.json 43 | !.vscode/extensions.json 44 | 45 | # misc 46 | /.sass-cache 47 | /connect.lock 48 | /coverage 49 | /libpeerconnection.log 50 | npm-debug.log 51 | yarn-error.log 52 | .pnpm-debug.log 53 | testem.log 54 | /typings 55 | dj_lint 56 | 57 | # System Files 58 | .DS_Store 59 | Thumbs.db 60 | 61 | # docs 62 | docs/.vitepress/cache 63 | 64 | # example data 65 | example/dubbo-observable-example/docker/*-data 66 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # . "$(dirname "$0")/_/husky.sh" 3 | 4 | # pnpm build-lint 5 | # ./dj-lint 6 | 7 | # npx pretty-quick --staged 8 | # pnpm test 9 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | auto-install-peers=true 3 | registry=https://registry.npmmirror.com 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | dist 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "semi": false, 6 | "printWidth": 80 7 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["nrwl.angular-console", "esbenp.prettier-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": ["codecov", "nrwl", "pnpm", "vitepress"] 3 | } 4 | -------------------------------------------------------------------------------- /CHANGE.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | welcome pull-request 2 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache Dubbo Js 2 | Copyright 2018-2024 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'body-leading-blank': [2, 'always'], 5 | 'footer-leading-blank': [1, 'always'], 6 | 'header-max-length': [2, 'always', 108], 7 | 'subject-empty': [2, 'never'], 8 | 'type-empty': [2, 'never'], 9 | 'subject-case': [0], 10 | 'type-enum': [ 11 | 2, 12 | 'always', 13 | [ 14 | 'feat', 15 | 'fix', 16 | 'perf', 17 | 'style', 18 | 'docs', 19 | 'test', 20 | 'refactor', 21 | 'build', 22 | 'ci', 23 | 'chore', 24 | 'revert', 25 | 'wip', 26 | 'workflow', 27 | 'types', 28 | 'release', 29 | ], 30 | ], 31 | }, 32 | } 33 | -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | # Dubbo-js API 2 | 3 | TODO... 4 | -------------------------------------------------------------------------------- /docs/config/index.md: -------------------------------------------------------------------------------- 1 | # Dubbo-js Options 2 | 3 | TODO... 4 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/GetRequestsAndCaching.md: -------------------------------------------------------------------------------- 1 | # GetRequestsAndCaching 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/GettingStarted.md: -------------------------------------------------------------------------------- 1 | # GettingStarted 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/ImplementingServices.md: -------------------------------------------------------------------------------- 1 | # ImplementingServices 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/Interceptors.md: -------------------------------------------------------------------------------- 1 | # Interceptors 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/ServerPlugins.md: -------------------------------------------------------------------------------- 1 | # ServerPlugins 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/Testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForNode/UsingClients.md: -------------------------------------------------------------------------------- 1 | # UsingClients 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/CancellationandTimeouts.md: -------------------------------------------------------------------------------- 1 | # CancellationandTimeouts 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/Choosingaprotocol.md: -------------------------------------------------------------------------------- 1 | # Choosing a protocol 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/CommonErrors.md: -------------------------------------------------------------------------------- 1 | # Common errors 2 | 3 | This section introduces common errors encountered when using Dubbo-js in browser and their corresponding solutions. 4 | 5 | ## CORS issues arise in browser requests 6 | 7 | Cross-origin issues stem from the Content Security Policy (CSP) of the browser, which prevents a page from properly handling responses when the browser sends a request whose URL differs in **scheme, domain, or port** from the target server's URL. For more detailed information, please refer to [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). 8 | 9 | To tackle this issue, our recommended approach is to configure CORS on the target server. 10 | 11 | 1. For a native Node.js server: 12 | ```typescript 13 | import { createServer } from "http"; 14 | import { dubboNodeAdapter } from "@apachedubbo/dubbo-node"; 15 | import dubboRoutes from "./router"; 16 | 17 | const server = createServer((req, res) => { 18 | res.setHeader("Access-Control-Allow-Origin", "*"); 19 | res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); 20 | res.setHeader("Access-Control-Allow-Headers", "*"); 21 | // replace "dubbo" with your actual service group 22 | res.setHeader("Tri-Service-Group", "dubbo"); 23 | // replace "1.0.0" with your actual service version 24 | res.setHeader("Tri-Service-Version", "1.0.0"); 25 | 26 | // Handling the preflight request (OPTIONS) 27 | if (req.method === "OPTIONS") { 28 | res.end(); 29 | return; 30 | } 31 | 32 | const handler = dubboNodeAdapter({ 33 | routes: dubboRoutes 34 | }); 35 | handler(req, res); 36 | }); 37 | 38 | server.listen(8000, () => { 39 | console.log("\ndubbo-js server is running on http://localhost:8000...\n"); 40 | }); 41 | ``` 42 | 2. For servers employing Node.js frameworks, we have devised some more convenient solutions to certain frameworks: 43 | - [express](/todo) 44 | - [fastify](/todo) 45 | - [next](/todo) 46 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/ConnectForTanStackQuery.md: -------------------------------------------------------------------------------- 1 | # ConnectForTanStackQuery 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/GeneratingCode.md: -------------------------------------------------------------------------------- 1 | # Generating code 2 | # todo 3 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/GetRequestsandCaching.md: -------------------------------------------------------------------------------- 1 | # Get Requests and Caching 2 | 3 | Dubbo supports performing idempotent, side-effect free requests using an HTTP GET-based protocol. This makes it easier to cache certain kinds of requests in the browser, on your CDN, or in proxies and other middleboxes. 4 | 5 | First, configure your server to handle HTTP GET requests using Dubbo. 6 | 7 | Afterwards, ensure that a new enough version of `@apachedubbo/dubbo-web` is set up; HTTP GET support is available inDubbo Web v3.3.0 or newer. Then, you can specify the `useHttpGet` option when creating the Dubbo transport: 8 | 9 | ```tsx 10 | const transport = createDubboTransport({ 11 | baseUrl: "http://localhost:8080", 12 | httpVersion: "1.1", 13 | }); 14 | const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); 15 | const res = client.say({ sentence: "Hello World" }); 16 | console.log(res); 17 | ``` 18 | 19 | Methods annotated as side-effect free will use GET requests. All other requests will continue to use POST. -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/HeadersandTrailers.md: -------------------------------------------------------------------------------- 1 | # HeadersandTrailers 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/Interceptors.md: -------------------------------------------------------------------------------- 1 | # Interceptors 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/SupportedBrowsersandFrameworks.md: -------------------------------------------------------------------------------- 1 | # Supported browsers and frameworks 2 | 3 | Dubbo-JS extends its support to all modern web browsers that embrace the widely implemented Fetch API and Encoding API standards. The library itself, along with the generated codebase, conforms to the ES2017 specification and is fully compatible with TypeScript 5. 4 | 5 | Embodying a neutral stance towards frameworks, Dubbo-JS comfortably operates in vanilla JavaScript environments and is equally adept at integrating with popular application and testing frameworks. These include React, Next.js from the React ecosystem, as well as others like Svelte, Vue, Playwright, and Vitest. Additionally, it harmoniously pairs with commonly used package managers such as npm, pnpm, and Yarn, offering immediate usability without additional configuration. 6 | 7 | Dubbo-JS also melds seamlessly with various module loaders and bundlers, including esbuild, Vite, and Rollup, catering to diverse development workflows. 8 | 9 | While striving for universality, it's worth noting that certain subtleties and common setup challenges may arise based on the specific tooling within your project. This section serves to shed light on these potential issues and presents actionable workarounds with accompanying examples to guide you through configuring Dubbo-JS in your technology stack effectively. 10 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/Testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | -------------------------------------------------------------------------------- /docs/guide/dubboForWEB/UsingClients.md: -------------------------------------------------------------------------------- 1 | # Using Clients 2 | # todo 3 | -------------------------------------------------------------------------------- /docs/guide/index.md: -------------------------------------------------------------------------------- 1 | # introduce 2 | -------------------------------------------------------------------------------- /docs/imgs/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/docs/imgs/arc.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Dubbo-js 5 | titleTemplate: blazing Fast Node RPC framework 6 | 7 | hero: 8 | name: Dubbo-js 9 | text: blazing Fast Node RPC framework 10 | image: 11 | src: /logo.png 12 | actions: 13 | - theme: brand 14 | text: Get Started 15 | link: /guide/ 16 | - theme: alt 17 | text: View on Github 18 | link: https://github.com/apache/dubbo-js 19 | --- 20 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dubbo-js-docs", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "dev": "vitepress dev", 6 | "build": "vitepress build" 7 | }, 8 | "devDependencies": { 9 | "vitepress": "^1.0.0-alpha.21", 10 | "vue": "^3.2.41", 11 | "@vuepress/plugin-search": "^1.8.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/docs/public/logo.png -------------------------------------------------------------------------------- /example/dubbo-node-example/client.ts: -------------------------------------------------------------------------------- 1 | import { createPromiseClient } from "@apachedubbo/dubbo"; 2 | import { ExampleService } from "./gen/example_dubbo"; 3 | import { createDubboTransport } from "@apachedubbo/dubbo-node"; 4 | 5 | const transport = createDubboTransport({ 6 | baseUrl: "http://localhost:8080", 7 | httpVersion: "1.1", 8 | }); 9 | 10 | async function main() { 11 | const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); 12 | const res = await client.say({ sentence: "Hello World" }); 13 | console.log(res); 14 | } 15 | void main(); -------------------------------------------------------------------------------- /example/dubbo-node-example/dubbo.ts: -------------------------------------------------------------------------------- 1 | import type { DubboRouter } from "@apachedubbo/dubbo"; 2 | import { ExampleService } from "./gen/example_dubbo"; 3 | 4 | export default (router: DubboRouter) => 5 | // registers apache.dubbo.demo.example.v1 6 | router.service(ExampleService, { 7 | // implements rpc Say 8 | async say(req) { 9 | return { 10 | sentence: `You said: ${req.sentence}`, 11 | }; 12 | }, 13 | }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); 14 | -------------------------------------------------------------------------------- /example/dubbo-node-example/gen/example_dubbo.ts: -------------------------------------------------------------------------------- 1 | // @generated by @apachedubbo/protoc-gen-apache-dubbo-es v3.0.0-alpha with parameter "target=ts" 2 | // @generated from file example.proto (package apache.dubbo.demo.example.v1, syntax proto3) 3 | /* eslint-disable */ 4 | // @ts-nocheck 5 | 6 | import { SayRequest, SayResponse } from "./example_pb.js"; 7 | import { MethodKind } from "@bufbuild/protobuf"; 8 | 9 | /** 10 | * @generated from service apache.dubbo.demo.example.v1.ExampleService 11 | */ 12 | export const ExampleService = { 13 | typeName: "apache.dubbo.demo.example.v1.ExampleService", 14 | methods: { 15 | /** 16 | * @generated from rpc apache.dubbo.demo.example.v1.ExampleService.Say 17 | */ 18 | say: { 19 | name: "Say", 20 | I: SayRequest, 21 | O: SayResponse, 22 | kind: MethodKind.Unary, 23 | }, 24 | } 25 | } as const; 26 | 27 | -------------------------------------------------------------------------------- /example/dubbo-node-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dubbo-node-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@bufbuild/protobuf": "^1.2.1", 13 | "@bufbuild/protoc-gen-es": "^1.2.1", 14 | "@fastify/cors": "^8.3.0", 15 | "@apachedubbo/dubbo": "3.0.0-alpha", 16 | "@apachedubbo/dubbo-fastify": "3.0.0-alpha", 17 | "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha", 18 | "fastify": "^4.19.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/dubbo-node-example/proto/example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package apache.dubbo.demo.example.v1; 4 | 5 | message SayRequest { 6 | string sentence = 1; 7 | } 8 | 9 | message SayResponse { 10 | string sentence = 1; 11 | } 12 | 13 | service ExampleService { 14 | rpc Say(SayRequest) returns (SayResponse) {} 15 | } -------------------------------------------------------------------------------- /example/dubbo-node-example/server.ts: -------------------------------------------------------------------------------- 1 | import { fastify } from "fastify"; 2 | import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify"; 3 | import routes from "./dubbo"; 4 | import cors from "@fastify/cors"; 5 | 6 | async function main() { 7 | const server = fastify(); 8 | await server.register(fastifyDubboPlugin, { 9 | routes, 10 | }); 11 | await server.register(cors, { 12 | origin: true, 13 | }); 14 | server.get("/", (_, reply) => { 15 | reply.type("text/plain"); 16 | reply.send("Hello World!"); 17 | }); 18 | await server.listen({ host: "localhost", port: 8080 }); 19 | console.log("server is listening at", server.addresses()); 20 | } 21 | 22 | void main(); -------------------------------------------------------------------------------- /example/dubbo-observable-example/README.md: -------------------------------------------------------------------------------- 1 | # 启动步骤 2 | 3 | 1. 启动服务提供者 4 | 5 | ```shell 6 | npx tsx server.ts 7 | ``` 8 | 9 | 2. 启动服务消费者 10 | 11 | ```shell 12 | npx tsx client.ts 13 | ``` 14 | 15 | 3. 请求服务 16 | 17 | ```shell 18 | 19 | curl localhost:8081/ 20 | 21 | ``` 22 | 23 | 4. 获取服务提供者监控指标 24 | 25 | ```shell 26 | curl http://localhost:9464/metrics 27 | ``` 28 | 29 | 5. 获取服务消费者监控指标 30 | 31 | ```shell 32 | curl http://localhost:9465/metrics 33 | ``` 34 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: es 4 | out: gen 5 | opt: 6 | - target=es 7 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/client.ts: -------------------------------------------------------------------------------- 1 | import { fastify } from "fastify"; 2 | import cors from "@fastify/cors"; 3 | import { createPromiseClient } from "@apachedubbo/dubbo"; 4 | import { ExampleService } from "./gen/example_dubbo"; 5 | import { createDubboTransport } from "@apachedubbo/dubbo-node"; 6 | import { PrometheusExporter } from '@opentelemetry/exporter-prometheus' 7 | // import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' 8 | // import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node' 9 | 10 | const transport = createDubboTransport({ 11 | baseUrl: "http://localhost:8080", 12 | httpVersion: "1.1", 13 | /** 14 | * Enable Observable Service on service consumer. 15 | */ 16 | observableOptions: { 17 | enable: true, 18 | configuration: { 19 | serviceName: "dubbo-observable-example", 20 | // instrumentations: [getNodeAutoInstrumentations()], 21 | // traceExporter: new ConsoleSpanExporter(), 22 | metricReader: new PrometheusExporter({ 23 | port: 9465 24 | }) 25 | } 26 | } 27 | }); 28 | 29 | async function main() { 30 | const server = fastify(); 31 | await server.register(cors, { 32 | origin: true, 33 | }); 34 | 35 | const client = createPromiseClient(ExampleService, transport, { serviceVersion: '1.0.0', serviceGroup: 'dubbo' }); 36 | 37 | server.get("/", (_, reply) => { 38 | client.say({ sentence: "Hello World" }).then(rs => { 39 | reply.type("application/json"); 40 | reply.send(rs.toJsonString()); 41 | }).catch(e => { 42 | reply.code(500); 43 | reply.send(String(e)); 44 | }); 45 | }); 46 | 47 | await server.listen({ host: "localhost", port: 8081 }); 48 | console.log("customer server is listening at", server.addresses()); 49 | } 50 | void main(); 51 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/docker/README.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 这个 docker compose 配置目前只提供了一套测试验证使用的指标采集及可视化展示环境, 3 | 指标采集和存储使用 [victoria-metrics](https://victoriametrics.com/),指标展示使用 [Grafana](https://grafana.com/)。详细使用步骤如下: 4 | 5 | 1. 启动服务 6 | ```shell 7 | cd dubbo-js/example/dubbo-observable-example/docker 8 | docker compose up -d 9 | ``` 10 | 11 | 2. 访问 Grafana 控制台: http://localhost:13000 12 | 13 | 3. 首次启动,需要添加 victoria metrics 数据源,如下: 14 | 1. 打开 [Grafana Data Source](http://localhost:13000/connections/datasources) 15 | 2. 点击 “+ Add new data source” 添加数据源 16 | 3. 选择 “Prometheus“数据源 17 | 4. Prometheus server URL 填写:http://vm:8428 18 | 5. 保存数据源 19 | 20 | 4. 默认配置采集 Provider 和 Consumer 指标,配置请查看 [prometheus.yml](prometheus.yml) 21 | 22 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | services: 3 | grafana: 4 | image: grafana/grafana-enterprise:10.0.0 5 | hostname: grafana 6 | networks: 7 | - dubbo-network 8 | volumes: 9 | - ./grafana-data:/var/lib/grafana 10 | ports: 11 | - "13000:3000" 12 | 13 | vm: 14 | image: victoriametrics/victoria-metrics:latest 15 | hostname: vm 16 | command: -storageDataPath /victoria-metrics-data -retentionPeriod 180d -promscrape.config /prometheus.yml -promscrape.httpSDCheckInterval 60s 17 | volumes: 18 | - ./prometheus.yml:/prometheus.yml 19 | - ./victoria-metrics-data:/victoria-metrics-data 20 | networks: 21 | - dubbo-network 22 | ports: 23 | - "18428:8428" 24 | 25 | networks: 26 | dubbo-network: 27 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/docker/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 1s 3 | 4 | scrape_configs: 5 | - job_name: dubbo_provider 6 | metrics_path: /metrics 7 | static_configs: 8 | - targets: 9 | - 'host.docker.internal:9464' 10 | - job_name: dubbo_customer 11 | metrics_path: /metrics 12 | static_configs: 13 | - targets: 14 | - 'host.docker.internal:9465' 15 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/dubbo.ts: -------------------------------------------------------------------------------- 1 | import type { DubboRouter } from "@apachedubbo/dubbo"; 2 | import { ExampleService } from "./gen/example_dubbo"; 3 | 4 | export default (router: DubboRouter) => 5 | // registers apache.dubbo.demo.example.v1 6 | router.service(ExampleService, { 7 | // implements rpc Say 8 | async say(req) { 9 | return { 10 | sentence: `You said: ${req.sentence}`, 11 | }; 12 | }, 13 | }, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); 14 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/gen/example_dubbo.ts: -------------------------------------------------------------------------------- 1 | // @generated by @apachedubbo/protoc-gen-apache-dubbo-es v3.0.0-alpha with parameter "target=ts" 2 | // @generated from file example.proto (package apache.dubbo.demo.example.v1, syntax proto3) 3 | /* eslint-disable */ 4 | // @ts-nocheck 5 | 6 | import { SayRequest, SayResponse } from "./example_pb.js"; 7 | import { MethodKind } from "@bufbuild/protobuf"; 8 | 9 | /** 10 | * @generated from service apache.dubbo.demo.example.v1.ExampleService 11 | */ 12 | export const ExampleService = { 13 | typeName: "apache.dubbo.demo.example.v1.ExampleService", 14 | methods: { 15 | /** 16 | * @generated from rpc apache.dubbo.demo.example.v1.ExampleService.Say 17 | */ 18 | say: { 19 | name: "Say", 20 | I: SayRequest, 21 | O: SayResponse, 22 | kind: MethodKind.Unary, 23 | }, 24 | } 25 | } as const; 26 | 27 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dubbo-observable-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@apachedubbo/dubbo": "workspace:3.0.0-alpha", 13 | "@apachedubbo/dubbo-fastify": "3.0.0-alpha", 14 | "@apachedubbo/dubbo-node": "3.0.0-alpha", 15 | "@apachedubbo/protoc-gen-apache-dubbo-es": "workspace:3.0.0-alpha", 16 | "@bufbuild/protobuf": "^1.8.0", 17 | "@bufbuild/protoc-gen-es": "^1.8.0", 18 | "@fastify/cors": "^8.5.0", 19 | "@opentelemetry/auto-instrumentations-node": "^0.44.0", 20 | "@opentelemetry/exporter-prometheus": "^0.50.0", 21 | "@opentelemetry/sdk-trace-node": "^1.23.0", 22 | "fastify": "^4.19.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/proto/example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package apache.dubbo.demo.example.v1; 4 | 5 | message SayRequest { 6 | string sentence = 1; 7 | } 8 | 9 | message SayResponse { 10 | string sentence = 1; 11 | } 12 | 13 | service ExampleService { 14 | rpc Say(SayRequest) returns (SayResponse) {} 15 | } 16 | -------------------------------------------------------------------------------- /example/dubbo-observable-example/server.ts: -------------------------------------------------------------------------------- 1 | import { fastify } from "fastify"; 2 | import { fastifyDubboPlugin } from "@apachedubbo/dubbo-fastify"; 3 | import routes from "./dubbo"; 4 | import cors from "@fastify/cors"; 5 | import { PrometheusExporter } from '@opentelemetry/exporter-prometheus' 6 | // import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' 7 | // import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node' 8 | 9 | async function main() { 10 | const server = fastify(); 11 | await server.register(fastifyDubboPlugin, { 12 | routes, 13 | /** 14 | * Enable Observable Service on service provider. 15 | */ 16 | observableOptions: { 17 | enable: true, 18 | configuration: { 19 | serviceName: "dubbo-observable-example", 20 | // instrumentations: [getNodeAutoInstrumentations()], 21 | // traceExporter: new ConsoleSpanExporter(), 22 | metricReader: new PrometheusExporter({ 23 | port: 9464 24 | }) 25 | } 26 | } 27 | }); 28 | await server.register(cors, { 29 | origin: true, 30 | }); 31 | server.get("/", (_, reply) => { 32 | reply.type("text/plain"); 33 | reply.send("Hello World!"); 34 | }); 35 | await server.listen({ host: "localhost", port: 8080 }); 36 | console.log("provider server is listening at", server.addresses()); 37 | } 38 | 39 | void main(); 40 | -------------------------------------------------------------------------------- /example/dubbo-web-example/doc/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/example/dubbo-web-example/doc/arc.png -------------------------------------------------------------------------------- /example/dubbo-web-example/doc/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/example/dubbo-web-example/doc/web.png -------------------------------------------------------------------------------- /example/dubbo-web-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/dubbo-web-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dubbo-web-example", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@bufbuild/protobuf": "^1.2.1", 14 | "@bufbuild/protoc-gen-es": "^1.2.1", 15 | "@apachedubbo/dubbo": "3.0.0-alpha", 16 | "@apachedubbo/dubbo-web": "3.0.0-alpha", 17 | "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha", 18 | "react": "^18.2.0", 19 | "react-dom": "^18.2.0" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^18.2.14", 23 | "@types/react-dom": "^18.2.6", 24 | "@typescript-eslint/eslint-plugin": "^5.61.0", 25 | "@typescript-eslint/parser": "^5.61.0", 26 | "@vitejs/plugin-react": "^4.0.1", 27 | "eslint": "^8.44.0", 28 | "eslint-plugin-react-hooks": "^4.6.0", 29 | "eslint-plugin-react-refresh": "^0.4.1", 30 | "typescript": "^5.0.2", 31 | "vite": "^4.4.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/dubbo-web-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/dubbo-web-example/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /example/dubbo-web-example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./App.css"; 3 | 4 | import { createPromiseClient } from "@apachedubbo/dubbo"; 5 | import { createDubboTransport } from "@apachedubbo/dubbo-web"; 6 | 7 | // Import service definition that you want to connect to. 8 | import { ExampleService } from "./util/gen/example_dubbo"; 9 | 10 | // The transport defines what type of endpoint we're hitting. 11 | // In our example we'll be communicating with a Dubbo endpoint. 12 | const transport = createDubboTransport({ 13 | baseUrl: "http://localhost:8080", 14 | }); 15 | 16 | // Here we make the client itself, combining the service 17 | // definition with the transport. 18 | const client = createPromiseClient(ExampleService, transport, { serviceGroup: 'dubbo', serviceVersion: '1.0.0' }); 19 | 20 | function App() { 21 | const [inputValue, setInputValue] = useState(""); 22 | const [messages, setMessages] = useState< 23 | { 24 | fromMe: boolean; 25 | message: string; 26 | }[] 27 | >([]); 28 | return ( 29 | <> 30 |
    31 | {messages.map((msg, index) => ( 32 |
  1. {`${msg.fromMe ? "ME:" : "Dubbo Server:"} ${msg.message}`}
  2. 33 | ))} 34 |
35 |
{ 37 | e.preventDefault(); 38 | // Clear inputValue since the user has submitted. 39 | setInputValue(""); 40 | // Store the inputValue in the chain of messages and 41 | // mark this message as coming from "me" 42 | setMessages((prev) => [ 43 | ...prev, 44 | { 45 | fromMe: true, 46 | message: inputValue, 47 | }, 48 | ]); 49 | const response = await client.say({ 50 | sentence: inputValue, 51 | }); 52 | setMessages((prev) => [ 53 | ...prev, 54 | { 55 | fromMe: false, 56 | message: response.sentence, 57 | }, 58 | ]); 59 | }} 60 | > 61 | setInputValue(e.target.value)} /> 62 | 63 |
64 | 65 | ); 66 | } 67 | 68 | export default App; -------------------------------------------------------------------------------- /example/dubbo-web-example/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/dubbo-web-example/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /example/dubbo-web-example/src/util/gen/example_dubbo.ts: -------------------------------------------------------------------------------- 1 | // @generated by @apachedubbo/protoc-gen-apache-dubbo-es v3.0.0-alpha with parameter "target=ts" 2 | // @generated from file example.proto (package apache.dubbo.demo.example.v1, syntax proto3) 3 | /* eslint-disable */ 4 | // @ts-nocheck 5 | 6 | import { SayRequest, SayResponse } from "./example_pb.js"; 7 | import { MethodKind } from "@bufbuild/protobuf"; 8 | 9 | /** 10 | * @generated from service apache.dubbo.demo.example.v1.ExampleService 11 | */ 12 | export const ExampleService = { 13 | typeName: "apache.dubbo.demo.example.v1.ExampleService", 14 | methods: { 15 | /** 16 | * @generated from rpc apache.dubbo.demo.example.v1.ExampleService.Say 17 | */ 18 | say: { 19 | name: "Say", 20 | I: SayRequest, 21 | O: SayResponse, 22 | kind: MethodKind.Unary, 23 | }, 24 | } 25 | } as const; 26 | 27 | -------------------------------------------------------------------------------- /example/dubbo-web-example/src/util/proto/example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package apache.dubbo.demo.example.v1; 4 | 5 | message SayRequest { 6 | string sentence = 1; 7 | } 8 | 9 | message SayResponse { 10 | string sentence = 1; 11 | } 12 | 13 | service ExampleService { 14 | rpc Say(SayRequest) returns (SayResponse) {} 15 | } -------------------------------------------------------------------------------- /example/dubbo-web-example/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/dubbo-web-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /example/dubbo-web-example/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /example/dubbo-web-example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /internal/proto/buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | lint: 3 | use: 4 | - DEFAULT 5 | ignore: 6 | # We don't control these definitions, so we ignore lint errors. 7 | - grpc/testing/empty.proto 8 | - grpc/testing/messages.proto 9 | - grpc/testing/test.proto 10 | breaking: 11 | use: 12 | - WIRE_JSON 13 | -------------------------------------------------------------------------------- /internal/proto/grpc/testing/empty.proto: -------------------------------------------------------------------------------- 1 | // This is copied from gRPC's testing Protobuf definitions: https://github.com/grpc/grpc/blob/master/src/proto/grpc/testing/empty.proto 2 | 3 | // Copyright 2015 gRPC authors. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | syntax = "proto3"; 18 | 19 | package grpc.testing; 20 | 21 | // An empty message that you can re-use to avoid defining duplicated empty 22 | // messages in your project. A typical example is to use it as argument or the 23 | // return value of a service API. For instance: 24 | // 25 | // service Foo { 26 | // rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; 27 | // }; 28 | // 29 | message Empty {} 30 | -------------------------------------------------------------------------------- /internal/proto/server/v1/server.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package server.v1; 18 | 19 | // ServerMetadata is the metadata returned from the server started by the server binary. 20 | message ServerMetadata { 21 | string host = 1; 22 | repeated ProtocolSupport protocols = 2; 23 | } 24 | 25 | enum Protocol { 26 | PROTOCOL_UNSPECIFIED = 0; 27 | PROTOCOL_GRPC = 1; 28 | PROTOCOL_GRPC_WEB = 2; 29 | } 30 | 31 | message ProtocolSupport { 32 | Protocol protocol = 1; 33 | repeated HTTPVersion http_versions = 2; 34 | string port = 3; 35 | } 36 | 37 | message HTTPVersion { 38 | int32 major = 1; 39 | int32 minor = 2; 40 | } 41 | -------------------------------------------------------------------------------- /lint/__license__/.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/lint/__license__/.npmignore -------------------------------------------------------------------------------- /lint/__license__/Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-js/55ad68a53a114a858cea773017c737d3adb5b280/lint/__license__/Makefile -------------------------------------------------------------------------------- /lint/__license__/fix.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main -------------------------------------------------------------------------------- /lint/__license__/fix.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | public class fix {} -------------------------------------------------------------------------------- /lint/__license__/fix.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | console.log('hello') 19 | -------------------------------------------------------------------------------- /lint/__license__/fix.sh: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo 'hello' -------------------------------------------------------------------------------- /lint/__license__/fix.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | console.log('hello') 19 | -------------------------------------------------------------------------------- /lint/__license__/fix.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /lint/__license__/fix.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | version: 1 17 | -------------------------------------------------------------------------------- /lint/__license__/fix_head.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 20 | -------------------------------------------------------------------------------- /lint/__license__/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | -------------------------------------------------------------------------------- /lint/__notice__/NOTICE: -------------------------------------------------------------------------------- 1 | Apache Dubbo Js 2 | Copyright 2018-2021 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /lint/__notice__/NOTICE_1: -------------------------------------------------------------------------------- 1 | Copyright 2018-2022 The Apache Software Foundation -------------------------------------------------------------------------------- /lint/go.mod: -------------------------------------------------------------------------------- 1 | module lint 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /lint/lint_color.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main 19 | 20 | import "fmt" 21 | 22 | // failed, show red text 23 | func failed(text string) string { 24 | return fmt.Sprintf("\033[91m%s\033[0m", text) 25 | } 26 | 27 | // success, show green text 28 | func success(text string) string { 29 | return fmt.Sprintf("\033[92m%s\033[0m", text) 30 | } 31 | 32 | // warning, show yellow text 33 | func warn(text string) string { 34 | return fmt.Sprintf("\033[93m%s\033[0m", text) 35 | } 36 | -------------------------------------------------------------------------------- /lint/lint_glob.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main 19 | 20 | import ( 21 | "io/fs" 22 | "path/filepath" 23 | ) 24 | 25 | // G is a dir and file filter setting 26 | type G struct { 27 | DirFilter func(root string) bool 28 | FileFilter func(root string) bool 29 | } 30 | 31 | // glob files with given filter 32 | func glob(dir string, g G) ([]string, error) { 33 | var files []string 34 | 35 | err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { 36 | if err != nil { 37 | return err 38 | } 39 | 40 | if d.IsDir() { 41 | // skip dir 42 | if g.DirFilter != nil && !g.DirFilter(path) { 43 | return filepath.SkipDir 44 | } 45 | return nil 46 | } 47 | 48 | // collect files 49 | if g.FileFilter != nil && g.FileFilter(path) { 50 | files = append(files, path) 51 | } 52 | 53 | return nil 54 | }) 55 | 56 | if err != nil { 57 | return nil, err 58 | } 59 | 60 | return files, nil 61 | } 62 | -------------------------------------------------------------------------------- /lint/lint_notice_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main 19 | 20 | import ( 21 | "os" 22 | "testing" 23 | ) 24 | 25 | func TestNoticeLinter_lint(t *testing.T) { 26 | l := NoticeLinter{ 27 | File: "./__notice__/NOTICE", 28 | } 29 | err := l.lint() 30 | if err == nil { 31 | t.Fatalf("lint error") 32 | } 33 | } 34 | 35 | func TestNoticeLinter_fixed(t *testing.T) { 36 | // write test data 37 | os.WriteFile("./__notice__/NOTICE_1", []byte("Copyright 2018-2021 The Apache Software Foundation"), 0644) 38 | 39 | // init notice linter 40 | l := NoticeLinter{ 41 | File: "./__notice__/NOTICE_1", 42 | } 43 | 44 | // fixed notice 45 | err := l.fix() 46 | if err != nil { 47 | t.Fatalf("fixed error") 48 | } 49 | 50 | // check notice 51 | err = l.lint() 52 | if err != nil { 53 | t.Fatalf("lint error") 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lint/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main 19 | 20 | import ( 21 | "flag" 22 | ) 23 | 24 | var ( 25 | fix = flag.String("fix", "", "fix mode") 26 | ) 27 | 28 | func main() { 29 | flag.Parse() 30 | 31 | switch *fix { 32 | case "": 33 | // lint all files 34 | lint(nl, ll) 35 | case "all": 36 | // fix all files 37 | fix_all(nl, ll) 38 | default: 39 | // fix single file 40 | fix_one(nl, ll, *fix) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "dubbo-js-private-workspace", 4 | "scripts": { 5 | "prepare": "husky install", 6 | "build": "npm run build --workspace=./packages/dubbo-observable && npm run build --workspace=./packages/dubbo && npm run build --workspace=./packages/dubbo-node && npm run build --workspace=./packages/dubbo-web && npm run build --workspace=./packages/dubbo-fastify && npm run build --workspace=./packages/dubbo-next && npm run build --workspace=./packages/dubbo-express" 7 | }, 8 | "workspaces": [ 9 | "./packages/dubbo", 10 | "./packages/protoc-gen-apache-dubbo-es", 11 | "./packages/protoc-gen-apache-dubbo-web", 12 | "./packages/dubbo-web", 13 | "./packages/dubbo-node", 14 | "./packages/dubbo-fastify", 15 | "./packages/dubbo-next", 16 | "./packages/dubbo-express", 17 | "./packages/dubbo-node-test", 18 | "./packages/dubbo-web-test", 19 | "./packages/dubbo-web-bench", 20 | "./packages/dubbo-observable" 21 | ], 22 | "engines": { 23 | "node": ">=16", 24 | "npm": ">=8" 25 | }, 26 | "engineStrict": true, 27 | "devDependencies": { 28 | "@commitlint/cli": "^19.2.1", 29 | "@commitlint/config-conventional": "^19.1.0", 30 | "@types/node": "^20.4.0", 31 | "@typescript-eslint/eslint-plugin": "^5.59.1", 32 | "@typescript-eslint/parser": "^5.59.2", 33 | "eslint": "^8.39.0", 34 | "eslint-import-resolver-typescript": "^3.5.5", 35 | "eslint-plugin-import": "^2.27.5", 36 | "eslint-plugin-node": "^11.1.0", 37 | "husky": "^6.0.0", 38 | "prettier": "^2.8.8", 39 | "typescript": "5.0.3" 40 | }, 41 | "license": "Apache-2.0" 42 | } 43 | -------------------------------------------------------------------------------- /packages/dubbo-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-express", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-express" 9 | }, 10 | "sideEffects": false, 11 | "scripts": { 12 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 13 | "build": "npm run build:cjs && npm run build:esm+types", 14 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 15 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "dependencies": { 29 | "@apachedubbo/dubbo": "3.0.0-alpha", 30 | "@apachedubbo/dubbo-node": "3.0.0-alpha", 31 | "@types/express": "^4.17.17" 32 | }, 33 | "peerDependencies": { 34 | "@bufbuild/protobuf": "^1.2.1" 35 | }, 36 | "files": [ 37 | "dist/**" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /packages/dubbo-express/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { expressDubboMiddleware } from "./express-dubbo-middleware.js"; 16 | -------------------------------------------------------------------------------- /packages/dubbo-express/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo-fastify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-fastify", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-fastify" 9 | }, 10 | "sideEffects": false, 11 | "scripts": { 12 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 13 | "build": "npm run build:cjs && npm run build:esm+types", 14 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 15 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "dependencies": { 29 | "@apachedubbo/dubbo": "3.0.0-alpha", 30 | "@apachedubbo/dubbo-observable": "3.0.0-alpha", 31 | "@apachedubbo/dubbo-node": "3.0.0-alpha", 32 | "fastify": "^4.17.0" 33 | }, 34 | "peerDependencies": { 35 | "@bufbuild/protobuf": "^1.2.1" 36 | }, 37 | "files": [ 38 | "dist/**" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /packages/dubbo-fastify/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { fastifyDubboPlugin } from "./fastify-dubbo-plugin.js"; 16 | -------------------------------------------------------------------------------- /packages/dubbo-fastify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo-next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-next", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-next" 9 | }, 10 | "sideEffects": false, 11 | "scripts": { 12 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 13 | "build": "npm run build:cjs && npm run build:esm+types", 14 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 15 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "dependencies": { 29 | "@apachedubbo/dubbo": "3.0.0-alpha", 30 | "@apachedubbo/dubbo-node": "3.0.0-alpha" 31 | }, 32 | "peerDependencies": { 33 | "@bufbuild/protobuf": "^1.2.1", 34 | "next": "^13.2.4" 35 | }, 36 | "files": [ 37 | "dist/**" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /packages/dubbo-next/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { nextJsApiRouter } from "./dubbo-nextjs-adapter.js"; 16 | -------------------------------------------------------------------------------- /packages/dubbo-next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | // We see a row of errors from Next.js typings here, most likely simply 6 | // because of dependencies we do not install. For simplicity, we are 7 | // ignoring them, because we do not want to check Next.js typings. 8 | "skipLibCheck": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/README.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | This package provides test coverage for @apachedubbo/dubbo-node with the test 4 | framework [Jasmine](https://jasmine.github.io/). 5 | 6 | Run the suite with `make testnode` from the project root. 7 | 8 | The tests run against: 9 | - dubbo-go (h1/h2) via Docker 10 | - grpc-go (h2) via Docker 11 | - @apachedubbo/dubbo-node (h1) 12 | 13 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: es 4 | out: src/gen 5 | opt: ts_nocheck=false,target=ts 6 | - plugin: apache-dubbo-es 7 | out: src/gen 8 | opt: ts_nocheck=false,target=ts 9 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "dist/esm", 3 | "spec_files": ["**/*.spec.js"], 4 | "helpers": ["helpers/**/*.js"], 5 | "env": { 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/localhost-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICpDCCAYwCCQD+JTyt/fekUTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls 3 | b2NhbGhvc3QwHhcNMjMwMjAzMTUwNjUzWhcNMjMxMTMwMTUwNjUzWjAUMRIwEAYD 4 | VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDo 5 | qr8+izYMjJ+N48c/JXACjvy/N7QaKpDNgPUc7daXbTAPCFc/FkETM33JXhROk/yv 6 | t8P+wYB95uGYDH4iURudjU/Jwiue/gLV5qhoWI28d0czMWO6XThP4gFJ70sVSPpU 7 | 7Hb6SJaQbr444OjAEnXzEEfjNwXLhZp35v/LPq5URS/XK1ogsKjAqnDV0dzd3nvp 8 | d5oIEIA2xJ6fx1ReKaTb6r0JeGtaTxtwrDTasutlVcpVVd3k4Y7sLFjmNYMZr6/N 9 | ZuctZqTf+VMSUiRQCpVk2UqwJgHsfeZDSFDeuw6BsjEoNvH7QuS7FSlbLj5lO29a 10 | 4nDuaDyH/AZGIXMgaur9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABJduliHc3y4 11 | 5TKvkxm0D8Uqg0PZTrkynUrJVtXndtvVcNq4jflCOiQ9jXeReYf8Td/CcIZni1TB 12 | 4jKJ9qMqdBBF720GEfPpYvDcp7xR7nrYgvzfCFATESYHseV8tqqAf7HWKj5eVsed 13 | UGfDyqAHuo3q4FBwc2atZXQmL2PdJZGY35nFn+km4Kv4/lexBtx4Dwu1wf+atTwX 14 | sPAe6pAnMXDQWOuD6eSh1ZBUydgyzEJdjigWAS50ItumB8LsFydqSiBF261yeZ4u 15 | SGon8TuNlh8/myWH+/n7OFA9SFa0OCp/7xzQIR1MphfDVSn+k9XdVqGnOT/xFbe5 16 | aFfhxTHgCHM= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/localhost-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDoqr8+izYMjJ+N 3 | 48c/JXACjvy/N7QaKpDNgPUc7daXbTAPCFc/FkETM33JXhROk/yvt8P+wYB95uGY 4 | DH4iURudjU/Jwiue/gLV5qhoWI28d0czMWO6XThP4gFJ70sVSPpU7Hb6SJaQbr44 5 | 4OjAEnXzEEfjNwXLhZp35v/LPq5URS/XK1ogsKjAqnDV0dzd3nvpd5oIEIA2xJ6f 6 | x1ReKaTb6r0JeGtaTxtwrDTasutlVcpVVd3k4Y7sLFjmNYMZr6/NZuctZqTf+VMS 7 | UiRQCpVk2UqwJgHsfeZDSFDeuw6BsjEoNvH7QuS7FSlbLj5lO29a4nDuaDyH/AZG 8 | IXMgaur9AgMBAAECggEAJtXRRCRCakfSngFmEYEzOAob3+LxWei+8L5Uq3Z7eh0M 9 | h4XR4kLZq9XNah4c75y98aqPuWcdBmbSQuna5+l33Y1nwvp5A3nMiV2NwJT/W3Th 10 | Wock6UeEDblgk7Gwa6YZurEZjt8s2oDRmXbZAq5SJ7cQ+LkHa5gqV1ckXQ1iVchB 11 | D/UKwEUnU6l71HST+Y/kXujff8sXh6LFYqI+NuTlcqs0gkiQ4coXFegg+uxjzUpr 12 | noF21fjDRizd2bvCwXDRDDFRwbCfXpqj/CYrR37gHr0w+zmk0MUgkoK/aHEhO454 13 | SyUJxYg8pVwMLqOqqBHUWJqFWwkvxgsrj0lrIeiZ4QKBgQD+X20OY3b4r+ISjHkn 14 | 6e2QVz6RdyeuADSkPBgar1WECDvxEyPTvNKTBVPyE/kBMUmjebBeApnrFEexwbke 15 | 1DezXMEdedAxo1OlDlydKqhNdYNSLLeRYXQ1EE4ymSwV86cmV6j9cO+hffjF1uQn 16 | 5Dx3asYItUAoT/cRAI+5Zva9yQKBgQDqJ8ZIbp5Z8tr2N40SU1sxSrjxJeA/jlaS 17 | PSA3VucfgMybe/T9OHVf6N7r56sVh2Dq8wYM37EKBSZ7yXuPp6b3hnk7ECK/LDfo 18 | gNTNGp15lKTSAaxcmDEAGPIpzgGCqQ58ZWL9fXohSocXa0yPyCbQMLp39cqdJDjf 19 | xw5JhnFNlQKBgHd05ukf6solBv0A/RCyeb8USazUkUzUieQq2IMHnhhQKZ4wB94y 20 | yY0DroV7va9CrztXNW0guZm9P2IKAN6qeLIBuCsYfp4g/nIACZxBYSJnMlGP8HEU 21 | nBcjXiXC6wIwF2oZNqI2vEJRv1dhcGoPdBn8iZ2jSMrlqrhQVC6UXQGJAoGBANMS 22 | L4azUEK8y+wOfzf5s8ZnGPcnsVEZOahxOU0pJQYc0FOIFXr9HbDq9aepGWs6sX6Y 23 | uud37NqfceU75gnEkpmlujonfWrerTcEis6oIzOpbjlwELMW7XStB/3vGSVyxwAT 24 | VHw0U5cW21ec/VLOlU4t3qisA4xLTolJofNdIV1RAoGBANYZH/lIwdTEUfOAqUqf 25 | WU2X9+jzMoM9ApoyN+9rKgvelxzvXkcoHDOKzZ4W2owy3Uxi3+ynnsWU1+flkb9F 26 | bH8QvzanfFAb2Qnmnj3TZ8OPQLVSjz90UYjGbdMLSedQOakOHkgL6DHVuXC23BZ9 27 | GElVgo1TCKx7sGS10omiCH5c 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-node-test", 3 | "private": true, 4 | "scripts": { 5 | "clean": "rm -rf ./dist/esm/*", 6 | "generate": "buf generate", 7 | "build": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm", 8 | "jasmine": "jasmine --config=jasmine.json" 9 | }, 10 | "type": "module", 11 | "types": "./dist/types/index.d.ts", 12 | "exports": { 13 | "import": "./dist/esm/index.js", 14 | "default": "./dist/esm/index.js" 15 | }, 16 | "dependencies": { 17 | "@bufbuild/protoc-gen-es": "^1.2.1", 18 | "@grpc/grpc-js": "^1.8.14", 19 | "@types/express": "^4.17.17", 20 | "@types/jasmine": "^4.3.0", 21 | "@apachedubbo/dubbo": "3.0.0-alpha", 22 | "@apachedubbo/dubbo-express": "3.0.0-alpha", 23 | "@apachedubbo/dubbo-fastify": "3.0.0-alpha", 24 | "@apachedubbo/dubbo-node": "3.0.0-alpha", 25 | "@apachedubbo/dubbo-web": "3.0.0-alpha", 26 | "esbuild": "^0.16.12", 27 | "express": "^4.18.2", 28 | "fastify": "^4.17.0", 29 | "jasmine": "^5.0.0", 30 | "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha" 31 | }, 32 | "peerDependencies": { 33 | "@bufbuild/protobuf": "^1.2.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/client_streaming.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { PayloadType } from "../gen/grpc/testing/messages_pb.js"; 18 | import { createTestServers } from "../helpers/testserver.js"; 19 | import { interop } from "../helpers/interop.js"; 20 | 21 | describe("client_streaming", () => { 22 | const sizes = [31415, 9, 2653, 58979]; 23 | const servers = createTestServers(); 24 | beforeAll(async () => await servers.start()); 25 | 26 | servers.describeTransports((transport) => { 27 | it("with promise client", async function () { 28 | async function* input() { 29 | for (const size of sizes) { 30 | yield { 31 | payload: interop.makeServerPayload(PayloadType.COMPRESSABLE, size), 32 | expectCompressed: { 33 | value: false, 34 | }, 35 | }; 36 | } 37 | await new Promise((resolve) => setTimeout(resolve, 1)); 38 | } 39 | const client = createPromiseClient(TestService, transport()); 40 | const { aggregatedPayloadSize } = await client.streamingInputCall( 41 | input() 42 | ); 43 | expect(aggregatedPayloadSize).toBe(sizes.reduce((p, c) => p + c, 0)); 44 | }); 45 | }); 46 | 47 | afterAll(async () => await servers.stop()); 48 | }); 49 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/empty_stream.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { StreamingOutputCallRequest } from "../gen/grpc/testing/messages_pb.js"; 18 | import { createTestServers } from "../helpers/testserver.js"; 19 | 20 | describe("empty_stream", function () { 21 | const servers = createTestServers(); 22 | beforeAll(async () => await servers.start()); 23 | 24 | servers.describeTransports((transport) => { 25 | const request = new StreamingOutputCallRequest(); 26 | it("with promise client", async function () { 27 | const client = createPromiseClient(TestService, transport()); 28 | try { 29 | for await (const response of client.streamingOutputCall(request)) { 30 | fail( 31 | `expecting no response in the empty stream, got: ${response.toJsonString()}` 32 | ); 33 | } 34 | } catch (e) { 35 | fail(`expecting no error in the empty stream, got: ${String(e)}`); 36 | } 37 | }); 38 | it("with callback client", function (done) { 39 | const client = createCallbackClient(TestService, transport()); 40 | client.streamingOutputCall( 41 | request, 42 | () => { 43 | fail("expecting no response in the empty stream"); 44 | }, 45 | (err) => { 46 | expect(err).toBeUndefined(); 47 | done(); 48 | } 49 | ); 50 | }); 51 | }); 52 | 53 | afterAll(async () => await servers.stop()); 54 | }); 55 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/empty_unary.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { Empty } from "../gen/grpc/testing/empty_pb.js"; 18 | import { createTestServers } from "../helpers/testserver.js"; 19 | 20 | describe("empty_unary", function () { 21 | const servers = createTestServers(); 22 | beforeAll(async () => await servers.start()); 23 | 24 | servers.describeTransports((transport) => { 25 | const empty = new Empty(); 26 | it("with promise client", async function () { 27 | const client = createPromiseClient(TestService, transport()); 28 | const response = await client.emptyCall(empty); 29 | expect(response).toEqual(empty); 30 | }); 31 | it("with callback client", function (done) { 32 | const client = createCallbackClient(TestService, transport()); 33 | client.emptyCall(empty, (err, response) => { 34 | expect(err).toBeUndefined(); 35 | expect(response).toEqual(empty); 36 | done(); 37 | }); 38 | }); 39 | }); 40 | 41 | afterAll(async () => await servers.stop()); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/empty_unary_with_timeout.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { Empty } from "../gen/grpc/testing/empty_pb.js"; 18 | import { createTestServers } from "../helpers/testserver.js"; 19 | 20 | describe("empty_unary_with_timeout", function () { 21 | const servers = createTestServers(); 22 | beforeAll(async () => await servers.start()); 23 | 24 | servers.describeTransports((transport) => { 25 | const empty = new Empty(); 26 | const deadlineMs = 1000; // 1 second 27 | it("with promise client", async function () { 28 | const client = createPromiseClient(TestService, transport()); 29 | const response = await client.emptyCall(empty, { timeoutMs: deadlineMs }); 30 | expect(response).toEqual(empty); 31 | }); 32 | it("with callback client", function (done) { 33 | const client = createCallbackClient(TestService, transport()); 34 | client.emptyCall( 35 | empty, 36 | (err, response) => { 37 | expect(err).toBeUndefined(); 38 | expect(response).toEqual(empty); 39 | done(); 40 | }, 41 | { timeoutMs: deadlineMs } 42 | ); 43 | }); 44 | }); 45 | 46 | afterAll(async () => await servers.stop()); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/large_unary.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { SimpleRequest } from "../gen/grpc/testing/messages_pb.js"; 18 | import { createTestServers } from "../helpers/testserver.js"; 19 | 20 | describe("large_unary", function () { 21 | const servers = createTestServers(); 22 | beforeAll(async () => await servers.start()); 23 | 24 | servers.describeTransports((transport) => { 25 | const request = new SimpleRequest({ 26 | responseSize: 314159, 27 | payload: { 28 | body: new Uint8Array(271828).fill(0), 29 | }, 30 | }); 31 | it("with promise client", async function () { 32 | const client = createPromiseClient(TestService, transport()); 33 | const response = await client.unaryCall(request); 34 | expect(response.payload).toBeDefined(); 35 | expect(response.payload?.body.length).toEqual(request.responseSize); 36 | }); 37 | it("with callback client", function (done) { 38 | const client = createCallbackClient(TestService, transport()); 39 | client.unaryCall(request, (err, response) => { 40 | expect(err).toBeUndefined(); 41 | expect(response.payload).toBeDefined(); 42 | expect(response.payload?.body.length).toEqual(request.responseSize); 43 | done(); 44 | }); 45 | }); 46 | }); 47 | 48 | afterAll(async () => await servers.stop()); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/unimplemented_method.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | Code, 17 | DubboError, 18 | createCallbackClient, 19 | createPromiseClient, 20 | } from "@apachedubbo/dubbo"; 21 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { createTestServers } from "../helpers/testserver.js"; 23 | 24 | describe("unimplemented_method", function () { 25 | const servers = createTestServers(); 26 | beforeAll(async () => await servers.start()); 27 | 28 | servers.describeTransports((transport) => { 29 | it("with promise client", async function () { 30 | const client = createPromiseClient(TestService, transport()); 31 | try { 32 | await client.unimplementedCall({}); 33 | fail("expected to catch an error"); 34 | } catch (e) { 35 | expect(e).toBeInstanceOf(DubboError); 36 | expect(DubboError.from(e).code).toBe(Code.Unimplemented); 37 | } 38 | }); 39 | it("with callback client", function (done) { 40 | const client = createCallbackClient(TestService, transport()); 41 | client.unimplementedCall({}, (err: DubboError | undefined) => { 42 | expect(err?.code).toBe(Code.Unimplemented); 43 | done(); 44 | }); 45 | }); 46 | }); 47 | 48 | afterAll(async () => await servers.stop()); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/crosstest/unimplemented_service.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | Code, 17 | DubboError, 18 | createCallbackClient, 19 | createPromiseClient, 20 | } from "@apachedubbo/dubbo"; 21 | import { UnimplementedService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { createTestServers } from "../helpers/testserver.js"; 23 | 24 | describe("unimplemented_service", function () { 25 | const servers = createTestServers(); 26 | beforeAll(async () => await servers.start()); 27 | 28 | servers.describeTransports((transport) => { 29 | it("with promise client", async function () { 30 | const client = createPromiseClient(UnimplementedService, transport()); 31 | try { 32 | await client.unimplementedCall({}); 33 | fail("expected to catch an error"); 34 | } catch (e) { 35 | expect(e).toBeInstanceOf(DubboError); 36 | expect(DubboError.from(e).code).toBe(Code.Unimplemented); 37 | } 38 | }); 39 | it("with callback client", function (done) { 40 | const client = createCallbackClient(UnimplementedService, transport()); 41 | client.unimplementedCall({}, (err: DubboError | undefined) => { 42 | expect(err?.code).toBe(Code.Unimplemented); 43 | done(); 44 | }); 45 | }); 46 | }); 47 | 48 | afterAll(async () => await servers.stop()); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/extra/create-grpc-client.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 16 | import { createGrpcClient } from "./create-grpc-client.js"; 17 | import * as grpc from "@grpc/grpc-js"; 18 | 19 | describe("createGrpcClient()", function () { 20 | it("should create the expected methods", function () { 21 | const grpcClient = createGrpcClient(TestService, { 22 | address: "localhost:5002", 23 | channelCredentials: grpc.ChannelCredentials.createInsecure(), 24 | clientOptions: {}, 25 | binaryOptions: {}, 26 | }); 27 | expect(grpcClient).toBeDefined(); 28 | expect(typeof grpcClient.emptyCall).toBe("function"); 29 | expect(typeof grpcClient.streamingOutputCall).toBe("function"); 30 | expect(typeof grpcClient.streamingInputCall).toBe("function"); 31 | expect(typeof grpcClient.fullDuplexCall).toBe("function"); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/helpers/import-express.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import type * as express from "express"; 16 | 17 | /** 18 | * Express requires the TS compiler setting allowSyntheticDefaultImports to be 19 | * enabled, but we don't want to enable it just for tests because it could 20 | * shadow other issues we want to be aware of. 21 | */ 22 | export async function importExpress(): Promise { 23 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 24 | // @ts-ignore 25 | const expressImport = (await import("express")) as { 26 | default: typeof express; 27 | }; 28 | return expressImport.default; 29 | } 30 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/src/helpers/interop.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | ErrorDetail, 17 | Payload, 18 | PayloadType, 19 | } from "../gen/grpc/testing/messages_pb.js"; 20 | 21 | export const interop = { 22 | /** 23 | * readable non-ASCII 24 | */ 25 | nonASCIIErrMsg: "soirée 🎉", 26 | 27 | /** 28 | * An error detail to be included in an error. 29 | */ 30 | errorDetail: new ErrorDetail({ 31 | reason: "soirée 🎉", 32 | domain: "connect-crosstest", 33 | }), 34 | 35 | leadingMetadataKey: "x-grpc-test-echo-initial", 36 | trailingMetadataKey: "x-grpc-test-echo-trailing-bin", 37 | 38 | makeServerPayload(payloadType: PayloadType, size: number): Payload { 39 | switch (payloadType) { 40 | case PayloadType.COMPRESSABLE: 41 | return new Payload({ 42 | body: new Uint8Array(size), 43 | type: PayloadType.COMPRESSABLE, 44 | }); 45 | default: 46 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions 47 | throw new Error(`unsupported payload type: ${payloadType}`); 48 | } 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /packages/dubbo-node-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo-node/.npmignore: -------------------------------------------------------------------------------- 1 | /src 2 | /*.json 3 | /dist/*/**/*.spec.js 4 | /dist/*/**/*.spec.d.ts 5 | -------------------------------------------------------------------------------- /packages/dubbo-node/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "dist/esm", 3 | "spec_files": ["**/*.spec.js"], 4 | "helpers": [], 5 | "env": { 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/dubbo-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-node", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-node" 9 | }, 10 | "scripts": { 11 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 12 | "build": "npm run build:cjs && npm run build:esm+types", 13 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 14 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types", 15 | "jasmine": "jasmine --config=jasmine.json" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "dependencies": { 29 | "@apachedubbo/dubbo": "3.0.0-alpha", 30 | "headers-polyfill": "^3.1.2" 31 | }, 32 | "peerDependencies": { 33 | "@bufbuild/protobuf": "^1.2.1" 34 | }, 35 | "devDependencies": { 36 | "@apachedubbo/dubbo-observable": "3.0.0-alpha", 37 | "@types/jasmine": "^4.3.1", 38 | "jasmine": "^5.0.0" 39 | }, 40 | "files": [ 41 | "dist/**" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /packages/dubbo-node/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Polyfill the Headers API for Node versions < 18 16 | import "./node-headers-polyfill.js"; 17 | 18 | export { createGrpcWebTransport } from "./grpc-web-transport.js"; 19 | export { createGrpcTransport } from "./grpc-transport.js"; 20 | export { createDubboTransport } from "./dubbo-transport.js"; 21 | export { compressionBrotli, compressionGzip } from "./compression.js"; 22 | export { dubboNodeAdapter } from "./dubbo-node-adapter.js"; 23 | 24 | export { 25 | universalRequestFromNodeRequest, 26 | universalResponseToNodeResponse, 27 | } from "./node-universal-handler.js"; 28 | 29 | export { createNodeHttpClient } from "./node-universal-client.js"; 30 | export { Http2SessionManager } from "./http2-session-manager.js"; 31 | -------------------------------------------------------------------------------- /packages/dubbo-node/src/node-headers-polyfill.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Headers as HeadersPolyfill } from "headers-polyfill"; 16 | 17 | // The global Headers class was introduced in Node v16.15.0, behind the 18 | // --experimental-fetch flag. It became available by default with Node 19 | // v18.0.0. 20 | // If this code runs in Node < 18, it installs an alternative 21 | // implementation if one has not already been polyfilled. 22 | 23 | const [major] = process.versions.node 24 | .split(".") 25 | .map((value) => parseInt(value, 10)); 26 | if (major < 18) { 27 | if (typeof globalThis.Headers === "undefined") { 28 | globalThis.Headers = HeadersPolyfill as unknown as typeof Headers; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/dubbo-node/src/node-universal-header.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { nodeHeaderToWebHeader } from "./node-universal-header.js"; 16 | 17 | describe("nodeHeaderToWebHeader", function () { 18 | it("should accept empty node header", function () { 19 | const h = nodeHeaderToWebHeader({}); 20 | let numHeaders = 0; 21 | h.forEach(() => numHeaders++); 22 | expect(numHeaders).toBe(0); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/dubbo-node/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "include": ["src/**/*.spec.ts"], 4 | "extends": "../../tsconfig.base.json" 5 | } 6 | -------------------------------------------------------------------------------- /packages/dubbo-observable/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "dist/esm", 3 | "spec_files": ["**/*.spec.js"], 4 | "helpers": [], 5 | "env": { 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/dubbo-observable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-observable", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-observable" 9 | }, 10 | "scripts": { 11 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 12 | "build": "npm run build:cjs && npm run build:esm+types", 13 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 14 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types", 15 | "jasmine": "jasmine --config=jasmine.json" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0" 27 | }, 28 | "dependencies": { 29 | "@opentelemetry/api": "^1.8.0", 30 | "@opentelemetry/sdk-metrics": "^1.23.0", 31 | "@opentelemetry/sdk-node": "^0.50.0", 32 | "@opentelemetry/sdk-trace-node": "^1.23.0" 33 | }, 34 | "devDependencies": { 35 | "@types/jasmine": "^4.3.1", 36 | "jasmine": "^5.0.0" 37 | }, 38 | "files": [ 39 | "dist/**" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /packages/dubbo-observable/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | export type { ObservableOptions, Observable } from "./observable.js"; 19 | export { createObservable } from "./observable.js"; 20 | 21 | export type { MeterCollectorOptions, MetricOptions } from "./meter-collector.js"; 22 | export { MeterCollector, ProviderMeterCollector, ConsumerMeterCollector, ValueType } from "./meter-collector.js"; 23 | -------------------------------------------------------------------------------- /packages/dubbo-observable/src/qps-counter.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { QpsCounter } from "./qps-counter.js"; 19 | 20 | describe("QpsCounter", function () { 21 | let qpsCounter = new QpsCounter(); 22 | 23 | beforeEach(function () { 24 | jasmine.clock().install(); 25 | jasmine.clock().mockDate(new Date()); 26 | qpsCounter = new QpsCounter(); 27 | }); 28 | 29 | afterEach(function () { 30 | jasmine.clock().uninstall(); 31 | qpsCounter.stop(); 32 | }); 33 | 34 | it("should initialize counter correctly", function () { 35 | expect(qpsCounter).toBeDefined(); 36 | expect(qpsCounter.getQps()).toBe(0); 37 | }); 38 | 39 | it("should increment the counter correctly", function () { 40 | qpsCounter.increment(); 41 | qpsCounter.increment(); 42 | qpsCounter.increment(); 43 | expect(qpsCounter.getQps()).toBe(0); 44 | 45 | jasmine.clock().tick(1000); 46 | 47 | expect(qpsCounter.getQps()).toBe(3); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-observable/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "include": ["src/**/*.spec.ts"], 4 | "extends": "../../tsconfig.base.json" 5 | } 6 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/README.md: -------------------------------------------------------------------------------- 1 | # Code size comparison 2 | 3 | This is a simple code size comparison between Dubbo-Web and gRPC-web. 4 | 5 | We are generating code for the module [buf.build/bufbuild/eliza](https://buf.build/bufbuild/eliza) 6 | once with `protoc-gen-grpc-web`, once with `protoc-gen-apache-dubbo-es`. 7 | Then we bundle a client for the service `buf.connect.demo.eliza.v1.ElizaService` 8 | with [esbuild](https://esbuild.github.io/), minify the bundle, and compress 9 | it like a web server would usually do. 10 | 11 | | code generator | bundle size | minified | compressed | 12 | | -------------- | ----------: | --------: | ---------: | 13 | | dubbo | 112,976 b | 49,590 b | 13,282 b | 14 | | grpc-web | 414,906 b | 301,127 b | 53,279 b | 15 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: es 4 | out: src/gen/connectweb 5 | opt: ts_nocheck=false,target=ts 6 | - plugin: apache-dubbo-es 7 | out: src/gen/connectweb 8 | opt: ts_nocheck=false,target=ts 9 | - plugin: buf.build/protocolbuffers/js:v3.21.2 10 | out: src/gen/grpcweb 11 | opt: import_style=commonjs 12 | - plugin: buf.build/grpc/web:v1.4.2 13 | out: src/gen/grpcweb 14 | opt: import_style=commonjs+dts,mode=grpcweb 15 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-web-bench", 3 | "private": true, 4 | "scripts": { 5 | "generate": "buf generate", 6 | "report": "node report.mjs > README.md", 7 | "clean": "rm -rf README.md src/gen" 8 | }, 9 | "dependencies": { 10 | "@apachedubbo/dubbo-web": "3.0.0-alpha", 11 | "@bufbuild/protobuf": "^1.2.1", 12 | "@bufbuild/protoc-gen-es": "^1.2.1", 13 | "brotli": "^1.3.3", 14 | "esbuild": "^0.16.12", 15 | "google-protobuf": "^3.21.0", 16 | "grpc-web": "^1.4.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/report.mjs: -------------------------------------------------------------------------------- 1 | import { buildSync } from 'esbuild' 2 | import { compress } from 'brotli' 3 | 4 | const dubbo = gather('src/entry-dubbo.ts') 5 | const grpcweb = gather('src/entry-grpcweb.ts') 6 | 7 | process.stdout.write(`# Code size comparison 8 | 9 | This is a simple code size comparison between Dubbo-Web and gRPC-web. 10 | 11 | We are generating code for the module [buf.build/bufbuild/eliza](https://buf.build/bufbuild/eliza) 12 | once with \`protoc-gen-grpc-web\`, once with \`protoc-gen-apache-dubbo-es\`. 13 | Then we bundle a client for the service \`buf.connect.demo.eliza.v1.ElizaService\` 14 | with [esbuild](https://esbuild.github.io/), minify the bundle, and compress 15 | it like a web server would usually do. 16 | 17 | | code generator | bundle size | minified | compressed | 18 | |----------------|-------------------:|-----------------------:|---------------------:| 19 | | dubbo | ${dubbo.size} | ${dubbo.minified} | ${dubbo.compressed} | 20 | | grpc-web | ${grpcweb.size} | ${grpcweb.minified} | ${grpcweb.compressed}| 21 | `) 22 | 23 | function gather(entryPoint) { 24 | const bundle = build(entryPoint, false, 'esm') 25 | const bundleMinified = build(entryPoint, true, 'esm') 26 | const compressed = compress(bundleMinified) 27 | return { 28 | entryPoint, 29 | size: formatSize(bundle.byteLength), 30 | minified: formatSize(bundleMinified.byteLength), 31 | compressed: formatSize(compressed.byteLength) 32 | } 33 | } 34 | 35 | function build(entryPoint, minify, format) { 36 | const result = buildSync({ 37 | entryPoints: [entryPoint], 38 | bundle: true, 39 | format: format, 40 | treeShaking: true, 41 | minify: minify, 42 | write: false 43 | }) 44 | if (result.outputFiles.length !== 1) { 45 | throw new Error() 46 | } 47 | return result.outputFiles[0].contents 48 | } 49 | 50 | function formatSize(bytes) { 51 | return new Intl.NumberFormat().format(bytes) + ' b' 52 | } 53 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/src/entry-dubbo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { createDubboTransport } from "@apachedubbo/dubbo-web"; 17 | import { ElizaService } from "./gen/connectweb/buf/connect/demo/eliza/v1/eliza_dubbo.js"; 18 | 19 | const client = createPromiseClient( 20 | ElizaService, 21 | createDubboTransport({ 22 | baseUrl: "https://demo.connect.build", 23 | }) 24 | ); 25 | 26 | // eslint-disable-next-line no-console -- log statement makes sure the variable is in use 27 | console.log(client); 28 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/src/entry-grpcweb.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { ElizaServiceClient } from "./gen/grpcweb/buf/connect/demo/eliza/v1/eliza_grpc_web_pb.js"; 16 | 17 | const client = new ElizaServiceClient("https://demo.connect.build"); 18 | 19 | // eslint-disable-next-line no-console -- log statement makes sure the variable is in use 20 | console.log(client); 21 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/src/gen/grpcweb/buf/connect/demo/eliza/v1/eliza_grpc_web_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as grpcWeb from 'grpc-web'; 2 | 3 | import * as buf_connect_demo_eliza_v1_eliza_pb from '../../../../../buf/connect/demo/eliza/v1/eliza_pb'; 4 | 5 | 6 | export class ElizaServiceClient { 7 | constructor (hostname: string, 8 | credentials?: null | { [index: string]: string; }, 9 | options?: null | { [index: string]: any; }); 10 | 11 | say( 12 | request: buf_connect_demo_eliza_v1_eliza_pb.SayRequest, 13 | metadata: grpcWeb.Metadata | undefined, 14 | callback: (err: grpcWeb.RpcError, 15 | response: buf_connect_demo_eliza_v1_eliza_pb.SayResponse) => void 16 | ): grpcWeb.ClientReadableStream; 17 | 18 | introduce( 19 | request: buf_connect_demo_eliza_v1_eliza_pb.IntroduceRequest, 20 | metadata?: grpcWeb.Metadata 21 | ): grpcWeb.ClientReadableStream; 22 | 23 | } 24 | 25 | export class ElizaServicePromiseClient { 26 | constructor (hostname: string, 27 | credentials?: null | { [index: string]: string; }, 28 | options?: null | { [index: string]: any; }); 29 | 30 | say( 31 | request: buf_connect_demo_eliza_v1_eliza_pb.SayRequest, 32 | metadata?: grpcWeb.Metadata 33 | ): Promise; 34 | 35 | introduce( 36 | request: buf_connect_demo_eliza_v1_eliza_pb.IntroduceRequest, 37 | metadata?: grpcWeb.Metadata 38 | ): grpcWeb.ClientReadableStream; 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /packages/dubbo-web-bench/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/README.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | This package provides test coverage for @apachedubbo/dubbo-web with the test 4 | framework [Jasmine](https://jasmine.github.io/) and the [Karma](https://karma-runner.github.io/) 5 | test runner. 6 | 7 | The test suite is run multiple times: 8 | 9 | 1. In a headless browser (Chrome). 10 | 2. In multiple old browsers on Browserstack. 11 | 3. In Node.js (v18 for the fetch API). 12 | 13 | The tests run against: 14 | - dubbo-go (h1/h2) via Docker 15 | - @apachedubbo/dubbo-node (h1) 16 | 17 | ### Running tests in a headless browser 18 | 19 | Run `make testwebbrowser` to run tests in a headless Chrome. This can be 20 | combined with Node.js by running `make testwebbrowser testwebnode` to get 21 | decent coverage quickly. 22 | 23 | ### Running tests in a local browser 24 | 25 | To run the test suite in local browsers, start the karma server with 26 | `make testlocalbrowser` from the project root. If you encounter a CORS 27 | error in your local browser, this is most likely because you need to 28 | explicitly trust the self-signed certificate of the test server. 29 | Open one of the failed requests from the browsers network inspector, 30 | and trust the self-signed certificate in the browser UI. 31 | 32 | ### Running tests in Node.js 33 | 34 | @apachedubbo/dubbo-web requires the fetch API. It is available since Node.js 35 | v18, and you can run this suite of tests on it with `make testwebnode`. 36 | Note that client-streaming and bidi-streaming are not fully supported because 37 | of limitations in browser APIs. 38 | 39 | ### Running tests in Browserstack 40 | 41 | We are running a few select tests on old browsers. Thanks to Browserstack 42 | for the sponsorship! 43 | 44 | To run these tests locally, you need to sign up on [browserstack.com](https://www.browserstack.com/) 45 | and provide your username and access key: 46 | 47 | ```bash 48 | BROWSERSTACK_USERNAME= BROWSERSTACK_ACCESS_KEY= make testwebbrowserstack 49 | ``` 50 | 51 | ### Running tests in Node.js 52 | 53 | Running in Node.js requires the fetch API implementation added in v18. 54 | You can conveniently run the suite with `make testwebnode` from the project 55 | root. 56 | 57 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: es 4 | out: src/gen 5 | opt: ts_nocheck=false,target=ts 6 | - plugin: apache-dubbo-es 7 | out: src/gen 8 | opt: ts_nocheck=false,target=ts 9 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "dist/esm", 3 | "spec_files": ["**/*.spec.js"], 4 | "helpers": ["helpers/**/*.js"], 5 | "env": { 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma-fixup-globalThis.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // https://mathiasbynens.be/notes/globalthis 16 | 17 | (function () { 18 | if (typeof globalThis === "object") return; 19 | Object.prototype.__defineGetter__("__magic__", function () { 20 | return this; 21 | }); 22 | __magic__.globalThis = __magic__; // eslint-disable-line 23 | delete Object.prototype.__magic__; 24 | })(); 25 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma-fixup-queueMicrotask.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | (function () { 16 | if (typeof globalThis.queueMicrotask === "function") { 17 | return; 18 | } 19 | 20 | globalThis.queueMicrotask = (callback) => 21 | typeof Promise === "function" && typeof Promise.resolve === "function" 22 | ? Promise.resolve().then(callback) 23 | : setTimeout(callback, 0); 24 | })(); 25 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma-fixup-symbolAsyncIterator.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // As long as for-await is transpiled to iterators, Symbol.asyncIterator is 16 | // only required to identify async iterables, and we only need to provide the 17 | // symbol. 18 | 19 | (function () { 20 | if (!Symbol.asyncIterator) { 21 | Symbol.asyncIterator = Symbol("fake-async-iterator"); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma-fixup.cjs: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | // This is a plugin for the test runner karma that injects some polyfills. 4 | // http://karma-runner.github.io/6.3/dev/plugins.html 5 | 6 | function fixupFactory(files) { 7 | files.unshift({ 8 | pattern: path.join(__dirname, "/karma-fixup-globalThis.js"), 9 | included: true, served: true, watched: false 10 | }, { 11 | pattern: path.join(__dirname, "/karma-fixup-AbortController.js"), 12 | included: true, served: true, watched: false 13 | }, { 14 | pattern: path.join(__dirname, "/karma-fixup-queueMicrotask.js"), 15 | included: true, served: true, watched: false 16 | }, { 17 | pattern: path.join(__dirname, "/karma-fixup-symbolAsyncIterator.js"), 18 | included: true, served: true, watched: false 19 | }); 20 | } 21 | 22 | fixupFactory.$inject = ["config.files"]; 23 | 24 | module.exports = { 25 | "framework:fixup": ["factory", fixupFactory] 26 | }; 27 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma.conf.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = function (config) { 16 | config.set({ 17 | plugins: [ 18 | require("karma-esbuild"), 19 | require("karma-jasmine"), 20 | require("karma-chrome-launcher") 21 | ], 22 | frameworks: ["jasmine"], 23 | files: [ 24 | "src/**/*.ts", 25 | ], 26 | exclude: [], 27 | singleRun: true, 28 | reporters: ["progress"], 29 | browsers: ["ChromeCustom"], 30 | preprocessors: {"/**/*.ts": "esbuild"}, 31 | esbuild: { 32 | target: "esnext", 33 | tsconfig: "./tsconfig.json", 34 | }, 35 | customLaunchers: { 36 | ChromeCustom: { 37 | base: "ChromeHeadless", 38 | // We ignore the certificate errors as the client certificates are managed by the browser. 39 | flags: ["--ignore-certificate-errors"], 40 | }, 41 | }, 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/karma.serve.conf.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = function (config) { 16 | require("./karma.conf.cjs")(config); 17 | config.set({ 18 | // Override the configuration settings so that we can simply serve 19 | // karma, instead of running against configured browsers. 20 | // This is used by the npm script "karma-serve", and the make target 21 | // "test-local-browser". 22 | singleRun: false, 23 | browsers: [], 24 | customLaunchers: {}, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-web-test", 3 | "private": true, 4 | "scripts": { 5 | "clean": "rm -rf ./dist/esm/*", 6 | "generate": "buf generate", 7 | "build": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm", 8 | "jasmine": "jasmine --config=jasmine.json", 9 | "karma": "karma start karma.conf.cjs", 10 | "karma-serve": "karma start karma.serve.conf.cjs", 11 | "karma-browserstack": "karma start karma.browserstack.conf.cjs" 12 | }, 13 | "type": "module", 14 | "types": "./dist/types/index.d.ts", 15 | "exports": { 16 | "import": "./dist/esm/index.js", 17 | "default": "./dist/esm/index.js" 18 | }, 19 | "peerDependencies": { 20 | "@bufbuild/protobuf": "^1.2.1" 21 | }, 22 | "dependencies": { 23 | "@apachedubbo/dubbo-web": "3.0.0-alpha", 24 | "@apachedubbo/dubbo": "3.0.0-alpha", 25 | "@types/jasmine": "^4.3.0", 26 | "esbuild": "^0.16.12", 27 | "jasmine": "^5.0.0", 28 | "@bufbuild/protoc-gen-es": "^1.2.1", 29 | "@apachedubbo/protoc-gen-apache-dubbo-es": "3.0.0-alpha", 30 | "karma": "^6.4.2", 31 | "karma-browserstack-launcher": "^1.6.0", 32 | "karma-chrome-launcher": "^3.2.0", 33 | "karma-esbuild": "^2.2.5", 34 | "karma-jasmine": "^5.1.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/browserstackonly/bigint.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { proto3, ScalarType } from "@bufbuild/protobuf"; 16 | 17 | describe("bigint", () => { 18 | it("survives binary roundtrip", () => { 19 | const M = proto3.makeMessageType("M", [ 20 | { no: 1, name: "f", kind: "scalar", T: ScalarType.INT64 }, 21 | ]); 22 | expect(String(M.fromBinary(new M({ f: "3409819015" }).toBinary()).f)).toBe( 23 | "3409819015" 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/browserstackonly/eliza.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { createDubboTransport } from "@apachedubbo/dubbo-web"; 17 | import { ElizaService } from "../gen/buf/connect/demo/eliza/v1/eliza_dubbo.js"; 18 | import { IntroduceRequest } from "../gen/buf/connect/demo/eliza/v1/eliza_pb.js"; 19 | 20 | const timeoutMs = 15000; 21 | 22 | describe("eliza", () => { 23 | const transport = createDubboTransport({ 24 | baseUrl: "https://demo.connect.build", 25 | }); 26 | it( 27 | "say()", 28 | async () => { 29 | const client = createPromiseClient(ElizaService, transport); 30 | const res = await client.say({ sentence: "I feel happy." }); 31 | expect(typeof res.sentence).toBe("string"); 32 | }, 33 | timeoutMs 34 | ); 35 | it( 36 | "introduce()", 37 | async () => { 38 | const client = createPromiseClient(ElizaService, transport); 39 | const request = new IntroduceRequest({ 40 | name: "Browser", 41 | }); 42 | let receivedMessages = 0; 43 | for await (const response of client.introduce(request)) { 44 | expect(response.sentence.length > 0).toBe(true); 45 | receivedMessages++; 46 | } 47 | expect(receivedMessages > 3).toBe(true); 48 | }, 49 | timeoutMs 50 | ); 51 | }); 52 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/browserstackonly/headers.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export {}; // Required to transpile this file with isolatedModules 16 | 17 | describe("Headers", () => { 18 | it("should accept undefined", () => { 19 | expect(() => new Headers(undefined)).not.toThrow(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/empty_stream.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { describeTransports } from "../helpers/crosstestserver.js"; 18 | import { StreamingOutputCallRequest } from "../gen/grpc/testing/messages_pb.js"; 19 | 20 | describe("empty_stream", function () { 21 | describeTransports((transport) => { 22 | const request = new StreamingOutputCallRequest(); 23 | it("with promise client", async function () { 24 | const client = createPromiseClient(TestService, transport()); 25 | try { 26 | for await (const response of client.streamingOutputCall(request)) { 27 | fail( 28 | `expecting no response in the empty stream, got: ${response.toJsonString()}` 29 | ); 30 | } 31 | } catch (e) { 32 | fail(`expecting no error in the empty stream, got: ${String(e)}`); 33 | } 34 | }); 35 | it("with callback client", function (done) { 36 | const client = createCallbackClient(TestService, transport()); 37 | client.streamingOutputCall( 38 | request, 39 | () => { 40 | fail("expecting no response in the empty stream"); 41 | }, 42 | (err) => { 43 | expect(err).toBeUndefined(); 44 | done(); 45 | } 46 | ); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/empty_unary.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { describeTransports } from "../helpers/crosstestserver.js"; 18 | import { Empty } from "../gen/grpc/testing/empty_pb.js"; 19 | 20 | describe("empty_unary", function () { 21 | describeTransports((transport) => { 22 | const empty = new Empty(); 23 | it("with promise client", async function () { 24 | const client = createPromiseClient(TestService, transport()); 25 | const response = await client.emptyCall(empty); 26 | expect(response).toEqual(empty); 27 | }); 28 | it("with callback client", function (done) { 29 | const client = createCallbackClient(TestService, transport()); 30 | client.emptyCall(empty, (err, response) => { 31 | expect(err).toBeUndefined(); 32 | expect(response).toEqual(empty); 33 | done(); 34 | }); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/empty_unary_with_timeout.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { describeTransports } from "../helpers/crosstestserver.js"; 18 | import { Empty } from "../gen/grpc/testing/empty_pb.js"; 19 | 20 | describe("empty_unary_with_timeout", function () { 21 | describeTransports((transport) => { 22 | const empty = new Empty(); 23 | const deadlineMs = 1000; // 1 second 24 | it("with promise client", async function () { 25 | const client = createPromiseClient(TestService, transport()); 26 | const response = await client.emptyCall(empty, { timeoutMs: deadlineMs }); 27 | expect(response).toEqual(empty); 28 | }); 29 | it("with callback client", function (done) { 30 | const client = createCallbackClient(TestService, transport()); 31 | client.emptyCall( 32 | empty, 33 | (err, response) => { 34 | expect(err).toBeUndefined(); 35 | expect(response).toEqual(empty); 36 | done(); 37 | }, 38 | { timeoutMs: deadlineMs } 39 | ); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/fail_unary.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | Code, 17 | DubboError, 18 | createCallbackClient, 19 | createPromiseClient, 20 | } from "@apachedubbo/dubbo"; 21 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { describeTransports } from "../helpers/crosstestserver.js"; 23 | import { ErrorDetail } from "../gen/grpc/testing/messages_pb.js"; 24 | import { interop } from "../helpers/interop.js"; 25 | 26 | describe("fail_unary", () => { 27 | function expectError(err: unknown) { 28 | expect(err).toBeInstanceOf(DubboError); 29 | if (err instanceof DubboError) { 30 | expect(err.code).toEqual(Code.ResourceExhausted); 31 | expect(err.rawMessage).toEqual(interop.nonASCIIErrMsg); 32 | const details = err.findDetails(ErrorDetail); 33 | expect(details).toEqual([interop.errorDetail]); 34 | } 35 | } 36 | describeTransports((transport) => { 37 | it("with promise client", async function () { 38 | const client = createPromiseClient(TestService, transport()); 39 | try { 40 | await client.failUnaryCall({}); 41 | fail("expected to catch an error"); 42 | } catch (e) { 43 | expectError(e); 44 | } 45 | }); 46 | it("with callback client", function (done) { 47 | const client = createCallbackClient(TestService, transport()); 48 | client.failUnaryCall({}, (err: DubboError | undefined) => { 49 | expectError(err); 50 | done(); 51 | }); 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/large_unary.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createCallbackClient, createPromiseClient } from "@apachedubbo/dubbo"; 16 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 17 | import { describeTransports } from "../helpers/crosstestserver.js"; 18 | import { SimpleRequest } from "../gen/grpc/testing/messages_pb.js"; 19 | 20 | describe("large_unary", function () { 21 | describeTransports((transport) => { 22 | const request = new SimpleRequest({ 23 | responseSize: 314159, 24 | payload: { 25 | body: new Uint8Array(271828).fill(0), 26 | }, 27 | }); 28 | it("with promise client", async function () { 29 | const client = createPromiseClient(TestService, transport()); 30 | const response = await client.unaryCall(request); 31 | expect(response.payload).toBeDefined(); 32 | expect(response.payload?.body.length).toEqual(request.responseSize); 33 | }); 34 | it("with callback client", function (done) { 35 | const client = createCallbackClient(TestService, transport()); 36 | client.unaryCall(request, (err, response) => { 37 | expect(err).toBeUndefined(); 38 | expect(response.payload).toBeDefined(); 39 | expect(response.payload?.body.length).toEqual(request.responseSize); 40 | done(); 41 | }); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/status_code_and_message.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | DubboError, 17 | createCallbackClient, 18 | createPromiseClient, 19 | Code, 20 | } from "@apachedubbo/dubbo"; 21 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { describeTransports } from "../helpers/crosstestserver.js"; 23 | import { SimpleRequest } from "../gen/grpc/testing/messages_pb.js"; 24 | 25 | describe("status_code_and_message", function () { 26 | describeTransports((transport) => { 27 | const TEST_STATUS_MESSAGE = "test status message"; 28 | const request = new SimpleRequest({ 29 | responseStatus: { 30 | code: Code.Unknown, 31 | message: TEST_STATUS_MESSAGE, 32 | }, 33 | }); 34 | function expectError(err: unknown) { 35 | expect(err).toBeInstanceOf(DubboError); 36 | if (err instanceof DubboError) { 37 | expect(err.code).toEqual(Code.Unknown); 38 | expect(err.rawMessage).toEqual(TEST_STATUS_MESSAGE); 39 | } 40 | } 41 | it("with promise client", async function () { 42 | const client = createPromiseClient(TestService, transport()); 43 | try { 44 | await client.unaryCall(request); 45 | fail("expected to catch an error"); 46 | } catch (e) { 47 | expectError(e); 48 | } 49 | }); 50 | it("with callback client", function (done) { 51 | const client = createCallbackClient(TestService, transport()); 52 | client.unaryCall(request, (err: DubboError | undefined) => { 53 | expectError(err); 54 | done(); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/unimplemented_method.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | DubboError, 17 | createCallbackClient, 18 | createPromiseClient, 19 | Code, 20 | } from "@apachedubbo/dubbo"; 21 | import { TestService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { describeTransports } from "../helpers/crosstestserver.js"; 23 | 24 | describe("unimplemented_method", function () { 25 | function expectError(err: unknown) { 26 | expect(err).toBeInstanceOf(DubboError); 27 | if (err instanceof DubboError) { 28 | expect(err.code).toEqual(Code.Unimplemented); 29 | } 30 | } 31 | describeTransports((transport) => { 32 | it("with promise client", async function () { 33 | const client = createPromiseClient(TestService, transport()); 34 | try { 35 | await client.unimplementedCall({}); 36 | fail("expected to catch an error"); 37 | } catch (e) { 38 | expectError(e); 39 | } 40 | }); 41 | it("with callback client", function (done) { 42 | const client = createCallbackClient(TestService, transport()); 43 | client.unimplementedCall({}, (err: DubboError | undefined) => { 44 | expectError(err); 45 | done(); 46 | }); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/crosstest/unimplemented_service.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | DubboError, 17 | createCallbackClient, 18 | createPromiseClient, 19 | Code, 20 | } from "@apachedubbo/dubbo"; 21 | import { UnimplementedService } from "../gen/grpc/testing/test_dubbo.js"; 22 | import { describeTransports } from "../helpers/crosstestserver.js"; 23 | 24 | describe("unimplemented_service", function () { 25 | function expectError(err: unknown) { 26 | // We expect this to be DEADLINE_EXCEEDED, however envoy is monitoring the stream timeout 27 | // and will return an HTTP status code 408 when stream max duration time reached, which 28 | // cannot be translated to a connect error code. 29 | expect(err).toBeInstanceOf(DubboError); 30 | if (err instanceof DubboError) { 31 | expect(err.code === Code.DeadlineExceeded); 32 | } 33 | } 34 | 35 | describeTransports((transport) => { 36 | it("with promise client", async function () { 37 | const client = createPromiseClient(UnimplementedService, transport()); 38 | try { 39 | await client.unimplementedCall({}); 40 | fail("expected to catch an error"); 41 | } catch (e) { 42 | expectError(e); 43 | } 44 | }); 45 | it("with callback client", function (done) { 46 | const client = createCallbackClient(UnimplementedService, transport()); 47 | client.unimplementedCall({}, (err: DubboError | undefined) => { 48 | expectError(err); 49 | done(); 50 | }); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/src/helpers/interop.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | ErrorDetail, 17 | Payload, 18 | PayloadType, 19 | } from "../gen/grpc/testing/messages_pb.js"; 20 | 21 | export const interop = { 22 | /** 23 | * readable non-ASCII 24 | */ 25 | nonASCIIErrMsg: "soirée 🎉", 26 | 27 | /** 28 | * An error detail to be included in an error. 29 | */ 30 | errorDetail: new ErrorDetail({ 31 | reason: "soirée 🎉", 32 | domain: "connect-crosstest", 33 | }), 34 | 35 | leadingMetadataKey: "x-grpc-test-echo-initial", 36 | trailingMetadataKey: "x-grpc-test-echo-trailing-bin", 37 | 38 | makeServerPayload(payloadType: PayloadType, size: number): Payload { 39 | switch (payloadType) { 40 | case PayloadType.COMPRESSABLE: 41 | return new Payload({ 42 | body: new Uint8Array(size), 43 | type: PayloadType.COMPRESSABLE, 44 | }); 45 | default: 46 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions 47 | throw new Error(`unsupported payload type: ${payloadType}`); 48 | } 49 | }, 50 | }; 51 | -------------------------------------------------------------------------------- /packages/dubbo-web-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/dubbo-web", 3 | "version": "3.0.0-alpha", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/apache/dubbo-js.git", 8 | "directory": "packages/dubbo-web" 9 | }, 10 | "sideEffects": false, 11 | "scripts": { 12 | "clean": "rm -rf ./dist/cjs/* ./dist/esm/* ./dist/types/*", 13 | "build": "npm run build:cjs && npm run build:esm+types", 14 | "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", 15 | "build:esm+types": "tsc --project tsconfig.json --module ES2015 --verbatimModuleSyntax --outDir ./dist/esm --declaration --declarationDir ./dist/types" 16 | }, 17 | "main": "./dist/cjs/index.js", 18 | "type": "module", 19 | "types": "./dist/types/index.d.ts", 20 | "exports": { 21 | "types": "./dist/types/index.d.ts", 22 | "import": "./dist/esm/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "dependencies": { 26 | "@apachedubbo/dubbo": "3.0.0-alpha" 27 | }, 28 | "peerDependencies": { 29 | "@bufbuild/protobuf": "^1.2.1" 30 | }, 31 | "files": [ 32 | "dist/**" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /packages/dubbo-web/src/assert-fetch-api.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * Asserts that the fetch API is available. 17 | */ 18 | export function assertFetchApi(): void { 19 | try { 20 | new Headers(); 21 | } catch (_) { 22 | throw new Error( 23 | "dubbo-web requires the fetch API. Are you running on an old version of Node.js? Node.js is not supported in Dubbo for Web - please stay tuned for Dubbo for Node." 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/dubbo-web/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { createDubboTransport } from "./dubbo-transport.js"; 16 | export { createGrpcWebTransport } from "./grpc-web-transport.js"; 17 | export type { DubboTransportOptions } from "./dubbo-transport.js"; 18 | export type { GrpcWebTransportOptions } from "./grpc-web-transport.js"; 19 | -------------------------------------------------------------------------------- /packages/dubbo-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/index.ts"], 3 | "extends": "../../tsconfig.base.json" 4 | } 5 | -------------------------------------------------------------------------------- /packages/dubbo/.npmignore: -------------------------------------------------------------------------------- 1 | /src 2 | /*.json 3 | /dist/*/**/*.spec.js 4 | /dist/*/**/*.spec.d.ts 5 | /buf.gen.yaml 6 | -------------------------------------------------------------------------------- /packages/dubbo/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | # buf.gen.yaml defines a local generation template. 2 | # For details, see https://docs.buf.build/configuration/v1/buf-gen-yaml 3 | version: v1 4 | plugins: 5 | - plugin: es 6 | out: src/protocol-grpc/gen 7 | opt: target=ts 8 | -------------------------------------------------------------------------------- /packages/dubbo/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "dist/esm", 3 | "spec_files": ["**/*.spec.js"], 4 | "helpers": [], 5 | "env": { 6 | "stopSpecOnExpectationFailure": false, 7 | "random": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/dubbo/protocol-dubbo.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Workaround for bundlers that do not support subpath exports. 16 | module.exports = require('./dist/cjs/protocol-triple/index.js') 17 | 18 | -------------------------------------------------------------------------------- /packages/dubbo/protocol-grpc-web.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // workaround for bundlers that do not support subpath exports. 16 | module.exports = require("./dist/cjs/protocol-grpc-web/index.js"); 17 | -------------------------------------------------------------------------------- /packages/dubbo/protocol-grpc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // workaround for bundlers that do not support subpath exports. 16 | module.exports = require("./dist/cjs/protocol-grpc/index.js"); 17 | -------------------------------------------------------------------------------- /packages/dubbo/protocol.js: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // workaround for bundlers that do not support subpath exports. 16 | module.exports = require("./dist/cjs/protocol/index.js"); 17 | -------------------------------------------------------------------------------- /packages/dubbo/src/any-client.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { makeAnyClient } from "./any-client.js"; 16 | import { Empty, MethodKind, Struct } from "@bufbuild/protobuf"; 17 | 18 | describe("makeAnyClient()", () => { 19 | const TestService = { 20 | typeName: "handwritten.TestService", 21 | methods: { 22 | foo: { 23 | name: "Foo", 24 | I: Empty, 25 | O: Struct, 26 | kind: MethodKind.Unary, 27 | }, 28 | }, 29 | } as const; 30 | 31 | it("works as expected", () => { 32 | const client = makeAnyClient(TestService, (method) => { 33 | return function (): string { 34 | return `This is method ${method.name} of service ${method.service.typeName}. It takes a ${method.I.typeName} as input and returns a ${method.O.typeName}.`; 35 | }; 36 | }); 37 | const result = client.foo(); // eslint-disable-line 38 | expect(result).toBe( 39 | "This is method Foo of service handwritten.TestService. It takes a google.protobuf.Empty as input and returns a google.protobuf.Struct." 40 | ); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/dubbo/src/any-client.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import type { ServiceType, MethodInfo } from "@bufbuild/protobuf"; 16 | 17 | /** 18 | * AnyClient is an arbitrary service client with any method signature. 19 | * 20 | * It usually has methods for all methods defined for a service, but may 21 | * omit some, for example because it's transport does not support streaming. 22 | */ 23 | export type AnyClient = Record; 24 | 25 | type AnyClientMethod = (...args: any[]) => any; // eslint-disable-line @typescript-eslint/no-explicit-any 26 | 27 | type CreateAnyClientMethod = ( 28 | method: MethodInfo & { localName: string; service: ServiceType } 29 | ) => AnyClientMethod | null; 30 | 31 | /** 32 | * Create any client for the given service. 33 | * 34 | * The given createMethod function is called for each method definition 35 | * of the service. The function it returns is added to the client object 36 | * as a method. 37 | */ 38 | export function makeAnyClient( 39 | service: ServiceType, 40 | createMethod: CreateAnyClientMethod 41 | ): AnyClient { 42 | const client: AnyClient = {}; 43 | for (const [localName, methodInfo] of Object.entries(service.methods)) { 44 | const method = createMethod({ 45 | ...methodInfo, 46 | localName, 47 | service, 48 | }); 49 | if (method != null) { 50 | client[localName] = method; 51 | } 52 | } 53 | return client; 54 | } 55 | -------------------------------------------------------------------------------- /packages/dubbo/src/call-options.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * Options for a call. Every client should accept CallOptions as optional 17 | * argument in its RPC methods. 18 | */ 19 | export interface CallOptions { 20 | /** 21 | * Timeout in milliseconds. 22 | */ 23 | timeoutMs?: number; 24 | 25 | /** 26 | * Custom headers to send with the request. 27 | */ 28 | headers?: HeadersInit; 29 | 30 | /** 31 | * An optional AbortSignal to cancel the call. 32 | * If cancelled, an error with Code.Canceled is raised. 33 | */ 34 | signal?: AbortSignal; 35 | 36 | /** 37 | * Called when response headers are received. 38 | */ 39 | onHeader?(headers: Headers): void; 40 | 41 | /** 42 | * Called when response trailers are received. 43 | */ 44 | onTrailer?(trailers: Headers): void; 45 | } 46 | -------------------------------------------------------------------------------- /packages/dubbo/src/fetch-headers.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export {}; // Required to transpile this file with isolatedModules 16 | 17 | describe("Fetch API Headers", function () { 18 | let headers: Headers; 19 | beforeEach(() => { 20 | headers = new Headers({ 21 | "Content-Type": "application/connect+json", 22 | }); 23 | }); 24 | it("get()", function () { 25 | expect(headers.get("Content-Type")).toEqual("application/connect+json"); 26 | expect(headers.get("content-type")).toEqual("application/connect+json"); 27 | }); 28 | it("forEach()", function () { 29 | headers.forEach((value, key) => { 30 | // Note all keys are lowercase when iterating over them 31 | expect(key).toEqual("content-type"); 32 | expect(value).toEqual("application/connect+json"); 33 | }); 34 | }); 35 | it("has()", function () { 36 | expect(headers.has("Content-Type")).toBeTrue(); 37 | expect(headers.has("content-type")).toBeTrue(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/dubbo/src/node16-polyfill-helper.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | ReadableStream as NodeReadableStream, 17 | TransformStream as NodeTransformStream, 18 | WritableStream as NodeWritableStream, 19 | } from "stream/web"; 20 | import { Headers as UndiciHeaders } from "undici"; 21 | 22 | /** 23 | * Make the Headers implementation of the fetch API available in the global 24 | * scope. 25 | */ 26 | export function node16FetchHeadersPolyfill() { 27 | if (typeof globalThis.Headers !== "function") { 28 | globalThis.Headers = UndiciHeaders as unknown as typeof Headers; 29 | } 30 | } 31 | 32 | /** 33 | * Make the WHATWG stream implementation of Node.js v16 available in the global 34 | * scope. 35 | */ 36 | export function node16WhatwgStreamPolyfill() { 37 | // node >= v16 has an implementation for WHATWG streams, but doesn't expose 38 | // them in the global scope, nor globalThis. 39 | if (typeof globalThis.ReadableStream !== "function") { 40 | globalThis.ReadableStream = 41 | NodeReadableStream as unknown as typeof ReadableStream; 42 | } 43 | if (typeof globalThis.WritableStream !== "function") { 44 | globalThis.WritableStream = 45 | NodeWritableStream as unknown as typeof WritableStream; 46 | } 47 | if (typeof globalThis.TransformStream !== "function") { 48 | globalThis.TransformStream = 49 | NodeTransformStream as unknown as typeof TransformStream; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc-web/content-type.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * Regular Expression that matches any valid gRPC-web Content-Type header value. 17 | * Note that this includes application/grpc-web-text with the additional base64 18 | * encoding. 19 | * 20 | * @private Internal code, does not follow semantic versioning. 21 | */ 22 | export const contentTypeRegExp = 23 | /^application\/grpc-web(-text)?(?:\+(?:(json)(?:; ?charset=utf-?8)?|proto))?$/i; 24 | 25 | export const contentTypeProto = "application/grpc-web+proto"; 26 | export const contentTypeJson = "application/grpc-web+json"; 27 | 28 | /** 29 | * Parse a gRPC-web Content-Type header value. 30 | * 31 | * @private Internal code, does not follow semantic versioning. 32 | */ 33 | export function parseContentType( 34 | contentType: string | null 35 | ): { text: boolean; binary: boolean } | undefined { 36 | const match = contentType?.match(contentTypeRegExp); 37 | if (!match) { 38 | return undefined; 39 | } 40 | const text = !!match[1]; 41 | const binary = !match[2]; 42 | return { text, binary }; 43 | } 44 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc-web/headers.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @private Internal code, does not follow semantic versioning. 17 | */ 18 | export { 19 | headerContentType, 20 | headerEncoding, 21 | headerAcceptEncoding, 22 | headerTimeout, 23 | headerGrpcStatus, 24 | headerGrpcMessage, 25 | headerStatusDetailsBin, 26 | } from "../protocol-grpc/headers.js"; 27 | 28 | /** 29 | * gRPC-web does not use the standard header User-Agent. 30 | * 31 | * @private Internal code, does not follow semantic versioning. 32 | */ 33 | export const headerXUserAgent = "X-User-Agent"; 34 | 35 | /** 36 | * The canonical grpc/grpc-web JavaScript implementation sets 37 | * this request header with value "1". 38 | * Some servers may rely on the header to identify gRPC-web 39 | * requests. For example the proxy by improbable: 40 | * https://github.com/improbable-eng/grpc-web/blob/53aaf4cdc0fede7103c1b06f0cfc560c003a5c41/go/grpcweb/wrapper.go#L231 41 | * 42 | * @private Internal code, does not follow semantic versioning. 43 | */ 44 | export const headerXGrpcWeb = "X-Grpc-Web"; 45 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc-web/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { createHandlerFactory } from "./handler-factory.js"; 16 | export { createTransport } from "./transport.js"; 17 | 18 | // All exports below are private — internal code that does not follow semantic 19 | // versioning. 20 | // We will try hard to avoid breaking changes, but if you depend on the 21 | // following exports, we recommend that you do so with an exact version 22 | // constraint (no ~ or ^). 23 | 24 | export { 25 | requestHeader, 26 | requestHeaderWithCompression, 27 | } from "./request-header.js"; 28 | export { 29 | parseContentType, 30 | contentTypeRegExp, 31 | contentTypeProto, 32 | contentTypeJson, 33 | } from "./content-type.js"; 34 | export { 35 | validateResponse, 36 | validateResponseWithCompression, 37 | } from "./validate-response.js"; 38 | export { 39 | trailerFlag, 40 | trailerParse, 41 | trailerSerialize, 42 | createTrailerSerialization, 43 | } from "./trailer.js"; 44 | export { 45 | parseTimeout, 46 | setTrailerStatus, 47 | validateTrailer, 48 | grpcStatusOk, 49 | } from "../protocol-grpc/index.js"; 50 | export * from "./headers.js"; 51 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/content-type.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { 16 | parseContentType, 17 | contentTypeProto, 18 | contentTypeJson, 19 | } from "./content-type.js"; 20 | 21 | describe("parseContentType()", function () { 22 | it("should parse", function () { 23 | expect(parseContentType(contentTypeProto)).toEqual({ 24 | binary: true, 25 | }); 26 | expect(parseContentType(contentTypeJson)).toEqual({ 27 | binary: false, 28 | }); 29 | expect(parseContentType("application/grpc")).toEqual({ 30 | binary: true, 31 | }); 32 | expect(parseContentType("application/GRPC")).toEqual({ 33 | binary: true, 34 | }); 35 | expect(parseContentType("application/grpc+proto")).toEqual({ 36 | binary: true, 37 | }); 38 | expect(parseContentType("application/grpc+json")).toEqual({ 39 | binary: false, 40 | }); 41 | expect(parseContentType("application/grpc+json;charset=utf8")).toEqual({ 42 | binary: false, 43 | }); 44 | expect(parseContentType("application/grpc+json; charset=utf-8")).toEqual({ 45 | binary: false, 46 | }); 47 | expect(parseContentType("application/octet-stream")).toBeUndefined(); 48 | expect( 49 | parseContentType("application/grpc-web+json;charset=iso-8859-1") 50 | ).toBeUndefined(); 51 | expect(parseContentType("application/grpc-web+thrift")).toBeUndefined(); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/content-type.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * Regular Expression that matches any valid gRPC Content-Type header value. 17 | * 18 | * @private Internal code, does not follow semantic versioning. 19 | */ 20 | export const contentTypeRegExp = 21 | /^application\/grpc(?:\+(?:(json)(?:; ?charset=utf-?8)?|proto))?$/i; 22 | 23 | export const contentTypeProto = "application/grpc+proto"; 24 | export const contentTypeJson = "application/grpc+json"; 25 | 26 | /** 27 | * Parse a gRPC Content-Type header. 28 | * 29 | * @private Internal code, does not follow semantic versioning. 30 | */ 31 | export function parseContentType( 32 | contentType: string | null 33 | ): { binary: boolean } | undefined { 34 | const match = contentType?.match(contentTypeRegExp); 35 | if (!match) { 36 | return undefined; 37 | } 38 | const binary = !match[1]; 39 | return { binary }; 40 | } 41 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/headers.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @private Internal code, does not follow semantic versioning. 17 | */ 18 | export const headerContentType = "Content-Type"; 19 | export const headerEncoding = "Grpc-Encoding"; 20 | export const headerAcceptEncoding = "Grpc-Accept-Encoding"; 21 | export const headerTimeout = "Grpc-Timeout"; 22 | export const headerGrpcStatus = "Grpc-Status"; 23 | export const headerGrpcMessage = "Grpc-Message"; 24 | export const headerStatusDetailsBin = "Grpc-Status-Details-Bin"; 25 | export const headerUserAgent = "User-Agent"; 26 | export const headerMessageType = "Grpc-Message-Type"; 27 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/http-status.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Code } from "../code.js"; 16 | 17 | /** 18 | * Determine the gRPC-web error code for the given HTTP status code. 19 | * See https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. 20 | * 21 | * @private Internal code, does not follow semantic versioning. 22 | */ 23 | export function codeFromHttpStatus(httpStatus: number): Code { 24 | switch (httpStatus) { 25 | case 400: // Bad Request 26 | return Code.Internal; 27 | case 401: // Unauthorized 28 | return Code.Unauthenticated; 29 | case 403: // Forbidden 30 | return Code.PermissionDenied; 31 | case 404: // Not Found 32 | return Code.Unimplemented; 33 | case 429: // Too Many Requests 34 | return Code.Unavailable; 35 | case 502: // Bad Gateway 36 | return Code.Unavailable; 37 | case 503: // Service Unavailable 38 | return Code.Unavailable; 39 | case 504: // Gateway Timeout 40 | return Code.Unavailable; 41 | default: 42 | // 200 is UNKNOWN because there should be a grpc-status in case of truly OK response. 43 | return Code.Unknown; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export { createHandlerFactory } from "./handler-factory.js"; 16 | export { createTransport } from "./transport.js"; 17 | 18 | // All exports below are private — internal code that does not follow semantic 19 | // versioning. 20 | // We will try hard to avoid breaking changes, but if you depend on the 21 | // following exports, we recommend that you do so with an exact version 22 | // constraint (no ~ or ^). 23 | 24 | export { codeFromHttpStatus } from "./http-status.js"; 25 | export { 26 | requestHeader, 27 | requestHeaderWithCompression, 28 | } from "./request-header.js"; 29 | export { 30 | parseContentType, 31 | contentTypeRegExp, 32 | contentTypeJson, 33 | contentTypeProto, 34 | } from "./content-type.js"; 35 | export { parseTimeout } from "./parse-timeout.js"; 36 | export { 37 | findTrailerError, 38 | setTrailerStatus, 39 | grpcStatusOk, 40 | } from "./trailer-status.js"; 41 | export { 42 | validateResponse, 43 | validateResponseWithCompression, 44 | } from "./validate-response.js"; 45 | export { validateTrailer } from "./validate-trailer.js"; 46 | export * from "./headers.js"; 47 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/parse-timeout.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Code } from "../code.js"; 16 | import { DubboError } from "../dubbo-error.js"; 17 | 18 | /** 19 | * Parse a gRPC Timeout (Deadline) header. 20 | * 21 | * @private Internal code, does not follow semantic versioning. 22 | */ 23 | export function parseTimeout( 24 | value: string | null, 25 | maxTimeoutMs: number 26 | ): 27 | | { timeoutMs?: number; error?: undefined } 28 | | { timeoutMs?: number; error: DubboError } { 29 | if (value === null) { 30 | return {}; 31 | } 32 | const results = /^(\d{1,8})([HMSmun])$/.exec(value); 33 | if (results === null) { 34 | return { 35 | error: new DubboError( 36 | `protocol error: invalid grpc timeout value: ${value}`, 37 | Code.InvalidArgument 38 | ), 39 | }; 40 | } 41 | const unitToMultiplicand = { 42 | H: 60 * 60 * 1000, // hour 43 | M: 60 * 1000, // minute 44 | S: 1000, // second 45 | m: 1, // millisecond 46 | u: 0.001, // microsecond 47 | n: 0.000001, // nanosecond 48 | }; 49 | const timeoutMs = 50 | unitToMultiplicand[results[2] as keyof typeof unitToMultiplicand] * 51 | parseInt(results[1]); 52 | if (timeoutMs > maxTimeoutMs) { 53 | return { 54 | timeoutMs: timeoutMs, 55 | error: new DubboError( 56 | `timeout ${timeoutMs}ms must be <= ${maxTimeoutMs}`, 57 | Code.InvalidArgument 58 | ), 59 | }; 60 | } 61 | return { 62 | timeoutMs, 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-grpc/validate-trailer.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { findTrailerError } from "./trailer-status.js"; 16 | 17 | /** 18 | * Validates a trailer for the gRPC and the gRPC-web protocol. 19 | * Throws a DubboError if the trailer contains an error status. 20 | * 21 | * @private Internal code, does not follow semantic versioning. 22 | */ 23 | export function validateTrailer(trailer: Headers): void { 24 | const err = findTrailerError(trailer); 25 | if (err) { 26 | throw err; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/client-service-options.ts: -------------------------------------------------------------------------------- 1 | export type TripleClientServiceOptions = { 2 | /** 3 | * The Dubbo framework supports a service isolation mechanism based on groups and versions, 4 | * so the Triple protocol introduces tri-service-group and tri-service-version support. 5 | * The serviceVersion needs to be passed during registration to 6 | * match the TRI-Service-Version request header field. 7 | */ 8 | serviceVersion?: string; 9 | 10 | /** 11 | * The Dubbo framework supports a service isolation mechanism based on groups and versions, 12 | * so the Triple protocol introduces tri-service-group and tri-service-version support. 13 | * The serviceGroup needs to be passed during registration to 14 | * match the TRI-Service-Group request header field. 15 | */ 16 | serviceGroup?: string; 17 | } -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/code-string.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Code } from "../code.js"; 16 | 17 | /** 18 | * codeToString returns the string representation of a Code. 19 | * 20 | * @private Internal code, does not follow semantic versioning. 21 | */ 22 | export function codeToString(value: Code): string { 23 | const name = Code[value] as string | undefined; 24 | if (typeof name != "string") { 25 | return value.toString(); 26 | } 27 | return ( 28 | name[0].toLowerCase() + 29 | name.substring(1).replace(/[A-Z]/g, (c) => "_" + c.toLowerCase()) 30 | ); 31 | } 32 | 33 | let stringToCode: Record | undefined; 34 | 35 | /** 36 | * codeFromString parses the string representation of a Code in snake_case. 37 | * For example, the string "permission_denied" parses into Code.PermissionDenied. 38 | * 39 | * If the given string cannot be parsed, the function returns undefined. 40 | * 41 | * @private Internal code, does not follow semantic versioning. 42 | */ 43 | export function codeFromString(value: string): Code | undefined { 44 | if (!stringToCode) { 45 | stringToCode = {}; 46 | for (const value of Object.values(Code)) { 47 | if (typeof value == "string") { 48 | continue; 49 | } 50 | stringToCode[codeToString(value)] = value; 51 | } 52 | } 53 | return stringToCode[value]; 54 | } 55 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/expand-handler.ts: -------------------------------------------------------------------------------- 1 | export interface ExpandHandlerOptions { 2 | /** 3 | * The Dubbo framework supports a service isolation mechanism based on groups and versions, 4 | * so the Triple protocol introduces tri-service-group and tri-service-version support. 5 | * The serviceVersion needs to be passed during registration to 6 | * match the TRI-Service-Version request header field. 7 | */ 8 | serviceVersion: string; 9 | 10 | /** 11 | * The Dubbo framework supports a service isolation mechanism based on groups and versions, 12 | * so the Triple protocol introduces tri-service-group and tri-service-version support. 13 | * The serviceGroup needs to be passed during registration to 14 | * match the TRI-Service-Group request header field. 15 | */ 16 | serviceGroup: string; 17 | } 18 | 19 | export interface ExpandHandler { 20 | /** 21 | * A matcher for TRI-Service-Version header value 22 | */ 23 | serviceVersion: string; 24 | 25 | /** 26 | * A matcher for TRI-Service-Group header value 27 | */ 28 | serviceGroup: string; 29 | } 30 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/headers.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @private Internal code, does not follow semantic versioning. 17 | */ 18 | export const headerContentType = "Content-Type"; 19 | export const headerUnaryContentLength = "Content-Length"; 20 | export const headerUnaryEncoding = "Content-Encoding"; 21 | export const headerStreamEncoding = "Connect-Content-Encoding"; 22 | export const headerUnaryAcceptEncoding = "Accept-Encoding"; 23 | export const headerStreamAcceptEncoding = "Connect-Accept-Encoding"; 24 | export const headerTimeout = "TRI-Service-Timeout"; 25 | export const headerProtocolVersion = "TRI-Protocol-Version"; 26 | export const headerServiceGroup = "TRI-Service-Group"; 27 | export const headerServiceVersion = "TRI-Service-Version"; 28 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/parse-timeout.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { Code } from "../code.js"; 16 | import { DubboError } from "../dubbo-error.js"; 17 | 18 | /** 19 | * Parse a Connect Timeout (Deadline) header. 20 | * 21 | * @private Internal code, does not follow semantic versioning. 22 | */ 23 | export function parseTimeout( 24 | value: string | null, 25 | maxTimeoutMs: number 26 | ): 27 | | { timeoutMs?: number; error?: undefined } 28 | | { timeoutMs?: number; error: DubboError } { 29 | if (value === null) { 30 | return {}; 31 | } 32 | const results = /^\d{1,10}$/.exec(value); 33 | if (results === null) { 34 | return { 35 | error: new DubboError( 36 | `protocol error: invalid connect timeout value: ${value}`, 37 | Code.InvalidArgument 38 | ), 39 | }; 40 | } 41 | const timeoutMs = parseInt(results[0]); 42 | if (timeoutMs > maxTimeoutMs) { 43 | return { 44 | timeoutMs: timeoutMs, 45 | error: new DubboError( 46 | `timeout ${timeoutMs}ms must be <= ${maxTimeoutMs}`, 47 | Code.InvalidArgument 48 | ), 49 | }; 50 | } 51 | return { 52 | timeoutMs: parseInt(results[0]), 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/query-params.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @private Internal code, does not follow semantic versioning. 17 | */ 18 | export const paramProtocolVersion = "triple"; 19 | export const paramEncoding = "encoding"; 20 | export const paramCompression = "compression"; 21 | export const paramBase64 = "base64"; 22 | export const paramMessage = "message"; 23 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol-triple/trailer-mux.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * In unary RPCs, Dubbo transports trailing metadata as response header 17 | * fields, prefixed with "trailer-". 18 | * 19 | * This function demuxes headers and trailers into two separate Headers 20 | * objects. 21 | * 22 | * @private Internal code, does not follow semantic versioning. 23 | */ 24 | export function trailerDemux( 25 | header: Headers 26 | ): [header: Headers, trailer: Headers] { 27 | const h = new Headers(), 28 | t = new Headers(); 29 | header.forEach((value, key) => { 30 | if (key.toLowerCase().startsWith("trailer-")) { 31 | t.set(key.substring(8), value); 32 | } else { 33 | h.set(key, value); 34 | } 35 | }); 36 | return [h, t]; 37 | } 38 | 39 | /** 40 | * In unary RPCs, Dubbo transports trailing metadata as response header 41 | * fields, prefixed with "trailer-". 42 | * 43 | * This function muxes a header and a trailer into a single Headers object. 44 | * 45 | * @private Internal code, does not follow semantic versioning. 46 | */ 47 | export function trailerMux(header: Headers, trailer: Headers): Headers { 48 | const h = new Headers(header); 49 | trailer.forEach((value, key) => { 50 | h.set(`trailer-${key}`, value); 51 | }); 52 | return h; 53 | } 54 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/async-iterable-helper.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | export async function* createAsyncIterableBytes( 16 | bytes: Uint8Array, 17 | chunkSize = 2, 18 | delay = 5 19 | ): AsyncIterable { 20 | let offset = 0; 21 | for (;;) { 22 | await new Promise((resolve) => setTimeout(resolve, delay)); 23 | const end = Math.min(offset + chunkSize, bytes.byteLength); 24 | yield bytes.slice(offset, end); 25 | offset = end; 26 | if (offset === bytes.length) { 27 | break; 28 | } 29 | } 30 | } 31 | 32 | export async function readAll(it: AsyncIterable): Promise { 33 | const all: T[] = []; 34 | for await (const item of it) { 35 | all.push(item); 36 | } 37 | return all; 38 | } 39 | 40 | export async function readAllBytes( 41 | it: AsyncIterable 42 | ): Promise { 43 | return (await readAll(it)).reduce((p, c) => { 44 | const n = new Uint8Array(p.byteLength + c.byteLength); 45 | n.set(p, 0); 46 | n.set(c, p.byteLength); 47 | return n; 48 | }, new Uint8Array(0)); 49 | } 50 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/content-type-matcher.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { contentTypeMatcher } from "./content-type-matcher.js"; 16 | 17 | describe("contentTypeMatcher()", function () { 18 | it("matches multiple regular expressions as expected", function () { 19 | const matcher = contentTypeMatcher(/a/, /b/); 20 | expect(matcher("a")).toBeTrue(); 21 | expect(matcher("b")).toBeTrue(); 22 | expect(matcher("c")).toBeFalse(); 23 | expect(matcher("d")).toBeFalse(); 24 | }); 25 | it("matches multiple content type matchers as expected", function () { 26 | const matcher = contentTypeMatcher( 27 | contentTypeMatcher(/a/, /b/), 28 | contentTypeMatcher(/c/) 29 | ); 30 | expect(matcher("a")).toBeTrue(); 31 | expect(matcher("b")).toBeTrue(); 32 | expect(matcher("c")).toBeTrue(); 33 | expect(matcher("d")).toBeFalse(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/content-type-matcher.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * A function that returns true if a given mime type is supported. 17 | * 18 | * @private Internal code, does not follow semantic versioning. 19 | */ 20 | export interface ContentTypeMatcher { 21 | (contentType: string | null): boolean; 22 | supported: RegExp[]; 23 | } 24 | 25 | const contentTypeMatcherCacheSize = 1024; 26 | 27 | /** 28 | * Create a function that returns true if the given mime type is supported. 29 | * A mime type is supported when one of the regular expressions match. 30 | * 31 | * @private Internal code, does not follow semantic versioning. 32 | */ 33 | export function contentTypeMatcher( 34 | ...supported: (RegExp | Pick)[] 35 | ): ContentTypeMatcher { 36 | const cache = new Map(); 37 | const source = supported.reduce( 38 | (previousValue: RegExp[], currentValue) => 39 | previousValue.concat( 40 | "supported" in currentValue ? currentValue.supported : currentValue 41 | ), 42 | [] 43 | ); 44 | function match(contentType: string | null): boolean { 45 | if (contentType === null || contentType.length == 0) { 46 | return false; 47 | } 48 | const cached = cache.get(contentType); 49 | if (cached !== undefined) { 50 | return cached; 51 | } 52 | const ok = source.some((re) => re.test(contentType)); 53 | if (cache.size < contentTypeMatcherCacheSize) { 54 | cache.set(contentType, ok); 55 | } 56 | return ok; 57 | } 58 | match.supported = source; 59 | return match; 60 | } 61 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/create-method-url.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import type { MethodInfo, ServiceType } from "@bufbuild/protobuf"; 16 | 17 | /** 18 | * Create a URL for the given RPC. This simply adds the qualified 19 | * service name, a slash, and the method name to the path of the given 20 | * baseUrl. 21 | * 22 | * For example, the baseUri https://example.com and method "Say" from 23 | * the service example.ElizaService results in: 24 | * https://example.com/example.ElizaService/Say 25 | * 26 | * This format is used by the protocols Triple, gRPC and Twirp. 27 | * 28 | * Note that this function also accepts a protocol-relative baseUrl. 29 | * If given an empty string or "/" as a baseUrl, it returns just the 30 | * path. 31 | */ 32 | export function createMethodUrl( 33 | baseUrl: string | URL, 34 | service: ServiceType | string, 35 | method: MethodInfo | string 36 | ): string { 37 | const s = typeof service == "string" ? service : service.typeName; 38 | const m = typeof method == "string" ? method : method.name; 39 | return baseUrl.toString().replace(/\/?$/, `/${s}/${m}`); 40 | } 41 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/limit-io.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { validateReadWriteMaxBytes } from "./limit-io.js"; 16 | 17 | describe("validateReadWriteMaxBytes()", function () { 18 | it("should set defaults", function () { 19 | const o = validateReadWriteMaxBytes(undefined, undefined, undefined); 20 | expect(o).toEqual({ 21 | readMaxBytes: 0xffffffff, 22 | writeMaxBytes: 0xffffffff, 23 | compressMinBytes: 1024, 24 | }); 25 | }); 26 | it("should accept inputs", function () { 27 | const o = validateReadWriteMaxBytes(666, 777, 888); 28 | expect(o).toEqual({ 29 | readMaxBytes: 666, 30 | writeMaxBytes: 777, 31 | compressMinBytes: 888, 32 | }); 33 | }); 34 | it("should assert sane limits for readMaxBytes", function () { 35 | expect(() => 36 | validateReadWriteMaxBytes(-1, undefined, undefined) 37 | ).toThrowError("[internal] readMaxBytes -1 must be >= 1 and <= 4294967295"); 38 | expect(() => 39 | validateReadWriteMaxBytes(0xffffffff + 1, undefined, undefined) 40 | ).toThrowError( 41 | "[internal] readMaxBytes 4294967296 must be >= 1 and <= 4294967295" 42 | ); 43 | }); 44 | it("should assert sane limits for writeMaxBytes", function () { 45 | expect(() => 46 | validateReadWriteMaxBytes(undefined, -1, undefined) 47 | ).toThrowError( 48 | "[internal] writeMaxBytes -1 must be >= 1 and <= 4294967295" 49 | ); 50 | expect(() => 51 | validateReadWriteMaxBytes(undefined, 0xffffffff + 1, undefined) 52 | ).toThrowError( 53 | "[internal] writeMaxBytes 4294967296 must be >= 1 and <= 4294967295" 54 | ); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /packages/dubbo/src/protocol/protocol-handler-factory.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import type { MethodImplSpec } from "../implementation.js"; 16 | import type { UniversalHandler } from "./universal-handler.js"; 17 | 18 | /** 19 | * Creates a handler function for an RPC definition and an RPC implementation, 20 | * for one specific protocol. 21 | * 22 | * @private Internal code, does not follow semantic versioning. 23 | */ 24 | export interface ProtocolHandlerFactory { 25 | /** 26 | * Create a new handler with the user-provided implementation of the procedure. 27 | */ 28 | (spec: MethodImplSpec): UniversalHandler; 29 | 30 | /** 31 | * The name of the protocol that the created handlers implement. 32 | */ 33 | protocolName: string; 34 | } 35 | -------------------------------------------------------------------------------- /packages/dubbo/src/router-transport.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createTransport } from "./protocol-triple/transport.js"; 16 | import type { CommonTransportOptions } from "./protocol/transport-options.js"; 17 | import { createUniversalHandlerClient } from "./protocol/universal-handler-client.js"; 18 | import { createDubboRouter } from "./router.js"; 19 | import type { DubboRouter, DubboRouterOptions } from "./router.js"; 20 | 21 | /** 22 | * Creates a Transport that routes requests to the configured router. Useful for testing 23 | * and calling services running in the same process. 24 | * 25 | * This can be used to test both client logic by using this to stub/mock the backend, 26 | * and to test server logic by using this to run without needing to spin up a server. 27 | * 28 | * Mainly used for testing of dubbo-node-test and dubbo-web-test 29 | */ 30 | export function createRouterTransport( 31 | routes: (router: DubboRouter) => void, 32 | options?: { 33 | transport?: Partial; 34 | router?: DubboRouterOptions; 35 | } 36 | ) { 37 | const router = createDubboRouter({ 38 | ...(options?.router ?? {}), 39 | triple: true, 40 | }); 41 | routes(router); 42 | return createTransport({ 43 | httpClient: createUniversalHandlerClient(router.handlers), 44 | baseUrl: "https://in-memory", 45 | useBinaryFormat: true, 46 | interceptors: [], 47 | acceptCompression: [], 48 | sendCompression: null, 49 | compressMinBytes: Number.MAX_SAFE_INTEGER, 50 | readMaxBytes: Number.MAX_SAFE_INTEGER, 51 | writeMaxBytes: Number.MAX_SAFE_INTEGER, 52 | ...(options?.transport ?? {}), 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /packages/dubbo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "src/index.ts", 4 | "src/protocol-triple/index.ts", 5 | "src/protocol-grpc/index.ts", 6 | "src/protocol-grpc-web/index.ts" 7 | ], 8 | "include": ["src/**/*.spec.ts"], 9 | "extends": "../../tsconfig.base.json" 10 | } 11 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-es/bin/protoc-gen-apache-dubbo-es: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { runNodeJs } = require('@bufbuild/protoplugin') 4 | const { 5 | protocGenDubboEs 6 | } = require('../dist/cjs/src/protoc-gen-apache-dubbo-es-plugin.js') 7 | 8 | runNodeJs(protocGenDubboEs) 9 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-es/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/protoc-gen-apache-dubbo-es", 3 | "version": "3.0.0-alpha", 4 | "description": "Code generator for Dubbo", 5 | "license": "Apache-2.0", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/apache/dubbo-js.git", 9 | "directory": "packages/protoc-gen-apache-dubbo-es" 10 | }, 11 | "bin": { 12 | "protoc-gen-apache-dubbo-es": "bin/protoc-gen-apache-dubbo-es" 13 | }, 14 | "engines": { 15 | "node": ">=16.0.0" 16 | }, 17 | "scripts": { 18 | "clean": "rm -rf ./dist/cjs/*", 19 | "build": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs" 20 | }, 21 | "preferUnplugged": true, 22 | "dependencies": { 23 | "@bufbuild/protobuf": "^1.2.1", 24 | "@bufbuild/protoplugin": "^1.2.1" 25 | }, 26 | "peerDependencies": { 27 | "@apachedubbo/dubbo": "3.0.0-alpha", 28 | "@bufbuild/protoc-gen-es": "^1.2.1" 29 | }, 30 | "peerDependenciesMeta": { 31 | "@apachedubbo/dubbo": { 32 | "optional": true 33 | }, 34 | "@bufbuild/protoc-gen-es": { 35 | "optional": true 36 | } 37 | }, 38 | "files": [ 39 | "dist/**" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-es/src/protoc-gen-apache-dubbo-es-plugin.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createEcmaScriptPlugin } from "@bufbuild/protoplugin"; 16 | import { generateTs } from "./typescript.js"; 17 | import { generateJs } from "./javascript.js"; 18 | import { generateDts } from "./declaration.js"; 19 | import { version } from "../package.json"; 20 | 21 | export const protocGenDubboEs = createEcmaScriptPlugin({ 22 | name: "@apachedubbo/protoc-gen-apache-dubbo-es", 23 | version: `v${String(version)}`, 24 | generateTs, 25 | generateJs, 26 | generateDts, 27 | }); 28 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-es/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/protoc-gen-apache-dubbo-es-plugin.ts"], 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "resolveJsonModule": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-web/README.md: -------------------------------------------------------------------------------- 1 | # @apachedubbo/protoc-gen-apache-dubbo-web 2 | 3 | This package is deprecated. 4 | 5 | The code generator `@apachedubbo/protoc-gen-apache-dubbo-web` can now be used for Dubbo on the 6 | Web, and for Dubbo on Node.js. 7 | For a better fit, we have renamed it to `@apachedubbo/protoc-gen-apache-dubbo-web` in 8 | [dubbo-js](https://github.com/apache/dubbo-js). 9 | 10 | The generated code is actually exactly the same, so it is not necessary to 11 | update right away, but we are not going to maintain this package anymore. 12 | 13 | Switching to [@apachedubbo/protoc-gen-apache-dubbo-web](https://www.npmjs.com/package/@apachedubbo/protoc-gen-apache-dubbo-web) 14 | is straight-forward: 15 | 16 | ```bash 17 | npm remove @apachedubbo/protoc-gen-apache-dubbo-es 18 | npm install @apachedubbo/protoc-gen-apache-dubbo-web 19 | ``` 20 | 21 | Update your `buf.gen.yaml`: 22 | 23 | ```diff 24 | version: v1 25 | plugins: 26 | - plugin: es 27 | out: src/gen 28 | - - plugin: connect-web 29 | + - plugin: apache-dubbo-es 30 | out: src/gen 31 | ``` 32 | 33 | And your import paths: 34 | 35 | ```diff 36 | - import { ElizaService } from "gen/eliza_dubboweb"; 37 | + import { ElizaService } from "gen/eliza_dubbo"; 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-web/bin/protoc-gen-apache-dubbo-web: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {runNodeJs} = require("@bufbuild/protoplugin"); 4 | const {protocGenDubboWeb} = require("../dist/cjs/src/protoc-gen-apache-dubbo-web-plugin.js"); 5 | 6 | runNodeJs(protocGenDubboWeb); 7 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@apachedubbo/protoc-gen-apache-dubbo-web", 3 | "version": "3.0.0-alpha", 4 | "description": "Code generator for Dubbo", 5 | "license": "Apache-2.0", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/apache/dubbo-js.git", 9 | "directory": "packages/protoc-gen-apache-dubbo-web" 10 | }, 11 | "bin": { 12 | "protoc-gen-apache-dubbo-web": "bin/protoc-gen-apache-dubbo-web" 13 | }, 14 | "engines": { 15 | "node": ">=16.0.0" 16 | }, 17 | "scripts": { 18 | "clean": "rm -rf ./dist/cjs/*", 19 | "build": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs" 20 | }, 21 | "preferUnplugged": true, 22 | "dependencies": { 23 | "@bufbuild/protobuf": "^1.2.1", 24 | "@bufbuild/protoplugin": "^1.2.1" 25 | }, 26 | "peerDependencies": { 27 | "@apachedubbo/dubbo": "3.0.0-alpha", 28 | "@bufbuild/protoc-gen-es": "^1.2.1" 29 | }, 30 | "peerDependenciesMeta": { 31 | "@apachedubbo/dubbo": { 32 | "optional": true 33 | }, 34 | "@bufbuild/protoc-gen-es": { 35 | "optional": true 36 | } 37 | }, 38 | "files": [ 39 | "dist/**" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-web/src/protoc-gen-apache-dubbo-web-plugin.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021-2023 Buf Technologies, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import { createEcmaScriptPlugin } from "@bufbuild/protoplugin"; 16 | import { generateTs } from "./typescript.js"; 17 | import { generateJs } from "./javascript.js"; 18 | import { generateDts } from "./declaration.js"; 19 | import { version } from "../package.json"; 20 | 21 | export const protocGenDubboWeb = createEcmaScriptPlugin({ 22 | name: "@apachedubbo/protoc-gen-apache-dubbo-web", 23 | version: `v${String(version)}`, 24 | generateTs, 25 | generateJs, 26 | generateDts, 27 | }); 28 | -------------------------------------------------------------------------------- /packages/protoc-gen-apache-dubbo-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["src/protoc-gen-apache-dubbo-web-plugin.ts"], 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "resolveJsonModule": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | packages: 17 | - "packages/*" 18 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "lib": [ 5 | "ES2017", 6 | // DOM for the fetch and streams API 7 | "DOM", 8 | // ES2018.AsyncIterable for AsyncIterator 9 | "ES2018.AsyncIterable" 10 | ], 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": false, 13 | "forceConsistentCasingInFileNames": true, 14 | "strict": true, 15 | "noImplicitAny": true, 16 | "strictNullChecks": true, 17 | "strictFunctionTypes": true, 18 | "strictBindCallApply": true, 19 | "strictPropertyInitialization": true, 20 | "noImplicitThis": true, 21 | "useUnknownInCatchVariables": true, 22 | "noUnusedLocals": true, 23 | "noImplicitReturns": true, 24 | "noFallthroughCasesInSwitch": true, 25 | "noImplicitOverride": true, 26 | 27 | // We need node's module resolution, so we do not have to skip lib checks 28 | "moduleResolution": "Node", 29 | "skipLibCheck": false 30 | } 31 | } 32 | --------------------------------------------------------------------------------