├── .compodocrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── .OwlBot.lock.yaml ├── .OwlBot.yaml ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── feature_request.md │ ├── question.md │ └── support_request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto-approve.yml ├── auto-label.yaml ├── generated-files-bot.yml ├── release-please.yml ├── release-trigger.yml ├── sync-repo-settings.yaml └── workflows │ └── ci.yaml ├── .gitignore ├── .jsdoc.js ├── .kokoro ├── .gitattributes ├── common.cfg ├── continuous │ └── node14 │ │ ├── common.cfg │ │ ├── lint.cfg │ │ ├── samples-test.cfg │ │ ├── system-test.cfg │ │ └── test.cfg ├── docs.sh ├── lint.sh ├── populate-secrets.sh ├── presubmit │ ├── node14 │ │ ├── common.cfg │ │ ├── samples-test.cfg │ │ ├── system-test.cfg │ │ └── test.cfg │ └── windows │ │ ├── common.cfg │ │ └── test.cfg ├── publish.sh ├── release │ ├── common.cfg │ ├── docs-devsite.cfg │ ├── docs-devsite.sh │ ├── docs.cfg │ ├── docs.sh │ └── publish.cfg ├── samples-test.sh ├── system-test.sh ├── test.bat ├── test.sh ├── trampoline.sh └── trampoline_v2.sh ├── .mocharc.js ├── .nycrc ├── .prettierignore ├── .prettierrc.js ├── .readme-partials.yaml ├── .repo-metadata.json ├── .trampolinerc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── doc └── images │ ├── breakpoint-hit.png │ ├── breakpoint-set.png │ └── debug-ui.png ├── linkinator.config.json ├── owlbot.py ├── package.json ├── renovate.json ├── samples ├── .eslintrc.yml ├── README.md ├── app.js ├── app.yaml ├── package.json ├── snippets.js └── test │ └── test.js ├── src ├── agent │ ├── config.ts │ ├── controller.ts │ ├── debuglet.ts │ ├── firebase-controller.ts │ ├── io │ │ ├── scanner.ts │ │ └── sourcemapper.ts │ ├── state │ │ └── inspector-state.ts │ ├── util │ │ ├── debug-assert.ts │ │ ├── utils.ts │ │ └── validator.ts │ └── v8 │ │ ├── debugapi.ts │ │ ├── inspector-debugapi.ts │ │ └── v8inspector.ts ├── client │ └── stackdriver │ │ └── status-message.ts ├── debuggee.ts ├── index.ts └── types │ ├── stackdriver.ts │ └── v8.ts ├── system-test ├── .eslintrc ├── fixtures │ └── sample │ │ ├── package.json │ │ ├── src │ │ ├── allowExpressions.ts │ │ ├── allowExpressionsJs.js │ │ ├── completeServiceContext.ts │ │ ├── firebase.ts │ │ ├── import.ts │ │ ├── noargs.ts │ │ ├── partialCapture.ts │ │ ├── partialServiceContext.ts │ │ ├── start.js │ │ └── startEmpty.js │ │ ├── tsconfig.json │ │ └── tslint.json ├── test-controller.ts ├── test-e2e.ts └── test-install.ts ├── test ├── .eslintrc ├── fixtures │ ├── a │ │ └── hello.js │ ├── b │ │ └── hello.js │ ├── broken-links │ │ └── broken-link.js │ ├── coffee │ │ ├── transpile.coffee │ │ ├── transpile.js │ │ └── transpile.js.map │ ├── es6 │ │ ├── transpile.es6 │ │ ├── transpile.js │ │ └── transpile.js.map │ ├── expensive-capture.js │ ├── fat-arrow.js │ ├── fib.js │ ├── foo.js │ ├── gcloud-credentials.json │ ├── hello.js │ ├── hello.jsz │ ├── key-bad.json │ ├── nojs │ │ └── README.md │ ├── sourcemapper │ │ ├── babel │ │ │ ├── build.sh │ │ │ ├── in.js │ │ │ ├── out.js │ │ │ ├── out.js.map │ │ │ └── package.json │ │ ├── coffeescript │ │ │ ├── build.sh │ │ │ ├── in.coffee │ │ │ ├── in.js │ │ │ └── in.js.map │ │ ├── typescript │ │ │ ├── build.sh │ │ │ ├── in.ts_ │ │ │ ├── out.js │ │ │ └── out.js.map │ │ └── webpack-ts │ │ │ ├── in.ts_ │ │ │ ├── out.js │ │ │ ├── out.js.map │ │ │ ├── package.json │ │ │ └── webpack.config.js │ ├── sourcemaps │ │ ├── css-file.css │ │ ├── css-map-file.css.map │ │ ├── empty-source-map.js.map │ │ ├── js-file.js │ │ └── js-map-file.js.map │ ├── test-config.js │ ├── transpiled-shorter │ │ ├── build.sh │ │ ├── in.coffee │ │ ├── in.js │ │ └── in.js.map │ └── ts │ │ ├── async.js │ │ └── async.ts_ ├── misc │ ├── bench-code.js │ ├── bench.ts │ └── test-leak.ts ├── mock-logger.ts ├── nocks.ts ├── test-circular-code.js ├── test-circular.ts ├── test-controller.ts ├── test-debug-assert.ts ├── test-debuggee.ts ├── test-debuglet.ts ├── test-duplicate-expressions-code.js ├── test-duplicate-expressions.ts ├── test-duplicate-nested-expressions-code.js ├── test-duplicate-nested-expressions.ts ├── test-evaluated-expressions-code.js ├── test-evaluated-expressions.ts ├── test-expression-side-effect-code.js ├── test-expression-side-effect.ts ├── test-fat-arrow.ts ├── test-firebase-controller.ts ├── test-max-data-size-code.js ├── test-max-data-size.ts ├── test-scanner.ts ├── test-sourcemapper.ts ├── test-this-context-code.js ├── test-this-context.ts ├── test-try-catch-code.js ├── test-try-catch.ts ├── test-v8debugapi-code.js ├── test-v8debugapi-ts-code.ts └── test-v8debugapi.ts └── tsconfig.json /.compodocrc: -------------------------------------------------------------------------------- 1 | --- 2 | tsconfig: ./tsconfig.json 3 | output: ./docs 4 | theme: material 5 | hideGenerator: true 6 | disablePrivate: true 7 | disableProtected: true 8 | disableInternal: true 9 | disableCoverage: true 10 | disableGraph: true 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [*.md] 14 | indent_size = 4 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts" 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ts text eol=lf 2 | *.js text eol=lf 3 | protos/* linguist-generated 4 | **/api-extractor.json linguist-language=JSON-with-Comments 5 | -------------------------------------------------------------------------------- /.github/.OwlBot.lock.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 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 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | digest: sha256:e92044720ab3cb6984a70b0c6001081204375959ba3599ef6c42dd99a7783a67 17 | # created: 2023-11-10T00:24:05.581078808Z 18 | -------------------------------------------------------------------------------- /.github/.OwlBot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 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 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | 17 | 18 | begin-after-commit-hash: 397c0bfd367a2427104f988d5329bc117caafd95 19 | 20 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | # 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | 7 | 8 | # The yoshi-nodejs team is the default owner for nodejs repositories. 9 | * @googleapis/yoshi-nodejs @googleapis/api-debug 10 | 11 | # The github automation team is the default owner for the auto-approve file. 12 | .github/auto-approve.yml @googleapis/github-automation 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | **Table of contents** 4 | 5 | * [Contributor License Agreements](#contributor-license-agreements) 6 | * [Contributing a patch](#contributing-a-patch) 7 | * [Running the tests](#running-the-tests) 8 | * [Releasing the library](#releasing-the-library) 9 | 10 | ## Contributor License Agreements 11 | 12 | We'd love to accept your sample apps and patches! Before we can take them, we 13 | have to jump a couple of legal hurdles. 14 | 15 | Please fill out either the individual or corporate Contributor License Agreement 16 | (CLA). 17 | 18 | * If you are an individual writing original source code and you're sure you 19 | own the intellectual property, then you'll need to sign an [individual CLA] 20 | (https://developers.google.com/open-source/cla/individual). 21 | * If you work for a company that wants to allow you to contribute your work, 22 | then you'll need to sign a [corporate CLA] 23 | (https://developers.google.com/open-source/cla/corporate). 24 | 25 | Follow either of the two links above to access the appropriate CLA and 26 | instructions for how to sign and return it. Once we receive it, we'll be able to 27 | accept your pull requests. 28 | 29 | ## Contributing A Patch 30 | 31 | 1. Submit an issue describing your proposed change to the repo in question. 32 | 1. The repo owner will respond to your issue promptly. 33 | 1. If your proposed change is accepted, and you haven't already done so, sign a 34 | Contributor License Agreement (see details above). 35 | 1. Fork the desired repo, develop and test your code changes. 36 | 1. Ensure that your code adheres to the existing style in the code to which 37 | you are contributing. 38 | 1. Ensure that your code has an appropriate set of tests which all pass. 39 | 1. Submit a pull request. 40 | 41 | ## Running the tests 42 | 43 | 1. [Prepare your environment for Node.js setup][setup]. 44 | 45 | 1. Install dependencies: 46 | 47 | npm install 48 | 49 | 1. Run the tests: 50 | 51 | npm test 52 | 53 | 1. Lint (and maybe fix) any changes: 54 | 55 | npm run fix 56 | 57 | [setup]: https://cloud.google.com/nodejs/docs/setup 58 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | labels: 'type: bug, priority: p2' 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | 1) Is this a client library issue or a product issue? 12 | This is the client library for . We will only be able to assist with issues that pertain to the behaviors of this library. If the issue you're experiencing is due to the behavior of the product itself, please visit the [ Support page]() to reach the most relevant engineers. 13 | 14 | 2) Did someone already solve this? 15 | - Search the issues already opened: https://github.com/googleapis/cloud-debug-nodejs/issues 16 | - Search the issues on our "catch-all" repository: https://github.com/googleapis/google-cloud-node 17 | - Search or ask on StackOverflow (engineers monitor these tags): http://stackoverflow.com/questions/tagged/google-cloud-platform+node.js 18 | 19 | 3) Do you have a support contract? 20 | Please create an issue in the [support console](https://cloud.google.com/support/) to ensure a timely response. 21 | 22 | If the support paths suggested above still do not result in a resolution, please provide the following details. 23 | 24 | #### Environment details 25 | 26 | - OS: 27 | - Node.js version: 28 | - npm version: 29 | - `@google-cloud/debug-agent` version: 30 | 31 | #### Steps to reproduce 32 | 33 | 1. ? 34 | 2. ? 35 | 36 | Making sure to follow these steps will guarantee the quickest resolution possible. 37 | 38 | Thanks! 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Google Cloud Support 3 | url: https://cloud.google.com/support/ 4 | about: If you have a support contract with Google, please use the Google Cloud Support portal. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this library 4 | labels: 'type: feature request, priority: p3' 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | **Additional context** 18 | Add any other context or screenshots about the feature request here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question 4 | labels: 'type: question, priority: p3' 5 | --- 6 | 7 | Thanks for stopping by to ask us a question! Please make sure to include: 8 | - What you're trying to do 9 | - What code you've already tried 10 | - Any error messages you're getting 11 | 12 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support request 3 | about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. 4 | 5 | --- 6 | 7 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 8 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: 2 | - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/cloud-debug-nodejs/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea 3 | - [ ] Ensure the tests and linter pass 4 | - [ ] Code coverage does not decrease (if any source code was changed) 5 | - [ ] Appropriate docs were updated (if necessary) 6 | 7 | Fixes # 🦕 8 | -------------------------------------------------------------------------------- /.github/auto-approve.yml: -------------------------------------------------------------------------------- 1 | processes: 2 | - "NodeDependency" 3 | - "OwlBotTemplateChanges" 4 | -------------------------------------------------------------------------------- /.github/auto-label.yaml: -------------------------------------------------------------------------------- 1 | requestsize: 2 | enabled: true 3 | -------------------------------------------------------------------------------- /.github/generated-files-bot.yml: -------------------------------------------------------------------------------- 1 | generatedFiles: 2 | - path: '.kokoro/**' 3 | message: '`.kokoro` files are templated and should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 4 | - path: '.github/CODEOWNERS' 5 | message: 'CODEOWNERS should instead be modified via the `codeowner_team` property in .repo-metadata.json' 6 | - path: '.github/workflows/ci.yaml' 7 | message: '`.github/workflows/ci.yaml` (GitHub Actions) should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 8 | - path: '.github/generated-files-bot.+(yml|yaml)' 9 | message: '`.github/generated-files-bot.(yml|yaml)` should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 10 | - path: 'README.md' 11 | message: '`README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 12 | - path: 'samples/README.md' 13 | message: '`samples/README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 14 | ignoreAuthors: 15 | - 'gcf-owl-bot[bot]' 16 | - 'yoshi-automation' 17 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | handleGHRelease: true 2 | releaseType: node 3 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | -------------------------------------------------------------------------------- /.github/sync-repo-settings.yaml: -------------------------------------------------------------------------------- 1 | branchProtectionRules: 2 | - pattern: main 3 | isAdminEnforced: true 4 | requiredApprovingReviewCount: 1 5 | requiresCodeOwnerReviews: true 6 | requiresStrictStatusChecks: true 7 | requiredStatusCheckContexts: 8 | - "ci/kokoro: Samples test" 9 | - "ci/kokoro: System test" 10 | - lint 11 | - test (14) 12 | - test (16) 13 | - test (18) 14 | - cla/google 15 | - windows 16 | - OwlBot Post Processor 17 | permissionRules: 18 | - team: yoshi-admins 19 | permission: admin 20 | - team: jsteam-admins 21 | permission: admin 22 | - team: jsteam 23 | permission: push 24 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | name: ci 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | node: [14, 16, 18, 20] 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: ${{ matrix.node }} 18 | - run: node --version 19 | # The first installation step ensures that all of our production 20 | # dependencies work on the given Node.js version, this helps us find 21 | # dependencies that don't match our engines field: 22 | - run: npm install --production --engine-strict --ignore-scripts --no-package-lock 23 | # Clean up the production install, before installing dev/production: 24 | - run: rm -rf node_modules 25 | - run: npm install 26 | - run: npm test 27 | - name: coverage 28 | uses: codecov/codecov-action@v4 29 | with: 30 | name: actions ${{ matrix.node }} 31 | fail_ci_if_error: false 32 | windows: 33 | runs-on: windows-latest 34 | steps: 35 | - uses: actions/checkout@v4 36 | - uses: actions/setup-node@v4 37 | with: 38 | node-version: 14 39 | - run: npm install 40 | - run: npm test 41 | - name: coverage 42 | uses: codecov/codecov-action@v4 43 | with: 44 | name: actions windows 45 | fail_ci_if_error: false 46 | lint: 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: actions/setup-node@v4 51 | with: 52 | node-version: 14 53 | - run: npm install 54 | - run: npm run lint 55 | docs: 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: actions/checkout@v4 59 | - uses: actions/setup-node@v4 60 | with: 61 | node-version: 14 62 | - run: npm install 63 | - run: npm run docs-test 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | coverage 3 | .coverage 4 | node_modules 5 | npm-debug.log 6 | .DS_Store 7 | .vscode 8 | yarn.lock 9 | google-cloud-debug-agent-*.tgz 10 | package-lock.json 11 | .nyc_output 12 | key.json 13 | docs/ 14 | __pycache__ 15 | -------------------------------------------------------------------------------- /.jsdoc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 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 | // https://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 | 'use strict'; 17 | 18 | module.exports = { 19 | opts: { 20 | readme: './README.md', 21 | package: './package.json', 22 | template: './node_modules/jsdoc-fresh', 23 | recurse: true, 24 | verbose: true, 25 | destination: './docs/' 26 | }, 27 | plugins: [ 28 | 'plugins/markdown', 29 | 'jsdoc-region-tag' 30 | ], 31 | source: { 32 | excludePattern: '(^|\\/|\\\\)[._]', 33 | include: [ 34 | 'src', 35 | ], 36 | includePattern: '\\.js$' 37 | }, 38 | templates: { 39 | copyright: 'Copyright 2019 Google, LLC.', 40 | includeDate: false, 41 | sourceFiles: false, 42 | systemName: '@google-cloud/debug-agent', 43 | theme: 'lumen', 44 | default: { 45 | outputSourceFiles: false 46 | } 47 | }, 48 | markdown: { 49 | idInHeadings: true 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /.kokoro/.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-generated=true 2 | -------------------------------------------------------------------------------- /.kokoro/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/cloud-debug-nodejs/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/cloud-debug-nodejs/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/lint.cfg: -------------------------------------------------------------------------------- 1 | env_vars: { 2 | key: "TRAMPOLINE_BUILD_FILE" 3 | value: "github/cloud-debug-nodejs/.kokoro/lint.sh" 4 | } 5 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/cloud-debug-nodejs/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/continuous/node14/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/cloud-debug-nodejs/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/continuous/node14/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/.kokoro/continuous/node14/test.cfg -------------------------------------------------------------------------------- /.kokoro/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | npm run docs-test 26 | -------------------------------------------------------------------------------- /.kokoro/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | # Install and link samples 26 | if [ -f samples/package.json ]; then 27 | cd samples/ 28 | npm link ../ 29 | npm install 30 | cd .. 31 | fi 32 | 33 | npm run lint 34 | -------------------------------------------------------------------------------- /.kokoro/populate-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 Google LLC. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # 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 file is called in the early stage of `trampoline_v2.sh` to 17 | # populate secrets needed for the CI builds. 18 | 19 | set -eo pipefail 20 | 21 | function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} 22 | function msg { println "$*" >&2 ;} 23 | function println { printf '%s\n' "$(now) $*" ;} 24 | 25 | # Populates requested secrets set in SECRET_MANAGER_KEYS 26 | 27 | # In Kokoro CI builds, we use the service account attached to the 28 | # Kokoro VM. This means we need to setup auth on other CI systems. 29 | # For local run, we just use the gcloud command for retrieving the 30 | # secrets. 31 | 32 | if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then 33 | GCLOUD_COMMANDS=( 34 | "docker" 35 | "run" 36 | "--entrypoint=gcloud" 37 | "--volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR}" 38 | "gcr.io/google.com/cloudsdktool/cloud-sdk" 39 | ) 40 | if [[ "${TRAMPOLINE_CI:-}" == "kokoro" ]]; then 41 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" 42 | else 43 | echo "Authentication for this CI system is not implemented yet." 44 | exit 2 45 | # TODO: Determine appropriate SECRET_LOCATION and the GCLOUD_COMMANDS. 46 | fi 47 | else 48 | # For local run, use /dev/shm or temporary directory for 49 | # KOKORO_GFILE_DIR. 50 | if [[ -d "/dev/shm" ]]; then 51 | export KOKORO_GFILE_DIR=/dev/shm 52 | else 53 | export KOKORO_GFILE_DIR=$(mktemp -d -t ci-XXXXXXXX) 54 | fi 55 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" 56 | GCLOUD_COMMANDS=("gcloud") 57 | fi 58 | 59 | msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" 60 | mkdir -p ${SECRET_LOCATION} 61 | 62 | for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") 63 | do 64 | msg "Retrieving secret ${key}" 65 | "${GCLOUD_COMMANDS[@]}" \ 66 | secrets versions access latest \ 67 | --project cloud-devrel-kokoro-resources \ 68 | --secret $key > \ 69 | "$SECRET_LOCATION/$key" 70 | if [[ $? == 0 ]]; then 71 | msg "Secret written to ${SECRET_LOCATION}/${key}" 72 | else 73 | msg "Error retrieving secret ${key}" 74 | exit 2 75 | fi 76 | done 77 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/cloud-debug-nodejs/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/cloud-debug-nodejs/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/cloud-debug-nodejs/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "long-door-651-kokoro-system-test-service-account" 12 | } -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/.kokoro/presubmit/node14/test.cfg -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/test.cfg: -------------------------------------------------------------------------------- 1 | # Use the test file directly 2 | build_file: "cloud-debug-nodejs/.kokoro/test.bat" 3 | -------------------------------------------------------------------------------- /.kokoro/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | # Start the releasetool reporter 22 | python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script 23 | 24 | cd $(dirname $0)/.. 25 | 26 | NPM_TOKEN=$(cat $KOKORO_KEYSTORE_DIR/73713_google-cloud-npm-token-1) 27 | echo "//wombat-dressing-room.appspot.com/:_authToken=${NPM_TOKEN}" > ~/.npmrc 28 | 29 | npm install 30 | npm pack . 31 | # npm provides no way to specify, observe, or predict the name of the tarball 32 | # file it generates. We have to look in the current directory for the freshest 33 | # .tgz file. 34 | TARBALL=$(ls -1 -t *.tgz | head -1) 35 | 36 | npm publish --access=public --registry=https://wombat-dressing-room.appspot.com "$TARBALL" 37 | 38 | # Kokoro collects *.tgz and package-lock.json files and stores them in Placer 39 | # so we can generate SBOMs and attestations. 40 | # However, we *don't* want Kokoro to collect package-lock.json and *.tgz files 41 | # that happened to be installed with dependencies. 42 | find node_modules -name package-lock.json -o -name "*.tgz" | xargs rm -f -------------------------------------------------------------------------------- /.kokoro/release/common.cfg: -------------------------------------------------------------------------------- 1 | before_action { 2 | fetch_keystore { 3 | keystore_resource { 4 | keystore_config_id: 73713 5 | keyname: "yoshi-automation-github-key" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/cloud-debug-nodejs/.kokoro/release/docs-devsite.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2021 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | if [[ -z "$CREDENTIALS" ]]; then 20 | # if CREDENTIALS are explicitly set, assume we're testing locally 21 | # and don't set NPM_CONFIG_PREFIX. 22 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 23 | export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" 24 | cd $(dirname $0)/../.. 25 | fi 26 | 27 | npm install 28 | npm install --no-save @google-cloud/cloud-rad@^0.4.0 29 | # publish docs to devsite 30 | npx @google-cloud/cloud-rad . cloud-rad 31 | -------------------------------------------------------------------------------- /.kokoro/release/docs.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/cloud-debug-nodejs/.kokoro/release/docs.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/release/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | # build jsdocs (Python is installed on the Node 10 docker image). 20 | if [[ -z "$CREDENTIALS" ]]; then 21 | # if CREDENTIALS are explicitly set, assume we're testing locally 22 | # and don't set NPM_CONFIG_PREFIX. 23 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 24 | export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" 25 | cd $(dirname $0)/../.. 26 | fi 27 | npm install 28 | npm run docs 29 | 30 | # create docs.metadata, based on package.json and .repo-metadata.json. 31 | npm i json@9.0.6 -g 32 | python3 -m docuploader create-metadata \ 33 | --name=$(cat .repo-metadata.json | json name) \ 34 | --version=$(cat package.json | json version) \ 35 | --language=$(cat .repo-metadata.json | json language) \ 36 | --distribution-name=$(cat .repo-metadata.json | json distribution_name) \ 37 | --product-page=$(cat .repo-metadata.json | json product_documentation) \ 38 | --github-repository=$(cat .repo-metadata.json | json repo) \ 39 | --issue-tracker=$(cat .repo-metadata.json | json issue_tracker) 40 | cp docs.metadata ./docs/docs.metadata 41 | 42 | # deploy the docs. 43 | if [[ -z "$CREDENTIALS" ]]; then 44 | CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account 45 | fi 46 | if [[ -z "$BUCKET" ]]; then 47 | BUCKET=docs-staging 48 | fi 49 | python3 -m docuploader upload ./docs --credentials $CREDENTIALS --staging-bucket $BUCKET 50 | -------------------------------------------------------------------------------- /.kokoro/release/publish.cfg: -------------------------------------------------------------------------------- 1 | before_action { 2 | fetch_keystore { 3 | keystore_resource { 4 | keystore_config_id: 73713 5 | keyname: "docuploader_service_account" 6 | } 7 | } 8 | } 9 | 10 | before_action { 11 | fetch_keystore { 12 | keystore_resource { 13 | keystore_config_id: 73713 14 | keyname: "google-cloud-npm-token-1" 15 | } 16 | } 17 | } 18 | 19 | env_vars: { 20 | key: "SECRET_MANAGER_KEYS" 21 | value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" 22 | } 23 | 24 | # Download trampoline resources. 25 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 26 | 27 | # Use the trampoline script to run in docker. 28 | build_file: "cloud-debug-nodejs/.kokoro/trampoline_v2.sh" 29 | 30 | # Configure the docker image for kokoro-trampoline. 31 | env_vars: { 32 | key: "TRAMPOLINE_IMAGE" 33 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 34 | } 35 | 36 | env_vars: { 37 | key: "TRAMPOLINE_BUILD_FILE" 38 | value: "github/cloud-debug-nodejs/.kokoro/publish.sh" 39 | } 40 | 41 | # Store the packages we uploaded to npmjs.org and their corresponding 42 | # package-lock.jsons in Placer. That way, we have a record of exactly 43 | # what we published, and which version of which tools we used to publish 44 | # it, which we can use to generate SBOMs and attestations. 45 | action { 46 | define_artifacts { 47 | regex: "github/**/*.tgz" 48 | regex: "github/**/package-lock.json" 49 | strip_prefix: "github" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.kokoro/samples-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | # Setup service account credentials. 22 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account 23 | export GCLOUD_PROJECT=long-door-651 24 | 25 | cd $(dirname $0)/.. 26 | 27 | # Run a pre-test hook, if a pre-samples-test.sh is in the project 28 | if [ -f .kokoro/pre-samples-test.sh ]; then 29 | set +x 30 | . .kokoro/pre-samples-test.sh 31 | set -x 32 | fi 33 | 34 | if [ -f samples/package.json ]; then 35 | npm install 36 | 37 | # Install and link samples 38 | cd samples/ 39 | npm link ../ 40 | npm install 41 | cd .. 42 | # If tests are running against main branch, configure flakybot 43 | # to open issues on failures: 44 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then 45 | export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml 46 | export MOCHA_REPORTER=xunit 47 | cleanup() { 48 | chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot 49 | $KOKORO_GFILE_DIR/linux_amd64/flakybot 50 | } 51 | trap cleanup EXIT HUP 52 | fi 53 | 54 | npm run samples-test 55 | fi 56 | 57 | # codecov combines coverage across integration and unit tests. Include 58 | # the logic below for any environment you wish to collect coverage for: 59 | COVERAGE_NODE=14 60 | if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then 61 | NYC_BIN=./node_modules/nyc/bin/nyc.js 62 | if [ -f "$NYC_BIN" ]; then 63 | $NYC_BIN report || true 64 | fi 65 | bash $KOKORO_GFILE_DIR/codecov.sh 66 | else 67 | echo "coverage is only reported for Node $COVERAGE_NODE" 68 | fi 69 | -------------------------------------------------------------------------------- /.kokoro/system-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | # Setup service account credentials. 22 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account 23 | export GCLOUD_PROJECT=long-door-651 24 | 25 | cd $(dirname $0)/.. 26 | 27 | # Run a pre-test hook, if a pre-system-test.sh is in the project 28 | if [ -f .kokoro/pre-system-test.sh ]; then 29 | set +x 30 | . .kokoro/pre-system-test.sh 31 | set -x 32 | fi 33 | 34 | npm install 35 | 36 | # If tests are running against main branch, configure flakybot 37 | # to open issues on failures: 38 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then 39 | export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml 40 | export MOCHA_REPORTER=xunit 41 | cleanup() { 42 | chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot 43 | $KOKORO_GFILE_DIR/linux_amd64/flakybot 44 | } 45 | trap cleanup EXIT HUP 46 | fi 47 | 48 | npm run system-test 49 | 50 | # codecov combines coverage across integration and unit tests. Include 51 | # the logic below for any environment you wish to collect coverage for: 52 | COVERAGE_NODE=14 53 | if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then 54 | NYC_BIN=./node_modules/nyc/bin/nyc.js 55 | if [ -f "$NYC_BIN" ]; then 56 | $NYC_BIN report || true 57 | fi 58 | bash $KOKORO_GFILE_DIR/codecov.sh 59 | else 60 | echo "coverage is only reported for Node $COVERAGE_NODE" 61 | fi 62 | -------------------------------------------------------------------------------- /.kokoro/test.bat: -------------------------------------------------------------------------------- 1 | @rem Copyright 2018 Google LLC. All rights reserved. 2 | @rem 3 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 4 | @rem you may not use this file except in compliance with the License. 5 | @rem You may obtain a copy of the License at 6 | @rem 7 | @rem http://www.apache.org/licenses/LICENSE-2.0 8 | @rem 9 | @rem Unless required by applicable law or agreed to in writing, software 10 | @rem distributed under the License is distributed on an "AS IS" BASIS, 11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | @rem See the License for the specific language governing permissions and 13 | @rem limitations under the License. 14 | 15 | @echo "Starting Windows build" 16 | 17 | cd /d %~dp0 18 | cd .. 19 | 20 | @rem npm path is not currently set in our image, we should fix this next time 21 | @rem we upgrade Node.js in the image: 22 | SET PATH=%PATH%;/cygdrive/c/Program Files/nodejs/npm 23 | 24 | call nvm use v14.17.3 25 | call which node 26 | 27 | call npm install || goto :error 28 | call npm run test || goto :error 29 | 30 | goto :EOF 31 | 32 | :error 33 | exit /b 1 34 | -------------------------------------------------------------------------------- /.kokoro/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 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 | # https://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 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | # If tests are running against main branch, configure flakybot 25 | # to open issues on failures: 26 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then 27 | export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml 28 | export MOCHA_REPORTER=xunit 29 | cleanup() { 30 | chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot 31 | $KOKORO_GFILE_DIR/linux_amd64/flakybot 32 | } 33 | trap cleanup EXIT HUP 34 | fi 35 | # Unit tests exercise the entire API surface, which may include 36 | # deprecation warnings: 37 | export MOCHA_THROW_DEPRECATION=false 38 | npm test 39 | 40 | # codecov combines coverage across integration and unit tests. Include 41 | # the logic below for any environment you wish to collect coverage for: 42 | COVERAGE_NODE=14 43 | if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then 44 | NYC_BIN=./node_modules/nyc/bin/nyc.js 45 | if [ -f "$NYC_BIN" ]; then 46 | $NYC_BIN report || true 47 | fi 48 | bash $KOKORO_GFILE_DIR/codecov.sh 49 | else 50 | echo "coverage is only reported for Node $COVERAGE_NODE" 51 | fi 52 | -------------------------------------------------------------------------------- /.kokoro/trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2017 Google Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # 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 file is not used any more, but we keep this file for making it 17 | # easy to roll back. 18 | # TODO: Remove this file from the template. 19 | 20 | set -eo pipefail 21 | 22 | # Always run the cleanup script, regardless of the success of bouncing into 23 | # the container. 24 | function cleanup() { 25 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 26 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 27 | echo "cleanup"; 28 | } 29 | trap cleanup EXIT 30 | 31 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets. 32 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" 33 | -------------------------------------------------------------------------------- /.mocharc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 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 | const config = { 15 | "enable-source-maps": true, 16 | "throw-deprecation": true, 17 | "timeout": 10000, 18 | "recursive": true 19 | } 20 | if (process.env.MOCHA_THROW_DEPRECATION === 'false') { 21 | delete config['throw-deprecation']; 22 | } 23 | if (process.env.MOCHA_REPORTER) { 24 | config.reporter = process.env.MOCHA_REPORTER; 25 | } 26 | if (process.env.MOCHA_REPORTER_OUTPUT) { 27 | config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; 28 | } 29 | module.exports = config 30 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "report-dir": "./.coverage", 3 | "reporter": ["text", "lcov"], 4 | "exclude": [ 5 | "**/*-test", 6 | "**/.coverage", 7 | "**/apis", 8 | "**/benchmark", 9 | "**/conformance", 10 | "**/docs", 11 | "**/samples", 12 | "**/scripts", 13 | "**/protos", 14 | "**/test", 15 | "**/*.d.ts", 16 | ".jsdoc.js", 17 | "**/.jsdoc.js", 18 | "karma.conf.js", 19 | "webpack-tests.config.js", 20 | "webpack.config.js" 21 | ], 22 | "exclude-after-remap": false, 23 | "all": true 24 | } 25 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 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 | // https://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 = { 16 | ...require('gts/.prettierrc.json') 17 | } 18 | -------------------------------------------------------------------------------- /.readme-partials.yaml: -------------------------------------------------------------------------------- 1 | introduction: |- 2 | > This module provides Snapshot Debugger support for Node.js applications. 3 | Snapshot Debugger is an open source product that lets you debug your 4 | applications in production without stopping or pausing your application. 5 | 6 | A Firebase Realtime Database instance is used to store your data. 7 | 8 | ## Project Status: Archived 9 | 10 | This project has been archived and is no longer supported. There will be no 11 | further bug fixes or security patches. The repository can be forked by users 12 | if they want to maintain it going forward. 13 | 14 | body: |- 15 | ## Debugger Agent Settings 16 | 17 | To customize the behaviour of the automatic debugger agent, specify options 18 | when starting the agent. The following code sample shows how to pass in a 19 | subset of the available options. 20 | 21 | ```js 22 | require('@google-cloud/debug-agent').start({ 23 | // .. auth settings .. 24 | 25 | // debug agent settings: 26 | allowExpressions: true, 27 | serviceContext: { 28 | service: 'my-service', 29 | version: 'version-1' 30 | }, 31 | capture: { maxFrames: 20, maxProperties: 100 } 32 | }); 33 | ``` 34 | 35 | The following options configure the connection to the Firebase database: 36 | * firebaseDbUrl - https://**PROJECT_ID**-cdbg.firebaseio.com will be used if 37 | not provided. where **PROJECT_ID** is your project ID. 38 | * firebaseKeyPath - Default google application credentials are used if not 39 | provided. 40 | 41 | Some key configuration options are: 42 | * allowExpressions - Whether or not it is permitted to evaluate 43 | epressions. Functionality is limited when this is not set, but there 44 | is some risk that malicious expressions can mutate program state. 45 | * serviceContext - This information is utilized in the UI to identify all 46 | the running instances of your service. Set this if you do not like the 47 | default values. 48 | * capture - Configuration options on what is captured on a snapshot. Set 49 | this if the default snapshot captures are too limited. Note that 50 | relaxing constraints may cause performance impact. 51 | 52 | See [the agent configuration][config-ts] for a list of possible configuration 53 | options. 54 | 55 | ## Using the Debugger 56 | 57 | Once your application is running, use the 58 | [Snapshot Debugger CLI](https://pypi.org/project/snapshot-dbg-cli/) or the 59 | [VSCode extension][extension-page] 60 | to debug your application. 61 | 62 | ## Historical note 63 | 64 | Version 6.x and 7.x of this agent supported both the now shutdown Cloud 65 | Debugger service (by default) and the 66 | [Snapshot Debugger](https://github.com/GoogleCloudPlatform/snapshot-debugger/) 67 | (Firebase RTDB backend) by setting the `useFirebase` flag to true. Version 8.0.0 68 | removed support for the Cloud Debugger service, making the Snapshot Debugger the 69 | default. To note the `useFirebase` flag is now obsolete, but still present for 70 | backward compatibility. 71 | 72 | ## Limitations and Requirements 73 | 74 | > Note: There is a known issue where enabling the agent may trigger memory 75 | leaks. See [#811](https://github.com/googleapis/cloud-debug-nodejs/issues/811) 76 | 77 | * Privacy issues can be created by setting snapshot conditions that watch 78 | expressions evaluated in the context of your application. You may be able 79 | to view sensitive user data when viewing the values of variables. 80 | * The debug agent tries to ensure that all conditions and watchpoints you 81 | add are read-only and have no side effects. It catches, and disallows, 82 | all expressions that may have static side effects to prevent accidental 83 | state change. However, it presently does not catch expressions that have 84 | dynamic side-effects. For example, `o.f` looks like a property access, 85 | but dynamically, it may end up calling a getter function. We presently do 86 | NOT detect such dynamic-side effects. 87 | * The root directory of your application needs to contain a `package.json` 88 | file. 89 | 90 | [config-ts]: https://github.com/googleapis/cloud-debug-nodejs/blob/main/src/agent/config.ts 91 | [extension-page]: https://github.com/GoogleCloudPlatform/snapshot-debugger/tree/main/snapshot_dbg_extension 92 | [snapshot-debugger-readme]: https://github.com/GoogleCloudPlatform/snapshot-debugger#readme 93 | -------------------------------------------------------------------------------- /.repo-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "debugger", 3 | "name_pretty": "Cloud Debugger", 4 | "product_documentation": "https://cloud.google.com/debugger", 5 | "client_documentation": "https://cloud.google.com/nodejs/docs/reference/debug-agent/latest", 6 | "issue_tracker": "https://issuetracker.google.com/savedsearches/559771", 7 | "release_level": "stable", 8 | "language": "nodejs", 9 | "repo": "googleapis/cloud-debug-nodejs", 10 | "distribution_name": "@google-cloud/debug-agent", 11 | "api_id": "clouddebugger.googleapis.com", 12 | "codeowner_team": "@googleapis/api-debug", 13 | "api_shortname": "clouddebugger", 14 | "library_type": "AGENT" 15 | } 16 | -------------------------------------------------------------------------------- /.trampolinerc: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 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 | # Template for .trampolinerc 16 | 17 | # Add required env vars here. 18 | required_envvars+=( 19 | ) 20 | 21 | # Add env vars which are passed down into the container here. 22 | pass_down_envvars+=( 23 | "AUTORELEASE_PR" 24 | "VERSION" 25 | ) 26 | 27 | # Prevent unintentional override on the default image. 28 | if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && \ 29 | [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 30 | echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image." 31 | exit 1 32 | fi 33 | 34 | # Define the default value if it makes sense. 35 | if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then 36 | TRAMPOLINE_IMAGE_UPLOAD="" 37 | fi 38 | 39 | if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 40 | TRAMPOLINE_IMAGE="" 41 | fi 42 | 43 | if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then 44 | TRAMPOLINE_DOCKERFILE="" 45 | fi 46 | 47 | if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then 48 | TRAMPOLINE_BUILD_FILE="" 49 | fi 50 | 51 | # Secret Manager secrets. 52 | source ${PROJECT_ROOT}/.kokoro/populate-secrets.sh 53 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | In the interest of fostering an open and welcoming environment, we as 7 | contributors and maintainers pledge to making participation in our project and 8 | our community a harassment-free experience for everyone, regardless of age, body 9 | size, disability, ethnicity, gender identity and expression, level of 10 | experience, education, socio-economic status, nationality, personal appearance, 11 | race, religion, or sexual identity and orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to creating a positive environment 16 | include: 17 | 18 | * Using welcoming and inclusive language 19 | * Being respectful of differing viewpoints and experiences 20 | * Gracefully accepting constructive criticism 21 | * Focusing on what is best for the community 22 | * Showing empathy towards other community members 23 | 24 | Examples of unacceptable behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual attention or 27 | advances 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | * Public or private harassment 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or reject 42 | comments, commits, code, wiki edits, issues, and other contributions that are 43 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 44 | contributor for other behaviors that they deem inappropriate, threatening, 45 | offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies both within project spaces and in public spaces 50 | when an individual is representing the project or its community. Examples of 51 | representing a project or community include using an official project e-mail 52 | address, posting via an official social media account, or acting as an appointed 53 | representative at an online or offline event. Representation of a project may be 54 | further defined and clarified by project maintainers. 55 | 56 | This Code of Conduct also applies outside the project spaces when the Project 57 | Steward has a reasonable belief that an individual's behavior may have a 58 | negative impact on the project or its community. 59 | 60 | ## Conflict Resolution 61 | 62 | We do not believe that all conflict is bad; healthy debate and disagreement 63 | often yield positive results. However, it is never okay to be disrespectful or 64 | to engage in behavior that violates the project’s code of conduct. 65 | 66 | If you see someone violating the code of conduct, you are encouraged to address 67 | the behavior directly with those involved. Many issues can be resolved quickly 68 | and easily, and this gives people more control over the outcome of their 69 | dispute. If you are unable to resolve the matter for any reason, or if the 70 | behavior is threatening or harassing, report it. We are dedicated to providing 71 | an environment where participants feel welcome and safe. 72 | 73 | Reports should be directed to *googleapis-stewards@google.com*, the 74 | Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to 75 | receive and address reported violations of the code of conduct. They will then 76 | work with a committee consisting of representatives from the Open Source 77 | Programs Office and the Google Open Source Strategy team. If for any reason you 78 | are uncomfortable reaching out to the Project Steward, please email 79 | opensource@google.com. 80 | 81 | We will investigate every complaint, but you may not receive a direct response. 82 | We will use our discretion in determining when and how to follow up on reported 83 | incidents, which may range from not taking action to permanent expulsion from 84 | the project and project-sponsored spaces. We will notify the accused of the 85 | report and provide them an opportunity to discuss it before any action is taken. 86 | The identity of the reporter will be omitted from the details of the report 87 | supplied to the accused. In potentially harmful situations, such as ongoing 88 | harassment or threats to anyone's safety, we may take action without notice. 89 | 90 | ## Attribution 91 | 92 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, 93 | available at 94 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | **Table of contents** 4 | 5 | * [Contributor License Agreements](#contributor-license-agreements) 6 | * [Contributing a patch](#contributing-a-patch) 7 | * [Running the tests](#running-the-tests) 8 | * [Releasing the library](#releasing-the-library) 9 | 10 | ## Contributor License Agreements 11 | 12 | We'd love to accept your sample apps and patches! Before we can take them, we 13 | have to jump a couple of legal hurdles. 14 | 15 | Please fill out either the individual or corporate Contributor License Agreement 16 | (CLA). 17 | 18 | * If you are an individual writing original source code and you're sure you 19 | own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). 20 | * If you work for a company that wants to allow you to contribute your work, 21 | then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). 22 | 23 | Follow either of the two links above to access the appropriate CLA and 24 | instructions for how to sign and return it. Once we receive it, we'll be able to 25 | accept your pull requests. 26 | 27 | ## Contributing A Patch 28 | 29 | 1. Submit an issue describing your proposed change to the repo in question. 30 | 1. The repo owner will respond to your issue promptly. 31 | 1. If your proposed change is accepted, and you haven't already done so, sign a 32 | Contributor License Agreement (see details above). 33 | 1. Fork the desired repo, develop and test your code changes. 34 | 1. Ensure that your code adheres to the existing style in the code to which 35 | you are contributing. 36 | 1. Ensure that your code has an appropriate set of tests which all pass. 37 | 1. Title your pull request following [Conventional Commits](https://www.conventionalcommits.org/) styling. 38 | 1. Submit a pull request. 39 | 40 | ### Before you begin 41 | 42 | 1. [Select or create a Cloud Platform project][projects]. 43 | 1. [Enable the Cloud Debugger API][enable_api]. 44 | 1. [Set up authentication with a service account][auth] so you can access the 45 | API from your local workstation. 46 | 47 | 48 | ## Running the tests 49 | 50 | 1. [Prepare your environment for Node.js setup][setup]. 51 | 52 | 1. Install dependencies: 53 | 54 | npm install 55 | 56 | 1. Run the tests: 57 | 58 | # Run unit tests. 59 | npm test 60 | 61 | # Run sample integration tests. 62 | npm run samples-test 63 | 64 | # Run all system tests. 65 | npm run system-test 66 | 67 | 1. Lint (and maybe fix) any changes: 68 | 69 | npm run fix 70 | 71 | [setup]: https://cloud.google.com/nodejs/docs/setup 72 | [projects]: https://console.cloud.google.com/project 73 | [billing]: https://support.google.com/cloud/answer/6293499#enable-billing 74 | [enable_api]: https://console.cloud.google.com/flows/enableapi?apiid=clouddebugger.googleapis.com 75 | [auth]: https://cloud.google.com/docs/authentication/getting-started -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /doc/images/breakpoint-hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/doc/images/breakpoint-hit.png -------------------------------------------------------------------------------- /doc/images/breakpoint-set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/doc/images/breakpoint-set.png -------------------------------------------------------------------------------- /doc/images/debug-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/doc/images/debug-ui.png -------------------------------------------------------------------------------- /linkinator.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "recurse": true, 3 | "skip": [ 4 | "https://codecov.io/gh/googleapis/", 5 | "www.googleapis.com", 6 | "img.shields.io" 7 | ], 8 | "silent": true, 9 | "concurrency": 10 10 | } 11 | -------------------------------------------------------------------------------- /owlbot.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 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 synthtool.languages.node as node 16 | 17 | node.owlbot_main(templates_excludes=['.eslintignore', '.mocharc.js', '.github/workflows/ci.yaml']) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-cloud/debug-agent", 3 | "version": "9.0.1", 4 | "author": "Google Inc.", 5 | "description": "Stackdriver Debug Agent for Node.js", 6 | "main": "./build/src/index", 7 | "types": "./build/src/index.d.ts", 8 | "repository": "googleapis/cloud-debug-nodejs", 9 | "keywords": [ 10 | "google", 11 | "debugger", 12 | "debug", 13 | "cloud", 14 | "cloud debug", 15 | "cloud debugger", 16 | "stackdriver debug", 17 | "stackdriver debugger", 18 | "stackdriver" 19 | ], 20 | "license": "Apache-2.0", 21 | "engines": { 22 | "node": ">=14.0.0" 23 | }, 24 | "files": [ 25 | "build/src" 26 | ], 27 | "scripts": { 28 | "prepare": "npm run compile", 29 | "samples-test": "cd samples/ && npm link ../ && npm install && npm test && cd ../", 30 | "presystem-test": "npm run compile", 31 | "system-test": "nyc mocha build/system-test --timeout 600000", 32 | "test": "nyc cross-env CLOUD_DEBUG_ASSERTIONS=1 mocha build/test --recursive false", 33 | "compile": "tsc -p .", 34 | "postcompile": "cpy \"test/\" build", 35 | "fix": "gts fix", 36 | "pretest": "npm run compile", 37 | "prepack": "npm run compile", 38 | "lint": "gts check", 39 | "docs": "compodoc src/", 40 | "docs-test": "linkinator docs", 41 | "predocs-test": "npm run docs", 42 | "prelint": "cd samples; npm link ../; npm install", 43 | "clean": "gts clean", 44 | "precompile": "gts clean" 45 | }, 46 | "dependencies": { 47 | "@google-cloud/common": "^5.0.0", 48 | "@fastify/busboy": "2.1.0", 49 | "acorn": "^8.0.0", 50 | "coffeescript": "^2.0.0", 51 | "console-log-level": "^1.4.0", 52 | "extend": "^3.0.2", 53 | "findit2": "^2.2.3", 54 | "firebase-admin": "^12.0.0", 55 | "gcp-metadata": "^6.0.0", 56 | "p-limit": "^3.0.1", 57 | "semver": "^7.0.0", 58 | "source-map": "^0.8.0-beta.0", 59 | "split": "^1.0.0" 60 | }, 61 | "overrides": { 62 | "firebase-admin": { 63 | "@fastify/busboy": "2.1.0" 64 | } 65 | }, 66 | "devDependencies": { 67 | "@babel/plugin-proposal-private-methods": "^7.18.6", 68 | "@compodoc/compodoc": "1.1.23", 69 | "@types/acorn": "^4.0.2", 70 | "@types/console-log-level": "^1.4.0", 71 | "@types/estree": "1.0.5", 72 | "@types/extend": "^3.0.0", 73 | "@types/mocha": "^9.0.0", 74 | "@types/mv": "^2.1.0", 75 | "@types/ncp": "^2.0.3", 76 | "@types/node": "^20.0.0", 77 | "@types/proxyquire": "^1.3.28", 78 | "@types/semver": "^7.0.0", 79 | "@types/tmp": "^0.2.0", 80 | "@types/uuid": "^9.0.0", 81 | "cpy-cli": "^4.0.0", 82 | "cross-env": "^7.0.0", 83 | "execa": "^5.0.0", 84 | "gts": "^5.0.0", 85 | "linkinator": "^4.0.0", 86 | "mocha": "^9.2.2", 87 | "mv": "^2.1.1", 88 | "ncp": "^2.0.0", 89 | "nock": "^13.0.0", 90 | "nyc": "^15.0.0", 91 | "proxyquire": "^2.0.0", 92 | "teeny-request": "^8.0.0", 93 | "tmp-promise": "^3.0.0", 94 | "typescript": "5.1.6", 95 | "uuid": "^9.0.0" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "docker:disable", 5 | ":disableDependencyDashboard" 6 | ], 7 | "pinVersions": false, 8 | "rebaseStalePrs": true, 9 | "schedule": [ 10 | "after 9am and before 3pm" 11 | ], 12 | "gitAuthor": null, 13 | "packageRules": [ 14 | { 15 | "extends": "packages:linters", 16 | "groupName": "linters" 17 | } 18 | ], 19 | "ignoreDeps": ["typescript"] 20 | } 21 | -------------------------------------------------------------------------------- /samples/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: off 4 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | [//]: # "This README.md file is auto-generated, all changes to this file will be lost." 2 | [//]: # "To regenerate it, use `python -m synthtool`." 3 | Google Cloud Platform logo 4 | 5 | # [Cloud Debugger: Node.js Samples](https://github.com/googleapis/cloud-debug-nodejs) 6 | 7 | [![Open in Cloud Shell][shell_img]][shell_link] 8 | 9 | > This module provides Snapshot Debugger support for Node.js applications. 10 | Snapshot Debugger is an open source product that lets you debug your 11 | applications in production without stopping or pausing your application. 12 | 13 | A Firebase Realtime Database instance is used to store your data. 14 | 15 | ## Project Status: Archived 16 | 17 | This project has been archived and is no longer supported. There will be no 18 | further bug fixes or security patches. The repository can be forked by users 19 | if they want to maintain it going forward. 20 | 21 | ## Table of Contents 22 | 23 | * [Before you begin](#before-you-begin) 24 | * [Samples](#samples) 25 | * [App](#app) 26 | * [Snippets](#snippets) 27 | 28 | ## Before you begin 29 | 30 | Before running the samples, make sure you've followed the steps outlined in 31 | [Using the client library](https://github.com/googleapis/cloud-debug-nodejs#using-the-client-library). 32 | 33 | `cd samples` 34 | 35 | `npm install` 36 | 37 | `cd ..` 38 | 39 | ## Samples 40 | 41 | 42 | 43 | ### App 44 | 45 | View the [source code](https://github.com/googleapis/cloud-debug-nodejs/blob/main/samples/app.js). 46 | 47 | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/cloud-debug-nodejs&page=editor&open_in_editor=samples/app.js,samples/README.md) 48 | 49 | __Usage:__ 50 | 51 | 52 | `node samples/app.js` 53 | 54 | 55 | ----- 56 | 57 | 58 | 59 | 60 | ### Snippets 61 | 62 | View the [source code](https://github.com/googleapis/cloud-debug-nodejs/blob/main/samples/snippets.js). 63 | 64 | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/cloud-debug-nodejs&page=editor&open_in_editor=samples/snippets.js,samples/README.md) 65 | 66 | __Usage:__ 67 | 68 | 69 | `node samples/snippets.js` 70 | 71 | 72 | 73 | 74 | 75 | 76 | [shell_img]: https://gstatic.com/cloudssh/images/open-btn.png 77 | [shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/cloud-debug-nodejs&page=editor&open_in_editor=samples/README.md 78 | [product-docs]: https://cloud.google.com/debugger 79 | -------------------------------------------------------------------------------- /samples/app.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 | 'use strict'; 16 | 17 | require('@google-cloud/debug-agent').start(); 18 | 19 | const express = require('express'); 20 | const app = express(); 21 | 22 | app.enable('trust proxy'); 23 | 24 | app.get('/', (req, res) => { 25 | // Try using the StackDriver Debugger dashboard to inspect the "req" object 26 | res.status(200).send('Hello, world!'); 27 | }); 28 | 29 | // Start the server 30 | const PORT = process.env.PORT || 8080; 31 | app.listen(PORT, () => { 32 | console.log(`App listening on port ${PORT}`); 33 | console.log('Press Ctrl+C to quit.'); 34 | }); 35 | -------------------------------------------------------------------------------- /samples/app.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2016, Google, Inc. 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | # [START app_yaml] 15 | runtime: nodejs10 16 | # [END app_yaml] 17 | -------------------------------------------------------------------------------- /samples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-docs-samples-debugger", 3 | "description": "Sample for Google Stackdriver Trace on Google App Engine Flexible Environment.", 4 | "private": true, 5 | "license": "Apache-2.0", 6 | "author": "Google LLC", 7 | "repository": "googleapis/cloud-debug-nodejs", 8 | "engines": { 9 | "node": ">=12.0.0" 10 | }, 11 | "files": [ 12 | "*.js" 13 | ], 14 | "scripts": { 15 | "deploy": "gcloud app deploy", 16 | "start": "node app.js", 17 | "test": "mocha" 18 | }, 19 | "dependencies": { 20 | "@google-cloud/debug-agent": "^9.0.1", 21 | "express": "4.18.2" 22 | }, 23 | "devDependencies": { 24 | "execa": "^5.0.0", 25 | "mocha": "^8.0.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/snippets.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 | 'use strict'; 16 | 17 | // [START debugger_setup_explicit] 18 | require('@google-cloud/debug-agent').start({ 19 | projectId: 'your-project-id', 20 | keyFilename: '/path/to/key.json', 21 | }); 22 | // [END debugger_setup_explicity] 23 | -------------------------------------------------------------------------------- /samples/test/test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 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 | 'use strict'; 16 | 17 | const execa = require('execa'); 18 | const {describe, it} = require('mocha'); 19 | 20 | describe('debug samples', () => { 21 | it('should run the quickstart', done => { 22 | // select a random port between 49152 and 65535 23 | const PORT = Math.floor(Math.random() * (65535 - 49152)) + 49152; 24 | const proc = execa('node', ['app.js'], { 25 | env: { 26 | PORT, 27 | }, 28 | }); 29 | proc.stdout.on('data', message => { 30 | // Listen to stdout and look for messages. If we get a `Press CTRL+...` 31 | // assume the process started. Wait a second to make sure there 32 | // is no stderr output signifying something may have gone wrong. 33 | message = message.toString('utf8'); 34 | if (/Press Ctrl/.test(message)) { 35 | setTimeout(() => { 36 | proc.kill(); 37 | done(); 38 | }, 1000); 39 | } 40 | }); 41 | proc.stderr.on('data', message => { 42 | // if anything comes through stderr, assume a bug 43 | done(new Error(message.toString('utf8'))); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/agent/controller.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google LLC 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 | * @module debug/controller 17 | */ 18 | 19 | import {Debuggee} from '../debuggee'; 20 | import * as stackdriver from '../types/stackdriver'; 21 | 22 | export interface Controller { 23 | /** 24 | * Register to the API (implementation) 25 | * 26 | * @param {!function(?Error,Object=)} callback 27 | */ 28 | register( 29 | debuggee: Debuggee, 30 | callback: ( 31 | err: Error | null, 32 | result?: { 33 | debuggee: Debuggee; 34 | agentId: string; 35 | } 36 | ) => void 37 | ): void; 38 | 39 | /** 40 | * Update the server about breakpoint state 41 | * @param {!Debuggee} debuggee 42 | * @param {!Breakpoint} breakpoint 43 | * @param {!Function} callback accepting (err, body) 44 | */ 45 | updateBreakpoint( 46 | debuggee: Debuggee, 47 | breakpoint: stackdriver.Breakpoint, 48 | callback: (err?: Error, body?: {}) => void 49 | ): void; 50 | 51 | /** 52 | * Start listening to breakpoints updates. The callback will be called when 53 | * there is an unrecoverable error or when the set of active breakpoints has changed. 54 | * @param {!Debuggee} debuggee 55 | * @param {!function(?Error,Object=)} callback accepting (err, breakpoints) 56 | */ 57 | subscribeToBreakpoints( 58 | debuggee: Debuggee, 59 | callback: (err: Error | null, breakpoints: stackdriver.Breakpoint[]) => void 60 | ): void; 61 | 62 | /** 63 | * Stops the Controller. This is for testing purposes only. 64 | */ 65 | stop(): void; 66 | } 67 | -------------------------------------------------------------------------------- /src/agent/util/debug-assert.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 * as realAssert from 'assert'; 16 | 17 | export interface FakeAssert { 18 | deepEqual: Function; 19 | deepStrictEqual: Function; 20 | doesNotThrow: Function; 21 | equal: Function; 22 | fail: Function; 23 | ifError: Function; 24 | notDeepEqual: Function; 25 | notDeepStrictEqual: Function; 26 | notEqual: Function; 27 | notStrictEqual: Function; 28 | ok: Function; 29 | strictEqual: Function; 30 | throws: Function; 31 | AssertionError: Function; 32 | rejects: Function; 33 | doesNotReject: Function; 34 | strict: Function; 35 | match: Function; 36 | doesNotMatch: Function; 37 | } 38 | 39 | const nop = (_: {}) => _; 40 | 41 | const fakeAssert: FakeAssert = { 42 | deepEqual: nop, 43 | deepStrictEqual: nop, 44 | doesNotThrow: nop, 45 | equal: nop, 46 | fail: nop, 47 | ifError: nop, 48 | notDeepEqual: nop, 49 | notDeepStrictEqual: nop, 50 | notEqual: nop, 51 | notStrictEqual: nop, 52 | ok: nop, 53 | strictEqual: nop, 54 | throws: nop, 55 | AssertionError: nop, 56 | rejects: nop, 57 | doesNotReject: nop, 58 | strict: nop, 59 | match: nop, 60 | doesNotMatch: nop, 61 | }; 62 | 63 | export function debugAssert(enableAssertions: boolean): FakeAssert { 64 | // The typecast is needed since the @types/node doesn't cover Node 10 yet 65 | return enableAssertions ? (realAssert as {} as FakeAssert) : fakeAssert; 66 | } 67 | -------------------------------------------------------------------------------- /src/agent/util/validator.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 * as estree from 'estree'; 16 | 17 | /** 18 | * Validates if the AST represented by the node has obvious side-effects. 19 | * It catches the most common cases such as assignments, method calls, and 20 | * control flow. It doesn't (presently) catch property access that may end 21 | * up calling accessors. 22 | * 23 | * @param {Object} node AST Node (as per the Mozilla Parser API) 24 | * @return {boolean} if the exper 25 | */ 26 | export function isValid(node: estree.Node | null): boolean { 27 | // Empty expression is allowed 28 | if (node === null) { 29 | return true; 30 | } 31 | 32 | switch (node.type) { 33 | case 'Program': 34 | return node.body.every(isValid); 35 | 36 | // 37 | // S T A T E M E N T S 38 | // 39 | case 'EmptyStatement': 40 | return true; 41 | case 'ExpressionStatement': 42 | return isValid(node.expression); 43 | case 'BlockStatement': 44 | return node.body.every(isValid); 45 | case 'LabeledStatement': 46 | return isValid(node.body); 47 | 48 | // 49 | // E X P R E S S I O N S 50 | // 51 | case 'AssignmentExpression': 52 | case 'CallExpression': 53 | case 'FunctionExpression': 54 | case 'NewExpression': 55 | case 'UpdateExpression': 56 | return false; 57 | 58 | case 'Identifier': 59 | case 'Literal': 60 | case 'ThisExpression': 61 | return true; 62 | 63 | case 'ArrayExpression': 64 | return node.elements.every(isValid); 65 | 66 | case 'BinaryExpression': 67 | case 'LogicalExpression': 68 | return isValid(node.left) && isValid(node.right); 69 | 70 | case 'ConditionalExpression': 71 | return ( 72 | isValid(node.test) && 73 | isValid(node.alternate) && 74 | isValid(node.consequent) 75 | ); 76 | 77 | case 'MemberExpression': 78 | return isValid(node.object) && isValid(node.property); 79 | 80 | case 'ObjectExpression': 81 | // every property is a valid expression 82 | return node.properties.every(prop => { 83 | return isValid((prop as {value: estree.Node}).value); 84 | }); 85 | 86 | case 'SequenceExpression': 87 | return node.expressions.every(isValid); 88 | 89 | case 'UnaryExpression': 90 | return isValid(node.argument); 91 | 92 | case 'SpreadElement': 93 | return isValid(node.argument); 94 | 95 | case 'TemplateLiteral': 96 | return node.quasis.every(isValid) && node.expressions.every(isValid); 97 | case 'TaggedTemplateExpression': 98 | return isValid(node.tag) && isValid(node.quasi); 99 | case 'TemplateElement': 100 | return true; 101 | 102 | default: 103 | return false; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/agent/v8/debugapi.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 consoleLogLevel = require('console-log-level'); 16 | import * as stackdriver from '../../types/stackdriver'; 17 | import {ResolvedDebugAgentConfig} from '../config'; 18 | import {ScanStats} from '../io/scanner'; 19 | import {SourceMapper} from '../io/sourcemapper'; 20 | import {InspectorDebugApi} from './inspector-debugapi'; 21 | 22 | export interface DebugApi { 23 | set( 24 | breakpoint: stackdriver.Breakpoint, 25 | cb: (err: Error | null) => void 26 | ): void; 27 | clear( 28 | breakpoint: stackdriver.Breakpoint, 29 | cb: (err: Error | null) => void 30 | ): void; 31 | wait( 32 | breakpoint: stackdriver.Breakpoint, 33 | callback: (err?: Error) => void 34 | ): void; 35 | log( 36 | breakpoint: stackdriver.Breakpoint, 37 | print: (format: string, exps: string[]) => void, 38 | shouldStop: () => boolean 39 | ): void; 40 | disconnect(): void; 41 | numBreakpoints_(): number; 42 | numListeners_(): number; 43 | } 44 | 45 | export const MODULE_WRAP_PREFIX_LENGTH = require('module') 46 | .wrap('☃') 47 | .indexOf('☃'); 48 | 49 | let singleton: DebugApi; 50 | 51 | export function create( 52 | logger: consoleLogLevel.Logger, 53 | config: ResolvedDebugAgentConfig, 54 | jsFiles: ScanStats, 55 | sourcemapper: SourceMapper 56 | ): DebugApi { 57 | if (singleton && !config.forceNewAgent_) { 58 | return singleton; 59 | } else if (singleton) { 60 | singleton.disconnect(); 61 | } 62 | 63 | singleton = new InspectorDebugApi(logger, config, jsFiles, sourcemapper); 64 | return singleton; 65 | } 66 | -------------------------------------------------------------------------------- /src/agent/v8/v8inspector.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 | // eslint-disable-next-line node/no-unsupported-features/node-builtins 16 | import * as inspector from 'inspector'; 17 | 18 | export class V8Inspector { 19 | private session: inspector.Session; 20 | constructor(session: inspector.Session) { 21 | this.session = session; 22 | } 23 | setBreakpointByUrl( 24 | options: inspector.Debugger.SetBreakpointByUrlParameterType 25 | ) { 26 | const result: { 27 | error?: Error; 28 | response?: inspector.Debugger.SetBreakpointByUrlReturnType; 29 | } = {}; 30 | this.session.post( 31 | 'Debugger.setBreakpointByUrl', 32 | options, 33 | ( 34 | error: Error | null, 35 | response: inspector.Debugger.SetBreakpointByUrlReturnType 36 | ) => { 37 | if (error) result.error = error; 38 | result.response = response; 39 | } 40 | ); 41 | return result; 42 | } 43 | 44 | removeBreakpoint(breakpointId: string) { 45 | const result: {error?: Error} = {}; 46 | this.session.post( 47 | 'Debugger.removeBreakpoint', 48 | {breakpointId}, 49 | (error: Error | null) => { 50 | if (error) result.error = error; 51 | } 52 | ); 53 | return result; 54 | } 55 | 56 | evaluateOnCallFrame( 57 | options: inspector.Debugger.EvaluateOnCallFrameParameterType 58 | ) { 59 | const result: { 60 | error?: Error; 61 | response?: inspector.Debugger.EvaluateOnCallFrameReturnType; 62 | } = {}; 63 | this.session.post( 64 | 'Debugger.evaluateOnCallFrame', 65 | options, 66 | ( 67 | error: Error | null, 68 | response: inspector.Debugger.EvaluateOnCallFrameReturnType 69 | ) => { 70 | if (error) result.error = error; 71 | result.response = response; 72 | } 73 | ); 74 | return result; 75 | } 76 | 77 | getProperties(options: inspector.Runtime.GetPropertiesParameterType) { 78 | const result: { 79 | error?: Error; 80 | response?: inspector.Runtime.GetPropertiesReturnType; 81 | } = {}; 82 | this.session.post( 83 | 'Runtime.getProperties', 84 | options, 85 | ( 86 | error: Error | null, 87 | response: inspector.Runtime.GetPropertiesReturnType 88 | ) => { 89 | if (error) result.error = error; 90 | result.response = response; 91 | } 92 | ); 93 | return result; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/client/stackdriver/status-message.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright 2015 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * 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 | 17 | import * as stackdriver from '../../types/stackdriver'; 18 | 19 | export class StatusMessage implements stackdriver.StatusMessage { 20 | refersTo: stackdriver.Reference; 21 | description: stackdriver.FormatMessage; 22 | isError: boolean; 23 | 24 | /** 25 | * Status Message to be sent to the server 26 | * @constructor 27 | */ 28 | constructor( 29 | refersTo: stackdriver.Reference, 30 | description: string, 31 | isError: boolean 32 | ) { 33 | this.refersTo = refersTo; 34 | this.description = {format: description}; 35 | this.isError = isError; 36 | } 37 | 38 | // These status messages come from a proto definition. 39 | // New status messages cannot be added here. 40 | static readonly UNSPECIFIED: stackdriver.Reference = 'UNSPECIFIED'; 41 | static readonly BREAKPOINT_SOURCE_LOCATION: stackdriver.Reference = 42 | 'BREAKPOINT_SOURCE_LOCATION'; 43 | static readonly BREAKPOINT_CONDITION: stackdriver.Reference = 44 | 'BREAKPOINT_CONDITION'; 45 | static readonly BREAKPOINT_EXPRESSION: stackdriver.Reference = 46 | 'BREAKPOINT_EXPRESSION'; 47 | static readonly VARIABLE_NAME: stackdriver.Reference = 'VARIABLE_NAME'; 48 | static readonly VARIABLE_VALUE: stackdriver.Reference = 'VARIABLE_VALUE'; 49 | static readonly BREAKPOINT_AGE: stackdriver.Reference = 'BREAKPOINT_AGE'; 50 | } 51 | -------------------------------------------------------------------------------- /src/debuggee.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google LLC 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 {PackageInfo} from './agent/debuglet'; 16 | import {StatusMessage} from './client/stackdriver/status-message'; 17 | 18 | export declare type CanaryMode = 19 | | 'CANARY_MODE_UNSPECIFIED' 20 | | 'CANARY_MODE_ALWAYS_ENABLED' 21 | | 'CANARY_MODE_ALWAYS_DISABLED' 22 | | 'CANARY_MODE_DEFAULT_ENABLED' 23 | | 'CANARY_MODE_DEFAULT_DISABLED'; 24 | 25 | // TODO: Determine how to get this interface to satisfy both the code and the 26 | // docs 27 | // In particular, the comments below state some of the properties are 28 | // required but the default properties in the code is {} 29 | export interface DebuggeeProperties { 30 | project?: string; 31 | uniquifier?: string; 32 | description?: string; 33 | agentVersion: string; 34 | labels?: { 35 | [key: string]: string; 36 | }; 37 | sourceContexts?: Array<{[key: string]: {}}>; 38 | statusMessage?: StatusMessage; 39 | packageInfo?: PackageInfo; 40 | canaryMode?: CanaryMode; 41 | } 42 | 43 | export class Debuggee { 44 | uniquifier?: string; 45 | description?: string; 46 | agentVersion?: string; 47 | sourceContexts?: Array<{[key: string]: {}}>; 48 | 49 | // Public to allow for testing 50 | project?: string; 51 | labels?: { 52 | [key: string]: string; 53 | }; 54 | statusMessage?: StatusMessage; 55 | id!: string; 56 | // TODO: This doesn't seem to ever be set but is referenced in the 57 | // debuglet.ts file. 58 | isDisabled?: boolean; 59 | isInactive?: boolean; 60 | canaryMode?: CanaryMode; 61 | 62 | /** 63 | * Creates a Debuggee service object. 64 | * @ref https://cloud.google.com/debugger/api/reference/rest/v2/Debuggee 65 | * 66 | * @param {object} properties - an object with properties to use for Debuggee 67 | * initialization. 68 | * @param {object} properties.project - Google Cloud Project ID 69 | * @param {string} properties.uniquifier - Debuggee uniquifier within the 70 | * project. Any string that identifies the application within the project 71 | * can be used. Including environment and version or build IDs is 72 | * recommended. 73 | * @param {string} properties.description - A user specified string identifying 74 | * this debuggable instance. 75 | * @param {?string} properties.agentVersion - version ID of the agent. (default: 76 | * the version of this module) 77 | * @param {?object} labels - a set of custom properties about the debuggee that 78 | * are reported to the service. 79 | * @param {?array} properties.sourceContexts 80 | * @param {?StatusMessage} properties.statusMessage - A error string to register 81 | * this as an erroring debuggable instance. This is useful if we have a 82 | * problem starting the debugger support, and want to report to the API so 83 | * that the user has a way of noticing. 84 | * TODO(ofrobots): has this been renamed to `status` in the API? 85 | */ 86 | constructor(properties: DebuggeeProperties) { 87 | if (!(this instanceof Debuggee)) { 88 | return new Debuggee(properties); 89 | } 90 | 91 | properties = properties || {}; 92 | 93 | if (typeof properties.project !== 'string') { 94 | throw new Error('properties.project must be a string'); 95 | } 96 | if (typeof properties.uniquifier !== 'string') { 97 | throw new Error('properties.uniquifier must be a string'); 98 | } 99 | if (typeof properties.description !== 'string') { 100 | throw new Error('properties.description must be a string'); 101 | } 102 | 103 | this.project = properties.project; 104 | this.uniquifier = properties.uniquifier; 105 | this.description = properties.description; 106 | this.agentVersion = properties.agentVersion; 107 | this.canaryMode = properties.canaryMode; 108 | if (properties.labels) { 109 | this.labels = properties.labels; 110 | } 111 | if (properties.sourceContexts) { 112 | this.sourceContexts = properties.sourceContexts; 113 | } 114 | if (properties.statusMessage) { 115 | this.statusMessage = properties.statusMessage; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 {DebugAgentConfig, StackdriverConfig} from './agent/config'; 16 | import {Debuglet, IsReady} from './agent/debuglet'; 17 | 18 | // eslint-disable-next-line @typescript-eslint/no-var-requires 19 | const pjson = require('../../package.json'); 20 | 21 | import * as util from 'util'; 22 | const debuglog = util.debuglog('cdbg'); 23 | 24 | // Singleton. 25 | let debuglet: Debuglet | undefined; 26 | 27 | /** 28 | * Start the Debug agent that will make your application available for debugging 29 | * with Stackdriver Debug. 30 | * 31 | * @param options - Authentication and agent configuration. 32 | * 33 | * @resource [Introductory video]{@link 34 | * https://www.youtube.com/watch?v=tyHcK_kAOpw} 35 | * 36 | * @example 37 | * ``` 38 | * debug.start(); 39 | * ``` 40 | */ 41 | export function start( 42 | options?: DebugAgentConfig | StackdriverConfig 43 | ): Debuglet | IsReady { 44 | options = options || {}; 45 | const agentConfig: DebugAgentConfig = mergeConfigs(options); 46 | 47 | // forceNewAgent_ is for testing purposes only. 48 | if (debuglet && !agentConfig.forceNewAgent_) { 49 | throw new Error('Debug Agent has already been started'); 50 | } 51 | 52 | debuglog('Running with firebase backend.'); 53 | debuglet = new Debuglet(pjson, agentConfig); 54 | 55 | debuglet.start(); 56 | 57 | return agentConfig.testMode_ ? debuglet : debuglet.isReadyManager; 58 | } 59 | 60 | /** 61 | * If the given `options` object has a `debug` property 62 | * of the same type, this function returns the union of the 63 | * properties in `options.debug` and `options` except that 64 | * the returned object no longer has a `debug` property. 65 | * If a field exists in both `options` and `options.debug`, 66 | * the value in `option.debug` takes precedence. 67 | */ 68 | function mergeConfigs(options: T & {debug?: T}): T { 69 | if (!options.debug) { 70 | return options; 71 | } 72 | const result = Object.assign({}, options); 73 | delete result.debug; 74 | return Object.assign(result, options.debug); 75 | } 76 | 77 | /* Used to access the agent if it has been started. Returns the agent 78 | * if the agent has been started. Otherwise, `undefined` is returned. 79 | */ 80 | export function get(): Debuglet | undefined { 81 | return debuglet; 82 | } 83 | 84 | /** 85 | * Cleanly shut down the debug agent. 86 | * 87 | * This will free up all resources. It may be necessary to call this to allow 88 | * your process to shut down cleanly. 89 | */ 90 | export function stop(): void { 91 | debuglet?.stop(); 92 | debuglet = undefined; 93 | } 94 | -------------------------------------------------------------------------------- /src/types/stackdriver.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 declare type Action = 'CAPTURE' | 'LOG'; 16 | 17 | export declare type Reference = 18 | | 'UNSPECIFIED' 19 | | 'BREAKPOINT_SOURCE_LOCATION' 20 | | 'BREAKPOINT_CONDITION' 21 | | 'BREAKPOINT_EXPRESSION' 22 | | 'BREAKPOINT_AGE' 23 | | 'VARIABLE_NAME' 24 | | 'VARIABLE_VALUE'; 25 | 26 | export interface FormatMessage { 27 | format: string; 28 | // TODO: The code expects the `parameters` field to be optional. 29 | // Verify if this aligns with the API reference. 30 | parameters?: string[]; 31 | } 32 | 33 | export interface StatusMessage { 34 | isError: boolean; 35 | refersTo: Reference; 36 | description: FormatMessage; 37 | } 38 | 39 | export interface SourceLocation { 40 | path: string; 41 | // TODO: The code assumes a SourceLocation has a `column` attribute, but 42 | // the API reference doesn't mention it. 43 | // TODO: The code doesn't always set the column attribute. Is it optional? 44 | column?: number; 45 | line: number; 46 | } 47 | 48 | export declare type LogLevel = 'INFO' | 'WARNING' | 'ERROR'; 49 | 50 | export interface Variable { 51 | // TODO: Some places in the code assume the fields below are all optional. 52 | // Determine if that is the case. 53 | varTableIndex?: number; 54 | name?: string; 55 | value?: string; 56 | type?: string; 57 | members?: Variable[]; 58 | status?: StatusMessage; 59 | } 60 | 61 | export interface StackFrame { 62 | function: string; 63 | location: SourceLocation; 64 | arguments: Variable[]; 65 | locals: Variable[]; 66 | } 67 | 68 | // TODO: This is only needed for the Breakpoint.create(d)Time attribute. 69 | // Determine if this is actually needed or if the create(d)Time attribute 70 | // should only be a string. 71 | export interface Timestamp { 72 | seconds: string; // int64 73 | nano: string; // int32 74 | } 75 | 76 | export interface Breakpoint { 77 | stackFrames: StackFrame[]; 78 | // TODO: Update the code so that `|null` is not needed. 79 | evaluatedExpressions: Array; 80 | // TODO: Update the code so that `|null` is not needed. 81 | variableTable: Array; 82 | id: BreakpointId; 83 | // TODO: The debug code assumes the rest of these members 84 | // are optional. Determine if this is correct. 85 | action?: Action; 86 | location?: SourceLocation; 87 | condition?: string; 88 | expressions?: string[]; 89 | logMessageFormat?: string; 90 | logLevel?: LogLevel; 91 | isFinalState?: boolean; 92 | // TODO: The API reference says the following attribute is `createTime` 93 | // However, the existing code is using `createdTime`. 94 | // See: 95 | // https://cloud.google.com/debugger/api/reference/rest/v2/debugger.debuggees.breakpoints#breakpoint 96 | // In addtion, the API reference says the `create(d)Time` attribute 97 | // is a string in Timestamp format, but the code assumes it is a 98 | // Timestamp object 99 | createdTime?: Timestamp; 100 | finalTime?: string; 101 | userEmail?: string; 102 | status?: StatusMessage; 103 | labels?: { 104 | [key: string]: string; 105 | }; 106 | } 107 | 108 | export type BreakpointId = string; 109 | 110 | export interface ListBreakpointsQuery { 111 | waitToken?: string; 112 | successOnTimeout?: boolean; 113 | agentId?: string; 114 | } 115 | 116 | export interface ListBreakpointsResponse { 117 | breakpoints: Breakpoint[]; 118 | nextWaitToken: string; 119 | waitExpired: boolean; 120 | } 121 | -------------------------------------------------------------------------------- /system-test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": ["*.js"] 3 | } 4 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample", 3 | "private": true, 4 | "description": "", 5 | "scripts": { 6 | "compile": "tsc -p .", 7 | "fix": "gts fix", 8 | "prepare": "npm run compile" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "Apache-2.0", 13 | "dependencies": { 14 | "@google-cloud/debug-agent": "./debug.tgz" 15 | }, 16 | "devDependencies": { 17 | "gts": "^2.0.0", 18 | "typescript": "4.8.4", 19 | "@types/node": "^20.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/allowExpressions.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start({allowExpressions: true}); 16 | debug.stop(); 17 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/allowExpressionsJs.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | require('@google-cloud/debug-agent').start({ 15 | allowExpressions: true, 16 | }); 17 | require('@google-cloud/debug-agent').stop(); 18 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/completeServiceContext.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start({ 16 | allowExpressions: true, 17 | serviceContext: { 18 | service: 'Some service', 19 | version: 'Some version', 20 | }, 21 | }); 22 | debug.stop(); 23 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/firebase.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start({useFirebase: true}); 16 | debug.stop(); 17 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/import.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start(); 16 | debug.stop(); 17 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/noargs.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start(); 16 | debug.stop(); 17 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/partialCapture.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start({ 16 | capture: { 17 | maxFrames: 1, 18 | }, 19 | }); 20 | debug.stop(); 21 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/partialServiceContext.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as debug from '@google-cloud/debug-agent'; 15 | debug.start({ 16 | allowExpressions: true, 17 | serviceContext: { 18 | service: 'Some service', 19 | }, 20 | }); 21 | debug.stop(); 22 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/start.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | require('@google-cloud/debug-agent').start(); 15 | require('@google-cloud/debug-agent').stop(); 16 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/src/startEmpty.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | require('@google-cloud/debug-agent').start({}); 15 | require('@google-cloud/debug-agent').stop(); 16 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts/tsconfig-google.json", 3 | "compilerOptions": { 4 | "lib": ["es2018", "dom"], 5 | "rootDir": ".", 6 | "outDir": "build", 7 | "allowJs": true, 8 | "declaration": false 9 | }, 10 | "include": [ 11 | "src/*.ts", 12 | "src/*.js" 13 | ], 14 | "exclude": [ 15 | "node_modules" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /system-test/fixtures/sample/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "gts/tslint.json", 3 | "linterOptions": { 4 | "exclude": [ 5 | "**/*.json" 6 | ] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /system-test/test-controller.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google LLC 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 * as assert from 'assert'; 16 | // import {describe, it} from 'mocha'; 17 | 18 | assert.ok( 19 | process.env.GCLOUD_PROJECT, 20 | 'Need to have GCLOUD_PROJECT defined to be able to run this test' 21 | ); 22 | assert.ok( 23 | process.env.GOOGLE_APPLICATION_CREDENTIALS, 24 | 'Need to have GOOGLE_APPLICATION_CREDENTIALS defined to be able to run ' + 25 | 'this test' 26 | ); 27 | 28 | // import * as stackdriver from '../src/types/stackdriver'; 29 | // import {Debuggee} from '../src/debuggee'; 30 | // import {PackageInfo} from '../src/agent/debuglet'; 31 | // import {defaultConfig as DEFAULT_CONFIG} from '../src/agent/config'; 32 | // import {MockLogger} from '../test/mock-logger'; 33 | 34 | // const packageInfo: PackageInfo = { 35 | // name: 'SomeName', 36 | // version: 'SomeVersion', 37 | // }; 38 | // const agentVersion = `${packageInfo.name}/client/${packageInfo.version}`; 39 | 40 | /* 41 | TODO: Write tests that work for Firebase backend, if they aren't covered by E2E. 42 | 43 | describe('Controller', function () { 44 | this.timeout(60 * 1000); 45 | const logger = new MockLogger(); 46 | 47 | it('should register successfully', done => { 48 | const controller = new OnePlatformController(debug, DEFAULT_CONFIG, logger); 49 | const debuggee = new Debuggee({ 50 | project: process.env.GCLOUD_PROJECT, 51 | uniquifier: 'test-uid-' + Date.now(), 52 | description: 'this is a system test', 53 | agentVersion, 54 | }); 55 | 56 | controller.register(debuggee, (err, maybeBody) => { 57 | assert.ifError(err); 58 | assert.ok(maybeBody); 59 | const body = maybeBody as {debuggee: Debuggee}; 60 | assert.ok(body.debuggee); 61 | assert.ok(body.debuggee.id); 62 | done(); 63 | }); 64 | }); 65 | 66 | it('should list breakpoints', done => { 67 | const controller = new OnePlatformController(debug, DEFAULT_CONFIG, logger); 68 | const debuggee = new Debuggee({ 69 | project: process.env.GCLOUD_PROJECT, 70 | uniquifier: 'test-uid-' + Date.now(), 71 | description: 'this is a system test', 72 | agentVersion, 73 | }); 74 | // TODO: Determine if the body parameter should be used. 75 | controller.register(debuggee, err1 => { 76 | assert.ifError(err1); 77 | 78 | // TODO: Determine if the response parameter should be used. 79 | controller.listBreakpoints(debuggee, (err2, response, maybeBody) => { 80 | assert.ifError(err2); 81 | assert.ok(maybeBody); 82 | const body2 = maybeBody as stackdriver.ListBreakpointsResponse; 83 | assert.ok(body2.nextWaitToken); 84 | done(); 85 | }); 86 | }); 87 | }); 88 | 89 | it('should pass success on timeout', done => { 90 | this.timeout(100000); 91 | const controller = new OnePlatformController(debug, DEFAULT_CONFIG, logger); 92 | const debuggee = new Debuggee({ 93 | project: process.env.GCLOUD_PROJECT, 94 | uniquifier: 'test-uid-' + Date.now(), 95 | description: 'this is a system test', 96 | agentVersion, 97 | }); 98 | // TODO: Determine if the body parameter should be used. 99 | controller.register(debuggee, err => { 100 | assert.ifError(err); 101 | 102 | // First list should set the wait token 103 | // TODO: Determine if the response parameter should be used. 104 | controller.listBreakpoints(debuggee, (err1, response1, maybeBody1) => { 105 | assert.ifError(err1); 106 | assert.ok(maybeBody1); 107 | const body1 = maybeBody1 as stackdriver.ListBreakpointsResponse; 108 | assert.ok(body1.nextWaitToken); 109 | // Second list should block until the wait timeout 110 | // TODO: Determine if the response parameter should be used. 111 | controller.listBreakpoints(debuggee, (err2, response2, maybeBody2) => { 112 | assert.ifError(err2); 113 | assert.ok(maybeBody2); 114 | const body2 = maybeBody2 as stackdriver.ListBreakpointsResponse; 115 | assert.ok(body2.nextWaitToken); 116 | // waitExpired will only be set if successOnTimeout was given 117 | // correctly 118 | assert.ok(body2.waitExpired); 119 | done(); 120 | }); 121 | }); 122 | }); 123 | }); 124 | 125 | // To be able to write the following test we need a service for adding a 126 | // breakpoint (need the debugger API). TODO. 127 | it('should update an active breakpoint'); 128 | }); 129 | */ 130 | -------------------------------------------------------------------------------- /system-test/test-install.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // https://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | import * as execa from 'execa'; 15 | import {after, before, describe, it} from 'mocha'; 16 | import * as mv from 'mv'; 17 | import {ncp} from 'ncp'; 18 | import * as tmp from 'tmp-promise'; 19 | import {promisify} from 'util'; 20 | 21 | const mvp = promisify(mv) as {} as (...args: string[]) => Promise; 22 | const ncpp = promisify(ncp); 23 | const stagingDir = tmp.dirSync({keep: false, unsafeCleanup: true}); 24 | const stagingPath = stagingDir.name; 25 | // eslint-disable-next-line @typescript-eslint/no-var-requires 26 | const pkg = require('../../package.json'); 27 | 28 | async function run(path: string) { 29 | await execa('node', ['--throw-deprecation', `build/src/${path}`], { 30 | cwd: `${stagingPath}/`, 31 | stdio: 'inherit', 32 | }); 33 | } 34 | 35 | describe('📦 pack and install', () => { 36 | // npm pack the module, and create a tmp staging directory 37 | before('pack and install', async () => { 38 | await execa('npm', ['pack', '--unsafe-perm'], {stdio: 'inherit'}); 39 | const tarball = `google-cloud-debug-agent-${pkg.version}.tgz`; 40 | await mvp(tarball, `${stagingPath}/debug.tgz`); 41 | await ncpp('system-test/fixtures/sample', `${stagingPath}/`); 42 | await execa('npm', ['install', '--unsafe-perm'], { 43 | cwd: `${stagingPath}/`, 44 | stdio: 'inherit', 45 | }); 46 | }); 47 | 48 | it('should import the module', async () => { 49 | await run('import.js'); 50 | }); 51 | 52 | it('should import the module and start without arguments', async () => { 53 | await run('noargs.js'); 54 | }); 55 | 56 | it('should start with allowExpressions', async () => { 57 | await run('allowExpressions.js'); 58 | }); 59 | 60 | it('should start with a partial serviceContext', async () => { 61 | await run('partialServiceContext.js'); 62 | }); 63 | 64 | it('should start with a complete serviceContext', async () => { 65 | await run('completeServiceContext.js'); 66 | }); 67 | 68 | it('should import and start with a partial capture', async () => { 69 | await run('partialCapture.js'); 70 | }); 71 | 72 | it('should start with js without arguments', async () => { 73 | await run('start.js'); 74 | }); 75 | 76 | it('should require the module and start with {}', async () => { 77 | await run('startEmpty.js'); 78 | }); 79 | 80 | it('should start with allowExpressions', async () => { 81 | await run('allowExpressionsJs.js'); 82 | }); 83 | 84 | after('cleanup staging', () => { 85 | stagingDir.removeCallback(); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": ["*.js"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/a/hello.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports.hello = function () { 3 | console.log('hello world from a'); 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/b/hello.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports.hello = function () { 3 | console.log('hello world from b'); 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/broken-links/broken-link.js: -------------------------------------------------------------------------------- 1 | intended-link.js -------------------------------------------------------------------------------- /test/fixtures/coffee/transpile.coffee: -------------------------------------------------------------------------------- 1 | foo = (n) -> 2 | return 0 if n == 0 3 | g 'n was non-zero' 4 | return 1 5 | 6 | g = (s) -> 7 | s 8 | 9 | module.exports.foo = foo 10 | 11 | // Copyright 2015 Google LLC 12 | // 13 | // Licensed under the Apache License, Version 2.0 (the "License"); 14 | // you may not use this file except in compliance with the License. 15 | // You may obtain a copy of the License at 16 | // 17 | // http://www.apache.org/licenses/LICENSE-2.0 18 | // 19 | // Unless required by applicable law or agreed to in writing, software 20 | // distributed under the License is distributed on an "AS IS" BASIS, 21 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | // See the License for the specific language governing permissions and 23 | // limitations under the License. 24 | -------------------------------------------------------------------------------- /test/fixtures/coffee/transpile.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | (function () { 3 | // eslint-disable-next-line no-var 4 | var foo, g; 5 | 6 | foo = function (n) { 7 | if (n === 0) { 8 | return 0; 9 | } 10 | g('n was non-zero'); 11 | return 1; 12 | }; 13 | 14 | g = function (s) { 15 | return s; 16 | }; 17 | 18 | module.exports.foo = foo; 19 | }.call(this)); 20 | 21 | //# sourceMappingURL=transpile.js.map 22 | -------------------------------------------------------------------------------- /test/fixtures/coffee/transpile.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "transpile.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "transpile.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AAAA;AAAA,MAAA;;EAAA,GAAA,GAAM,SAAC,CAAD;IACJ,IAAY,CAAA,KAAK,CAAjB;AAAA,aAAO,EAAP;;IACA,CAAA,CAAE,gBAAF;AACA,WAAO;EAHH;;EAKN,CAAA,GAAI,SAAC,CAAD;WACF;EADE;;EAGJ,MAAM,CAAC,OAAO,CAAC,GAAf,GAAqB;AARrB" 10 | } -------------------------------------------------------------------------------- /test/fixtures/es6/transpile.es6: -------------------------------------------------------------------------------- 1 | var i = 1; 2 | var foo = (j) => { 3 | return i + j + `hi`; 4 | } 5 | 6 | module.exports.foo = foo 7 | 8 | // Copyright 2015 Google LLC 9 | // 10 | // Licensed under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | -------------------------------------------------------------------------------- /test/fixtures/es6/transpile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const i = 1; 3 | const foo = function foo(j) { 4 | return i + j + 'hi'; 5 | }; 6 | 7 | module.exports.foo = foo; 8 | 9 | // Copyright 2015 Google LLC 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | -------------------------------------------------------------------------------- /test/fixtures/es6/transpile.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "transpile.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "transpile.es6" 7 | ], 8 | "names": [], 9 | "mappings": ";;AAAA,IAAI,CAAC,GAAG,CAAC,CAAC;AACV,IAAI,GAAG,GAAG,SAAN,GAAG,CAAI,CAAC,EAAK;AACf,SAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;CACvB,CAAA;;AAED,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAA", 10 | "sourcesContent": [ "var i = 0;\nvar foo = (j) => {\n return ++i + j + `hi`;\n}\n\nmodule.exports.foo = foo\n\n/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n" ] 11 | } -------------------------------------------------------------------------------- /test/fixtures/expensive-capture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // eslint-disable-next-line no-unused-vars 3 | const a = new Array(50).map(() => { 4 | return ','; 5 | }); 6 | module.exports.rec = function rec(n) { 7 | if (n === 0) { 8 | return 5; 9 | } else { 10 | return rec(n - 1); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/fat-arrow.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /*2*/ 'use strict'; 3 | /*3*/ function foo() { 4 | /*4*/ const a = b => { 5 | /*5*/ b += 1; 6 | /*6*/ return b; 7 | /*7*/ 8 | }; 9 | /*8*/ return a(1); 10 | /*9*/ 11 | } 12 | /*10*/ module.exports = foo; 13 | /*11*/ 14 | -------------------------------------------------------------------------------- /test/fixtures/fib.js: -------------------------------------------------------------------------------- 1 | /* KEEP THIS CODE AT THE TOP SO THAT THE BREAKPOINT LINE NUMBERS DON'T CHANGE */ 2 | 'use strict'; 3 | function fib(n) { 4 | if (n < 2) { return n; } var o = { a: [1, 'hi', true] }; 5 | return fib(n - 1, o) + fib(n - 2, o); // adding o to appease linter. 6 | } 7 | 8 | // Copyright 2016 Google LLC 9 | // 10 | // Licensed under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // Unless required by applicable law or agreed to in writing, software 17 | // distributed under the License is distributed on an "AS IS" BASIS, 18 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | // See the License for the specific language governing permissions and 20 | // limitations under the License. 21 | 22 | const uuid = require('uuid'); 23 | // eslint-disable-next-line node/no-missing-require 24 | const nocks = require('../nocks.js'); 25 | nocks.projectId('fake-project-id'); 26 | // mock the metadata instance to uniformly make this look like a non-gcp 27 | // environment. 28 | nocks.metadataInstance(); 29 | 30 | const UUID = process.argv[2] || uuid.v4(); 31 | 32 | console.log('UUID: ', UUID); 33 | 34 | // eslint-disable-next-line node/no-missing-require 35 | const debuglet = require('../../..').start({ 36 | debug: { 37 | logLevel: 2, 38 | log: { 39 | maxLogsPerSecond: 2, 40 | logDelaySeconds: 5, 41 | // Use a custom logpoint function that converts everything lower case. 42 | logFunction: message => { 43 | console.log(message.toLowerCase()); 44 | }, 45 | }, 46 | breakpointUpdateIntervalSec: 1, 47 | testMode_: true, 48 | allowExpressions: true, 49 | description: UUID, 50 | }, 51 | }); 52 | 53 | // Make troubleshooting easier if run by itself 54 | if (!process.send) { 55 | process.send = console.log; 56 | } 57 | 58 | let timedOut = false; 59 | const registrationTimeout = setTimeout(() => { 60 | timedOut = true; 61 | process.send({error: "debuggee didn't register in time"}); 62 | setTimeout(() => { 63 | // eslint-disable-next-line no-process-exit 64 | process.exit(1); 65 | }, 2000); 66 | }, 5000); 67 | 68 | debuglet.once('registered', () => { 69 | if (timedOut) { 70 | return; 71 | } 72 | clearTimeout(registrationTimeout); 73 | 74 | let errorMessage; 75 | function setErrorIfNotOk(predicate, message) { 76 | if (!errorMessage && !predicate) { 77 | errorMessage = message; 78 | } 79 | } 80 | 81 | const debuggee = debuglet.debuggee; 82 | setErrorIfNotOk(debuggee, 'should create debuggee'); 83 | setErrorIfNotOk(debuggee.project, 'debuggee should have a project'); 84 | setErrorIfNotOk(debuggee.id, 'debuggee should have registered'); 85 | if (!errorMessage) { 86 | // The parent process needs to know the debuggee and project IDs. 87 | process.send({debuggeeId: debuggee.id, projectId: debuggee.project}); 88 | setInterval(fib.bind(null, 12), 2000); 89 | } else { 90 | process.send({error: errorMessage}); 91 | setTimeout(() => { 92 | // eslint-disable-next-line no-process-exit 93 | process.exit(1); 94 | }, 2000); 95 | } 96 | }); 97 | -------------------------------------------------------------------------------- /test/fixtures/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; module.exports = function() { return 42; }; 2 | // DO NOT CHANGE THE ABOVE LINE AS WE HAVE ^ 3 | // A BREAKPOINT TEST ON IT RIGHT HERE-------' 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/gcloud-credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "client_id": "x", 3 | "client_secret": "y", 4 | "refresh_token": "z", 5 | "type": "authorized_user" 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/hello.js: -------------------------------------------------------------------------------- 1 | console.log('hello world'); 2 | -------------------------------------------------------------------------------- /test/fixtures/hello.jsz: -------------------------------------------------------------------------------- 1 | console.log('hello world'); 2 | -------------------------------------------------------------------------------- /test/fixtures/key-bad.json: -------------------------------------------------------------------------------- 1 | { 2 | "private_key_id": "key123", 3 | "private_key": "privatekey", 4 | "client_email": "clientidentifier@developer.gserviceaccount.com", 5 | "client_id": "clientidentifier.apps.googleusercontent.com", 6 | "type": "service_account" 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/nojs/README.md: -------------------------------------------------------------------------------- 1 | There are no js files in this directory. 2 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/babel/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | babel --presets es2015,stage-2 -o out.js -s true in.js 4 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/babel/in.js: -------------------------------------------------------------------------------- 1 | // arrow functions 2 | // eslint-disable-next-line no-unused-vars 3 | const f = (x, y, z) => { 4 | const a = x + 1; 5 | const b = y - 1; 6 | const c = z * 2; 7 | const result = a + 2 * b - c; 8 | 9 | return result; 10 | }; 11 | 12 | // classes 13 | class Point2D { 14 | constructor(x, y) { 15 | this.x = x; 16 | this.y = y; 17 | } 18 | 19 | translate(x, y) { 20 | this.x += x; 21 | this.y += y; 22 | } 23 | 24 | static origin() { 25 | return new Point2D(0, 0); 26 | } 27 | } 28 | 29 | // eslint-disable-next-line no-unused-vars 30 | class Point3D extends Point2D { 31 | constructor(x, y, z) { 32 | super(x, y); 33 | this.z = z; 34 | } 35 | 36 | translate(x, y, z) { 37 | super.translate(x, y); 38 | this.z += z; 39 | } 40 | 41 | static origin() { 42 | return new Point3D(0, 0, 0); 43 | } 44 | } 45 | 46 | // enhanced object literals 47 | const someOb = { 48 | // short for someOb : someOb 49 | someOb, 50 | 51 | // dynamic property names 52 | ['property' + (1 + 41)]: 42, 53 | }; 54 | 55 | // template strings 56 | const animal = 'cat'; 57 | const hobby = 'sleep'; 58 | console.log(`The ${animal} likes to ${hobby}`); 59 | 60 | // destructuring 61 | // eslint-disable-next-line no-unused-vars 62 | const [x, y, z] = [1, 2, 3]; 63 | 64 | // default values 65 | function someFunction(x, y = 32) { 66 | return x + y; 67 | } 68 | 69 | console.log(someFunction(10) === 42); 70 | 71 | // rest and spread 72 | function varArgsFunction(x, ...y) { 73 | return x + y.length; 74 | } 75 | 76 | console.log(varArgsFunction(10, 1, 2, 3, 4, 5) === 15); 77 | console.log(varArgsFunction(...[10, 1, 2, 3, 4, 5]) === 15); 78 | 79 | // let and const 80 | const SOME_VALUE = 10; 81 | for (let i = 0; i < 10; i++) { 82 | console.log(SOME_VALUE + i); 83 | } 84 | 85 | /* 86 | * Copyright 2016 Google Inc. All Rights Reserved. 87 | * 88 | * Licensed under the Apache License, Version 2.0 (the 'License'); 89 | * you may not use this file except in compliance with the License. 90 | * You may obtain a copy of the License at 91 | * 92 | * http://www.apache.org/licenses/LICENSE-2.0 93 | * 94 | * Unless required by applicable law or agreed to in writing, software 95 | * distributed under the License is distributed on an 'AS IS' BASIS, 96 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 97 | * See the License for the specific language governing permissions and 98 | * limitations under the License. 99 | */ 100 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/babel/out.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["in.js"],"names":[],"mappings":";;;;;;;;;;;;;;AACA;AACA,IAAI,IAAI,SAAJ,CAAI,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAa;AACnB,MAAI,IAAI,IAAI,CAAZ;AACA,MAAI,IAAI,IAAI,CAAZ;AACA,MAAI,IAAI,IAAI,CAAZ;AACA,MAAI,SAAS,IAAI,IAAE,CAAN,GAAU,CAAvB;;AAEA,SAAO,MAAP;AACD,CAPD;;AASA;;IACM,O;AACJ,mBAAY,CAAZ,EAAe,CAAf,EAAkB;AAAA;;AAChB,SAAK,CAAL,GAAS,CAAT;AACA,SAAK,CAAL,GAAS,CAAT;AACD;;;;8BAES,C,EAAG,C,EAAG;AACd,WAAK,CAAL,IAAU,CAAV;AACA,WAAK,CAAL,IAAU,CAAV;AACD;;;6BAEe;AACd,aAAO,IAAI,OAAJ,CAAY,CAAZ,EAAe,CAAf,CAAP;AACD;;;;;;IAGG,O;;;AACJ,mBAAY,CAAZ,EAAe,CAAf,EAAkB,CAAlB,EAAqB;AAAA;;AAAA,kHACb,CADa,EACV,CADU;;AAEnB,UAAK,CAAL,GAAS,CAAT;AAFmB;AAGpB;;;;8BAES,C,EAAG,C,EAAG,C,EAAG;AACjB,kHAAgB,CAAhB,EAAmB,CAAnB;AACA,WAAK,CAAL,IAAU,CAAV;AACD;;;6BAEe;AACd,aAAO,IAAI,OAAJ,CAAY,CAAZ,EAAe,CAAf,EAAkB,CAAlB,CAAP;AACD;;;;EAbmB,O;;AAgBtB;;;AACA,IAAI;AACF;AACA;;AAFE,GAKD,cAAc,IAAI,EAAlB,CALC,EAKwB,EALxB,CAAJ;;AAQA;AACA,IAAI,SAAS,KAAb;AACA,IAAI,QAAQ,OAAZ;AACA,QAAQ,GAAR,UAAmB,MAAnB,kBAAsC,KAAtC;;AAEA;IACK,C,GAAY,C;IAAT,C,GAAY,C;IAAT,C,GAAY,C;;AAEvB;;AACA,SAAS,YAAT,CAAsB,CAAtB,EAA8B;AAAA,MAAL,CAAK,uEAAH,EAAG;;AAC5B,SAAO,IAAI,CAAX;AACD;;AAED,QAAQ,GAAR,CAAY,aAAa,EAAb,MAAqB,EAAjC;;AAEA;AACA,SAAS,eAAT,CAAyB,CAAzB,EAAkC;AAChC,SAAO,sDAAP;AACD;;AAED,QAAQ,GAAR,CAAY,gBAAgB,EAAhB,EAAoB,CAApB,EAAuB,CAAvB,EAA0B,CAA1B,EAA8B,CAA9B,EAAiC,CAAjC,MAAwC,EAApD;AACA,QAAQ,GAAR,CAAY,iCAAmB,CAAC,EAAD,EAAK,CAAL,EAAQ,CAAR,EAAW,CAAX,EAAc,CAAd,EAAiB,CAAjB,CAAnB,MAA4C,EAAxD;;AAEA;AACA,IAAM,aAAa,EAAnB;AACA,KAAK,IAAI,IAAE,CAAX,EAAc,IAAE,EAAhB,EAAoB,GAApB,EAAwB;AACtB,UAAQ,GAAR,CAAY,aAAa,CAAzB;AACD;;AAED","file":"out.js","sourcesContent":["\n// arrow functions\nvar f = (x, y, z) => {\n var a = x + 1;\n var b = y - 1;\n var c = z * 2;\n var result = a + 2*b - c;\n\n return result;\n};\n\n// classes\nclass Point2D {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n }\n\n translate(x, y) {\n this.x += x;\n this.y += y;\n }\n\n static origin() {\n return new Point2D(0, 0);\n }\n}\n\nclass Point3D extends Point2D {\n constructor(x, y, z) {\n super(x, y);\n this.z = z;\n }\n\n translate(x, y, z) {\n super.translate(x, y);\n this.z += z;\n }\n\n static origin() {\n return new Point3D(0, 0, 0);\n }\n}\n\n// enhanced object literals\nvar someOb = {\n // short for someOb : someOb\n someOb,\n\n // dynamic property names\n [\"property\" + (1 + 41)] : 42\n}\n\n// template strings\nvar animal = 'cat';\nvar hobby = 'sleep';\nconsole.log(`The ${animal} likes to ${hobby}`);\n\n// destructuring\nvar [x, y, z] = [1, 2, 3];\n\n// default values\nfunction someFunction(x, y=32){\n return x + y;\n}\n\nconsole.log(someFunction(10) === 42);\n\n// rest and spread\nfunction varArgsFunction(x, ...y) {\n return x + y.length;\n}\n\nconsole.log(varArgsFunction(10, 1, 2, 3 , 4, 5) === 15);\nconsole.log(varArgsFunction(...[10, 1, 2, 3, 4, 5]) === 15);\n\n// let and const\nconst SOME_VALUE = 10;\nfor (let i=0; i<10; i++){\n console.log(SOME_VALUE + i);\n}\n\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the 'License');\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an 'AS IS' BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"]} -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-babel-sourcemaps", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "in.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | }, 13 | "devDependencies": { 14 | "babel-preset-es2015": "^6.16.0", 15 | "babel-preset-stage-2": "^6.17.0", 16 | "babel-cli": "^6.16.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/coffeescript/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Install 'coffee' using 'npm install -g coffeescript' 4 | coffee --map --output . in.coffee 5 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/coffeescript/in.coffee: -------------------------------------------------------------------------------- 1 | 2 | class Animal 3 | constructor: (name, sound) -> 4 | @name = name 5 | @sound = sound 6 | 7 | hello: () -> 8 | return 'The ' + name + ' says ' + sound 9 | 10 | class Lion extends Animal 11 | constructor: () -> 12 | super('Lion', 'roar') 13 | 14 | someOb = 15 | a : 'a', 16 | b : 'b' 17 | 18 | console.log new Lion().alert 19 | 20 | nums = [1, 2, 3, 4, 5] 21 | square = (x) -> x*x; 22 | allSquares = (square x for x in nums) 23 | 24 | # 25 | # Copyright 2016 Google Inc. All Rights Reserved. 26 | # 27 | # Licensed under the Apache License, Version 2.0 (the 'License'); 28 | # you may not use this file except in compliance with the License. 29 | # You may obtain a copy of the License at 30 | # 31 | # http://www.apache.org/licenses/LICENSE-2.0 32 | # 33 | # Unless required by applicable law or agreed to in writing, software 34 | # distributed under the License is distributed on an 'AS IS' BASIS, 35 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | # See the License for the specific language governing permissions and 37 | # limitations under the License. 38 | # 39 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/coffeescript/in.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.11.0 2 | (function () { 3 | // eslint-disable-next-line no-var, no-unused-vars 4 | var Animal, 5 | Lion, 6 | // eslint-disable-next-line no-unused-vars 7 | allSquares, 8 | nums, 9 | // eslint-disable-next-line no-unused-vars 10 | someOb, 11 | square, 12 | x, 13 | extend = function (child, parent) { 14 | for (const key in parent) { 15 | if (hasProp.call(parent, key)) child[key] = parent[key]; 16 | } 17 | function ctor() { 18 | this.constructor = child; 19 | } 20 | ctor.prototype = parent.prototype; 21 | child.prototype = new ctor(); 22 | child.__super__ = parent.prototype; 23 | return child; 24 | }, 25 | hasProp = {}.hasOwnProperty; 26 | 27 | Animal = (function () { 28 | function Animal(name, sound) { 29 | this.name = name; 30 | this.sound = sound; 31 | } 32 | 33 | Animal.prototype.hello = function () { 34 | // eslint-disable-next-line no-undef 35 | return 'The ' + name + ' says ' + sound; 36 | }; 37 | 38 | return Animal; 39 | })(); 40 | 41 | Lion = (function (superClass) { 42 | extend(Lion, superClass); 43 | 44 | function Lion() { 45 | Lion.__super__.constructor.call(this, 'Lion', 'roar'); 46 | } 47 | 48 | return Lion; 49 | })(Animal); 50 | 51 | someOb = { 52 | a: 'a', 53 | b: 'b', 54 | }; 55 | 56 | console.log(new Lion().alert); 57 | 58 | nums = [1, 2, 3, 4, 5]; 59 | 60 | square = function (x) { 61 | return x * x; 62 | }; 63 | 64 | allSquares = (function () { 65 | let i, len, results; 66 | // eslint-disable-next-line prefer-const 67 | results = []; 68 | for (i = 0, len = nums.length; i < len; i++) { 69 | x = nums[i]; 70 | results.push(square(x)); 71 | } 72 | return results; 73 | })(); 74 | }.call(this)); 75 | 76 | //# sourceMappingURL=in.js.map 77 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/coffeescript/in.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "in.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "in.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AACA;AAAA,MAAA,iDAAA;IAAA;;;EAAM;IACS,gBAAC,IAAD,EAAO,KAAP;MACX,IAAC,CAAA,IAAD,GAAQ;MACR,IAAC,CAAA,KAAD,GAAS;IAFE;;qBAIb,KAAA,GAAO,SAAA;AACL,aAAO,MAAA,GAAS,IAAT,GAAgB,QAAhB,GAA2B;IAD7B;;;;;;EAGH;;;IACS,cAAA;MACX,sCAAM,MAAN,EAAc,MAAd;IADW;;;;KADI;;EAInB,MAAA,GACE;IAAA,CAAA,EAAI,GAAJ;IACA,CAAA,EAAI,GADJ;;;EAGF,OAAO,CAAC,GAAR,CAAY,IAAI,IAAA,CAAA,CAAM,CAAC,KAAvB;;EAEA,IAAA,GAAO,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,EAAa,CAAb;;EACP,MAAA,GAAS,SAAC,CAAD;WAAO,CAAA,GAAE;EAAT;;EACT,UAAA;;AAAc;SAAA,sCAAA;;mBAAA,MAAA,CAAO,CAAP;AAAA;;;AApBd" 10 | } -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/typescript/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Install 'tsc' with 'npm install -g typescript' 4 | tsc --sourceMap --outFile out.js in.ts 5 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/typescript/in.ts_: -------------------------------------------------------------------------------- 1 | 2 | class Animal { 3 | constructor(public name: string, public sound: string){ 4 | this.name = name; 5 | this.sound = sound; 6 | } 7 | 8 | hello() { 9 | return "The " + this.name + " says " + this.sound; 10 | } 11 | } 12 | 13 | class Lion extends Animal { 14 | constructor(){ 15 | super('Lion', 'roar'); 16 | } 17 | } 18 | 19 | function hello(name: string){ 20 | return 'Hello ' + name; 21 | } 22 | 23 | hello('you'); 24 | new Lion().hello(); 25 | 26 | /* 27 | * Copyright 2016 Google Inc. All Rights Reserved. 28 | * 29 | * Licensed under the Apache License, Version 2.0 (the 'License'); 30 | * you may not use this file except in compliance with the License. 31 | * You may obtain a copy of the License at 32 | * 33 | * http://www.apache.org/licenses/LICENSE-2.0 34 | * 35 | * Unless required by applicable law or agreed to in writing, software 36 | * distributed under the License is distributed on an 'AS IS' BASIS, 37 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 38 | * See the License for the specific language governing permissions and 39 | * limitations under the License. 40 | */ 41 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/typescript/out.js: -------------------------------------------------------------------------------- 1 | const __extends = 2 | (this && this.__extends) || 3 | function (d, b) { 4 | for (const p in b) 5 | if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; 6 | function __() { 7 | this.constructor = d; 8 | } 9 | d.prototype = 10 | b === null ? Object.create(b) : ((__.prototype = b.prototype), new __()); 11 | }; 12 | const Animal = (function () { 13 | function Animal(name, sound) { 14 | this.name = name; 15 | this.sound = sound; 16 | this.name = name; 17 | this.sound = sound; 18 | } 19 | Animal.prototype.hello = function () { 20 | return 'The ' + this.name + ' says ' + this.sound; 21 | }; 22 | return Animal; 23 | })(); 24 | const Lion = (function (_super) { 25 | __extends(Lion, _super); 26 | function Lion() { 27 | _super.call(this, 'Lion', 'roar'); 28 | } 29 | return Lion; 30 | })(Animal); 31 | function hello(name) { 32 | return 'Hello ' + name; 33 | } 34 | hello('you'); 35 | new Lion().hello(); 36 | /* 37 | * Copyright 2016 Google Inc. All Rights Reserved. 38 | * 39 | * Licensed under the Apache License, Version 2.0 (the 'License'); 40 | * you may not use this file except in compliance with the License. 41 | * You may obtain a copy of the License at 42 | * 43 | * http://www.apache.org/licenses/LICENSE-2.0 44 | * 45 | * Unless required by applicable law or agreed to in writing, software 46 | * distributed under the License is distributed on an 'AS IS' BASIS, 47 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | * See the License for the specific language governing permissions and 49 | * limitations under the License. 50 | */ 51 | //# sourceMappingURL=out.js.map 52 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/typescript/out.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"out.js","sourceRoot":"","sources":["in.ts"],"names":[],"mappings":";;;;;AACA;IACE,gBAAmB,IAAY,EAAS,KAAa;QAAlC,SAAI,GAAJ,IAAI,CAAQ;QAAS,UAAK,GAAL,KAAK,CAAQ;QACnD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,sBAAK,GAAL;QACE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;IACpD,CAAC;IACH,aAAC;AAAD,CAAC,AATD,IASC;AAED;IAAmB,wBAAM;IACvB;QACE,kBAAM,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,CAAC;IACH,WAAC;AAAD,CAAC,AAJD,CAAmB,MAAM,GAIxB;AAED,eAAe,IAAY;IACzB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,KAAK,CAAC,KAAK,CAAC,CAAC;AACb,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;AAEnB;;;;;;;;;;;;;;GAcG"} -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/webpack-ts/in.ts_: -------------------------------------------------------------------------------- 1 | 2 | function someFunction() { 3 | const x = 1; 4 | const y = 2; 5 | console.log(x + y); 6 | } 7 | 8 | someFunction(); 9 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/webpack-ts/out.js: -------------------------------------------------------------------------------- 1 | /******/ (function (modules) { 2 | // webpackBootstrap 3 | /******/ // The module cache 4 | /******/ const installedModules = {}; // The require function 5 | /******/ 6 | /******/ /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if (installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ 12 | } // Create a new module (and put it into the cache) 13 | /******/ /******/ const module = (installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {}, 17 | /******/ 18 | }); // Execute the module function 19 | /******/ 20 | /******/ /******/ modules[moduleId].call( 21 | module.exports, 22 | module, 23 | module.exports, 24 | __webpack_require__ 25 | ); // Flag the module as loaded 26 | /******/ 27 | /******/ /******/ module.l = true; // Return the exports of the module 28 | /******/ 29 | /******/ /******/ return module.exports; 30 | /******/ 31 | } // expose the modules object (__webpack_modules__) 32 | /******/ 33 | /******/ 34 | /******/ /******/ __webpack_require__.m = modules; // expose the module cache 35 | /******/ 36 | /******/ /******/ __webpack_require__.c = installedModules; // define getter function for harmony exports 37 | /******/ 38 | /******/ /******/ __webpack_require__.d = function (exports, name, getter) { 39 | /******/ if (!__webpack_require__.o(exports, name)) { 40 | /******/ Object.defineProperty(exports, name, { 41 | enumerable: true, 42 | get: getter, 43 | }); 44 | /******/ 45 | } 46 | /******/ 47 | }; // define __esModule on exports 48 | /******/ 49 | /******/ /******/ __webpack_require__.r = function (exports) { 50 | /******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { 51 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { 52 | value: 'Module', 53 | }); 54 | /******/ 55 | } 56 | /******/ Object.defineProperty(exports, '__esModule', {value: true}); 57 | /******/ 58 | }; // create a fake namespace object // mode & 1: value is a module id, require it // mode & 2: merge all properties of value into the ns // mode & 4: return value when already ns object // mode & 8|1: behave like require 59 | /******/ 60 | /******/ /******/ /******/ /******/ /******/ /******/ __webpack_require__.t = function ( 61 | value, 62 | mode 63 | ) { 64 | /******/ if (mode & 1) value = __webpack_require__(value); 65 | /******/ if (mode & 8) return value; 66 | /******/ if ( 67 | mode & 4 && 68 | typeof value === 'object' && 69 | value && 70 | value.__esModule 71 | ) 72 | return value; 73 | /******/ const ns = Object.create(null); 74 | /******/ __webpack_require__.r(ns); 75 | /******/ Object.defineProperty(ns, 'default', { 76 | enumerable: true, 77 | value: value, 78 | }); 79 | /******/ if (mode & 2 && typeof value !== 'string') 80 | for (const key in value) 81 | __webpack_require__.d( 82 | ns, 83 | key, 84 | (key => { 85 | return value[key]; 86 | }).bind(null, key) 87 | ); 88 | /******/ return ns; 89 | /******/ 90 | }; // getDefaultExport function for compatibility with non-harmony modules 91 | /******/ 92 | /******/ /******/ __webpack_require__.n = function (module) { 93 | /******/ const getter = 94 | module && module.__esModule 95 | ? /******/ function getDefault() { 96 | return module['default']; 97 | } 98 | : /******/ function getModuleExports() { 99 | return module; 100 | }; 101 | /******/ __webpack_require__.d(getter, 'a', getter); 102 | /******/ return getter; 103 | /******/ 104 | }; // Object.prototype.hasOwnProperty.call 105 | /******/ 106 | /******/ /******/ __webpack_require__.o = function (object, property) { 107 | return Object.prototype.hasOwnProperty.call(object, property); 108 | }; // __webpack_public_path__ 109 | /******/ 110 | /******/ /******/ __webpack_require__.p = ''; // Load entry module and return exports 111 | /******/ 112 | /******/ 113 | /******/ /******/ return __webpack_require__((__webpack_require__.s = 0)); 114 | /******/ 115 | })( 116 | /************************************************************************/ 117 | /******/ [ 118 | /* 0 */ 119 | // eslint-disable-next-line no-unused-vars 120 | /***/ function (module, exports) { 121 | function someFunction() { 122 | const x = 1; 123 | const y = 2; 124 | console.log(x + y); 125 | } 126 | 127 | someFunction(); 128 | 129 | /***/ 130 | }, 131 | /******/ 132 | ] 133 | ); 134 | //# sourceMappingURL=out.js.map 135 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/webpack-ts/out.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./in.ts_"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;ACjFA;AACA;AACA;AACA;AACA;;AAEA","file":"out.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","\nfunction someFunction() {\n const x = 1;\n const y = 2;\n console.log(x + y);\n}\n\nsomeFunction();\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/webpack-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-ts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "compile": "webpack" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "webpack": "^4.29.4", 14 | "webpack-cli": "^3.2.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/fixtures/sourcemapper/webpack-ts/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'none', 5 | entry: './in.ts_', 6 | output: { 7 | path: path.resolve(__dirname), 8 | filename: 'out.js', 9 | }, 10 | devtool: 'source-map', 11 | optimization: { 12 | nodeEnv: false, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/sourcemaps/css-file.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/test/fixtures/sourcemaps/css-file.css -------------------------------------------------------------------------------- /test/fixtures/sourcemaps/css-map-file.css.map: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/test/fixtures/sourcemaps/css-map-file.css.map -------------------------------------------------------------------------------- /test/fixtures/sourcemaps/empty-source-map.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":[],"names":[],"mappings":"","sourcesContent":[],"file":"js-file.js"} -------------------------------------------------------------------------------- /test/fixtures/sourcemaps/js-file.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/cloud-debug-nodejs/10f202ba8b6efc67651fe066040cb19578673249/test/fixtures/sourcemaps/js-file.js -------------------------------------------------------------------------------- /test/fixtures/sourcemaps/js-map-file.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"out.js","sourceRoot":"","sources":["in.ts"],"names":[],"mappings":";;;;;AACA;IACE,gBAAmB,IAAY,EAAS,KAAa;QAAlC,SAAI,GAAJ,IAAI,CAAQ;QAAS,UAAK,GAAL,KAAK,CAAQ;QACnD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,sBAAK,GAAL;QACE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;IACpD,CAAC;IACH,aAAC;AAAD,CAAC,AATD,IASC;AAED;IAAmB,wBAAM;IACvB;QACE,kBAAM,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,CAAC;IACH,WAAC;AAAD,CAAC,AAJD,CAAmB,MAAM,GAIxB;AAED,eAAe,IAAY;IACzB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,KAAK,CAAC,KAAK,CAAC,CAAC;AACb,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;AAEnB;;;;;;;;;;;;;;GAcG"} -------------------------------------------------------------------------------- /test/fixtures/test-config.js: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 | 'use strict'; 15 | 16 | // Default configuration 17 | module.exports = { 18 | debug: { 19 | enabled: true, 20 | 21 | // An identifier for the current code deployment. 22 | description: 'test config', 23 | 24 | serviceContext: { 25 | // An identifier for the current code's service name 26 | service: 'test service name', 27 | 28 | // An identifier for the current code's version 29 | version: 'test version', 30 | }, 31 | 32 | // Log levels: 0-disabled,1-error,2-warn,3-info,4-debug. 33 | logLevel: 4, 34 | 35 | capture: { 36 | // Whether to include details about stack frames belonging to node-core. 37 | includeNodeModules: true, 38 | }, 39 | 40 | // This is only for testing the config priority 41 | testPriority: 'from the config file', 42 | 43 | // These configuration options are for internal experimentation only. 44 | internal: { 45 | registerDelayOnFetcherErrorSec: 300, // 5 minutes. 46 | }, 47 | }, 48 | }; 49 | -------------------------------------------------------------------------------- /test/fixtures/transpiled-shorter/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Install 'coffee' using 'npm install -g coffeescript' 4 | coffee --map --output . in.coffee 5 | -------------------------------------------------------------------------------- /test/fixtures/transpiled-shorter/in.coffee: -------------------------------------------------------------------------------- 1 | 2 | # This file has extra blank lines so that the 3 | # transpiled file has fewer lines than this file. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | someFunction = () -> 60 | nums = [1, 2, 3, 4, 5] 61 | square = (x) -> x*x; 62 | allSquares = (square x for x in nums) 63 | 64 | module.exports = someFunction 65 | 66 | # 67 | # Copyright 2018 Google LLC 68 | # 69 | # Licensed under the Apache License, Version 2.0 (the 'License'); 70 | # you may not use this file except in compliance with the License. 71 | # You may obtain a copy of the License at 72 | # 73 | # http://www.apache.org/licenses/LICENSE-2.0 74 | # 75 | # Unless required by applicable law or agreed to in writing, software 76 | # distributed under the License is distributed on an 'AS IS' BASIS, 77 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 78 | # See the License for the specific language governing permissions and 79 | # limitations under the License. 80 | # 81 | -------------------------------------------------------------------------------- /test/fixtures/transpiled-shorter/in.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars, prefer-const*/ 2 | // Generated by CoffeeScript 2.3.1 3 | (function () { 4 | // This file has extra blank lines so that the 5 | // transpiled file has fewer lines than this file. 6 | let someFunction; 7 | 8 | someFunction = function () { 9 | let allSquares, nums, square, x; 10 | nums = [1, 2, 3, 4, 5]; 11 | square = function (x) { 12 | return x * x; 13 | }; 14 | return (allSquares = (function () { 15 | let i, len, results; 16 | results = []; 17 | for (i = 0, len = nums.length; i < len; i++) { 18 | x = nums[i]; 19 | results.push(square(x)); 20 | } 21 | return results; 22 | })()); 23 | }; 24 | 25 | module.exports = someFunction; 26 | 27 | // eslint-disable-next-line prettier/prettier 28 | 29 | // Copyright 2018 Google LLC 30 | 31 | // Licensed under the Apache License, Version 2.0 (the 'License'); 32 | // you may not use this file except in compliance with the License. 33 | // You may obtain a copy of the License at 34 | 35 | // http://www.apache.org/licenses/LICENSE-2.0 36 | 37 | // Unless required by applicable law or agreed to in writing, software 38 | // distributed under the License is distributed on an 'AS IS' BASIS, 39 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | // See the License for the specific language governing permissions and 41 | // limitations under the License. 42 | }.call(this)); 43 | 44 | //# sourceMappingURL=in.js.map 45 | -------------------------------------------------------------------------------- /test/fixtures/transpiled-shorter/in.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "file": "in.js", 4 | "sourceRoot": "", 5 | "sources": [ 6 | "in.coffee" 7 | ], 8 | "names": [], 9 | "mappings": ";AAAA;EAAA;;AAAA,MAAA;;EA0DA,YAAA,GAAe,QAAA,CAAA,CAAA;AACb,QAAA,UAAA,EAAA,IAAA,EAAA,MAAA,EAAA;IAAA,IAAA,GAAO,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,EAAa,CAAb;IACP,MAAA,GAAS,QAAA,CAAC,CAAD,CAAA;aAAO,CAAA,GAAE;IAAT;WACT,UAAA;;AAAuB;MAAA,KAAA,sCAAA;;qBAAT,MAAA,CAAO,CAAP;MAAS,CAAA;;;EAHV;;EAKf,MAAM,CAAC,OAAP,GAAiB;;EA/DjB;;;;;;;;;;;;;;;AAAA", 10 | "sourcesContent": [ 11 | "\n# This file has extra blank lines so that the\n# transpiled file has fewer lines than this file.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nsomeFunction = () ->\n nums = [1, 2, 3, 4, 5]\n square = (x) -> x*x;\n allSquares = (square x for x in nums)\n\nmodule.exports = someFunction\n\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the 'License');\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an 'AS IS' BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n" 12 | ] 13 | } -------------------------------------------------------------------------------- /test/fixtures/ts/async.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-arrow-callback, no-var, prettier/prettier, no-unused-vars */ 2 | // compile with 3 | // $ tsc --lib es6 --target es5 async.ts 4 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 5 | return new (P || (P = Promise))(function (resolve, reject) { 6 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 7 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 8 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 9 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 10 | }); 11 | }; 12 | var __generator = (this && this.__generator) || function (thisArg, body) { 13 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 14 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 15 | function verb(n) { return function (v) { return step([n, v]); }; } 16 | function step(op) { 17 | if (f) throw new TypeError("Generator is already executing."); 18 | while (_) try { 19 | if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; 20 | if (y = 0, t) op = [0, t.value]; 21 | switch (op[0]) { 22 | case 0: case 1: t = op; break; 23 | case 4: _.label++; return { value: op[1], done: false }; 24 | case 5: _.label++; y = op[1]; op = [0]; continue; 25 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 26 | default: 27 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 28 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 29 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 30 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 31 | if (t[2]) _.ops.pop(); 32 | _.trys.pop(); continue; 33 | } 34 | op = body.call(thisArg, _); 35 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 36 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 37 | } 38 | }; 39 | function delay(t) { 40 | return new Promise(function (resolve, reject) { 41 | setTimeout(resolve, t); 42 | }); 43 | } 44 | function get(path, handler) { 45 | var _this = this; 46 | delay(10).then(function () { 47 | var req = { 48 | name: 'fake request', 49 | path: path 50 | }; 51 | var res = { 52 | name: 'fake response', 53 | status: function (statusCode) { 54 | _this.statusCode = statusCode; 55 | return _this; 56 | }, 57 | send: function (msg) { 58 | console.log(msg); 59 | } 60 | }; 61 | handler(req, res); 62 | }); 63 | } 64 | function run() { 65 | var _this = this; 66 | get('/foo', function (req, res) { return __awaiter(_this, void 0, void 0, function () { 67 | return __generator(this, function (_a) { 68 | switch (_a.label) { 69 | case 0: return [4 /*yield*/, delay(10)]; 70 | case 1: 71 | _a.sent(); 72 | res.status(200); 73 | return [2 /*return*/]; 74 | } 75 | }); 76 | }); }); 77 | } 78 | module.exports = run; 79 | -------------------------------------------------------------------------------- /test/fixtures/ts/async.ts_: -------------------------------------------------------------------------------- 1 | // compile with 2 | // $ tsc --lib es6 --target es5 async.ts 3 | 4 | function delay(t) { 5 | return new Promise((resolve, reject) => { 6 | setTimeout(resolve, t); 7 | }); 8 | } 9 | 10 | function get(path, handler) { 11 | delay(10).then(() => { 12 | const req = { 13 | name: 'fake request', 14 | path: path 15 | }; 16 | const res = { 17 | name: 'fake response', 18 | status: (statusCode) => { 19 | this.statusCode = statusCode; 20 | return this; 21 | }, 22 | send: (msg) => { 23 | console.log(msg); 24 | } 25 | } 26 | handler(req, res); 27 | }); 28 | } 29 | 30 | function run() { 31 | get('/foo', async (req, res) => { 32 | await delay(10); 33 | res.status(200); 34 | }); 35 | } 36 | 37 | module.exports = run; 38 | -------------------------------------------------------------------------------- /test/misc/bench-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ 2 | /*2*/ 'use strict'; 3 | /*3*/ function fib(n) { 4 | /*4*/ return n < 2 ? n : fib(n - 2) + fib(n - 1); 5 | /*5*/ 6 | } 7 | /*6*/ module.exports = fib; 8 | -------------------------------------------------------------------------------- /test/misc/bench.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 | // eslint-disable-next-line @typescript-eslint/no-var-requires 16 | const v8debugapi = require('../src/v8debugapi.js'); 17 | const config = require('../config.js').default; 18 | import * as assert from 'assert'; 19 | // eslint-disable-next-line @typescript-eslint/no-var-requires 20 | const pretty = require('pretty-hrtime'); 21 | // eslint-disable-next-line @typescript-eslint/no-var-requires 22 | const fib = require('./bench-code.js'); 23 | 24 | // tslint:disable:variable-name 25 | // eslint-disable-next-line @typescript-eslint/no-var-requires 26 | const Logger = require('../src/logger.js'); 27 | const logger = new Logger(config.logLevel); 28 | assert.ok(v8debugapi.init(logger, config)); 29 | 30 | function bench(message: {}, f: Function) { 31 | let t = process.hrtime(); 32 | f(); 33 | t = process.hrtime(t); 34 | console.log(message + ': ' + pretty(t)); 35 | } 36 | 37 | bench('100x set', () => { 38 | for (let i = 0; i < 100; i++) { 39 | const bp = {id: 'fake-breakpoint', location: {path: __filename, line: 4}}; 40 | v8debugapi.set(bp); 41 | v8debugapi.clear(bp); 42 | } 43 | }); 44 | 45 | bench('100x set + validate', () => { 46 | for (let i = 0; i < 100; i++) { 47 | const bp = { 48 | id: 'breakpoint1', 49 | location: {path: __filename, line: 4}, 50 | condition: 'x === 1, 2, {f: 2}, process.env, (this ? this : this)', 51 | }; 52 | v8debugapi.set(bp); 53 | v8debugapi.clear(bp); 54 | } 55 | }); 56 | 57 | bench('fib(29)', () => { 58 | fib(29); 59 | }); 60 | 61 | // FIXME: the following test isn't really working because of a V8 bug. 62 | (() => { 63 | const bp = { 64 | id: 'breakpoint1', 65 | location: {path: __filename, line: 4}, 66 | condition: 'n > 50000', 67 | }; 68 | v8debugapi.set(bp); 69 | bench('fib(29) with breakpoint: ', () => { 70 | fib(29); 71 | }); 72 | v8debugapi.clear(bp); 73 | })(); 74 | -------------------------------------------------------------------------------- /test/misc/test-leak.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const v8debugapi = require('../src/v8debugapi.js'); 5 | const config = require('../config.js').default; 6 | import * as assert from 'assert'; 7 | import * as util from 'util'; 8 | 9 | // tslint:disable:variable-name 10 | // eslint-disable-next-line @typescript-eslint/no-var-requires 11 | const Logger = require('../src/logger.js'); 12 | const logger = new Logger(config.logLevel); 13 | 14 | assert.ok(v8debugapi.init(logger, config)); 15 | 16 | let iters = 0; 17 | 18 | function test() { 19 | iters++; 20 | 21 | const bp = {id: 'fake-breakpoint', location: {path: __filename, line: 4}}; 22 | v8debugapi.set(bp); 23 | v8debugapi.clear(bp); 24 | 25 | if (iters % 100 === 0) { 26 | console.log(iters + ' ' + util.inspect(process.memoryUsage())); 27 | } 28 | 29 | // infinite loop 30 | setImmediate(test); 31 | } 32 | 33 | test(); 34 | -------------------------------------------------------------------------------- /test/mock-logger.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google LLC 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 consoleLogLevel = require('console-log-level'); 16 | 17 | export type Arguments = string[]; 18 | export interface Call { 19 | type: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; 20 | args: Arguments; 21 | } 22 | 23 | export class MockLogger implements consoleLogLevel.Logger { 24 | traces: Call[] = []; 25 | debugs: Call[] = []; 26 | infos: Call[] = []; 27 | warns: Call[] = []; 28 | errors: Call[] = []; 29 | fatals: Call[] = []; 30 | 31 | allCalls() { 32 | return this.traces.concat( 33 | this.debugs, 34 | this.infos, 35 | this.warns, 36 | this.errors, 37 | this.fatals 38 | ); 39 | } 40 | 41 | clear() { 42 | this.traces = []; 43 | this.debugs = []; 44 | this.infos = []; 45 | this.warns = []; 46 | this.errors = []; 47 | this.fatals = []; 48 | } 49 | 50 | trace(...args: Arguments) { 51 | this.traces.push({type: 'trace', args}); 52 | } 53 | 54 | debug(...args: Arguments) { 55 | this.debugs.push({type: 'debug', args}); 56 | } 57 | 58 | info(...args: Arguments) { 59 | this.infos.push({type: 'info', args}); 60 | } 61 | 62 | warn(...args: Arguments) { 63 | this.warns.push({type: 'warn', args}); 64 | } 65 | 66 | error(...args: Arguments) { 67 | this.errors.push({type: 'error', args}); 68 | } 69 | 70 | fatal(...args: Arguments) { 71 | this.fatals.push({type: 'fatal', args}); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /test/nocks.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google LLC 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 * as gcpMetadata from 'gcp-metadata'; 16 | import * as nock from 'nock'; 17 | 18 | // In the future _=>true. 19 | function accept(): true { 20 | return true; 21 | } 22 | 23 | export type Validator = (body: { 24 | client_id: string; 25 | client_secret: string; 26 | refresh_token: string; 27 | }) => boolean; 28 | 29 | // TODO: Determine if the type of `validator` is correct. 30 | export function oauth2(validator?: Validator): nock.Scope { 31 | validator = validator || accept; 32 | return nock('https://oauth2.googleapis.com') 33 | .post('/token', validator) 34 | .once() 35 | .reply(200, { 36 | refresh_token: 'hello', 37 | access_token: 'goodbye', 38 | expiry_date: new Date(9999, 1, 1), 39 | }); 40 | } 41 | 42 | // TODO: Determine if the type of `validator` is correct. 43 | export function register(validator?: Validator): nock.Scope { 44 | validator = validator || accept; 45 | return nock('https://clouddebugger.googleapis.com') 46 | .post('/v2/controller/debuggees/register', validator) 47 | .once() 48 | .reply(200, {debuggee: {}}); 49 | } 50 | 51 | export function projectId(reply: string): nock.Scope { 52 | return nock(gcpMetadata.HOST_ADDRESS) 53 | .get('/computeMetadata/v1/project/project-id') 54 | .once() 55 | .reply(200, reply); 56 | } 57 | 58 | export function metadataInstance(): nock.Scope { 59 | return nock(gcpMetadata.HOST_ADDRESS) 60 | .get('/computeMetadata/v1/instance') 61 | .replyWithError({code: 'ENOTFOUND', message: 'nocked request'}); 62 | } 63 | -------------------------------------------------------------------------------- /test/test-circular-code.js: -------------------------------------------------------------------------------- 1 | /* 1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /* 2*/'use strict'; 3 | /* 3*/module.exports.foo = function () { 4 | /* 4*/ const a = {}; 5 | /* 5*/ const b = { a, c: this }; 6 | /* 6*/ a.b = b; 7 | /* 7*/ this.x = this; 8 | /* 8*/ this.y = a; 9 | /* 9*/ return this; 10 | /*10*/} 11 | -------------------------------------------------------------------------------- /test/test-debug-assert.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 * as realAssert from 'assert'; 16 | import {debugAssert} from '../src/agent/util/debug-assert'; 17 | import {describe, it} from 'mocha'; 18 | 19 | describe('debug-assert', () => { 20 | it('should fire assertions when enabled', () => { 21 | realAssert.throws(() => { 22 | const assert = debugAssert(true); 23 | assert.strictEqual(1, 2); 24 | }); 25 | }); 26 | 27 | describe('disabled', () => { 28 | const assert = debugAssert(false); 29 | 30 | it('should not fire assertions when disabled', () => { 31 | assert.strictEqual(1, 2); 32 | }); 33 | 34 | it.skip('should cover the full assert API', () => { 35 | Object.keys(realAssert).forEach(key => { 36 | realAssert.strictEqual( 37 | typeof (assert as {} as {[key: string]: Function})[key], 38 | 'function', 39 | `${key} does not exist on the debug assert library` 40 | ); 41 | }); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/test-debuggee.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google LLC 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 * as assert from 'assert'; 16 | import {describe, it} from 'mocha'; 17 | import {Debuggee} from '../src/debuggee'; 18 | 19 | const agentVersion = 'SomeName/client/SomeVersion'; 20 | 21 | describe('Debuggee', () => { 22 | it('should create a Debuggee instance on valid input', () => { 23 | const debuggee = new Debuggee({ 24 | project: 'project', 25 | uniquifier: 'uid', 26 | description: 'unit test', 27 | agentVersion, 28 | }); 29 | assert.ok(debuggee instanceof Debuggee); 30 | }); 31 | 32 | it('should create a Debuggee on a call without new', () => { 33 | const debuggee = new Debuggee({ 34 | project: 'project', 35 | uniquifier: 'uid', 36 | description: 'unit test', 37 | agentVersion, 38 | }); 39 | assert.ok(debuggee instanceof Debuggee); 40 | }); 41 | 42 | it('should throw on invalid input', () => { 43 | assert.throws(() => { 44 | return new Debuggee({agentVersion}); 45 | }); 46 | assert.throws(() => { 47 | return new Debuggee({project: '5', agentVersion}); 48 | }); 49 | assert.throws(() => { 50 | return new Debuggee({project: undefined, agentVersion}); 51 | }); 52 | assert.throws(() => { 53 | return new Debuggee({project: 'test', agentVersion}); 54 | }); 55 | assert.throws(() => { 56 | new Debuggee({ 57 | project: 'test', 58 | uniquifier: undefined, 59 | agentVersion, 60 | }); 61 | assert.throws(() => { 62 | return new Debuggee({project: 'test', uniquifier: 'uid', agentVersion}); 63 | }); 64 | }); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /test/test-debuglet.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 {describe, it} from 'mocha'; 16 | import * as path from 'path'; 17 | 18 | import {defaultConfig as DEFAULT_CONFIG} from '../src/agent/config'; 19 | 20 | DEFAULT_CONFIG.allowExpressions = true; 21 | DEFAULT_CONFIG.workingDirectory = path.join(__dirname, '..', '..'); 22 | import {CachedPromise} from '../src/agent/debuglet'; 23 | 24 | import * as nock from 'nock'; 25 | nock.disableNetConnect(); 26 | 27 | describe('CachedPromise', () => { 28 | it('CachedPromise.get() will resolve after CachedPromise.resolve()', function (done) { 29 | this.timeout(2000); 30 | const cachedPromise = new CachedPromise(); 31 | cachedPromise.get().then(() => { 32 | done(); 33 | }); 34 | cachedPromise.resolve(); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/test-duplicate-expressions-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ 2 | /*2*/'use strict'; 3 | /*3*/function foo(a) { 4 | /*4*/ process.nextTick(function() { 5 | /*5*/ a = 0; 6 | /*6*/ }); 7 | /*7*/} 8 | /*8*/module.exports = foo; -------------------------------------------------------------------------------- /test/test-duplicate-expressions.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 consoleLogLevel = require('console-log-level'); 16 | import * as stackdriver from '../src/types/stackdriver'; 17 | 18 | // TODO: Have this actually implement Breakpoint 19 | const breakpointInFoo: stackdriver.Breakpoint = { 20 | id: 'fake-id-123', 21 | location: {path: 'test-duplicate-expressions-code.js', line: 4}, 22 | } as stackdriver.Breakpoint; 23 | 24 | import * as assert from 'assert'; 25 | import {afterEach, beforeEach, describe, it} from 'mocha'; 26 | import * as extend from 'extend'; 27 | import * as debugapi from '../src/agent/v8/debugapi'; 28 | import {defaultConfig} from '../src/agent/config'; 29 | import * as SourceMapper from '../src/agent/io/sourcemapper'; 30 | import * as scanner from '../src/agent/io/scanner'; 31 | import {Debuglet} from '../src/agent/debuglet'; 32 | // eslint-disable-next-line @typescript-eslint/no-var-requires 33 | const foo = require('./test-duplicate-expressions-code.js'); 34 | 35 | // TODO: Determine why this must be named `stateIsClean1`. 36 | function stateIsClean1(api: debugapi.DebugApi): boolean { 37 | assert.strictEqual( 38 | api.numBreakpoints_(), 39 | 0, 40 | 'there should be no breakpoints active' 41 | ); 42 | assert.strictEqual( 43 | api.numListeners_(), 44 | 0, 45 | 'there should be no listeners active' 46 | ); 47 | return true; 48 | } 49 | 50 | describe(__filename, () => { 51 | const config = extend({}, defaultConfig, { 52 | workingDirectory: __dirname, 53 | forceNewAgent_: true, 54 | }); 55 | const logger = consoleLogLevel({ 56 | level: Debuglet.logLevelToName(config.logLevel), 57 | }); 58 | let api: debugapi.DebugApi; 59 | 60 | beforeEach(done => { 61 | if (!api) { 62 | scanner.scan(config.workingDirectory, /.js$/).then(async fileStats => { 63 | assert.strictEqual(fileStats.errors().size, 0); 64 | const jsStats = fileStats.selectStats(/.js$/); 65 | const mapFiles = fileStats.selectFiles(/.map$/, process.cwd()); 66 | const mapper = await SourceMapper.create(mapFiles, logger); 67 | // TODO: Handle the case when mapper is undefined 68 | // TODO: Handle the case when v8debugapi.create returns null 69 | api = debugapi.create( 70 | logger, 71 | config, 72 | jsStats, 73 | mapper as SourceMapper.SourceMapper 74 | ) as debugapi.DebugApi; 75 | assert.ok(api, 'should be able to create the api'); 76 | done(); 77 | }); 78 | } else { 79 | assert(stateIsClean1(api)); 80 | done(); 81 | } 82 | }); 83 | afterEach(() => { 84 | assert(stateIsClean1(api)); 85 | }); 86 | 87 | it('should not duplicate expressions', done => { 88 | api.set(breakpointInFoo, err1 => { 89 | assert.ifError(err1); 90 | api.wait(breakpointInFoo, err2 => { 91 | assert.ifError(err2); 92 | // TODO: Determine how to remove this cast to any. 93 | const frames = breakpointInFoo.stackFrames[0]; 94 | const exprs = frames.arguments.concat(frames.locals); 95 | const varTableIndicesSeen: number[] = []; 96 | exprs.forEach(expr => { 97 | // TODO: Handle the case when expr.varTableIndex is undefined 98 | assert.strictEqual( 99 | varTableIndicesSeen.indexOf(expr.varTableIndex as number), 100 | -1 101 | ); 102 | varTableIndicesSeen.push(expr.varTableIndex as number); 103 | }); 104 | api.clear(breakpointInFoo, err => { 105 | assert.ifError(err); 106 | done(); 107 | }); 108 | }); 109 | process.nextTick(foo); 110 | }); 111 | }); 112 | }); 113 | -------------------------------------------------------------------------------- /test/test-duplicate-nested-expressions-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /*2*/'use strict'; 3 | /*3*/function foo(a) { 4 | /*4*/ var a = 10; 5 | /*5*/ a += 1; 6 | /*6*/ return (function (b) { 7 | /*7*/ var a = true; 8 | /*8*/ return a; 9 | /*9*/ }()); 10 | /*10*/} 11 | /*11*/module.exports = foo; -------------------------------------------------------------------------------- /test/test-evaluated-expressions-code.js: -------------------------------------------------------------------------------- 1 | /* 1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /* 2*/'use strict'; 3 | /* 3*/const nock = require('nock'); 4 | /* 4*/const http = require('http'); 5 | /* 5*/function foo() { 6 | /* 6*/ nock.disableNetConnect(); 7 | /* 7*/ const scope = nock('http://www.someinvalidsite.com') 8 | /* 8*/ .get('/some/missing/path') 9 | /* 9*/ .once() 10 | /*10*/ .reply(200); 11 | /*11*/ const options = { 12 | /*12*/ host: 'www.someinvalidsite.com', 13 | /*13*/ path: '/some/missing/path' 14 | /*14*/ }; 15 | /*15*/ http.request(options, res => { 16 | /*16*/ const someObject = { aNumber: 1, aString : 'some string' }; 17 | /*17*/ const someArray = [1, 2, 3]; 18 | /*18*/ const someRegex = /abc+/; 19 | /*19*/ scope.done(); 20 | /*20*/ }).end(); 21 | /*21*/} 22 | /*22*/module.exports = { 23 | /*23*/ foo: foo 24 | /*24*/}; -------------------------------------------------------------------------------- /test/test-expression-side-effect-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /*2*/'use strict'; 3 | /*3*/class Item { 4 | /*4*/ constructor() { 5 | /*5*/ this.price = 2; 6 | /*6*/ } 7 | /*7*/ getPrice() { 8 | /*8*/ return this.price; 9 | /*9*/ } 10 | /*10*/ increasePriceByOne() { 11 | /*11*/ this.price += 1; 12 | /*12*/ } 13 | /*13*/} 14 | /*14*/function foo() { 15 | /*15*/ var item = new Item(); 16 | /*16*/ item.increasePriceByOne(); 17 | /*17*/ item.increasePriceByOne(); 18 | /*18*/} 19 | /*19*/module.exports = { 20 | /*20*/ foo: foo 21 | /*21*/}; 22 | -------------------------------------------------------------------------------- /test/test-expression-side-effect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 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 | import * as assert from 'assert'; 15 | import {before, describe, it} from 'mocha'; 16 | import * as extend from 'extend'; 17 | 18 | import {defaultConfig} from '../src/agent/config'; 19 | import {Debuglet} from '../src/agent/debuglet'; 20 | import * as scanner from '../src/agent/io/scanner'; 21 | import * as SourceMapper from '../src/agent/io/sourcemapper'; 22 | import * as utils from '../src/agent/util/utils'; 23 | import * as debugapi from '../src/agent/v8/debugapi'; 24 | import {StatusMessage} from '../src/client/stackdriver/status-message'; 25 | import consoleLogLevel = require('console-log-level'); 26 | import * as stackdriver from '../src/types/stackdriver'; 27 | 28 | // eslint-disable-next-line @typescript-eslint/no-var-requires 29 | const code = require('./test-expression-side-effect-code.js'); 30 | 31 | // the inspector protocol is only used on Node >= 10 and thus isn't 32 | // tested on earlier versions 33 | const itWithInspector = utils.satisfies(process.version, '>=10') ? it : it.skip; 34 | 35 | describe('evaluating expressions', () => { 36 | let api: debugapi.DebugApi; 37 | const config = extend({}, defaultConfig, {forceNewAgent_: true}); 38 | 39 | before(done => { 40 | const logger = consoleLogLevel({ 41 | level: Debuglet.logLevelToName(config.logLevel), 42 | }); 43 | scanner.scan(config.workingDirectory, /\.js$/).then(async fileStats => { 44 | const jsStats = fileStats.selectStats(/\.js$/); 45 | const mapFiles = fileStats.selectFiles(/\.map$/, process.cwd()); 46 | const mapper = await SourceMapper.create(mapFiles, logger); 47 | assert(mapper); 48 | api = debugapi.create(logger, config, jsStats, mapper!); 49 | done(); 50 | }); 51 | }); 52 | 53 | itWithInspector('should evaluate expressions without side effects', done => { 54 | // this test makes sure that the necessary environment variables to 55 | // enable asserts are present during testing. Use run-tests.sh, or 56 | // export CLOUD_DEBUG_ASSERTIONS=1 to make sure this test passes. 57 | const bp: stackdriver.Breakpoint = { 58 | id: 'fake-id-123', 59 | location: { 60 | path: 'build/test/test-expression-side-effect-code.js', 61 | line: 16, 62 | }, 63 | expressions: ['item.getPrice()'], 64 | } as stackdriver.Breakpoint; 65 | 66 | api.set(bp, err => { 67 | assert.ifError(err); 68 | api.wait(bp, err => { 69 | assert.ifError(err); 70 | const watch = bp.evaluatedExpressions[0]; 71 | assert.strictEqual((watch as {value: string}).value, '2'); 72 | api.clear(bp, err => { 73 | assert.ifError(err); 74 | done(); 75 | }); 76 | }); 77 | process.nextTick(() => { 78 | code.foo(); 79 | }); 80 | }); 81 | }); 82 | 83 | itWithInspector('should not evaluate expressions with side effects', done => { 84 | // this test makes sure that the necessary environment variables to 85 | // enable asserts are present during testing. Use run-tests.sh, or 86 | // export CLOUD_DEBUG_ASSERTIONS=1 to make sure this test passes. 87 | const bp: stackdriver.Breakpoint = { 88 | id: 'fake-id-123', 89 | location: { 90 | path: 'build/test/test-expression-side-effect-code.js', 91 | line: 16, 92 | }, 93 | expressions: ['item.increasePriceByOne()'], 94 | } as stackdriver.Breakpoint; 95 | 96 | api.set(bp, err => { 97 | assert.ifError(err); 98 | api.wait(bp, err => { 99 | assert.ifError(err); 100 | const watch = bp.evaluatedExpressions[0]; 101 | assert((watch as {status: StatusMessage}).status.isError); 102 | api.clear(bp, err => { 103 | assert.ifError(err); 104 | done(); 105 | }); 106 | }); 107 | process.nextTick(() => { 108 | code.foo(); 109 | }); 110 | }); 111 | }); 112 | 113 | itWithInspector('should not evaluate process.title', done => { 114 | // this test makes sure that the necessary environment variables to enable 115 | // asserts are present during testing. Use run-tests.sh, or export 116 | // CLOUD_DEBUG_ASSERTIONS=1 to make sure this test passes. 117 | const bp: stackdriver.Breakpoint = { 118 | id: 'fake-id-123', 119 | location: { 120 | path: 'build/test/test-expression-side-effect-code.js', 121 | line: 16, 122 | }, 123 | expressions: ['process'], 124 | } as stackdriver.Breakpoint; 125 | 126 | api.set(bp, err => { 127 | assert.ifError(err); 128 | api.wait(bp, err => { 129 | assert.ifError(err); 130 | const exp = bp.evaluatedExpressions[0]; 131 | assert(exp); 132 | const varIndex = exp!.varTableIndex; 133 | assert(varIndex); 134 | const members = bp.variableTable[varIndex!]!.members; 135 | assert(members); 136 | for (const entry of members!) { 137 | if (entry.name === 'title') { 138 | assert(entry.value === undefined); 139 | } 140 | } 141 | 142 | api.clear(bp, err => { 143 | assert.ifError(err); 144 | done(); 145 | }); 146 | }); 147 | process.nextTick(() => { 148 | code.foo(); 149 | }); 150 | }); 151 | }); 152 | }); 153 | -------------------------------------------------------------------------------- /test/test-fat-arrow.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 * as assert from 'assert'; 16 | import {before, beforeEach, afterEach, describe, it} from 'mocha'; 17 | import * as extend from 'extend'; 18 | 19 | import {defaultConfig} from '../src/agent/config'; 20 | import {Debuglet} from '../src/agent/debuglet'; 21 | import * as scanner from '../src/agent/io/scanner'; 22 | import * as SourceMapper from '../src/agent/io/sourcemapper'; 23 | import * as debugapi from '../src/agent/v8/debugapi'; 24 | import consoleLogLevel = require('console-log-level'); 25 | import * as stackdriver from '../src/types/stackdriver'; 26 | 27 | process.env.GCLOUD_PROJECT = '0'; 28 | 29 | function stateIsClean(api: debugapi.DebugApi): boolean { 30 | assert.strictEqual( 31 | api.numBreakpoints_(), 32 | 0, 33 | 'there should be no breakpoints active' 34 | ); 35 | assert.strictEqual( 36 | api.numListeners_(), 37 | 0, 38 | 'there should be no listeners active' 39 | ); 40 | return true; 41 | } 42 | 43 | describe(__filename, () => { 44 | const config = extend({}, defaultConfig, { 45 | workingDirectory: __dirname, 46 | forceNewAgent_: true, 47 | }); 48 | const logger = consoleLogLevel({ 49 | level: Debuglet.logLevelToName(config.logLevel), 50 | }); 51 | let api: debugapi.DebugApi; 52 | let foo: () => number; 53 | before(() => { 54 | foo = require('./fixtures/fat-arrow.js'); 55 | }); 56 | beforeEach(done => { 57 | if (!api) { 58 | scanner.scan(config.workingDirectory, /.js$/).then(async fileStats => { 59 | assert.strictEqual(fileStats.errors().size, 0); 60 | const jsStats = fileStats.selectStats(/.js$/); 61 | const mapFiles = fileStats.selectFiles(/.map$/, process.cwd()); 62 | // TODO: Determine if the err parameter should be used. 63 | const mapper = await SourceMapper.create(mapFiles, logger); 64 | // TODO: Handle the case when mapper is undefined 65 | // TODO: Handle the case when v8debugapi.create returns null 66 | api = debugapi.create( 67 | logger, 68 | config, 69 | jsStats, 70 | mapper as SourceMapper.SourceMapper 71 | ) as debugapi.DebugApi; 72 | assert.ok(api, 'should be able to create the api'); 73 | done(); 74 | }); 75 | } else { 76 | assert(stateIsClean(api)); 77 | done(); 78 | } 79 | }); 80 | afterEach(() => { 81 | assert(stateIsClean(api)); 82 | }); 83 | it('Should read the argument value of the fat arrow', done => { 84 | // TODO: Have this implement Breakpoint 85 | const brk: stackdriver.Breakpoint = { 86 | id: 'fake-id-123', 87 | location: {path: 'fixtures/fat-arrow.js', line: 5}, 88 | } as stackdriver.Breakpoint; 89 | api.set(brk, err1 => { 90 | assert.ifError(err1); 91 | api.wait(brk, err2 => { 92 | assert.ifError(err2); 93 | const frame = brk.stackFrames[0]; 94 | const args = frame.arguments; 95 | const locals = frame.locals; 96 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 97 | assert.strictEqual(locals.length, 1, 'There should be one local'); 98 | assert.deepStrictEqual(locals[0], {name: 'b', value: '1'}); 99 | api.clear(brk, err3 => { 100 | assert.ifError(err3); 101 | done(); 102 | }); 103 | }); 104 | process.nextTick(foo.bind(null)); 105 | }); 106 | }); 107 | it('Should process the argument value change of the fat arrow', done => { 108 | // TODO: Have this implement Breakpoint 109 | const brk: stackdriver.Breakpoint = { 110 | id: 'fake-id-123', 111 | location: {path: 'fixtures/fat-arrow.js', line: 6}, 112 | } as stackdriver.Breakpoint; 113 | api.set(brk, err1 => { 114 | assert.ifError(err1); 115 | api.wait(brk, err2 => { 116 | assert.ifError(err2); 117 | // TODO: Fix this explicit cast. 118 | const frame = brk.stackFrames[0]; 119 | const args = frame.arguments; 120 | const locals = frame.locals; 121 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 122 | assert.strictEqual(locals.length, 1, 'There should be one local'); 123 | assert.deepStrictEqual(locals[0], {name: 'b', value: '2'}); 124 | api.clear(brk, err3 => { 125 | assert.ifError(err3); 126 | done(); 127 | }); 128 | }); 129 | process.nextTick(foo.bind(null)); 130 | }); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /test/test-max-data-size-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ 2 | /*2*/'use strict'; 3 | /*3*/function foo(n) { 4 | /*4*/ var A = new Array(3); return n+42+A[0]; 5 | /*5*/} 6 | /*6*/module.exports = foo; -------------------------------------------------------------------------------- /test/test-max-data-size.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 | process.env.GCLOUD_DIAGNOSTICS_CONFIG = 'test/fixtures/test-config.js'; 16 | 17 | import consoleLogLevel = require('console-log-level'); 18 | import * as stackdriver from '../src/types/stackdriver'; 19 | 20 | import * as assert from 'assert'; 21 | import {before, describe, it} from 'mocha'; 22 | import * as extend from 'extend'; 23 | import * as debugapi from '../src/agent/v8/debugapi'; 24 | import * as SourceMapper from '../src/agent/io/sourcemapper'; 25 | import * as scanner from '../src/agent/io/scanner'; 26 | import {Debuglet} from '../src/agent/debuglet'; 27 | import {defaultConfig} from '../src/agent/config'; 28 | // eslint-disable-next-line @typescript-eslint/no-var-requires 29 | const foo = require('./test-max-data-size-code.js'); 30 | let api: debugapi.DebugApi; 31 | 32 | // TODO: Have this actually implement Breakpoint 33 | const breakpointInFoo: stackdriver.Breakpoint = { 34 | id: 'fake-id-123', 35 | location: {path: 'build/test/test-max-data-size-code.js', line: 4}, 36 | } as stackdriver.Breakpoint; 37 | 38 | describe('maxDataSize', () => { 39 | const config = extend({}, defaultConfig, {forceNewAgent_: true}); 40 | 41 | before(done => { 42 | if (!api) { 43 | const logger = consoleLogLevel({ 44 | level: Debuglet.logLevelToName(config.logLevel), 45 | }); 46 | scanner.scan(config.workingDirectory, /.js$/).then(async fileStats => { 47 | assert.strictEqual(fileStats.errors().size, 0); 48 | const jsStats = fileStats.selectStats(/.js$/); 49 | const mapFiles = fileStats.selectFiles(/.map$/, process.cwd()); 50 | const mapper = await SourceMapper.create(mapFiles, logger); 51 | // TODO: Handle the case when mapper is undefined 52 | // TODO: Handle the case when v8debugapi.create returns null 53 | api = debugapi.create( 54 | logger, 55 | config, 56 | jsStats, 57 | mapper as SourceMapper.SourceMapper 58 | ) as debugapi.DebugApi; 59 | done(); 60 | }); 61 | } else { 62 | done(); 63 | } 64 | }); 65 | 66 | it('should limit data reported', done => { 67 | const oldMaxData = config.capture.maxDataSize; 68 | config.capture.maxDataSize = 5; 69 | // clone a clean breakpointInFoo 70 | // TODO: Have this actually implement Breakpoint. 71 | const bp: stackdriver.Breakpoint = { 72 | id: breakpointInFoo.id, 73 | location: breakpointInFoo.location, 74 | } as stackdriver.Breakpoint; 75 | // TODO: Determine how to remove this cast to any. 76 | api.set(bp, err1 => { 77 | assert.ifError(err1); 78 | api.wait(bp, (err2?: Error) => { 79 | assert.ifError(err2); 80 | assert( 81 | bp.variableTable.some(v => { 82 | return v!.status!.description.format === 'Max data size reached'; 83 | }) 84 | ); 85 | api.clear(bp, err3 => { 86 | config.capture.maxDataSize = oldMaxData; 87 | assert.ifError(err3); 88 | done(); 89 | }); 90 | }); 91 | process.nextTick(() => { 92 | foo(2); 93 | }); 94 | }); 95 | }); 96 | 97 | it('should be unlimited if 0', done => { 98 | const oldMaxData = config.capture.maxDataSize; 99 | config.capture.maxDataSize = 0; 100 | // clone a clean breakpointInFoo 101 | // TODO: Have this actually implement breakpoint 102 | const bp: stackdriver.Breakpoint = { 103 | id: breakpointInFoo.id, 104 | location: breakpointInFoo.location, 105 | } as stackdriver.Breakpoint; 106 | api.set(bp, err1 => { 107 | assert.ifError(err1); 108 | api.wait(bp, (err2?: Error) => { 109 | assert.ifError(err2); 110 | // TODO: The function supplied to reduce is of the wrong type. 111 | // Fix this. 112 | assert( 113 | bp.variableTable.reduce( 114 | ( 115 | acc: Function | stackdriver.Variable | null, 116 | elem: stackdriver.Variable | null 117 | ) => { 118 | return ( 119 | acc && 120 | ((!elem!.status || 121 | elem!.status!.description.format !== 122 | 'Max data size reached') as {} as stackdriver.Variable) 123 | ); 124 | } 125 | ) 126 | ); 127 | api.clear(bp, err3 => { 128 | config.capture.maxDataSize = oldMaxData; 129 | assert.ifError(err3); 130 | done(); 131 | }); 132 | }); 133 | process.nextTick(() => { 134 | foo(2); 135 | }); 136 | }); 137 | }); 138 | }); 139 | -------------------------------------------------------------------------------- /test/test-this-context-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ 2 | /*2*/'use strict'; 3 | /*3*/function foo(b) {/* jshint validthis: true */ 4 | /*4*/ this.a = 10; 5 | /*5*/ this.a += b; 6 | /*6*/ return this; 7 | /*7*/} 8 | /*8*/function bar(j) { 9 | /*9*/ return j; 10 | /*10*/} 11 | /*11*/module.exports = { 12 | /*12*/ foo: foo, 13 | /*13*/ bar: bar 14 | /*14*/}; -------------------------------------------------------------------------------- /test/test-try-catch-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ /* jshint shadow:true */ 2 | /*2*/'use strict'; 3 | /*3*/function foo() { 4 | /*4*/ try { 5 | /*5*/ throw new Error('A test'); 6 | /*6*/ } catch (e) { 7 | /*7*/ var e = 2; 8 | /*8*/ return e; 9 | /*9*/ } 10 | /*10*/} 11 | /*11*/module.exports = foo; -------------------------------------------------------------------------------- /test/test-try-catch.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 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 * as assert from 'assert'; 16 | import {afterEach, beforeEach, describe, it} from 'mocha'; 17 | import * as extend from 'extend'; 18 | 19 | import {defaultConfig} from '../src/agent/config'; 20 | import {Debuglet} from '../src/agent/debuglet'; 21 | import * as scanner from '../src/agent/io/scanner'; 22 | import * as SourceMapper from '../src/agent/io/sourcemapper'; 23 | import * as debugapi from '../src/agent/v8/debugapi'; 24 | import consoleLogLevel = require('console-log-level'); 25 | import * as stackdriver from '../src/types/stackdriver'; 26 | 27 | // eslint-disable-next-line @typescript-eslint/no-var-requires 28 | const foo = require('./test-try-catch-code.js'); 29 | 30 | function stateIsClean(api: debugapi.DebugApi): boolean { 31 | assert.strictEqual( 32 | api.numBreakpoints_(), 33 | 0, 34 | 'there should be no breakpoints active' 35 | ); 36 | assert.strictEqual( 37 | api.numListeners_(), 38 | 0, 39 | 'there should be no listeners active' 40 | ); 41 | return true; 42 | } 43 | 44 | describe(__filename, () => { 45 | const config = extend({}, defaultConfig, { 46 | workingDirectory: __dirname, 47 | forceNewAgent_: true, 48 | }); 49 | const logger = consoleLogLevel({ 50 | level: Debuglet.logLevelToName(config.logLevel), 51 | }); 52 | let api: debugapi.DebugApi; 53 | 54 | beforeEach(done => { 55 | if (!api) { 56 | scanner.scan(config.workingDirectory, /.js$/).then(async fileStats => { 57 | assert.strictEqual(fileStats.errors().size, 0); 58 | const jsStats = fileStats.selectStats(/.js$/); 59 | const mapFiles = fileStats.selectFiles(/.map$/, process.cwd()); 60 | const mapper = await SourceMapper.create(mapFiles, logger); 61 | // TODO: Handle the case when mapper is undefined 62 | // TODO: Handle the case when v8debugapi.create returns null 63 | api = debugapi.create( 64 | logger, 65 | config, 66 | jsStats, 67 | mapper as SourceMapper.SourceMapper 68 | ) as debugapi.DebugApi; 69 | assert.ok(api, 'should be able to create the api'); 70 | done(); 71 | }); 72 | } else { 73 | assert(stateIsClean(api)); 74 | done(); 75 | } 76 | }); 77 | afterEach(() => { 78 | assert(stateIsClean(api)); 79 | }); 80 | it('Should read e as the caught error', done => { 81 | // TODO: Have this actually implement Breakpoint 82 | const brk: stackdriver.Breakpoint = { 83 | id: 'fake-id-123', 84 | location: {path: 'test-try-catch-code.js', line: 7}, 85 | } as stackdriver.Breakpoint; 86 | api.set(brk, err1 => { 87 | assert.ifError(err1); 88 | api.wait(brk, err2 => { 89 | assert.ifError(err2); 90 | const frame = brk.stackFrames[0]; 91 | const args = frame.arguments; 92 | const locals = frame.locals; 93 | assert.strictEqual(locals.length, 1, 'There should be one local'); 94 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 95 | const e = locals[0]; 96 | assert(e.name === 'e'); 97 | // Number.isInteger will return false if varTableIndex is `undefined` 98 | assert(Number.isInteger(e.varTableIndex!)); 99 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 100 | api.clear(brk, err3 => { 101 | assert.ifError(err3); 102 | done(); 103 | }); 104 | }); 105 | process.nextTick(foo.bind(null, 'test')); 106 | }); 107 | }); 108 | it('Should read e as the local error', done => { 109 | // TODO: Have this actually implement Breakpoint 110 | const brk: stackdriver.Breakpoint = { 111 | id: 'fake-id-123', 112 | location: {path: 'test-try-catch-code.js', line: 8}, 113 | } as stackdriver.Breakpoint; 114 | api.set(brk, err1 => { 115 | assert.ifError(err1); 116 | api.wait(brk, err2 => { 117 | assert.ifError(err2); 118 | const frame = brk.stackFrames[0]; 119 | const args = frame.arguments; 120 | const locals = frame.locals; 121 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 122 | assert.strictEqual(locals.length, 1, 'There should be one local'); 123 | assert.deepStrictEqual(locals[0], {name: 'e', value: '2'}); 124 | assert.strictEqual(args.length, 0, 'There should be zero arguments'); 125 | api.clear(brk, err3 => { 126 | assert.ifError(err3); 127 | done(); 128 | }); 129 | }); 130 | process.nextTick(foo.bind(null, 'test')); 131 | }); 132 | }); 133 | }); 134 | -------------------------------------------------------------------------------- /test/test-v8debugapi-code.js: -------------------------------------------------------------------------------- 1 | /*1* KEEP THIS CODE AT THE TOP TO AVOID LINE NUMBER CHANGES */ 2 | /*2*/'use strict'; 3 | /*3*/function foo(n) { 4 | /*4*/ // some comments. 5 | /*5*/ var A = [1, 2, 3]; var B = { a: 5, b: 6, c: 7 }; 6 | /*6*/ return n+42+A[0]+B.b; 7 | /*7*/} 8 | /*8*/function getterObject() { 9 | /*9*/ var hasGetter = { _a: 5, get a() { return this._a; }, b: 'hello world' }; 10 | /*10*/ return hasGetter.a; 11 | /*11*/} 12 | /*12*/module.exports = { 13 | /*13*/ foo: foo, 14 | /*14*/ getterObject: getterObject 15 | /*15*/}; 16 | -------------------------------------------------------------------------------- /test/test-v8debugapi-ts-code.ts: -------------------------------------------------------------------------------- 1 | /* 1 TESTS RELY ON THE PRECISE LINE NUMBERS IN THIS FILE */ 2 | /* 2*/ export interface Point { 3 | /* 3*/ x: number; 4 | /* 4*/ y: number; 5 | /* 5*/ 6 | } 7 | /* 6*/ 8 | /* 7*/ export function dist(pt1: Point, pt2: Point) { 9 | /* 8*/ const xdiff = pt1.x - pt2.x; 10 | /* 9*/ const ydiff = pt1.y - pt2.y; 11 | /*10*/ const pnorm1 = Math.abs(xdiff) + Math.abs(ydiff); 12 | /*11*/ const pnorm2 = Math.sqrt(xdiff * xdiff + ydiff * ydiff); 13 | /*12*/ return {pnorm1, pnorm2}; 14 | /*13*/ 15 | } 16 | 17 | /* 18 | * Copyright 2018 Google LLC 19 | * 20 | * Licensed under the Apache License, Version 2.0 (the 'License'); 21 | * you may not use this file except in compliance with the License. 22 | * You may obtain a copy of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an 'AS IS' BASIS, 28 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | * See the License for the specific language governing permissions and 30 | * limitations under the License. 31 | */ 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts/tsconfig-google.json", 3 | "compilerOptions": { 4 | "lib": ["es2018", "dom"], 5 | "rootDir": ".", 6 | "outDir": "build" 7 | }, 8 | "include": [ 9 | "src/*.ts", 10 | "src/**/*.ts", 11 | "test/*.ts", 12 | "test/**/*.ts", 13 | "system-test/*.ts" 14 | ] 15 | } 16 | --------------------------------------------------------------------------------