From 99edb01ad27b297f57d8c76843fb0084c28e1004 Mon Sep 17 00:00:00 2001 From: Sofia Leon Date: Fri, 20 Oct 2023 01:21:42 -0700 Subject: [PATCH] chore: update synthtool to include esm --- synthtool/gcp/common.py | 8 +- .../node_esm_mono_repo_library/.eslintignore | 11 + .../node_esm_mono_repo_library/.eslintrc.json | 3 + .../node_esm_mono_repo_library/.gitattributes | 4 + .../node_esm_mono_repo_library/.mocharc.cjs | 29 + .../node_esm_mono_repo_library/.nycrc | 24 + .../.prettierignore | 6 + .../.prettierrc.cjs | 17 + .../CODE_OF_CONDUCT.md | 94 + .../CONTRIBUTING.md | 76 + .../node_esm_mono_repo_library/LICENSE | 202 + .../node_esm_mono_repo_library/README.md | 174 + .../samples/README.md | 66 + .../index.ts.j2 | 25 + synthtool/languages/node_mono_repo.py | 84 +- .../index_esm_samples/esm/src/index.ts | 28 + .../esm/src/invalid_index/index.ts | 17 + .../index_esm_samples/esm/src/v1/index.ts | 19 + .../index_esm_samples/multiple_index.ts | 20 + .../index_esm_samples/sample_index.ts | 28 + .../index_esm_samples/single_index.ts | 19 + .../.github/.OwlBot.lock.yaml | 4 + .../nodejs_mono_repo_esm/.github/.OwlBot.yaml | 23 + .../nodejs_mono_repo_esm/.github/CODEOWNERS | 9 + .../.github/ISSUE_TEMPLATE/bug_report.md | 38 + .../.github/ISSUE_TEMPLATE/feature_request.md | 18 + .../.github/ISSUE_TEMPLATE/support_request.md | 7 + .../.github/PULL_REQUEST_TEMPLATE.md | 7 + .../.github/release-please.yml | 1 + .../.github/workflows/ci.yaml | 63 + .../.kokoro/.gitattributes | 1 + .../nodejs_mono_repo_esm/.kokoro/common.cfg | 24 + .../.kokoro/continuous/node10/common.cfg | 34 + .../.kokoro/continuous/node10/docs.cfg | 4 + .../.kokoro/continuous/node10/test.cfg | 9 + .../.kokoro/continuous/node12/common.cfg | 24 + .../.kokoro/continuous/node12/lint.cfg | 4 + .../continuous/node12/samples-test.cfg | 7 + .../.kokoro/continuous/node12/system-test.cfg | 7 + .../.kokoro/continuous/node12/test.cfg | 0 .../.kokoro/continuous/node8/common.cfg | 24 + .../.kokoro/continuous/node8/test.cfg | 0 .../nodejs_mono_repo_esm/.kokoro/docs.sh | 25 + .../nodejs_mono_repo_esm/.kokoro/lint.sh | 33 + .../.kokoro/populate-secrets.sh | 76 + .../.kokoro/presubmit/node10/common.cfg | 34 + .../.kokoro/presubmit/node10/docs.cfg | 4 + .../.kokoro/presubmit/node10/lint.cfg | 4 + .../.kokoro/presubmit/node10/test.cfg | 0 .../.kokoro/presubmit/node12/common.cfg | 24 + .../.kokoro/presubmit/node12/samples-test.cfg | 7 + .../.kokoro/presubmit/node12/system-test.cfg | 7 + .../.kokoro/presubmit/node12/test.cfg | 0 .../.kokoro/presubmit/node8/common.cfg | 24 + .../.kokoro/presubmit/node8/test.cfg | 0 .../.kokoro/presubmit/windows/common.cfg | 2 + .../.kokoro/presubmit/windows/test.cfg | 2 + .../nodejs_mono_repo_esm/.kokoro/publish.sh | 31 + .../.kokoro/release/docs-devsite.cfg | 26 + .../.kokoro/release/docs-devsite.sh | 71 + .../.kokoro/release/docs.cfg | 26 + .../.kokoro/release/docs.sh | 50 + .../.kokoro/release/publish.cfg | 70 + .../.kokoro/samples-test.sh | 68 + .../.kokoro/system-test.sh | 61 + .../nodejs_mono_repo_esm/.kokoro/test.bat | 33 + .../nodejs_mono_repo_esm/.kokoro/test.sh | 48 + .../.kokoro/trampoline.sh | 32 + .../.kokoro/trampoline_v2.sh | 490 ++ .../packages/dlp/.eslintignore | 6 + .../packages/dlp/.eslintrc.json | 3 + .../packages/dlp/.gitattributes | 4 + .../packages/dlp/.gitignore | 14 + .../packages/dlp/.jsdoc.cjs | 55 + .../packages/dlp/.mocharc.cjs | 29 + .../nodejs_mono_repo_esm/packages/dlp/.nycrc | 24 + .../packages/dlp/.prettierignore | 6 + .../packages/dlp/.prettierrc.cjs | 17 + .../packages/dlp/.readme-partials.yml | 4 + .../packages/dlp/.repo-metadata.json | 14 + .../packages/dlp/.trampolinerc | 51 + .../packages/dlp/CHANGELOG.md | 399 ++ .../packages/dlp/CODE_OF_CONDUCT.md | 94 + .../packages/dlp/CONTRIBUTING.md | 76 + .../nodejs_mono_repo_esm/packages/dlp/LICENSE | 202 + .../packages/dlp/README.md | 226 + .../packages/dlp/api-extractor.json | 369 + .../packages/dlp/esm/src/index.ts | 27 + .../dlp/esm/src/service_proto_list.json | 1 + .../dlp/esm/src/v2/dlp_service_client.ts | 6109 ++++++++++++++++ .../esm/src/v2/dlp_service_client_config.json | 196 + .../esm/src/v2/dlp_service_proto_list.json | 4 + .../dlp/esm/src/v2/gapic_metadata.json | 383 + .../packages/dlp/esm/src/v2/index.ts | 19 + .../packages/dlp/linkinator.config.json | 10 + .../packages/dlp/package.json | 72 + .../packages/dlp/renovate.json | 19 + .../packages/dlp/samples/.eslintrc.yml | 5 + .../packages/dlp/samples/.gitignore | 3 + .../packages/dlp/samples/README.md | 574 ++ .../dlp/samples/categoricalRiskAnalysis.js | 160 + .../dlp/samples/createInspectTemplate.js | 102 + .../packages/dlp/samples/createTrigger.js | 138 + .../dlp/samples/deidentifyWithDateShift.js | 191 + .../packages/dlp/samples/deidentifyWithFpe.js | 101 + .../dlp/samples/deidentifyWithMask.js | 80 + .../dlp/samples/deidentifyWithReplacement.js | 76 + .../dlp/samples/deleteInspectTemplate.js | 55 + .../packages/dlp/samples/deleteJob.js | 59 + .../packages/dlp/samples/deleteTrigger.js | 54 + .../packages/dlp/samples/inspectBigQuery.js | 195 + .../packages/dlp/samples/inspectDatastore.js | 198 + .../packages/dlp/samples/inspectFile.js | 143 + .../packages/dlp/samples/inspectGCSFile.js | 187 + .../packages/dlp/samples/inspectString.js | 134 + .../dlp/samples/kAnonymityAnalysis.js | 165 + .../dlp/samples/kMapEstimationAnalysis.js | 179 + .../dlp/samples/lDiversityAnalysis.js | 180 + .../dlp/samples/listInspectTemplates.js | 74 + .../packages/dlp/samples/listJobs.js | 62 + .../packages/dlp/samples/listTriggers.js | 69 + .../packages/dlp/samples/metadata.js | 60 + .../dlp/samples/numericalRiskAnalysis.js | 161 + .../packages/dlp/samples/package.json | 30 + .../packages/dlp/samples/quickstart.js | 91 + .../packages/dlp/samples/redactImage.js | 96 + .../packages/dlp/samples/redactText.js | 80 + .../packages/dlp/samples/reidentifyWithFpe.js | 103 + .../dlp/samples/resources/accounts.txt | 1 + .../packages/dlp/samples/resources/dates.csv | 5 + .../dlp/samples/resources/harmless.txt | 1 + .../packages/dlp/samples/resources/test.png | Bin 0 -> 31282 bytes .../packages/dlp/samples/resources/test.txt | 1 + .../dlp/samples/system-test/deid.test.js | 121 + .../dlp/samples/system-test/inspect.test.js | 282 + .../dlp/samples/system-test/jobs.test.js | 158 + .../dlp/samples/system-test/metadata.test.js | 42 + .../samples/system-test/quickstart.test.js | 35 + .../dlp/samples/system-test/redact.test.js | 135 + .../resources/date-shift-context.expected.csv | 5 + .../redact-multiple-types.expected.png | Bin 0 -> 15869 bytes .../resources/redact-single-type.expected.png | Bin 0 -> 21318 bytes .../dlp/samples/system-test/risk.test.js | 208 + .../dlp/samples/system-test/temp.result.csv | 5 + .../dlp/samples/system-test/templates.test.js | 103 + .../dlp/samples/system-test/triggers.test.js | 91 + .../packages/dlp/test/gapic_dlp_service_v2.ts | 6256 +++++++++++++++++ .../packages/dlp/tsconfig.json | 19 + .../packages/dlp/webpack.config.js | 64 + tests/test_node_mono_repo.py | 112 + 150 files changed, 22370 insertions(+), 22 deletions(-) create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.eslintignore create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.eslintrc.json create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.gitattributes create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.mocharc.cjs create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.nycrc create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.prettierignore create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/.prettierrc.cjs create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/CODE_OF_CONDUCT.md create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/CONTRIBUTING.md create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/LICENSE create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/README.md create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_library/samples/README.md create mode 100644 synthtool/gcp/templates/node_esm_mono_repo_split_library/index.ts.j2 create mode 100644 tests/fixtures/node_templates/index_esm_samples/esm/src/index.ts create mode 100644 tests/fixtures/node_templates/index_esm_samples/esm/src/invalid_index/index.ts create mode 100644 tests/fixtures/node_templates/index_esm_samples/esm/src/v1/index.ts create mode 100644 tests/fixtures/node_templates/index_esm_samples/multiple_index.ts create mode 100644 tests/fixtures/node_templates/index_esm_samples/sample_index.ts create mode 100644 tests/fixtures/node_templates/index_esm_samples/single_index.ts create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.lock.yaml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.yaml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/CODEOWNERS create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/support_request.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/release-please.yml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.github/workflows/ci.yaml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/.gitattributes create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/docs.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/lint.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/samples-test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/system-test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/docs.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/lint.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/populate-secrets.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/docs.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/lint.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/samples-test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/system-test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/common.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/test.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/publish.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/publish.cfg create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/samples-test.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/system-test.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.bat create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline_v2.sh create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintignore create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintrc.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitattributes create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitignore create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.jsdoc.cjs create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.mocharc.cjs create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.nycrc create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierignore create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierrc.cjs create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.readme-partials.yml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.repo-metadata.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.trampolinerc create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CHANGELOG.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CODE_OF_CONDUCT.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CONTRIBUTING.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/LICENSE create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/README.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/api-extractor.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/index.ts create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/service_proto_list.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client.ts create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client_config.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_proto_list.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/gapic_metadata.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/index.ts create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/linkinator.config.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/package.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/renovate.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.eslintrc.yml create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.gitignore create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/README.md create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/categoricalRiskAnalysis.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createInspectTemplate.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createTrigger.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithDateShift.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithFpe.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithMask.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithReplacement.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteInspectTemplate.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteJob.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteTrigger.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectBigQuery.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectDatastore.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectFile.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectGCSFile.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectString.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kAnonymityAnalysis.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kMapEstimationAnalysis.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/lDiversityAnalysis.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listInspectTemplates.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listJobs.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listTriggers.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/metadata.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/numericalRiskAnalysis.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/package.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/quickstart.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactImage.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactText.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/reidentifyWithFpe.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/accounts.txt create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/dates.csv create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/harmless.txt create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/test.png create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/test.txt create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/deid.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/inspect.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/jobs.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/metadata.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/quickstart.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/redact.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/date-shift-context.expected.csv create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/redact-multiple-types.expected.png create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/redact-single-type.expected.png create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/risk.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/temp.result.csv create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/templates.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/triggers.test.js create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/test/gapic_dlp_service_v2.ts create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/tsconfig.json create mode 100644 tests/fixtures/nodejs_mono_repo_esm/packages/dlp/webpack.config.js diff --git a/synthtool/gcp/common.py b/synthtool/gcp/common.py index b7a5a59b2..d2169e994 100644 --- a/synthtool/gcp/common.py +++ b/synthtool/gcp/common.py @@ -353,7 +353,7 @@ def node_library(self, **kwargs) -> Path: return self._generic_library("node_library", **kwargs) - def node_mono_repo_library(self, relative_dir, **kwargs) -> Path: + def node_mono_repo_library(self, relative_dir, is_esm=False, **kwargs) -> Path: # TODO: once we've migrated all Node.js repos to either having # .repo-metadata.json, or excluding README.md, we can remove this. if not os.path.exists(Path(relative_dir, ".repo-metadata.json").resolve()): @@ -377,10 +377,14 @@ def node_mono_repo_library(self, relative_dir, **kwargs) -> Path: default_version=kwargs["default_version"], relative_dir=relative_dir, year=str(date.today().year), + is_esm=is_esm, ) + templates_location = ( + "node_mono_repo_library" if not is_esm else "node_esm_mono_repo_library" + ) return self._generic_library( - "node_mono_repo_library", relative_dir=relative_dir, **kwargs + templates_location, relative_dir=relative_dir, **kwargs ) def php_library(self, **kwargs) -> Path: diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintignore b/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintignore new file mode 100644 index 000000000..5d3af467d --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintignore @@ -0,0 +1,11 @@ +**/node_modules +**/coverage +test/fixtures +build/ +docs/ +protos/ +samples/ +esm/src/**/*.d.ts +esm/test/**/*.d.ts +esm/system-test/**/*.d.ts +esm/system-test/fixtures/sample/src/*.ts diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintrc.json b/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintrc.json new file mode 100644 index 000000000..782153495 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/gts" +} diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.gitattributes b/synthtool/gcp/templates/node_esm_mono_repo_library/.gitattributes new file mode 100644 index 000000000..33739cb74 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.gitattributes @@ -0,0 +1,4 @@ +*.ts text eol=lf +*.js text eol=lf +protos/* linguist-generated +**/api-extractor.json linguist-language=JSON-with-Comments diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.mocharc.cjs b/synthtool/gcp/templates/node_esm_mono_repo_library/.mocharc.cjs new file mode 100644 index 000000000..80df58673 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.mocharc.cjs @@ -0,0 +1,29 @@ +// Copyright {{ metadata['year'] }} Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +const config = { + "enable-source-maps": true, + "throw-deprecation": true, + "timeout": 10000, + "recursive": true +} +if (process.env.MOCHA_THROW_DEPRECATION === 'false') { + delete config['throw-deprecation']; +} +if (process.env.MOCHA_REPORTER) { + config.reporter = process.env.MOCHA_REPORTER; +} +if (process.env.MOCHA_REPORTER_OUTPUT) { + config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; +} +module.exports = config diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.nycrc b/synthtool/gcp/templates/node_esm_mono_repo_library/.nycrc new file mode 100644 index 000000000..b18d5472b --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.nycrc @@ -0,0 +1,24 @@ +{ + "report-dir": "./.coverage", + "reporter": ["text", "lcov"], + "exclude": [ + "**/*-test", + "**/.coverage", + "**/apis", + "**/benchmark", + "**/conformance", + "**/docs", + "**/samples", + "**/scripts", + "**/protos", + "**/test", + "**/*.d.ts", + ".jsdoc.js", + "**/.jsdoc.js", + "karma.conf.js", + "webpack-tests.config.js", + "webpack.config.js" + ], + "exclude-after-remap": false, + "all": true +} diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierignore b/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierignore new file mode 100644 index 000000000..9340ad9b8 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierignore @@ -0,0 +1,6 @@ +**/node_modules +**/coverage +test/fixtures +build/ +docs/ +protos/ diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierrc.cjs b/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierrc.cjs new file mode 100644 index 000000000..fd866e54c --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/.prettierrc.cjs @@ -0,0 +1,17 @@ +// Copyright {{ metadata['year'] }} Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +module.exports = { + ...require('gts/.prettierrc.json') +} diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/CODE_OF_CONDUCT.md b/synthtool/gcp/templates/node_esm_mono_repo_library/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..2add2547a --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/CODE_OF_CONDUCT.md @@ -0,0 +1,94 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/CONTRIBUTING.md b/synthtool/gcp/templates/node_esm_mono_repo_library/CONTRIBUTING.md new file mode 100644 index 000000000..e8f43fd39 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/CONTRIBUTING.md @@ -0,0 +1,76 @@ +# How to become a contributor and submit your own code + +**Table of contents** + +* [Contributor License Agreements](#contributor-license-agreements) +* [Contributing a patch](#contributing-a-patch) +* [Running the tests](#running-the-tests) +* [Releasing the library](#releasing-the-library) + +## Contributor License Agreements + +We'd love to accept your sample apps and patches! Before we can take them, we +have to jump a couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement +(CLA). + + * If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). + * If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. Once we receive it, we'll be able to +accept your pull requests. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the repo in question. +1. The repo owner will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a + Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Ensure that your code adheres to the existing style in the code to which + you are contributing. +1. Ensure that your code has an appropriate set of tests which all pass. +1. Title your pull request following [Conventional Commits](https://www.conventionalcommits.org/) styling. +1. Submit a pull request. + +### Before you begin + +1. [Select or create a Cloud Platform project][projects].{% if metadata['repo']['requires_billing'] %} +1. [Enable billing for your project][billing].{% endif %} {% if metadata['repo']['api_id'] %} +1. [Enable the {{ metadata['repo']['name_pretty'] }} API][enable_api]. {% endif %} +1. [Set up authentication with a service account][auth] so you can access the + API from your local workstation. + + +## Running the tests + +1. [Prepare your environment for Node.js setup][setup]. + +1. Install dependencies: + + npm install + +1. Run the tests: + + # Run unit tests. + npm test + + # Run sample integration tests. + npm run samples-test + + # Run all system tests. + npm run system-test + +1. Lint (and maybe fix) any changes: + + npm run fix + +[setup]: https://cloud.google.com/nodejs/docs/setup +[projects]: https://console.cloud.google.com/project +[billing]: https://support.google.com/cloud/answer/6293499#enable-billing +{% if metadata['repo']['api_id'] %}[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid={{ metadata['repo']['api_id'] }}{% endif %} +[auth]: https://cloud.google.com/docs/authentication/getting-started \ No newline at end of file diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/LICENSE b/synthtool/gcp/templates/node_esm_mono_repo_library/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/README.md b/synthtool/gcp/templates/node_esm_mono_repo_library/README.md new file mode 100644 index 000000000..ad876625b --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/README.md @@ -0,0 +1,174 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." +Google Cloud Platform logo + +{% if 'partials' in metadata and metadata['partials']['title'] -%} +{{ metadata['partials']['title'] }} +{% else -%} +# [{{ metadata['repo']['name_pretty'] }}: {{ metadata['repo']['language']|language_pretty }} Client]({{ metadata['homepage'] }}) +{%- endif %} + +{{ metadata['repo']['release_level']|release_quality_badge }} +[![npm version](https://img.shields.io/npm/v/{{ metadata['name'] }}.svg)](https://www.npmjs.org/package/{{ metadata['name'] }}) + +{% if metadata['deprecated'] %} +| :warning: Deprecated Module | +| --- | +| This library is **deprecated**. {{ metadata['deprecated'] }} | +{% endif %} + +{% if 'partials' in metadata and metadata['partials']['introduction'] %} +{{ metadata['partials']['introduction'] }} +{% else %} +{{ metadata['description'] }} +{% endif %} + +A comprehensive list of changes in each version may be found in +[the CHANGELOG]({{ metadata['homepage'] }}/CHANGELOG.md). + +{% if metadata['repo']['client_documentation'] %}* [{{ metadata['repo']['name_pretty'] }} {{ metadata['repo']['language']|language_pretty }} Client API Reference][client-docs]{% endif %} +{% if metadata['repo']['product_documentation'] %}* [{{ metadata['repo']['name_pretty'] }} Documentation][product-docs]{% endif %} +* [github.com/{{ metadata['full_directory_path'] }}]({{ metadata['homepage'] }}) + +Read more about the client libraries for Cloud APIs, including the older +Google APIs Client Libraries, in [Client Libraries Explained][explained]. + +[explained]: https://cloud.google.com/apis/docs/client-libraries-explained + +**Table of contents:** + + +* [Quickstart](#quickstart) +{% if metadata['repo']['api_id'] %} * [Before you begin](#before-you-begin){% endif %} + * [Installing the client library](#installing-the-client-library) +{% if metadata['quickstart'] %} * [Using the client library](#using-the-client-library){% endif %} +{% if metadata['samples']|length %}* [Samples](#samples){% endif %} +* [Versioning](#versioning) +* [Contributing](#contributing) +* [License](#license) + +## Quickstart +{% if metadata['repo']['api_id'] %} +### Before you begin + +1. [Select or create a Cloud Platform project][projects].{% if metadata['repo']['requires_billing'] %} +1. [Enable billing for your project][billing].{% endif %} +1. [Enable the {{ metadata['repo']['name_pretty'] }} API][enable_api]. +1. [Set up authentication with a service account][auth] so you can access the + API from your local workstation. +{% endif %} +### Installing the client library + +```bash +{{ metadata['lib_install_cmd'] }} +``` + +{% if metadata['quickstart'] %} +### Using the client library + +```{{ metadata['repo']['language']|syntax_highlighter }} +{{ metadata['quickstart'] }} +``` +{% endif %}{% if 'partials' in metadata and metadata['partials']['body'] %}{{ metadata['partials']['body'] }}{% endif %} + +{% if metadata['samples']|length %} +## Samples + +Samples are in the [`samples/`]({{ metadata['homepage'] }}/samples) directory. Each sample's `README.md` has instructions for running its sample. + +| Sample | Source Code | Try it | +| --------------------------- | --------------------------------- | ------ | +{% for sample in metadata['samples'] %}| {{ sample.title }} | [source code](https://github.com/{{ metadata['repo']['repo'] }}/blob/{{ metadata['repo']['default_branch'] }}/{{ sample.file }}) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor={{ sample.file }},{{ metadata['directory_path'] }}/samples/README.md) | +{% endfor %} +{% endif %} +{% if metadata['repo']['client_documentation'] %} +The [{{ metadata['repo']['name_pretty'] }} {{ metadata['repo']['language']|language_pretty }} Client API Reference][client-docs] documentation +also contains samples. +{% endif %} +## Supported Node.js Versions + +Our client libraries follow the [Node.js release schedule](https://github.com/nodejs/release#release-schedule). +Libraries are compatible with all current _active_ and _maintenance_ versions of +Node.js. +If you are using an end-of-life version of Node.js, we recommend that you update +as soon as possible to an actively supported LTS version. + +Google's client libraries support legacy versions of Node.js runtimes on a +best-efforts basis with the following warnings: + +* Legacy versions are not tested in continuous integration. +* Some security patches and features cannot be backported. +* Dependencies cannot be kept up-to-date. + +Client libraries targeting some end-of-life versions of Node.js are available, and +can be installed through npm [dist-tags](https://docs.npmjs.com/cli/dist-tag). +The dist-tags follow the naming convention `legacy-(version)`. +For example, `{{ metadata['lib_install_cmd'] }}@legacy-8` installs client libraries +for versions compatible with Node.js 8. + +## Versioning + +This library follows [Semantic Versioning](http://semver.org/). + +{% if metadata['repo']['release_level'] == 'ga' %} +This library is considered to be **General Availability (GA)**. This means it +is stable; the code surface will not change in backwards-incompatible ways +unless absolutely necessary (e.g. because of critical security issues) or with +an extensive deprecation period. Issues and requests against **GA** libraries +are addressed with the highest priority. +{% endif %} +{% if metadata['repo']['release_level'] == 'stable' %} +This library is considered to be **stable**. The code surface will not change in backwards-incompatible ways +unless absolutely necessary (e.g. because of critical security issues) or with +an extensive deprecation period. Issues and requests against **stable** libraries +are addressed with the highest priority. +{% endif %} +{% if metadata['repo']['release_level'] == 'beta' %} +This library is considered to be in **beta**. This means it is expected to be +mostly stable while we work toward a general availability release; however, +complete stability is not guaranteed. We will address issues and requests +against beta libraries with a high priority. +{% endif %} +{% if metadata['repo']['release_level'] == 'alpha' %} +This library is considered to be in **alpha**. This means it is still a +work-in-progress and under active development. Any release is subject to +backwards-incompatible changes at any time. +{% endif %} +{% if metadata['release_level'] == 'deprecated' %} +This library is **deprecated**. This means that it is no longer being +actively maintained and the only updates the library will receive will +be for critical security issues. {% if metadata['deprecated'] %}{{ metadata['deprecated'] }}{% endif %} +{% endif %} +{% if metadata['repo']['release_level'] == 'preview' %} +This library is considered to be in **preview**. This means it is still a +work-in-progress and under active development. Any release is subject to +backwards-incompatible changes at any time. +{% endif %} + +More Information: [Google Cloud Platform Launch Stages][launch_stages] + +[launch_stages]: https://cloud.google.com/terms/launch-stages + +## Contributing + +Contributions welcome! See the [Contributing Guide](https://github.com/{{ metadata['repo']['repo'] }}/blob/{{ metadata['repo']['default_branch'] }}/CONTRIBUTING.md). + +Please note that this `README.md`, the `samples/README.md`, +and a variety of configuration files in this repository (including `.nycrc` and `tsconfig.json`) +are generated from a central template. To edit one of these files, make an edit +to its templates in +[directory](https://github.com/googleapis/synthtool). + +## License + +Apache Version 2.0 + +See [LICENSE](https://github.com/{{ metadata['repo']['repo'] }}/blob/{{ metadata['repo']['default_branch'] }}/LICENSE) + +{% if metadata['repo']['client_documentation'] %}[client-docs]: {{ metadata['repo']['client_documentation'] }}{% endif %} +{% if metadata['repo']['product_documentation'] %}[product-docs]: {{ metadata['repo']['product_documentation'] }}{% endif %} +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png +[projects]: https://console.cloud.google.com/project +[billing]: https://support.google.com/cloud/answer/6293499#enable-billing +{% if metadata['repo']['api_id'] %}[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid={{ metadata['repo']['api_id'] }}{% endif %} +[auth]: https://cloud.google.com/docs/authentication/getting-started diff --git a/synthtool/gcp/templates/node_esm_mono_repo_library/samples/README.md b/synthtool/gcp/templates/node_esm_mono_repo_library/samples/README.md new file mode 100644 index 000000000..d7d698549 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_library/samples/README.md @@ -0,0 +1,66 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." +Google Cloud Platform logo + +{% if 'partials' in metadata and metadata['partials']['title'] -%} +{{ metadata['partials']['title'] }} Samples +{% else -%} +# [{{ metadata['repo']['name_pretty'] }}: {{ metadata['repo']['language']|language_pretty }} Samples](https://github.com/{{ metadata['repo']['repo'] }}) +{%- endif %} + +[![Open in Cloud Shell][shell_img]][shell_link] + +{% if metadata['partials'] and metadata['partials']['introduction'] %}{{ metadata['partials']['introduction'] }}{% endif %} + +## Table of Contents + +* [Before you begin](#before-you-begin) +* [Samples](#samples){% if metadata['samples']|length %}{% for sample in metadata['samples'] %} + * [{{ sample.title }}](#{{ sample.title|slugify }}){% endfor %}{% endif %} + +## Before you begin + +Before running the samples, make sure you've followed the steps outlined in +[Using the client library](https://github.com/{{ metadata['repo']['repo'] }}#using-the-client-library). + +{% if 'partials' in metadata and metadata['partials']['samples_body'] %}{{ metadata['partials']['samples_body'] }} + +{% endif -%} + +`cd samples` + +`npm install` + +`cd ..` + +## Samples +{% if metadata['samples']|length %} +{% for sample in metadata['samples'] %} + +### {{sample.title}} + +{%- if 'description' in sample %} + +{{ sample.description }} + +{%- endif %} + +View the [source code](https://github.com/{{ metadata['repo']['repo'] }}/blob/{{ metadata['repo']['default_branch'] }}/{{ sample.file }}). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor={{ sample.file }},samples/README.md) + +__Usage:__ + + +{% if 'usage' in sample %}`{{ sample.usage }}`{% else %}`node {{ sample.file }}`{% endif %} + +{% if not loop.last %} +----- +{% endif %} + +{% endfor %} +{% endif %} + +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png +[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor=samples/README.md +[product-docs]: {{ metadata['repo']['product_documentation'] }} diff --git a/synthtool/gcp/templates/node_esm_mono_repo_split_library/index.ts.j2 b/synthtool/gcp/templates/node_esm_mono_repo_split_library/index.ts.j2 new file mode 100644 index 000000000..1f20c3f83 --- /dev/null +++ b/synthtool/gcp/templates/node_esm_mono_repo_split_library/index.ts.j2 @@ -0,0 +1,25 @@ +// Copyright {{year}} Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by synthtool. ** +// ** https://github.com/googleapis/synthtool ** +// ** All changes to this file may be overwritten. ** + +{% for version in versions %}import * as {{ version }} from './{{ version}}.js';{{ "\n" }}{% endfor %} +{% for client in clients %}const {{ client }} = {{ default_version }}.{{ client }}; +type {{ client }} = {{ default_version }}.{{ client }};{{ "\n" }}{% endfor %} +export {{ "{" }}{{ versions|join(', ')}}, {{ clients|join(', ')}}{{ "}" }}; +export default {{ "{" }}{{ versions|join(', ')}}, {{ clients|join(', ')}}{{ "}" }}; +import * as protos from '../../protos/protos.js'; +export {protos}; diff --git a/synthtool/languages/node_mono_repo.py b/synthtool/languages/node_mono_repo.py index 9ceb87481..74191d2c1 100644 --- a/synthtool/languages/node_mono_repo.py +++ b/synthtool/languages/node_mono_repo.py @@ -186,7 +186,11 @@ def extract_clients(filePath: Path) -> List[str]: def generate_index_ts( - versions: List[str], default_version: str, relative_dir: str, year: str + versions: List[str], + default_version: str, + relative_dir: str, + year: str, + is_esm=False, ) -> None: """ generate src/index.ts to export the client name and versions in the client library. @@ -214,7 +218,15 @@ def generate_index_ts( # compose default version's index.ts file path versioned_index_ts_path = ( - Path(relative_dir) / Path("src") / default_version / "index.ts" + (Path(relative_dir) / Path("src") / default_version / "index.ts") + if not is_esm + else ( + Path(relative_dir) + / Path("esm") + / Path("src") + / default_version + / "index.ts" + ) ) clients = extract_clients(versioned_index_ts_path) if not clients: @@ -224,11 +236,21 @@ def generate_index_ts( # compose template directory template_path = ( - Path(__file__).parent.parent - / "gcp" - / "templates" - / "node_mono_repo_split_library" + ( + Path(__file__).parent.parent + / "gcp" + / "templates" + / "node_mono_repo_split_library" + ) + if not is_esm + else ( + Path(__file__).parent.parent + / "gcp" + / "templates" + / "node_esm_mono_repo_split_library" + ) ) + template_loader = FileSystemLoader(searchpath=str(template_path)) template_env = Environment(loader=template_loader, keep_trailing_newline=True) TEMPLATE_FILE = "index.ts.j2" @@ -237,7 +259,12 @@ def generate_index_ts( output_text = index_template.render( versions=versions, default_version=default_version, clients=clients, year=year ) - with open(Path(relative_dir, "src/index.ts").resolve(), "w") as fh: + index_ts_path = ( + Path(relative_dir, "src/index.ts").resolve() + if not is_esm + else Path(relative_dir, "esm", "src/index.ts").resolve() + ) + with open(Path(relative_dir, index_ts_path).resolve(), "w") as fh: fh.write(output_text) logger.info("successfully generate `src/index.ts`") @@ -308,46 +335,56 @@ def fix_hermetic(relative_dir, hide_output=False): ) -def compile_protos(hide_output=False): +def compile_protos(hide_output=False, is_esm=False): """ Compiles protos into .json, .js, and .d.ts files using compileProtos script from google-gax. """ logger.debug("Compiling protos...") - shell.run(["npx", "compileProtos", "src"], hide_output=hide_output) + command = ( + ["npx", "compileProtos", "src"] + if not is_esm + else ["npx", "compileProtos", "esm/src", "--esm"] + ) + shell.run(command, hide_output=hide_output) -def compile_protos_hermetic(relative_dir, hide_output=False): +def compile_protos_hermetic(relative_dir, is_esm=False, hide_output=False): """ Compiles protos into .json, .js, and .d.ts files using compileProtos script from google-gax. Assumes that compileProtos is already installed in a well known location on disk (node_modules/.bin). """ logger.debug("Compiling protos...") + command = ( + [f"{_TOOLS_DIRECTORY}/node_modules/.bin/compileProtos", "esm/src", "--esm"] + if not is_esm + else [f"{_TOOLS_DIRECTORY}/node_modules/.bin/compileProtos", "esm/src", "--esm"] + ) shell.run( - [f"{_TOOLS_DIRECTORY}/node_modules/.bin/compileProtos", "src"], + command, cwd=relative_dir, check=True, hide_output=hide_output, ) -def postprocess_gapic_library(hide_output=False): +def postprocess_gapic_library(hide_output=False, is_esm=False): logger.debug("Post-processing GAPIC library...") install(hide_output=hide_output) fix(hide_output=hide_output) - compile_protos(hide_output=hide_output) + compile_protos(hide_output=hide_output, is_esm=is_esm) logger.debug("Post-processing completed") -def postprocess_gapic_library_hermetic(relative_dir, hide_output=False): +def postprocess_gapic_library_hermetic(relative_dir, hide_output=False, is_esm=False): logger.debug("Post-processing GAPIC library...") fix_hermetic(relative_dir, hide_output=hide_output) - compile_protos_hermetic(relative_dir, hide_output=hide_output) + compile_protos_hermetic(relative_dir, hide_output=hide_output, is_esm=is_esm) logger.debug("Post-processing completed") -default_staging_excludes = ["package.json", "src/index.ts"] +default_staging_excludes = ["package.json", "src/index.ts", "esm/src/index.ts"] default_templates_excludes: List[str] = [] @@ -444,6 +481,13 @@ def owlbot_main( default_version = json.load( open(Path(relative_dir, ".repo-metadata.json").resolve(), "rt") ).get("default_version") + is_esm = False + src = Path(Path(relative_dir), "src").resolve() + source_location = "build/src" + if (Path(Path(relative_dir), "esm", "src").resolve()).is_dir(): + is_esm = True + src = Path(Path(relative_dir), "esm", "src").resolve() + source_location = "build/esm/src" staging = Path("owl-bot-staging", Path(relative_dir).name).resolve() s_copy = transforms.move if default_version is None: @@ -466,7 +510,6 @@ def owlbot_main( shutil.rmtree(staging) else: # Collect the subdirectories of the src directory. - src = Path(Path(relative_dir), "src").resolve() versions = [v.name for v in src.iterdir() if v.is_dir()] # Reorder the versions so the default version always comes last. versions = [v for v in versions if v != default_version] + [default_version] @@ -477,15 +520,16 @@ def owlbot_main( if default_version: templates = common_templates.node_mono_repo_library( relative_dir=relative_dir, - source_location="build/src", + source_location=source_location, versions=versions, default_version=default_version, + is_esm=is_esm, ) s_copy([templates], destination=relative_dir, excludes=templates_excludes) - postprocess_gapic_library_hermetic(relative_dir=relative_dir) + postprocess_gapic_library_hermetic(relative_dir=relative_dir, is_esm=is_esm) else: templates = common_templates.node_mono_repo_library( - relative_dir=relative_dir, source_location="build/src" + relative_dir=relative_dir, source_location=source_location ) s_copy([templates], destination=relative_dir, excludes=templates_excludes) diff --git a/tests/fixtures/node_templates/index_esm_samples/esm/src/index.ts b/tests/fixtures/node_templates/index_esm_samples/esm/src/index.ts new file mode 100644 index 000000000..bcbcd1679 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/esm/src/index.ts @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by synthtool. ** +// ** https://github.com/googleapis/synthtool ** +// ** All changes to this file may be overwritten. ** + +import * as v1 from './v1.js'; +import * as v1beta1 from './v1beta1.js'; + +const TextToSpeechClient = v1.TextToSpeechClient; +type TextToSpeechClient = v1.TextToSpeechClient; + +export {v1, v1beta1, TextToSpeechClient}; +export default {v1, v1beta1, TextToSpeechClient}; +import * as protos from '../../protos/protos.js'; +export {protos}; diff --git a/tests/fixtures/node_templates/index_esm_samples/esm/src/invalid_index/index.ts b/tests/fixtures/node_templates/index_esm_samples/esm/src/invalid_index/index.ts new file mode 100644 index 000000000..aaf15e588 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/esm/src/invalid_index/index.ts @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** diff --git a/tests/fixtures/node_templates/index_esm_samples/esm/src/v1/index.ts b/tests/fixtures/node_templates/index_esm_samples/esm/src/v1/index.ts new file mode 100644 index 000000000..8d9f10083 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/esm/src/v1/index.ts @@ -0,0 +1,19 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +export {TextToSpeechClient} from './text_to_speech_client'; diff --git a/tests/fixtures/node_templates/index_esm_samples/multiple_index.ts b/tests/fixtures/node_templates/index_esm_samples/multiple_index.ts new file mode 100644 index 000000000..949a15228 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/multiple_index.ts @@ -0,0 +1,20 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +export {StreamingVideoIntelligenceServiceClient} from './streaming_video_intelligence_service_client'; +export {VideoIntelligenceServiceClient} from './video_intelligence_service_client'; diff --git a/tests/fixtures/node_templates/index_esm_samples/sample_index.ts b/tests/fixtures/node_templates/index_esm_samples/sample_index.ts new file mode 100644 index 000000000..bcbcd1679 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/sample_index.ts @@ -0,0 +1,28 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by synthtool. ** +// ** https://github.com/googleapis/synthtool ** +// ** All changes to this file may be overwritten. ** + +import * as v1 from './v1.js'; +import * as v1beta1 from './v1beta1.js'; + +const TextToSpeechClient = v1.TextToSpeechClient; +type TextToSpeechClient = v1.TextToSpeechClient; + +export {v1, v1beta1, TextToSpeechClient}; +export default {v1, v1beta1, TextToSpeechClient}; +import * as protos from '../../protos/protos.js'; +export {protos}; diff --git a/tests/fixtures/node_templates/index_esm_samples/single_index.ts b/tests/fixtures/node_templates/index_esm_samples/single_index.ts new file mode 100644 index 000000000..8d9f10083 --- /dev/null +++ b/tests/fixtures/node_templates/index_esm_samples/single_index.ts @@ -0,0 +1,19 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +export {TextToSpeechClient} from './text_to_speech_client'; diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.lock.yaml b/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.lock.yaml new file mode 100644 index 000000000..a7f1dde89 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.lock.yaml @@ -0,0 +1,4 @@ +docker: + digest: sha256:b317576c0e66d348ab6c1ae50dc43405df37f957b58433c988c1e9ca257ba3d4 + image: gcr.io/repo-automation-bots/owlbot-nodejs:latest + diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.yaml b/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.yaml new file mode 100644 index 000000000..f16929608 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/.OwlBot.yaml @@ -0,0 +1,23 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +docker: + image: gcr.io/repo-automation-bots/owlbot-nodejs:latest + +deep-remove-regex: + - /owl-bot-staging + +deep-copy-regex: + - source: /google/privacy/dlp/(.*)/.*-nodejs/(.*) + dest: /owl-bot-staging/$1/$2 + diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/CODEOWNERS b/tests/fixtures/nodejs_mono_repo_esm/.github/CODEOWNERS new file mode 100644 index 000000000..d904d1e2b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/CODEOWNERS @@ -0,0 +1,9 @@ +# Code owners file. +# This file controls who is tagged for review for any given pull request. +# +# For syntax help see: +# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax + + +# The yoshi-nodejs team is the default owner for nodejs repositories. +* @googleapis/yoshi-nodejs diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/bug_report.md b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..5996924b2 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +Thanks for stopping by to let us know something could be better! + +**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. + +1) Is this a client library issue or a product issue? +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. + +2) Did someone already solve this? + - Search the issues already opened: https://github.com/googleapis/nodejs-dlp/issues + - Search the issues on our "catch-all" repository: https://github.com/googleapis/google-cloud-node + - Search or ask on StackOverflow (engineers monitor these tags): http://stackoverflow.com/questions/tagged/google-cloud-platform+node.js + +3) Do you have a support contract? +Please create an issue in the [support console](https://cloud.google.com/support/) to ensure a timely response. + +If the support paths suggested above still do not result in a resolution, please provide the following details. + +#### Environment details + + - OS: + - Node.js version: + - npm version: + - `@google-cloud/dlp` version: + +#### Steps to reproduce + + 1. ? + 2. ? + +Making sure to follow these steps will guarantee the quickest resolution possible. + +Thanks! diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/feature_request.md b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..6365857f3 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Suggest an idea for this library + +--- + +Thanks for stopping by to let us know something could be better! + +**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. + + **Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + **Describe the solution you'd like** +A clear and concise description of what you want to happen. + **Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + **Additional context** +Add any other context or screenshots about the feature request here. diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/support_request.md b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/support_request.md new file mode 100644 index 000000000..995869032 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/ISSUE_TEMPLATE/support_request.md @@ -0,0 +1,7 @@ +--- +name: Support request +about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. + +--- + +**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. diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/PULL_REQUEST_TEMPLATE.md b/tests/fixtures/nodejs_mono_repo_esm/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..bff0975de --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +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: +- [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/nodejs-dlp/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea +- [ ] Ensure the tests and linter pass +- [ ] Code coverage does not decrease (if any source code was changed) +- [ ] Appropriate docs were updated (if necessary) + +Fixes # 🦕 diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/release-please.yml b/tests/fixtures/nodejs_mono_repo_esm/.github/release-please.yml new file mode 100644 index 000000000..85344b92c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/release-please.yml @@ -0,0 +1 @@ +releaseType: node diff --git a/tests/fixtures/nodejs_mono_repo_esm/.github/workflows/ci.yaml b/tests/fixtures/nodejs_mono_repo_esm/.github/workflows/ci.yaml new file mode 100644 index 000000000..891c92531 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.github/workflows/ci.yaml @@ -0,0 +1,63 @@ +on: + push: + branches: + - master + pull_request: +name: ci +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node: [10, 12, 14, 15] + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - run: node --version + # The first installation step ensures that all of our production + # dependencies work on the given Node.js version, this helps us find + # dependencies that don't match our engines field: + - run: npm install --production --engine-strict --ignore-scripts --no-package-lock + # Clean up the production install, before installing dev/production: + - run: rm -rf node_modules + - run: npm install + - run: npm test + - name: coverage + uses: codecov/codecov-action@v1 + with: + name: actions ${{ matrix.node }} + fail_ci_if_error: false + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - run: npm install + - run: npm test + - name: coverage + uses: codecov/codecov-action@v1 + with: + name: actions windows + fail_ci_if_error: false + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - run: npm install + - run: npm run lint + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - run: npm install + - run: npm run docs-test diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/.gitattributes b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/.gitattributes new file mode 100644 index 000000000..87acd4f48 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/.gitattributes @@ -0,0 +1 @@ +* linguist-generated=true diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/common.cfg new file mode 100644 index 000000000..e1764896d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/common.cfg new file mode 100644 index 000000000..6ac8b0387 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Bring in codecov.io master token into the build as $KOKORO_KEYSTORE_DIR/73713_dpebot_codecov_token +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "dpebot_codecov_token" + } + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/docs.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/docs.cfg new file mode 100644 index 000000000..4e6b33beb --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/docs.cfg @@ -0,0 +1,4 @@ +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/docs.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/test.cfg new file mode 100644 index 000000000..468b8c719 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node10/test.cfg @@ -0,0 +1,9 @@ +# Bring in codecov.io master token into the build as $KOKORO_KEYSTORE_DIR/73713_dpebot_codecov_token +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "dpebot_codecov_token" + } + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/common.cfg new file mode 100644 index 000000000..bf4d3661f --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/lint.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/lint.cfg new file mode 100644 index 000000000..2bf8333fc --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/lint.cfg @@ -0,0 +1,4 @@ +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/lint.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/samples-test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/samples-test.cfg new file mode 100644 index 000000000..52157942d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/samples-test.cfg @@ -0,0 +1,7 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/samples-test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/system-test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/system-test.cfg new file mode 100644 index 000000000..769c7afc3 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/system-test.cfg @@ -0,0 +1,7 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/system-test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node12/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/common.cfg new file mode 100644 index 000000000..351e2e983 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:8-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/continuous/node8/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/docs.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/docs.sh new file mode 100644 index 000000000..85901242b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/docs.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +cd $(dirname $0)/.. + +npm install + +npm run docs-test diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/lint.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/lint.sh new file mode 100644 index 000000000..aef4866e4 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/lint.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +cd $(dirname $0)/.. + +npm install + +# Install and link samples +if [ -f samples/package.json ]; then + cd samples/ + npm link ../ + npm install + cd .. +fi + +npm run lint diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/populate-secrets.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/populate-secrets.sh new file mode 100644 index 000000000..deb2b199e --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/populate-secrets.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# Copyright 2020 Google LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is called in the early stage of `trampoline_v2.sh` to +# populate secrets needed for the CI builds. + +set -eo pipefail + +function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} +function msg { println "$*" >&2 ;} +function println { printf '%s\n' "$(now) $*" ;} + +# Populates requested secrets set in SECRET_MANAGER_KEYS + +# In Kokoro CI builds, we use the service account attached to the +# Kokoro VM. This means we need to setup auth on other CI systems. +# For local run, we just use the gcloud command for retrieving the +# secrets. + +if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then + GCLOUD_COMMANDS=( + "docker" + "run" + "--entrypoint=gcloud" + "--volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR}" + "gcr.io/google.com/cloudsdktool/cloud-sdk" + ) + if [[ "${TRAMPOLINE_CI:-}" == "kokoro" ]]; then + SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" + else + echo "Authentication for this CI system is not implemented yet." + exit 2 + # TODO: Determine appropriate SECRET_LOCATION and the GCLOUD_COMMANDS. + fi +else + # For local run, use /dev/shm or temporary directory for + # KOKORO_GFILE_DIR. + if [[ -d "/dev/shm" ]]; then + export KOKORO_GFILE_DIR=/dev/shm + else + export KOKORO_GFILE_DIR=$(mktemp -d -t ci-XXXXXXXX) + fi + SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" + GCLOUD_COMMANDS=("gcloud") +fi + +msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" +mkdir -p ${SECRET_LOCATION} + +for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") +do + msg "Retrieving secret ${key}" + "${GCLOUD_COMMANDS[@]}" \ + secrets versions access latest \ + --project cloud-devrel-kokoro-resources \ + --secret $key > \ + "$SECRET_LOCATION/$key" + if [[ $? == 0 ]]; then + msg "Secret written to ${SECRET_LOCATION}/${key}" + else + msg "Error retrieving secret ${key}" + exit 2 + fi +done diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/common.cfg new file mode 100644 index 000000000..6ac8b0387 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Bring in codecov.io master token into the build as $KOKORO_KEYSTORE_DIR/73713_dpebot_codecov_token +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "dpebot_codecov_token" + } + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/docs.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/docs.cfg new file mode 100644 index 000000000..4e6b33beb --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/docs.cfg @@ -0,0 +1,4 @@ +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/docs.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/lint.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/lint.cfg new file mode 100644 index 000000000..2bf8333fc --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/lint.cfg @@ -0,0 +1,4 @@ +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/lint.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node10/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/common.cfg new file mode 100644 index 000000000..bf4d3661f --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/samples-test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/samples-test.cfg new file mode 100644 index 000000000..52157942d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/samples-test.cfg @@ -0,0 +1,7 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/samples-test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/system-test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/system-test.cfg new file mode 100644 index 000000000..769c7afc3 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/system-test.cfg @@ -0,0 +1,7 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/system-test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node12/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/common.cfg new file mode 100644 index 000000000..351e2e983 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:8-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/test.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/node8/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/common.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/common.cfg new file mode 100644 index 000000000..d6e25e0b1 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/common.cfg @@ -0,0 +1,2 @@ +# Format: //devtools/kokoro/config/proto/build.proto + diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/test.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/test.cfg new file mode 100644 index 000000000..c698bb86c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/presubmit/windows/test.cfg @@ -0,0 +1,2 @@ +# Use the test file directly +build_file: "nodejs-dlp/.kokoro/test.bat" diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/publish.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/publish.sh new file mode 100644 index 000000000..4db6bf1c7 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/publish.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +# Start the releasetool reporter +python3 -m pip install gcp-releasetool +python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script + +cd $(dirname $0)/.. + +NPM_TOKEN=$(cat $KOKORO_GFILE_DIR/secret_manager/npm_publish_token) +echo "//wombat-dressing-room.appspot.com/:_authToken=${NPM_TOKEN}" > ~/.npmrc + +npm install +npm publish --access=public --registry=https://wombat-dressing-room.appspot.com diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.cfg new file mode 100644 index 000000000..5ada1865d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.cfg @@ -0,0 +1,26 @@ +# service account used to publish up-to-date docs. +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "docuploader_service_account" + } + } +} + +# doc publications use a Python image. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/release/docs-devsite.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.sh new file mode 100644 index 000000000..7657be337 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs-devsite.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +# build jsdocs (Python is installed on the Node 10 docker image). +if [[ -z "$CREDENTIALS" ]]; then + # if CREDENTIALS are explicitly set, assume we're testing locally + # and don't set NPM_CONFIG_PREFIX. + export NPM_CONFIG_PREFIX=${HOME}/.npm-global + export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" + cd $(dirname $0)/../.. +fi + +mkdir ./etc + +npm install +npm run api-extractor +npm run api-documenter + +npm i json@9.0.6 -g +NAME=$(cat .repo-metadata.json | json name) + +mkdir ./_devsite +cp ./yaml/$NAME/* ./_devsite + +# Clean up TOC +# Delete SharePoint item, see https://github.com/microsoft/rushstack/issues/1229 +sed -i -e '1,3d' ./yaml/toc.yml +sed -i -e 's/^ //' ./yaml/toc.yml +# Delete interfaces from TOC (name and uid) +sed -i -e '/name: I[A-Z]/{N;d;}' ./yaml/toc.yml +sed -i -e '/^ *\@google-cloud.*:interface/d' ./yaml/toc.yml + +cp ./yaml/toc.yml ./_devsite/toc.yml + +# create docs.metadata, based on package.json and .repo-metadata.json. +pip install -U pip +python3 -m pip install --user gcp-docuploader +python3 -m docuploader create-metadata \ + --name=$NAME \ + --version=$(cat package.json | json version) \ + --language=$(cat .repo-metadata.json | json language) \ + --distribution-name=$(cat .repo-metadata.json | json distribution_name) \ + --product-page=$(cat .repo-metadata.json | json product_documentation) \ + --github-repository=$(cat .repo-metadata.json | json repo) \ + --issue-tracker=$(cat .repo-metadata.json | json issue_tracker) +cp docs.metadata ./_devsite/docs.metadata + +# deploy the docs. +if [[ -z "$CREDENTIALS" ]]; then + CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account +fi +if [[ -z "$BUCKET" ]]; then + BUCKET=docs-staging-v2 +fi + +python3 -m docuploader upload ./_devsite --destination-prefix docfx --credentials $CREDENTIALS --staging-bucket $BUCKET diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.cfg new file mode 100644 index 000000000..370d49c11 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.cfg @@ -0,0 +1,26 @@ +# service account used to publish up-to-date docs. +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "docuploader_service_account" + } + } +} + +# doc publications use a Python image. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user" +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/release/docs.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.sh new file mode 100644 index 000000000..4c866c860 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/docs.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +# build jsdocs (Python is installed on the Node 10 docker image). +if [[ -z "$CREDENTIALS" ]]; then + # if CREDENTIALS are explicitly set, assume we're testing locally + # and don't set NPM_CONFIG_PREFIX. + export NPM_CONFIG_PREFIX=${HOME}/.npm-global + export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" + cd $(dirname $0)/../.. +fi +npm install +npm run docs + +# create docs.metadata, based on package.json and .repo-metadata.json. +npm i json@9.0.6 -g +python3 -m pip install --user gcp-docuploader +python3 -m docuploader create-metadata \ + --name=$(cat .repo-metadata.json | json name) \ + --version=$(cat package.json | json version) \ + --language=$(cat .repo-metadata.json | json language) \ + --distribution-name=$(cat .repo-metadata.json | json distribution_name) \ + --product-page=$(cat .repo-metadata.json | json product_documentation) \ + --github-repository=$(cat .repo-metadata.json | json repo) \ + --issue-tracker=$(cat .repo-metadata.json | json issue_tracker) +cp docs.metadata ./docs/docs.metadata + +# deploy the docs. +if [[ -z "$CREDENTIALS" ]]; then + CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account +fi +if [[ -z "$BUCKET" ]]; then + BUCKET=docs-staging +fi +python3 -m docuploader upload ./docs --credentials $CREDENTIALS --staging-bucket $BUCKET diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/publish.cfg b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/publish.cfg new file mode 100644 index 000000000..061f3c242 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/release/publish.cfg @@ -0,0 +1,70 @@ +# Get npm token from Keystore +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "google_cloud_npm_token" + backend_type: FASTCONFIGPUSH + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "yoshi-automation-github-key" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "docuploader_service_account" + } + } +} + +# Fetch magictoken to use with Magic Github Proxy +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "releasetool-magictoken" + } + } +} + +# Fetch api key to use with Magic Github Proxy +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "magic-github-proxy-api-key" + } + } +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "npm_publish_token,releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "nodejs-dlp/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/nodejs-dlp/.kokoro/publish.sh" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/samples-test.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/samples-test.sh new file mode 100644 index 000000000..950f84834 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/samples-test.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +# Setup service account credentials. +export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json +export GCLOUD_PROJECT=long-door-651 + +cd $(dirname $0)/.. + +# Run a pre-test hook, if a pre-samples-test.sh is in the project +if [ -f .kokoro/pre-samples-test.sh ]; then + set +x + . .kokoro/pre-samples-test.sh + set -x +fi + +if [ -f samples/package.json ]; then + npm install + + # Install and link samples + cd samples/ + npm link ../ + npm install + cd .. + # If tests are running against master, configure flakybot + # to open issues on failures: + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP + fi + + npm run samples-test +fi + +# codecov combines coverage across integration and unit tests. Include +# the logic below for any environment you wish to collect coverage for: +COVERAGE_NODE=10 +if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then + NYC_BIN=./node_modules/nyc/bin/nyc.js + if [ -f "$NYC_BIN" ]; then + $NYC_BIN report || true + fi + bash $KOKORO_GFILE_DIR/codecov.sh +else + echo "coverage is only reported for Node $COVERAGE_NODE" +fi diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/system-test.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/system-test.sh new file mode 100644 index 000000000..319d1e0ed --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/system-test.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +# Setup service account credentials. +export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json +export GCLOUD_PROJECT=long-door-651 + +cd $(dirname $0)/.. + +# Run a pre-test hook, if a pre-system-test.sh is in the project +if [ -f .kokoro/pre-system-test.sh ]; then + set +x + . .kokoro/pre-system-test.sh + set -x +fi + +npm install + +# If tests are running against master, configure flakybot +# to open issues on failures: +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP +fi + +npm run system-test + +# codecov combines coverage across integration and unit tests. Include +# the logic below for any environment you wish to collect coverage for: +COVERAGE_NODE=10 +if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then + NYC_BIN=./node_modules/nyc/bin/nyc.js + if [ -f "$NYC_BIN" ]; then + $NYC_BIN report || true + fi + bash $KOKORO_GFILE_DIR/codecov.sh +else + echo "coverage is only reported for Node $COVERAGE_NODE" +fi diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.bat b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.bat new file mode 100644 index 000000000..ae59e59be --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.bat @@ -0,0 +1,33 @@ +@rem Copyright 2018 Google LLC. All rights reserved. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. + +@echo "Starting Windows build" + +cd /d %~dp0 +cd .. + +@rem npm path is not currently set in our image, we should fix this next time +@rem we upgrade Node.js in the image: +SET PATH=%PATH%;/cygdrive/c/Program Files/nodejs/npm + +call nvm use v12.14.1 +call which node + +call npm install || goto :error +call npm run test || goto :error + +goto :EOF + +:error +exit /b 1 diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.sh new file mode 100644 index 000000000..5d6383fcb --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/test.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +export NPM_CONFIG_PREFIX=${HOME}/.npm-global + +cd $(dirname $0)/.. + +npm install +# If tests are running against master, configure flakybot +# to open issues on failures: +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]] || [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"nightly"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP +fi +npm test + +# codecov combines coverage across integration and unit tests. Include +# the logic below for any environment you wish to collect coverage for: +COVERAGE_NODE=10 +if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then + NYC_BIN=./node_modules/nyc/bin/nyc.js + if [ -f "$NYC_BIN" ]; then + $NYC_BIN report || true + fi + bash $KOKORO_GFILE_DIR/codecov.sh +else + echo "coverage is only reported for Node $COVERAGE_NODE" +fi diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline.sh new file mode 100644 index 000000000..f693a1ce7 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Copyright 2017 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file is not used any more, but we keep this file for making it +# easy to roll back. +# TODO: Remove this file from the template. + +set -eo pipefail + +# Always run the cleanup script, regardless of the success of bouncing into +# the container. +function cleanup() { + chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + echo "cleanup"; +} +trap cleanup EXIT + +$(dirname $0)/populate-secrets.sh # Secret Manager secrets. +python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" diff --git a/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline_v2.sh b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline_v2.sh new file mode 100644 index 000000000..4d0311212 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/.kokoro/trampoline_v2.sh @@ -0,0 +1,490 @@ +#!/usr/bin/env bash +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# trampoline_v2.sh +# +# If you want to make a change to this file, consider doing so at: +# https://github.com/googlecloudplatform/docker-ci-helper +# +# This script is for running CI builds. For Kokoro builds, we +# set this script to `build_file` field in the Kokoro configuration. + +# This script does 3 things. +# +# 1. Prepare the Docker image for the test +# 2. Run the Docker with appropriate flags to run the test +# 3. Upload the newly built Docker image +# +# in a way that is somewhat compatible with trampoline_v1. +# +# These environment variables are required: +# TRAMPOLINE_IMAGE: The docker image to use. +# TRAMPOLINE_DOCKERFILE: The location of the Dockerfile. +# +# You can optionally change these environment variables: +# TRAMPOLINE_IMAGE_UPLOAD: +# (true|false): Whether to upload the Docker image after the +# successful builds. +# TRAMPOLINE_BUILD_FILE: The script to run in the docker container. +# TRAMPOLINE_WORKSPACE: The workspace path in the docker container. +# Defaults to /workspace. +# Potentially there are some repo specific envvars in .trampolinerc in +# the project root. +# +# Here is an example for running this script. +# TRAMPOLINE_IMAGE=gcr.io/cloud-devrel-kokoro-resources/node:10-user \ +# TRAMPOLINE_BUILD_FILE=.kokoro/system-test.sh \ +# .kokoro/trampoline_v2.sh + +set -euo pipefail + +TRAMPOLINE_VERSION="2.0.7" + +if command -v tput >/dev/null && [[ -n "${TERM:-}" ]]; then + readonly IO_COLOR_RED="$(tput setaf 1)" + readonly IO_COLOR_GREEN="$(tput setaf 2)" + readonly IO_COLOR_YELLOW="$(tput setaf 3)" + readonly IO_COLOR_RESET="$(tput sgr0)" +else + readonly IO_COLOR_RED="" + readonly IO_COLOR_GREEN="" + readonly IO_COLOR_YELLOW="" + readonly IO_COLOR_RESET="" +fi + +function function_exists { + [ $(LC_ALL=C type -t $1)"" == "function" ] +} + +# Logs a message using the given color. The first argument must be one +# of the IO_COLOR_* variables defined above, such as +# "${IO_COLOR_YELLOW}". The remaining arguments will be logged in the +# given color. The log message will also have an RFC-3339 timestamp +# prepended (in UTC). You can disable the color output by setting +# TERM=vt100. +function log_impl() { + local color="$1" + shift + local timestamp="$(date -u "+%Y-%m-%dT%H:%M:%SZ")" + echo "================================================================" + echo "${color}${timestamp}:" "$@" "${IO_COLOR_RESET}" + echo "================================================================" +} + +# Logs the given message with normal coloring and a timestamp. +function log() { + log_impl "${IO_COLOR_RESET}" "$@" +} + +# Logs the given message in green with a timestamp. +function log_green() { + log_impl "${IO_COLOR_GREEN}" "$@" +} + +# Logs the given message in yellow with a timestamp. +function log_yellow() { + log_impl "${IO_COLOR_YELLOW}" "$@" +} + +# Logs the given message in red with a timestamp. +function log_red() { + log_impl "${IO_COLOR_RED}" "$@" +} + +readonly tmpdir=$(mktemp -d -t ci-XXXXXXXX) +readonly tmphome="${tmpdir}/h" +mkdir -p "${tmphome}" + +function cleanup() { + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +RUNNING_IN_CI="${RUNNING_IN_CI:-false}" + +# The workspace in the container, defaults to /workspace. +TRAMPOLINE_WORKSPACE="${TRAMPOLINE_WORKSPACE:-/workspace}" + +pass_down_envvars=( + # TRAMPOLINE_V2 variables. + # Tells scripts whether they are running as part of CI or not. + "RUNNING_IN_CI" + # Indicates which CI system we're in. + "TRAMPOLINE_CI" + # Indicates the version of the script. + "TRAMPOLINE_VERSION" + # Contains path to build artifacts being executed. + "KOKORO_BUILD_ARTIFACTS_SUBDIR" +) + +log_yellow "Building with Trampoline ${TRAMPOLINE_VERSION}" + +# Detect which CI systems we're in. If we're in any of the CI systems +# we support, `RUNNING_IN_CI` will be true and `TRAMPOLINE_CI` will be +# the name of the CI system. Both envvars will be passing down to the +# container for telling which CI system we're in. +if [[ -n "${KOKORO_BUILD_ID:-}" ]]; then + # descriptive env var for indicating it's on CI. + RUNNING_IN_CI="true" + TRAMPOLINE_CI="kokoro" + if [[ "${TRAMPOLINE_USE_LEGACY_SERVICE_ACCOUNT:-}" == "true" ]]; then + if [[ ! -f "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" ]]; then + log_red "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json does not exist. Did you forget to mount cloud-devrel-kokoro-resources/trampoline? Aborting." + exit 1 + fi + # This service account will be activated later. + TRAMPOLINE_SERVICE_ACCOUNT="${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" + else + if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then + gcloud auth list + fi + log_yellow "Configuring Container Registry access" + gcloud auth configure-docker --quiet + fi + pass_down_envvars+=( + # KOKORO dynamic variables. + "KOKORO_BUILD_NUMBER" + "KOKORO_BUILD_ID" + "KOKORO_JOB_NAME" + "KOKORO_GIT_COMMIT" + "KOKORO_GITHUB_COMMIT" + "KOKORO_GITHUB_PULL_REQUEST_NUMBER" + "KOKORO_GITHUB_PULL_REQUEST_COMMIT" + # For flakybot + "KOKORO_GITHUB_COMMIT_URL" + "KOKORO_GITHUB_PULL_REQUEST_URL" + ) +elif [[ "${TRAVIS:-}" == "true" ]]; then + RUNNING_IN_CI="true" + TRAMPOLINE_CI="travis" + pass_down_envvars+=( + "TRAVIS_BRANCH" + "TRAVIS_BUILD_ID" + "TRAVIS_BUILD_NUMBER" + "TRAVIS_BUILD_WEB_URL" + "TRAVIS_COMMIT" + "TRAVIS_COMMIT_MESSAGE" + "TRAVIS_COMMIT_RANGE" + "TRAVIS_JOB_NAME" + "TRAVIS_JOB_NUMBER" + "TRAVIS_JOB_WEB_URL" + "TRAVIS_PULL_REQUEST" + "TRAVIS_PULL_REQUEST_BRANCH" + "TRAVIS_PULL_REQUEST_SHA" + "TRAVIS_PULL_REQUEST_SLUG" + "TRAVIS_REPO_SLUG" + "TRAVIS_SECURE_ENV_VARS" + "TRAVIS_TAG" + ) +elif [[ -n "${GITHUB_RUN_ID:-}" ]]; then + RUNNING_IN_CI="true" + TRAMPOLINE_CI="github-workflow" + pass_down_envvars+=( + "GITHUB_WORKFLOW" + "GITHUB_RUN_ID" + "GITHUB_RUN_NUMBER" + "GITHUB_ACTION" + "GITHUB_ACTIONS" + "GITHUB_ACTOR" + "GITHUB_REPOSITORY" + "GITHUB_EVENT_NAME" + "GITHUB_EVENT_PATH" + "GITHUB_SHA" + "GITHUB_REF" + "GITHUB_HEAD_REF" + "GITHUB_BASE_REF" + ) +elif [[ "${CIRCLECI:-}" == "true" ]]; then + RUNNING_IN_CI="true" + TRAMPOLINE_CI="circleci" + pass_down_envvars+=( + "CIRCLE_BRANCH" + "CIRCLE_BUILD_NUM" + "CIRCLE_BUILD_URL" + "CIRCLE_COMPARE_URL" + "CIRCLE_JOB" + "CIRCLE_NODE_INDEX" + "CIRCLE_NODE_TOTAL" + "CIRCLE_PREVIOUS_BUILD_NUM" + "CIRCLE_PROJECT_REPONAME" + "CIRCLE_PROJECT_USERNAME" + "CIRCLE_REPOSITORY_URL" + "CIRCLE_SHA1" + "CIRCLE_STAGE" + "CIRCLE_USERNAME" + "CIRCLE_WORKFLOW_ID" + "CIRCLE_WORKFLOW_JOB_ID" + "CIRCLE_WORKFLOW_UPSTREAM_JOB_IDS" + "CIRCLE_WORKFLOW_WORKSPACE_ID" + ) +fi + +# Configure the service account for pulling the docker image. +function repo_root() { + local dir="$1" + while [[ ! -d "${dir}/.git" ]]; do + dir="$(dirname "$dir")" + done + echo "${dir}" +} + +# Detect the project root. In CI builds, we assume the script is in +# the git tree and traverse from there, otherwise, traverse from `pwd` +# to find `.git` directory. +if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then + PROGRAM_PATH="$(realpath "$0")" + PROGRAM_DIR="$(dirname "${PROGRAM_PATH}")" + PROJECT_ROOT="$(repo_root "${PROGRAM_DIR}")" +else + PROJECT_ROOT="$(repo_root $(pwd))" +fi + +log_yellow "Changing to the project root: ${PROJECT_ROOT}." +cd "${PROJECT_ROOT}" + +# To support relative path for `TRAMPOLINE_SERVICE_ACCOUNT`, we need +# to use this environment variable in `PROJECT_ROOT`. +if [[ -n "${TRAMPOLINE_SERVICE_ACCOUNT:-}" ]]; then + + mkdir -p "${tmpdir}/gcloud" + gcloud_config_dir="${tmpdir}/gcloud" + + log_yellow "Using isolated gcloud config: ${gcloud_config_dir}." + export CLOUDSDK_CONFIG="${gcloud_config_dir}" + + log_yellow "Using ${TRAMPOLINE_SERVICE_ACCOUNT} for authentication." + gcloud auth activate-service-account \ + --key-file "${TRAMPOLINE_SERVICE_ACCOUNT}" + log_yellow "Configuring Container Registry access" + gcloud auth configure-docker --quiet +fi + +required_envvars=( + # The basic trampoline configurations. + "TRAMPOLINE_IMAGE" + "TRAMPOLINE_BUILD_FILE" +) + +if [[ -f "${PROJECT_ROOT}/.trampolinerc" ]]; then + source "${PROJECT_ROOT}/.trampolinerc" +fi + +log_yellow "Checking environment variables." +for e in "${required_envvars[@]}" +do + if [[ -z "${!e:-}" ]]; then + log "Missing ${e} env var. Aborting." + exit 1 + fi +done + +# We want to support legacy style TRAMPOLINE_BUILD_FILE used with V1 +# script: e.g. "github/repo-name/.kokoro/run_tests.sh" +TRAMPOLINE_BUILD_FILE="${TRAMPOLINE_BUILD_FILE#github/*/}" +log_yellow "Using TRAMPOLINE_BUILD_FILE: ${TRAMPOLINE_BUILD_FILE}" + +# ignore error on docker operations and test execution +set +e + +log_yellow "Preparing Docker image." +# We only download the docker image in CI builds. +if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then + # Download the docker image specified by `TRAMPOLINE_IMAGE` + + # We may want to add --max-concurrent-downloads flag. + + log_yellow "Start pulling the Docker image: ${TRAMPOLINE_IMAGE}." + if docker pull "${TRAMPOLINE_IMAGE}"; then + log_green "Finished pulling the Docker image: ${TRAMPOLINE_IMAGE}." + has_image="true" + else + log_red "Failed pulling the Docker image: ${TRAMPOLINE_IMAGE}." + has_image="false" + fi +else + # For local run, check if we have the image. + if docker images "${TRAMPOLINE_IMAGE}" | grep "${TRAMPOLINE_IMAGE%:*}"; then + has_image="true" + else + has_image="false" + fi +fi + + +# The default user for a Docker container has uid 0 (root). To avoid +# creating root-owned files in the build directory we tell docker to +# use the current user ID. +user_uid="$(id -u)" +user_gid="$(id -g)" +user_name="$(id -un)" + +# To allow docker in docker, we add the user to the docker group in +# the host os. +docker_gid=$(cut -d: -f3 < <(getent group docker)) + +update_cache="false" +if [[ "${TRAMPOLINE_DOCKERFILE:-none}" != "none" ]]; then + # Build the Docker image from the source. + context_dir=$(dirname "${TRAMPOLINE_DOCKERFILE}") + docker_build_flags=( + "-f" "${TRAMPOLINE_DOCKERFILE}" + "-t" "${TRAMPOLINE_IMAGE}" + "--build-arg" "UID=${user_uid}" + "--build-arg" "USERNAME=${user_name}" + ) + if [[ "${has_image}" == "true" ]]; then + docker_build_flags+=("--cache-from" "${TRAMPOLINE_IMAGE}") + fi + + log_yellow "Start building the docker image." + if [[ "${TRAMPOLINE_VERBOSE:-false}" == "true" ]]; then + echo "docker build" "${docker_build_flags[@]}" "${context_dir}" + fi + + # ON CI systems, we want to suppress docker build logs, only + # output the logs when it fails. + if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then + if docker build "${docker_build_flags[@]}" "${context_dir}" \ + > "${tmpdir}/docker_build.log" 2>&1; then + if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then + cat "${tmpdir}/docker_build.log" + fi + + log_green "Finished building the docker image." + update_cache="true" + else + log_red "Failed to build the Docker image, aborting." + log_yellow "Dumping the build logs:" + cat "${tmpdir}/docker_build.log" + exit 1 + fi + else + if docker build "${docker_build_flags[@]}" "${context_dir}"; then + log_green "Finished building the docker image." + update_cache="true" + else + log_red "Failed to build the Docker image, aborting." + exit 1 + fi + fi +else + if [[ "${has_image}" != "true" ]]; then + log_red "We do not have ${TRAMPOLINE_IMAGE} locally, aborting." + exit 1 + fi +fi + +# We use an array for the flags so they are easier to document. +docker_flags=( + # Remove the container after it exists. + "--rm" + + # Use the host network. + "--network=host" + + # Run in priviledged mode. We are not using docker for sandboxing or + # isolation, just for packaging our dev tools. + "--privileged" + + # Run the docker script with the user id. Because the docker image gets to + # write in ${PWD} you typically want this to be your user id. + # To allow docker in docker, we need to use docker gid on the host. + "--user" "${user_uid}:${docker_gid}" + + # Pass down the USER. + "--env" "USER=${user_name}" + + # Mount the project directory inside the Docker container. + "--volume" "${PROJECT_ROOT}:${TRAMPOLINE_WORKSPACE}" + "--workdir" "${TRAMPOLINE_WORKSPACE}" + "--env" "PROJECT_ROOT=${TRAMPOLINE_WORKSPACE}" + + # Mount the temporary home directory. + "--volume" "${tmphome}:/h" + "--env" "HOME=/h" + + # Allow docker in docker. + "--volume" "/var/run/docker.sock:/var/run/docker.sock" + + # Mount the /tmp so that docker in docker can mount the files + # there correctly. + "--volume" "/tmp:/tmp" + # Pass down the KOKORO_GFILE_DIR and KOKORO_KEYSTORE_DIR + # TODO(tmatsuo): This part is not portable. + "--env" "TRAMPOLINE_SECRET_DIR=/secrets" + "--volume" "${KOKORO_GFILE_DIR:-/dev/shm}:/secrets/gfile" + "--env" "KOKORO_GFILE_DIR=/secrets/gfile" + "--volume" "${KOKORO_KEYSTORE_DIR:-/dev/shm}:/secrets/keystore" + "--env" "KOKORO_KEYSTORE_DIR=/secrets/keystore" +) + +# Add an option for nicer output if the build gets a tty. +if [[ -t 0 ]]; then + docker_flags+=("-it") +fi + +# Passing down env vars +for e in "${pass_down_envvars[@]}" +do + if [[ -n "${!e:-}" ]]; then + docker_flags+=("--env" "${e}=${!e}") + fi +done + +# If arguments are given, all arguments will become the commands run +# in the container, otherwise run TRAMPOLINE_BUILD_FILE. +if [[ $# -ge 1 ]]; then + log_yellow "Running the given commands '" "${@:1}" "' in the container." + readonly commands=("${@:1}") + if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then + echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" + fi + docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" +else + log_yellow "Running the tests in a Docker container." + docker_flags+=("--entrypoint=${TRAMPOLINE_BUILD_FILE}") + if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then + echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" + fi + docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" +fi + + +test_retval=$? + +if [[ ${test_retval} -eq 0 ]]; then + log_green "Build finished with ${test_retval}" +else + log_red "Build finished with ${test_retval}" +fi + +# Only upload it when the test passes. +if [[ "${update_cache}" == "true" ]] && \ + [[ $test_retval == 0 ]] && \ + [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]]; then + log_yellow "Uploading the Docker image." + if docker push "${TRAMPOLINE_IMAGE}"; then + log_green "Finished uploading the Docker image." + else + log_red "Failed uploading the Docker image." + fi + # Call trampoline_after_upload_hook if it's defined. + if function_exists trampoline_after_upload_hook; then + trampoline_after_upload_hook + fi + +fi + +exit "${test_retval}" diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintignore b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintignore new file mode 100644 index 000000000..9340ad9b8 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintignore @@ -0,0 +1,6 @@ +**/node_modules +**/coverage +test/fixtures +build/ +docs/ +protos/ diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintrc.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintrc.json new file mode 100644 index 000000000..782153495 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/gts" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitattributes b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitattributes new file mode 100644 index 000000000..33739cb74 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitattributes @@ -0,0 +1,4 @@ +*.ts text eol=lf +*.js text eol=lf +protos/* linguist-generated +**/api-extractor.json linguist-language=JSON-with-Comments diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitignore b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitignore new file mode 100644 index 000000000..5d32b2378 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.gitignore @@ -0,0 +1,14 @@ +**/*.log +**/node_modules +.coverage +coverage +.nyc_output +docs/ +out/ +build/ +system-test/secrets.js +system-test/*key.json +*.lock +.DS_Store +package-lock.json +__pycache__ diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.jsdoc.cjs b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.jsdoc.cjs new file mode 100644 index 000000000..797d40d19 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.jsdoc.cjs @@ -0,0 +1,55 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +'use strict'; + +module.exports = { + opts: { + readme: './README.md', + package: './package.json', + template: './node_modules/jsdoc-fresh', + recurse: true, + verbose: true, + destination: './docs/' + }, + plugins: [ + 'plugins/markdown', + 'jsdoc-region-tag' + ], + source: { + excludePattern: '(^|\\/|\\\\)[._]', + include: [ + 'build/src', + 'protos' + ], + includePattern: '\\.js$' + }, + templates: { + copyright: 'Copyright 2021 Google LLC', + includeDate: false, + sourceFiles: false, + systemName: '@google-cloud/dlp', + theme: 'lumen', + default: { + outputSourceFiles: false + } + }, + markdown: { + idInHeadings: true + } +}; diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.mocharc.cjs b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.mocharc.cjs new file mode 100644 index 000000000..0b600509b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.mocharc.cjs @@ -0,0 +1,29 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +const config = { + "enable-source-maps": true, + "throw-deprecation": true, + "timeout": 10000, + "recursive": true +} +if (process.env.MOCHA_THROW_DEPRECATION === 'false') { + delete config['throw-deprecation']; +} +if (process.env.MOCHA_REPORTER) { + config.reporter = process.env.MOCHA_REPORTER; +} +if (process.env.MOCHA_REPORTER_OUTPUT) { + config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; +} +module.exports = config diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.nycrc b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.nycrc new file mode 100644 index 000000000..b18d5472b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.nycrc @@ -0,0 +1,24 @@ +{ + "report-dir": "./.coverage", + "reporter": ["text", "lcov"], + "exclude": [ + "**/*-test", + "**/.coverage", + "**/apis", + "**/benchmark", + "**/conformance", + "**/docs", + "**/samples", + "**/scripts", + "**/protos", + "**/test", + "**/*.d.ts", + ".jsdoc.js", + "**/.jsdoc.js", + "karma.conf.js", + "webpack-tests.config.js", + "webpack.config.js" + ], + "exclude-after-remap": false, + "all": true +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierignore b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierignore new file mode 100644 index 000000000..9340ad9b8 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierignore @@ -0,0 +1,6 @@ +**/node_modules +**/coverage +test/fixtures +build/ +docs/ +protos/ diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierrc.cjs b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierrc.cjs new file mode 100644 index 000000000..d1b95106f --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.prettierrc.cjs @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +module.exports = { + ...require('gts/.prettierrc.json') +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.readme-partials.yml b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.readme-partials.yml new file mode 100644 index 000000000..99f553664 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.readme-partials.yml @@ -0,0 +1,4 @@ +introduction: |- + The [Data Loss Prevention API](https://cloud.google.com/dlp/docs/) provides programmatic access to a + powerful detection engine for personally identifiable information and other privacy-sensitive + data in unstructured data streams. diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.repo-metadata.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.repo-metadata.json new file mode 100644 index 000000000..f3b7e84f5 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.repo-metadata.json @@ -0,0 +1,14 @@ +{ + "client_documentation": "https://googleapis.dev/nodejs/dlp/latest", + "api_id": "dlp.googleapis.com", + "distribution_name": "@google-cloud/dlp", + "release_level": "ga", + "default_version": "v2", + "language": "nodejs", + "name_pretty": "Cloud Data Loss Prevention", + "repo": "googleapis/nodejs-dlp", + "product_documentation": "https://cloud.google.com/dlp/docs/", + "requires_billing": true, + "name": "dlp", + "issue_tracker": "https://issuetracker.google.com/savedsearches/5548083" +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.trampolinerc b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.trampolinerc new file mode 100644 index 000000000..164613b9e --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/.trampolinerc @@ -0,0 +1,51 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Template for .trampolinerc + +# Add required env vars here. +required_envvars+=( +) + +# Add env vars which are passed down into the container here. +pass_down_envvars+=( + "AUTORELEASE_PR" +) + +# Prevent unintentional override on the default image. +if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && \ + [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then + echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image." + exit 1 +fi + +# Define the default value if it makes sense. +if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then + TRAMPOLINE_IMAGE_UPLOAD="" +fi + +if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then + TRAMPOLINE_IMAGE="" +fi + +if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then + TRAMPOLINE_DOCKERFILE="" +fi + +if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then + TRAMPOLINE_BUILD_FILE="" +fi + +# Secret Manager secrets. +source ${PROJECT_ROOT}/.kokoro/populate-secrets.sh diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CHANGELOG.md b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CHANGELOG.md new file mode 100644 index 000000000..b20038d83 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CHANGELOG.md @@ -0,0 +1,399 @@ +# Changelog + +[npm history][1] + +[1]: https://www.npmjs.com/package/PACKAGE NAME?activeTab=versions + +## [3.1.0](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.6...v3.1.0) (2021-01-09) + + +### Features + +* adds style enumeration ([#569](https://www.github.com/googleapis/nodejs-dlp/issues/569)) ([3c8acf2](https://www.github.com/googleapis/nodejs-dlp/commit/3c8acf24523f2b130abc48bb18927ccac6cb6c3a)) + +### [3.0.6](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.5...v3.0.6) (2020-11-25) + + +### Bug Fixes + +* **window:** check for fetch on window ([8d9d49f](https://www.github.com/googleapis/nodejs-dlp/commit/8d9d49f9d9fbfec291ca0c3cf1bef64870cc8e3d)) + +### [3.0.5](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.4...v3.0.5) (2020-11-07) + + +### Bug Fixes + +* do not modify options object, use defaultScopes ([#560](https://www.github.com/googleapis/nodejs-dlp/issues/560)) ([5b29b1d](https://www.github.com/googleapis/nodejs-dlp/commit/5b29b1df9205e4f59a48c31f9ce6a2e2a9f18936)) + +### [3.0.4](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.3...v3.0.4) (2020-10-15) + + +### Bug Fixes + +* retrieve job config for risk analysis jobs; docs: clarify timespan config for BigQuery and Datastore. ([#547](https://www.github.com/googleapis/nodejs-dlp/issues/547)) ([3b25dd6](https://www.github.com/googleapis/nodejs-dlp/commit/3b25dd66350ca5729ddebe48f0a3718b756633ae)) + +### [3.0.3](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.2...v3.0.3) (2020-09-12) + + +### Bug Fixes + +* **deps:** update dependency yargs to v16 ([#536](https://www.github.com/googleapis/nodejs-dlp/issues/536)) ([39db29a](https://www.github.com/googleapis/nodejs-dlp/commit/39db29adcef20b7baed4b8a4351d12bcf2bc605f)) + +### [3.0.2](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.1...v3.0.2) (2020-07-15) + + +### Bug Fixes + +* **samples:** include locations/global in parent field ([#488](https://www.github.com/googleapis/nodejs-dlp/issues/488)) ([a5ec2f3](https://www.github.com/googleapis/nodejs-dlp/commit/a5ec2f3baafbc770336596bdfe4737b61aba947e)) + +### [3.0.1](https://www.github.com/googleapis/nodejs-dlp/compare/v3.0.0...v3.0.1) (2020-06-15) + + +### Bug Fixes + +* proper fallback option handling ([#486](https://www.github.com/googleapis/nodejs-dlp/issues/486)) ([11cd656](https://www.github.com/googleapis/nodejs-dlp/commit/11cd656e3d980d8bf87f045f4cd22379134b6e44)) + +## [3.0.0](https://www.github.com/googleapis/nodejs-dlp/compare/v2.2.0...v3.0.0) (2020-05-26) + + +### ⚠ BREAKING CHANGES + +* The library now supports Node.js v10+. The last version to support Node.js v8 is tagged legacy-8 on NPM. + +### Features + +* adds missing fields to Finding and adds support for hybrid jobs ([#435](https://www.github.com/googleapis/nodejs-dlp/issues/435)) ([3643d02](https://www.github.com/googleapis/nodejs-dlp/commit/3643d0218cabecd40bd04c86bc51d3fa3be21666)) +* drop node8 support, support for async iterators ([#440](https://www.github.com/googleapis/nodejs-dlp/issues/440)) ([82a2091](https://www.github.com/googleapis/nodejs-dlp/commit/82a2091f8c948b303c03629ecf77dc8cefb3248c)) + + +### Bug Fixes + +* embedding location into parent ([#476](https://www.github.com/googleapis/nodejs-dlp/issues/476)) ([9308a6a](https://www.github.com/googleapis/nodejs-dlp/commit/9308a6ace48a4128def4a408f18a75b0d74a359a)), closes [#474](https://www.github.com/googleapis/nodejs-dlp/issues/474) +* regen protos and tests, fix formatting ([#467](https://www.github.com/googleapis/nodejs-dlp/issues/467)) ([9924817](https://www.github.com/googleapis/nodejs-dlp/commit/9924817d39a4eec302d461092c3d8f3c292dcc17)) +* remove eslint, update gax, fix generated protos, run the generator ([#449](https://www.github.com/googleapis/nodejs-dlp/issues/449)) ([e00c5da](https://www.github.com/googleapis/nodejs-dlp/commit/e00c5dac055785dd361bf51d587e2a174f3d40a6)) +* sample inspect customInfoTypes infoType name ([#439](https://www.github.com/googleapis/nodejs-dlp/issues/439)) ([07ef721](https://www.github.com/googleapis/nodejs-dlp/commit/07ef72156567d3fe8318fc95fe187dd2f3868516)) +* support request params {key} with no =value ([#463](https://www.github.com/googleapis/nodejs-dlp/issues/463)) ([e3ef1c6](https://www.github.com/googleapis/nodejs-dlp/commit/e3ef1c69529775d16984fc381e6af47a13264b99)) +* synth.py clean up for multiple version ([#469](https://www.github.com/googleapis/nodejs-dlp/issues/469)) ([5f2cb9b](https://www.github.com/googleapis/nodejs-dlp/commit/5f2cb9ba9e6d8957cda0bd8495a72f96dcabd9c2)) +* **deps:** update dependency @google-cloud/pubsub to v2 ([#475](https://www.github.com/googleapis/nodejs-dlp/issues/475)) ([b6ce129](https://www.github.com/googleapis/nodejs-dlp/commit/b6ce1297fa179dc0a8cc9b97797acb2e05d22574)) + +## [2.2.0](https://www.github.com/googleapis/nodejs-dlp/compare/v2.1.0...v2.2.0) (2020-03-06) + + +### Features + +* deferred client initialization ([#420](https://www.github.com/googleapis/nodejs-dlp/issues/420)) ([a37da40](https://www.github.com/googleapis/nodejs-dlp/commit/a37da4095bab94a8d3539c67e9fcda4620d6e3a1)) + +## [2.1.0](https://www.github.com/googleapis/nodejs-dlp/compare/v2.0.1...v2.1.0) (2020-02-29) + + +### Features + +* export protos in src/index.ts ([dc75b9e](https://www.github.com/googleapis/nodejs-dlp/commit/dc75b9e104378f001f819086c434f574341e5b92)) + +### [2.0.1](https://www.github.com/googleapis/nodejs-dlp/compare/v2.0.0...v2.0.1) (2020-02-12) + + +### Bug Fixes + +* pass x-goog-request-params header for streaming calls ([ad49a5b](https://www.github.com/googleapis/nodejs-dlp/commit/ad49a5b645e65d256f7db5804e4410692952dc3a)) + +## [2.0.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.9.0...v2.0.0) (2020-01-28) + + +### ⚠ BREAKING CHANGES + +* move to typescript code generation (#393) + +### Features + +* move to typescript code generation ([#393](https://www.github.com/googleapis/nodejs-dlp/issues/393)) ([67e0811](https://www.github.com/googleapis/nodejs-dlp/commit/67e08118c6c64e525b9ac1e7363353acf1cb0875)) + +## [1.9.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.8.0...v1.9.0) (2019-12-30) + + +### Features + +* introduces locationId ([745f3c1](https://www.github.com/googleapis/nodejs-dlp/commit/745f3c1112e8968dd088e8c5cd90863ecbad6679)) + +## [1.8.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.7.1...v1.8.0) (2019-12-05) + + +### Features + +* add plural and singular resource descriptor ([#365](https://www.github.com/googleapis/nodejs-dlp/issues/365)) ([29e876b](https://www.github.com/googleapis/nodejs-dlp/commit/29e876b70c39d0e4533d151132139c52ad8767fe)) + + +### Bug Fixes + +* **deps:** pin TypeScript below 3.7.0 ([346b756](https://www.github.com/googleapis/nodejs-dlp/commit/346b7564e7b97c77ede1483207b83faef3aae6c1)) +* **docs:** bump release level to GA ([#363](https://www.github.com/googleapis/nodejs-dlp/issues/363)) ([67dfc81](https://www.github.com/googleapis/nodejs-dlp/commit/67dfc816ec097b91248a0a9f63e39d25c90c5647)) + +### [1.7.1](https://www.github.com/googleapis/nodejs-dlp/compare/v1.7.0...v1.7.1) (2019-11-18) + + +### Bug Fixes + +* **deps:** update dependency yargs to v15 ([#361](https://www.github.com/googleapis/nodejs-dlp/issues/361)) ([884c89e](https://www.github.com/googleapis/nodejs-dlp/commit/884c89e4f01fa66fe86c33a6d1d5b5fa4c9c94e2)) + +## [1.7.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.6.1...v1.7.0) (2019-11-14) + + +### Features + +* add support for publishToStackdriver field ([#358](https://www.github.com/googleapis/nodejs-dlp/issues/358)) ([5e5a384](https://www.github.com/googleapis/nodejs-dlp/commit/5e5a384a6ee122f7fd3bf07e04892dd70d748897)) + + +### Bug Fixes + +* **docs:** snippets are now replaced in jsdoc comments ([#357](https://www.github.com/googleapis/nodejs-dlp/issues/357)) ([678fad7](https://www.github.com/googleapis/nodejs-dlp/commit/678fad7dbe3d0c3255de61edd253b02947e2f9ab)) + +### [1.6.1](https://www.github.com/googleapis/nodejs-dlp/compare/v1.6.0...v1.6.1) (2019-10-22) + + +### Bug Fixes + +* **deps:** bump google-gax to 1.7.5 ([#351](https://www.github.com/googleapis/nodejs-dlp/issues/351)) ([bd3d7de](https://www.github.com/googleapis/nodejs-dlp/commit/bd3d7de8bbaa8d3ce88420fd6ecf7d0483283bf8)) + +## [1.6.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.5.0...v1.6.0) (2019-10-08) + + +### Bug Fixes + +* **deps:** update dependency @google-cloud/pubsub to v1 ([#339](https://www.github.com/googleapis/nodejs-dlp/issues/339)) ([7b44459](https://www.github.com/googleapis/nodejs-dlp/commit/7b44459)) +* use compatible version of google-gax ([37f3b5b](https://www.github.com/googleapis/nodejs-dlp/commit/37f3b5b)) + + +### Features + +* .d.ts for protos ([#342](https://www.github.com/googleapis/nodejs-dlp/issues/342)) ([1eea5f5](https://www.github.com/googleapis/nodejs-dlp/commit/1eea5f5)) + +## [1.5.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.4.0...v1.5.0) (2019-09-12) + + +### Bug Fixes + +* **deps:** update dependency yargs to v14 ([#328](https://www.github.com/googleapis/nodejs-dlp/issues/328)) ([92e53b9](https://www.github.com/googleapis/nodejs-dlp/commit/92e53b9)) + + +### Features + +* load protos from JSON, grpc-fallback support ([#330](https://www.github.com/googleapis/nodejs-dlp/issues/330)) ([9403ebe](https://www.github.com/googleapis/nodejs-dlp/commit/9403ebe)) + +## [1.4.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.3.1...v1.4.0) (2019-07-09) + + +### Features + +* add DataCatalog action to DlpJobs ([#317](https://www.github.com/googleapis/nodejs-dlp/issues/317)) ([92d0252](https://www.github.com/googleapis/nodejs-dlp/commit/92d0252)) + +### [1.3.1](https://www.github.com/googleapis/nodejs-dlp/compare/v1.3.0...v1.3.1) (2019-06-26) + + +### Bug Fixes + +* **docs:** link to reference docs section on googleapis.dev ([#313](https://www.github.com/googleapis/nodejs-dlp/issues/313)) ([3a7b991](https://www.github.com/googleapis/nodejs-dlp/commit/3a7b991)) + +## [1.3.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.2.1...v1.3.0) (2019-06-19) + + +### Features + +* add avro support ([#310](https://www.github.com/googleapis/nodejs-dlp/issues/310)) ([ac4f6d9](https://www.github.com/googleapis/nodejs-dlp/commit/ac4f6d9)) + +### [1.2.1](https://www.github.com/googleapis/nodejs-dlp/compare/v1.2.0...v1.2.1) (2019-06-16) + + +### Bug Fixes + +* **docs:** move to new client docs URL ([#306](https://www.github.com/googleapis/nodejs-dlp/issues/306)) ([c2c018d](https://www.github.com/googleapis/nodejs-dlp/commit/c2c018d)) + +## [1.2.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.1.0...v1.2.0) (2019-06-06) + + +### Features + +* add statistics about storedInfoType version ([#301](https://www.github.com/googleapis/nodejs-dlp/issues/301)) ([4482d02](https://www.github.com/googleapis/nodejs-dlp/commit/4482d02)) +* support apiEndpoint override in client constructor ([#299](https://www.github.com/googleapis/nodejs-dlp/issues/299)) ([663545c](https://www.github.com/googleapis/nodejs-dlp/commit/663545c)) + +## [1.1.0](https://www.github.com/googleapis/nodejs-dlp/compare/v1.0.0...v1.1.0) (2019-05-28) + + +### Features + +* auto-generate READMEs, add .repo-metdata.json ([#293](https://www.github.com/googleapis/nodejs-dlp/issues/293)) ([6895e23](https://www.github.com/googleapis/nodejs-dlp/commit/6895e23)) + +## [1.0.0](https://www.github.com/googleapis/nodejs-dlp/compare/v0.12.0...v1.0.0) (2019-05-20) + + +### ⚠ BREAKING CHANGES + +* upgrade engines field to >=8.10.0 (#272) + +### Bug Fixes + +* DEADLINE_EXCEEDED no longer treated as idempotent and retried ([1a0000c](https://www.github.com/googleapis/nodejs-dlp/commit/1a0000c)) +* DEADLINE_EXCEEDED retry code is idempotent ([#281](https://www.github.com/googleapis/nodejs-dlp/issues/281)) ([9c00cf6](https://www.github.com/googleapis/nodejs-dlp/commit/9c00cf6)) +* **deps:** update dependency @google-cloud/pubsub to ^0.29.0 ([#283](https://www.github.com/googleapis/nodejs-dlp/issues/283)) ([b1f9ee1](https://www.github.com/googleapis/nodejs-dlp/commit/b1f9ee1)) +* **deps:** update dependency google-gax to ^0.26.0 ([#270](https://www.github.com/googleapis/nodejs-dlp/issues/270)) ([68258a6](https://www.github.com/googleapis/nodejs-dlp/commit/68258a6)) +* **deps:** update dependency google-gax to v1 ([#280](https://www.github.com/googleapis/nodejs-dlp/issues/280)) ([2cbb997](https://www.github.com/googleapis/nodejs-dlp/commit/2cbb997)) + + +### Build System + +* upgrade engines field to >=8.10.0 ([#272](https://www.github.com/googleapis/nodejs-dlp/issues/272)) ([233e814](https://www.github.com/googleapis/nodejs-dlp/commit/233e814)) + +## v0.12.0 + +04-26-2019 12:39 PDT + +### New Features + +- feat: add x-goog-request-params header +- feat: add deterministic encryption ([#263](https://github.com/googleapis/nodejs-dlp/pull/263)) + +## v0.11.0 + +03-12-2019 15:22 PDT + +Greetings! This release has a few new features, bug fixes, and doc updates. Enjoy! + +### New Features +- feat: add support for triggers and matching types ([#243](https://github.com/googleapis/nodejs-dlp/pull/243)) + +### Bug Fixes +- fix: throw on invalid credentials ([#238](https://github.com/googleapis/nodejs-dlp/pull/238)) + +### Dependencies +- fix(deps): update dependency google-gax to ^0.25.0 ([#226](https://github.com/googleapis/nodejs-dlp/pull/226)) + +### Documentation +- docs: update links in contrib guide ([#240](https://github.com/googleapis/nodejs-dlp/pull/240)) +- docs: move CONTRIBUTING.md to root ([#231](https://github.com/googleapis/nodejs-dlp/pull/231)) +- docs: update samples in comments ([#230](https://github.com/googleapis/nodejs-dlp/pull/230)) +- docs: update contributing path in README ([#232](https://github.com/googleapis/nodejs-dlp/pull/232)) +- docs: add lint/fix example to contributing guide ([#228](https://github.com/googleapis/nodejs-dlp/pull/228)) + +### Internal / Testing Changes +- fix(deps): update dependency @google-cloud/pubsub to ^0.28.0 ([#253](https://github.com/googleapis/nodejs-dlp/pull/253)) +- refactor: update json import paths ([#254](https://github.com/googleapis/nodejs-dlp/pull/254)) +- build: Add docuploader credentials to node publish jobs ([#251](https://github.com/googleapis/nodejs-dlp/pull/251)) +- build: use node10 to run samples-test, system-test etc ([#250](https://github.com/googleapis/nodejs-dlp/pull/250)) +- chore: update release config and proto formatting +- chore: sync latest proto docs ([#245](https://github.com/googleapis/nodejs-dlp/pull/245)) +- fix(test): increase minLikelihood option threshold to VERY_LIKELY ([#248](https://github.com/googleapis/nodejs-dlp/pull/248)) +- chore(deps): update dependency mocha to v6 +- fix(deps): update dependency yargs to v13 ([#235](https://github.com/googleapis/nodejs-dlp/pull/235)) +- build: use linkinator for docs test ([#239](https://github.com/googleapis/nodejs-dlp/pull/239)) +- refactor: modernize the sample tests ([#237](https://github.com/googleapis/nodejs-dlp/pull/237)) +- build: create docs test npm scripts ([#234](https://github.com/googleapis/nodejs-dlp/pull/234)) +- build: test using @grpc/grpc-js in CI ([#233](https://github.com/googleapis/nodejs-dlp/pull/233)) +- chore(deps): update dependency eslint-config-prettier to v4 ([#223](https://github.com/googleapis/nodejs-dlp/pull/223)) +- chore: update the copyright date in the header. ([#224](https://github.com/googleapis/nodejs-dlp/pull/224)) +- build: ignore googleapis.com in doc link check ([#220](https://github.com/googleapis/nodejs-dlp/pull/220)) +- build: check broken links in generated docs ([#213](https://github.com/googleapis/nodejs-dlp/pull/213)) +- fix(samples-test): increase likelihood threshold ([#222](https://github.com/googleapis/nodejs-dlp/pull/222)) + +## v0.10.0 + +01-04-2019 15:04 PST + +### New Features +- feat: add excluded field field for storage ([#169](https://github.com/googleapis/nodejs-dlp/pull/169)) +- feat: add support for storedInfoTypes ([#157](https://github.com/googleapis/nodejs-dlp/pull/157)) +- feat: add CloudStorageRegexFileSet ([#153](https://github.com/googleapis/nodejs-dlp/pull/153)) +- feat: add sorting and ordering of results ([#147](https://github.com/googleapis/nodejs-dlp/pull/147)) + +### Dependencies +- fix(deps): update dependency @google-cloud/pubsub to ^0.22.0 ([#192](https://github.com/googleapis/nodejs-dlp/pull/192)) +- fix(deps): update dependency @google-cloud/pubsub to ^0.21.0 ([#183](https://github.com/googleapis/nodejs-dlp/pull/183)) +- fix(deps): update dependency google-gax to ^0.22.0 ([#182](https://github.com/googleapis/nodejs-dlp/pull/182)) +- chore(deps): update dependency @google-cloud/nodejs-repo-tools to v3 ([#180](https://github.com/googleapis/nodejs-dlp/pull/180)) +- chore(deps): update dependency eslint-plugin-node to v8 ([#170](https://github.com/googleapis/nodejs-dlp/pull/170)) +- chore(deps): update dependency eslint-plugin-prettier to v3 ([#151](https://github.com/googleapis/nodejs-dlp/pull/151)) +- fix(deps): update dependency @google-cloud/pubsub to ^0.20.0 ([#137](https://github.com/googleapis/nodejs-dlp/pull/137)) +- fix(deps): update dependency google-gax to ^0.20.0 ([#138](https://github.com/googleapis/nodejs-dlp/pull/138)) + +### Documentation +- samples: Added custom dictionary and regex code samples ([#204](https://github.com/googleapis/nodejs-dlp/pull/204)) +- refactor(samples): convert sample tests from ava to mocha ([#186](https://github.com/googleapis/nodejs-dlp/pull/186)) +- docs: update readme badges ([#194](https://github.com/googleapis/nodejs-dlp/pull/194)) +- docs(samples): samples to use async/await ([#190](https://github.com/googleapis/nodejs-dlp/pull/190)) + +### Internal / Testing Changes +- nit: reordered gRPC message types ([#214](https://github.com/googleapis/nodejs-dlp/pull/214)) +- tests: construct pubsub properly ([#143](https://github.com/googleapis/nodejs-dlp/pull/143)) +- chore(build): inject yoshi automation key ([#209](https://github.com/googleapis/nodejs-dlp/pull/209)) +- chore: update nyc and eslint configs ([#208](https://github.com/googleapis/nodejs-dlp/pull/208)) +- chore: fix publish.sh permission +x ([#206](https://github.com/googleapis/nodejs-dlp/pull/206)) +- fix(build): fix Kokoro release script ([#205](https://github.com/googleapis/nodejs-dlp/pull/205)) +- build: add Kokoro configs for autorelease ([#203](https://github.com/googleapis/nodejs-dlp/pull/203)) +- chore: add synth.metadata ([#201](https://github.com/googleapis/nodejs-dlp/pull/201)) +- chore: always nyc report before calling codecov ([#199](https://github.com/googleapis/nodejs-dlp/pull/199)) +- chore: nyc ignore build/test by default ([#198](https://github.com/googleapis/nodejs-dlp/pull/198)) +- chore: update license file ([#196](https://github.com/googleapis/nodejs-dlp/pull/196)) +- fix(build): fix system key decryption ([#191](https://github.com/googleapis/nodejs-dlp/pull/191)) +- build: fix the lint rules ([#187](https://github.com/googleapis/nodejs-dlp/pull/187)) +- chore: update eslintignore config ([#181](https://github.com/googleapis/nodejs-dlp/pull/181)) +- chore: drop contributors from multiple places ([#179](https://github.com/googleapis/nodejs-dlp/pull/179)) +- chore: use latest npm on Windows ([#178](https://github.com/googleapis/nodejs-dlp/pull/178)) +- chore: update CircleCI config ([#177](https://github.com/googleapis/nodejs-dlp/pull/177)) +- chore: include build in eslintignore ([#174](https://github.com/googleapis/nodejs-dlp/pull/174)) +- chore: update issue templates ([#168](https://github.com/googleapis/nodejs-dlp/pull/168)) +- chore: remove old issue template ([#166](https://github.com/googleapis/nodejs-dlp/pull/166)) +- build: run tests on node11 ([#165](https://github.com/googleapis/nodejs-dlp/pull/165)) +- chores(build): do not collect sponge.xml from windows builds ([#164](https://github.com/googleapis/nodejs-dlp/pull/164)) +- chores(build): run codecov on continuous builds ([#163](https://github.com/googleapis/nodejs-dlp/pull/163)) +- chore: update new issue template ([#162](https://github.com/googleapis/nodejs-dlp/pull/162)) +- build: fix codecov uploading on Kokoro ([#156](https://github.com/googleapis/nodejs-dlp/pull/156)) +- Update kokoro config ([#152](https://github.com/googleapis/nodejs-dlp/pull/152)) +- build: prevent system/sample-test from leaking credentials +- test: remove appveyor config ([#146](https://github.com/googleapis/nodejs-dlp/pull/146)) +- Update the kokoro config ([#145](https://github.com/googleapis/nodejs-dlp/pull/145)) +- Fix the linter ([#142](https://github.com/googleapis/nodejs-dlp/pull/142)) +- Enable prefer-const in the eslint config ([#141](https://github.com/googleapis/nodejs-dlp/pull/141)) +- Enable no-var in eslint ([#140](https://github.com/googleapis/nodejs-dlp/pull/140)) +- Switch to let/const ([#139](https://github.com/googleapis/nodejs-dlp/pull/139)) + +## v0.9.0 + +### New Features +- Bring in new feature: + - StoredInfoTypes + +### Dependencies +- chore(deps): update dependency eslint-config-prettier to v3 (#110) +- chore(deps): lock file maintenance (#104) +- chore(deps): lock file maintenance (#103) +- fix(deps): update dependency google-gax to ^0.18.0 (#100) +- chore(deps): lock file maintenance (#99) +- chore(deps): lock file maintenance (#94) +- chore(deps): update dependency eslint-plugin-node to v7 (#91) +- chore(deps): lock file maintenance (#90) + +### Documentation +- doc: add missing namespace (#108) +- DLP sample: Add autoPopulateTimespan option for creating job triggers. (#64) +- feat: Add code samples for DLP text redaction (#61) + +### Internal / Testing Changes +- Update synth.py (#112) +- test: use strictEqual in tests (#92) +- chore: do not use npm ci (#107) +- chore: ignore package-lock.json (#105) +- chore: update renovate config (#102) +- remove that whitespace (#101) +- chore: move mocha options to mocha.opts (#97) +- chore: add node templates to synth.py (#95) +- fix: requiring samples/ node engine >7.6 because async/await was used (#93) + +## v0.8.0 + +### BREAKING CHANGE +- fix: drop support for node.js 4.x and 9.x (#81) + +### Documentation +- docs: export google.privacy.* namespace instead of google.cloud.* so rpc doc links work (#80) + +### Internal / Testing Changes +- chore(build): use `npm ci` instead of `npm install` (#86) +- chore: really delete node4 and node9 (#83) diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CODE_OF_CONDUCT.md b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..2add2547a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CODE_OF_CONDUCT.md @@ -0,0 +1,94 @@ + +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CONTRIBUTING.md b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CONTRIBUTING.md new file mode 100644 index 000000000..167fbe1bc --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/CONTRIBUTING.md @@ -0,0 +1,76 @@ +# How to become a contributor and submit your own code + +**Table of contents** + +* [Contributor License Agreements](#contributor-license-agreements) +* [Contributing a patch](#contributing-a-patch) +* [Running the tests](#running-the-tests) +* [Releasing the library](#releasing-the-library) + +## Contributor License Agreements + +We'd love to accept your sample apps and patches! Before we can take them, we +have to jump a couple of legal hurdles. + +Please fill out either the individual or corporate Contributor License Agreement +(CLA). + + * If you are an individual writing original source code and you're sure you + own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). + * If you work for a company that wants to allow you to contribute your work, + then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. Once we receive it, we'll be able to +accept your pull requests. + +## Contributing A Patch + +1. Submit an issue describing your proposed change to the repo in question. +1. The repo owner will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a + Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Ensure that your code adheres to the existing style in the code to which + you are contributing. +1. Ensure that your code has an appropriate set of tests which all pass. +1. Title your pull request following [Conventional Commits](https://www.conventionalcommits.org/) styling. +1. Submit a pull request. + +### Before you begin + +1. [Select or create a Cloud Platform project][projects]. +1. [Enable billing for your project][billing]. +1. [Enable the Cloud Data Loss Prevention API][enable_api]. +1. [Set up authentication with a service account][auth] so you can access the + API from your local workstation. + + +## Running the tests + +1. [Prepare your environment for Node.js setup][setup]. + +1. Install dependencies: + + npm install + +1. Run the tests: + + # Run unit tests. + npm test + + # Run sample integration tests. + npm run samples-test + + # Run all system tests. + npm run system-test + +1. Lint (and maybe fix) any changes: + + npm run fix + +[setup]: https://cloud.google.com/nodejs/docs/setup +[projects]: https://console.cloud.google.com/project +[billing]: https://support.google.com/cloud/answer/6293499#enable-billing +[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid=dlp.googleapis.com +[auth]: https://cloud.google.com/docs/authentication/getting-started \ No newline at end of file diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/LICENSE b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/README.md b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/README.md new file mode 100644 index 000000000..da7b0c876 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/README.md @@ -0,0 +1,226 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." +Google Cloud Platform logo + +# [Cloud Data Loss Prevention: Node.js Client](https://github.com/googleapis/nodejs-dlp) + +[![release level](https://img.shields.io/badge/release%20level-general%20availability%20%28GA%29-brightgreen.svg?style=flat)](https://cloud.google.com/terms/launch-stages) +[![npm version](https://img.shields.io/npm/v/@google-cloud/dlp.svg)](https://www.npmjs.org/package/@google-cloud/dlp) +[![codecov](https://img.shields.io/codecov/c/github/googleapis/nodejs-dlp/master.svg?style=flat)](https://codecov.io/gh/googleapis/nodejs-dlp) + + + + +The [Data Loss Prevention API](https://cloud.google.com/dlp/docs/) provides programmatic access to a +powerful detection engine for personally identifiable information and other privacy-sensitive +data in unstructured data streams. + + +A comprehensive list of changes in each version may be found in +[the CHANGELOG](https://github.com/googleapis/nodejs-dlp/blob/master/CHANGELOG.md). + +* [Cloud Data Loss Prevention Node.js Client API Reference][client-docs] +* [Cloud Data Loss Prevention Documentation][product-docs] +* [github.com/googleapis/nodejs-dlp](https://github.com/googleapis/nodejs-dlp) + +Read more about the client libraries for Cloud APIs, including the older +Google APIs Client Libraries, in [Client Libraries Explained][explained]. + +[explained]: https://cloud.google.com/apis/docs/client-libraries-explained + +**Table of contents:** + + +* [Quickstart](#quickstart) + * [Before you begin](#before-you-begin) + * [Installing the client library](#installing-the-client-library) + * [Using the client library](#using-the-client-library) +* [Samples](#samples) +* [Versioning](#versioning) +* [Contributing](#contributing) +* [License](#license) + +## Quickstart + +### Before you begin + +1. [Select or create a Cloud Platform project][projects]. +1. [Enable billing for your project][billing]. +1. [Enable the Cloud Data Loss Prevention API][enable_api]. +1. [Set up authentication with a service account][auth] so you can access the + API from your local workstation. + +### Installing the client library + +```bash +npm install @google-cloud/dlp +``` + + +### Using the client library + +```javascript + +// Instantiates a client +const dlp = new DLP.DlpServiceClient(); + +// The string to inspect +const string = 'Robert Frost'; + +// The project ID to run the API call under +// const projectId = 'my-project'; + +async function quickStart() { + // The minimum likelihood required before returning a match + const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report (0 = server maximum) + const maxFindings = 0; + + // The infoTypes of information to match + const infoTypes = [{name: 'PERSON_NAME'}, {name: 'US_STATE'}]; + + // Whether to include the matching string + const includeQuote = true; + + // Construct item to inspect + const item = {value: string}; + + // Construct request + const request = { + parent: `projects/${projectId}/locations/global`, + inspectConfig: { + infoTypes: infoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + includeQuote: includeQuote, + }, + item: item, + }; + + // Run request + const [response] = await dlp.inspectContent(request); + const findings = response.result.findings; + if (findings.length > 0) { + console.log('Findings:'); + findings.forEach(finding => { + if (includeQuote) { + console.log(`\tQuote: ${finding.quote}`); + } + console.log(`\tInfo type: ${finding.infoType.name}`); + console.log(`\tLikelihood: ${finding.likelihood}`); + }); + } else { + console.log('No findings.'); + } +} +quickStart(); + +``` + + + +## Samples + +Samples are in the [`samples/`](https://github.com/googleapis/nodejs-dlp/tree/master/samples) directory. Each sample's `README.md` has instructions for running its sample. + +| Sample | Source Code | Try it | +| --------------------------- | --------------------------------- | ------ | +| Categorical Risk Analysis | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/categoricalRiskAnalysis.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/categoricalRiskAnalysis.js,samples/README.md) | +| Inspect Templates | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/createInspectTemplate.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/createInspectTemplate.js,samples/README.md) | +| Job Triggers | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/createTrigger.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/createTrigger.js,samples/README.md) | +| Deidentify with Date Shift | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithDateShift.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithDateShift.js,samples/README.md) | +| Deidentify with FPE | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithFpe.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithFpe.js,samples/README.md) | +| Deidentify with Mask | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithMask.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithMask.js,samples/README.md) | +| Deidentify with Replacement | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithReplacement.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithReplacement.js,samples/README.md) | +| Delete Inspect Templates | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteInspectTemplate.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteInspectTemplate.js,samples/README.md) | +| Delete Job | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteJob.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteJob.js,samples/README.md) | +| Delete Trigger | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteTrigger.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteTrigger.js,samples/README.md) | +| Inspect Bigquery | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectBigQuery.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectBigQuery.js,samples/README.md) | +| Inspect Datastore | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectDatastore.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectDatastore.js,samples/README.md) | +| Inspect File | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectFile.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectFile.js,samples/README.md) | +| Inspect GCS File | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectGCSFile.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectGCSFile.js,samples/README.md) | +| Inspects strings | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectString.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectString.js,samples/README.md) | +| kAnonymity Analysis | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/kAnonymityAnalysis.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/kAnonymityAnalysis.js,samples/README.md) | +| kMap Estimation Analysis | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/kMapEstimationAnalysis.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/kMapEstimationAnalysis.js,samples/README.md) | +| l Diversity Analysis | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/lDiversityAnalysis.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/lDiversityAnalysis.js,samples/README.md) | +| List Inspect Templates | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listInspectTemplates.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listInspectTemplates.js,samples/README.md) | +| List jobs | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listJobs.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listJobs.js,samples/README.md) | +| List Triggers | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listTriggers.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listTriggers.js,samples/README.md) | +| Metadata | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/metadata.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/metadata.js,samples/README.md) | +| Numerical Risk Analysis | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/numericalRiskAnalysis.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/numericalRiskAnalysis.js,samples/README.md) | +| Quickstart | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/quickstart.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/quickstart.js,samples/README.md) | +| Redact Image | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/redactImage.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/redactImage.js,samples/README.md) | +| Redact Text | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/redactText.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/redactText.js,samples/README.md) | +| Reidentify with FPE | [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/reidentifyWithFpe.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/reidentifyWithFpe.js,samples/README.md) | + + + +The [Cloud Data Loss Prevention Node.js Client API Reference][client-docs] documentation +also contains samples. + +## Supported Node.js Versions + +Our client libraries follow the [Node.js release schedule](https://github.com/nodejs/release#release-schedule). +Libraries are compatible with all current _active_ and _maintenance_ versions of +Node.js. + +Client libraries targeting some end-of-life versions of Node.js are available, and +can be installed via npm [dist-tags](https://docs.npmjs.com/cli/dist-tag). +The dist-tags follow the naming convention `legacy-(version)`. + +_Legacy Node.js versions are supported as a best effort:_ + +* Legacy versions will not be tested in continuous integration. +* Some security patches may not be able to be backported. +* Dependencies will not be kept up-to-date, and features will not be backported. + +#### Legacy tags available + +* `legacy-8`: install client libraries from this dist-tag for versions + compatible with Node.js 8. + +## Versioning + +This library follows [Semantic Versioning](http://semver.org/). + + +This library is considered to be **General Availability (GA)**. This means it +is stable; the code surface will not change in backwards-incompatible ways +unless absolutely necessary (e.g. because of critical security issues) or with +an extensive deprecation period. Issues and requests against **GA** libraries +are addressed with the highest priority. + + + + + +More Information: [Google Cloud Platform Launch Stages][launch_stages] + +[launch_stages]: https://cloud.google.com/terms/launch-stages + +## Contributing + +Contributions welcome! See the [Contributing Guide](https://github.com/googleapis/nodejs-dlp/blob/master/CONTRIBUTING.md). + +Please note that this `README.md`, the `samples/README.md`, +and a variety of configuration files in this repository (including `.nycrc` and `tsconfig.json`) +are generated from a central template. To edit one of these files, make an edit +to its template in this +[directory](https://github.com/googleapis/synthtool/tree/master/synthtool/gcp/templates/node_library). + +## License + +Apache Version 2.0 + +See [LICENSE](https://github.com/googleapis/nodejs-dlp/blob/master/LICENSE) + +[client-docs]: https://googleapis.dev/nodejs/dlp/latest +[product-docs]: https://cloud.google.com/dlp/docs/ +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png +[projects]: https://console.cloud.google.com/project +[billing]: https://support.google.com/cloud/answer/6293499#enable-billing +[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid=dlp.googleapis.com +[auth]: https://cloud.google.com/docs/authentication/getting-started diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/api-extractor.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/api-extractor.json new file mode 100644 index 000000000..de228294b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/api-extractor.json @@ -0,0 +1,369 @@ +/** + * Config file for API Extractor. For more info, please visit: https://api-extractor.com + */ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + + /** + * Optionally specifies another JSON config file that this file extends from. This provides a way for + * standard settings to be shared across multiple projects. + * + * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains + * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be + * resolved using NodeJS require(). + * + * SUPPORTED TOKENS: none + * DEFAULT VALUE: "" + */ + // "extends": "./shared/api-extractor-base.json" + // "extends": "my-package/include/api-extractor-base.json" + + /** + * Determines the "" token that can be used with other config file settings. The project folder + * typically contains the tsconfig.json and package.json config files, but the path is user-defined. + * + * The path is resolved relative to the folder of the config file that contains the setting. + * + * The default value for "projectFolder" is the token "", which means the folder is determined by traversing + * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder + * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error + * will be reported. + * + * SUPPORTED TOKENS: + * DEFAULT VALUE: "" + */ + // "projectFolder": "..", + + /** + * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor + * analyzes the symbols exported by this module. + * + * The file extension must be ".d.ts" and not ".ts". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + */ + "mainEntryPointFilePath": "/protos/protos.d.ts", + + /** + * A list of NPM package names whose exports should be treated as part of this package. + * + * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", + * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part + * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly + * imports library2. To avoid this, we can specify: + * + * "bundledPackages": [ "library2" ], + * + * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been + * local files for library1. + */ + "bundledPackages": [ ], + + /** + * Determines how the TypeScript compiler engine will be invoked by API Extractor. + */ + "compiler": { + /** + * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * Note: This setting will be ignored if "overrideTsconfig" is used. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/tsconfig.json" + */ + // "tsconfigFilePath": "/tsconfig.json", + + /** + * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. + * The object must conform to the TypeScript tsconfig schema: + * + * http://json.schemastore.org/tsconfig + * + * If omitted, then the tsconfig.json file will be read from the "projectFolder". + * + * DEFAULT VALUE: no overrideTsconfig section + */ + // "overrideTsconfig": { + // . . . + // } + + /** + * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended + * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when + * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses + * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. + * + * DEFAULT VALUE: false + */ + // "skipLibCheck": true, + }, + + /** + * Configures how the API report file (*.api.md) will be generated. + */ + "apiReport": { + /** + * (REQUIRED) Whether to generate an API report. + */ + "enabled": true, + + /** + * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce + * a full file path. + * + * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". + * + * SUPPORTED TOKENS: , + * DEFAULT VALUE: ".api.md" + */ + // "reportFileName": ".api.md", + + /** + * Specifies the folder where the API report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, + * e.g. for an API review. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/etc/" + */ + // "reportFolder": "/etc/", + + /** + * Specifies the folder where the temporary report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * After the temporary file is written to disk, it is compared with the file in the "reportFolder". + * If they are different, a production build will fail. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/" + */ + // "reportTempFolder": "/temp/" + }, + + /** + * Configures how the doc model file (*.api.json) will be generated. + */ + "docModel": { + /** + * (REQUIRED) Whether to generate a doc model file. + */ + "enabled": true, + + /** + * The output path for the doc model file. The file extension should be ".api.json". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/.api.json" + */ + // "apiJsonFilePath": "/temp/.api.json" + }, + + /** + * Configures how the .d.ts rollup file will be generated. + */ + "dtsRollup": { + /** + * (REQUIRED) Whether to generate the .d.ts rollup file. + */ + "enabled": true, + + /** + * Specifies the output path for a .d.ts rollup file to be generated without any trimming. + * This file will include all declarations that are exported by the main entry point. + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/dist/.d.ts" + */ + // "untrimmedFilePath": "/dist/.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. + * This file will include only declarations that are marked as "@public" or "@beta". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "betaTrimmedFilePath": "/dist/-beta.d.ts", + + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. + * This file will include only declarations that are marked as "@public". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "publicTrimmedFilePath": "/dist/-public.d.ts", + + /** + * When a declaration is trimmed, by default it will be replaced by a code comment such as + * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the + * declaration completely. + * + * DEFAULT VALUE: false + */ + // "omitTrimmingComments": true + }, + + /** + * Configures how the tsdoc-metadata.json file will be generated. + */ + "tsdocMetadata": { + /** + * Whether to generate the tsdoc-metadata.json file. + * + * DEFAULT VALUE: true + */ + // "enabled": true, + + /** + * Specifies where the TSDoc metadata file should be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", + * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup + * falls back to "tsdoc-metadata.json" in the package folder. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" + }, + + /** + * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files + * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. + * To use the OS's default newline kind, specify "os". + * + * DEFAULT VALUE: "crlf" + */ + // "newlineKind": "crlf", + + /** + * Configures how API Extractor reports error and warning messages produced during analysis. + * + * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. + */ + "messages": { + /** + * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing + * the input .d.ts files. + * + * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "compilerMessageReporting": { + /** + * Configures the default routing for messages that don't match an explicit rule in this table. + */ + "default": { + /** + * Specifies whether the message should be written to the the tool's output log. Note that + * the "addToApiReportFile" property may supersede this option. + * + * Possible values: "error", "warning", "none" + * + * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail + * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes + * the "--local" option), the warning is displayed but the build will not fail. + * + * DEFAULT VALUE: "warning" + */ + "logLevel": "warning", + + /** + * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), + * then the message will be written inside that file; otherwise, the message is instead logged according to + * the "logLevel" option. + * + * DEFAULT VALUE: false + */ + // "addToApiReportFile": false + }, + + // "TS2551": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by API Extractor during its analysis. + * + * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" + * + * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings + */ + "extractorMessageReporting": { + "default": { + "logLevel": "warning", + // "addToApiReportFile": false + }, + + // "ae-extra-release-tag": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by the TSDoc parser when analyzing code comments. + * + * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "tsdocMessageReporting": { + "default": { + "logLevel": "warning", + // "addToApiReportFile": false + } + + // "tsdoc-link-tag-unescaped-text": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + } + } + +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/index.ts b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/index.ts new file mode 100644 index 000000000..d44dd0b99 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/index.ts @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by synthtool. ** +// ** https://github.com/googleapis/synthtool ** +// ** All changes to this file may be overwritten. ** + +import * as v2 from './v2.js'; + +const DlpServiceClient = v2.DlpServiceClient; +type DlpServiceClient = v2.DlpServiceClient; + +export {v2, DlpServiceClient}; +export default {v2, DlpServiceClient}; +import * as protos from '../../protos/protos.js'; +export {protos}; diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/service_proto_list.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/service_proto_list.json new file mode 100644 index 000000000..5a79338f1 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/service_proto_list.json @@ -0,0 +1 @@ +["../protos/google/privacy/dlp/v2/dlp.proto", "../protos/google/privacy/dlp/v2/storage.proto"] \ No newline at end of file diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client.ts b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client.ts new file mode 100644 index 000000000..a20755a10 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client.ts @@ -0,0 +1,6109 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +/* global window */ +import * as gax from 'google-gax'; +import { + Callback, + CallOptions, + Descriptors, + ClientOptions, + PaginationCallback, + GaxCall, +} from 'google-gax'; +import * as path from 'path'; + +import {Transform} from 'stream'; +import {RequestType} from 'google-gax/build/src/apitypes'; +import * as protos from '../../protos/protos'; +/** + * Client JSON configuration object, loaded from + * `src/v2/dlp_service_client_config.json`. + * This file defines retry strategy and timeouts for all API methods in this library. + */ +import * as gapicConfig from './dlp_service_client_config.json'; + +const version = require('../../../package.json').version; + +/** + * The Cloud Data Loss Prevention (DLP) API is a service that allows clients + * to detect the presence of Personally Identifiable Information (PII) and other + * privacy-sensitive data in user-supplied, unstructured data streams, like text + * blocks or images. + * The service also includes methods for sensitive data redaction and + * scheduling of data scans on Google Cloud Platform based data sets. + * + * To learn more about concepts and find how-to guides see + * https://cloud.google.com/dlp/docs/. + * @class + * @memberof v2 + */ +export class DlpServiceClient { + private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; + auth: gax.GoogleAuth; + descriptors: Descriptors = { + page: {}, + stream: {}, + longrunning: {}, + batching: {}, + }; + innerApiCalls: {[name: string]: Function}; + pathTemplates: {[name: string]: gax.PathTemplate}; + dlpServiceStub?: Promise<{[name: string]: Function}>; + + /** + * Construct an instance of DlpServiceClient. + * + * @param {object} [options] - The configuration object. + * The options accepted by the constructor are described in detail + * in [this document](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#creating-the-client-instance). + * The common options are: + * @param {object} [options.credentials] - Credentials object. + * @param {string} [options.credentials.client_email] + * @param {string} [options.credentials.private_key] + * @param {string} [options.email] - Account email address. Required when + * using a .pem or .p12 keyFilename. + * @param {string} [options.keyFilename] - Full path to the a .json, .pem, or + * .p12 key downloaded from the Google Developers Console. If you provide + * a path to a JSON file, the projectId option below is not necessary. + * NOTE: .pem and .p12 require you to specify options.email as well. + * @param {number} [options.port] - The port on which to connect to + * the remote host. + * @param {string} [options.projectId] - The project ID from the Google + * Developer's Console, e.g. 'grape-spaceship-123'. We will also check + * the environment variable GCLOUD_PROJECT for your project ID. If your + * app is running in an environment which supports + * {@link https://developers.google.com/identity/protocols/application-default-credentials Application Default Credentials}, + * your project ID will be detected automatically. + * @param {string} [options.apiEndpoint] - The domain name of the + * API remote host. + * @param {gax.ClientConfig} [options.clientConfig] - Client configuration override. + * Follows the structure of {@link gapicConfig}. + * @param {boolean} [options.fallback] - Use HTTP fallback mode. + * In fallback mode, a special browser-compatible transport implementation is used + * instead of gRPC transport. In browser context (if the `window` object is defined) + * the fallback mode is enabled automatically; set `options.fallback` to `false` + * if you need to override this behavior. + */ + constructor(opts?: ClientOptions) { + // Ensure that options include all the required fields. + const staticMembers = this.constructor as typeof DlpServiceClient; + const servicePath = + opts?.servicePath || opts?.apiEndpoint || staticMembers.servicePath; + const port = opts?.port || staticMembers.port; + const clientConfig = opts?.clientConfig ?? {}; + const fallback = + opts?.fallback ?? + (typeof window !== 'undefined' && typeof window?.fetch === 'function'); + opts = Object.assign({servicePath, port, clientConfig, fallback}, opts); + + // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case. + if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) { + opts['scopes'] = staticMembers.scopes; + } + + // Choose either gRPC or proto-over-HTTP implementation of google-gax. + this._gaxModule = opts.fallback ? gax.fallback : gax; + + // Create a `gaxGrpc` object, with any grpc-specific options sent to the client. + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; + + // Save the auth object to the client, for use by other methods. + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; + + // Set the default scopes in auth client if needed. + if (servicePath === staticMembers.servicePath) { + this.auth.defaultScopes = staticMembers.scopes; + } + + // Determine the client header string. + const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${this._gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); + } + if (opts.libName && opts.libVersion) { + clientHeader.push(`${opts.libName}/${opts.libVersion}`); + } + // Load the applicable protos. + // For Node.js, pass the path to JSON proto file. + // For browsers, pass the JSON content. + + const nodejsProtoPath = path.join( + __dirname, + '..', + '..', + 'protos', + 'protos.json' + ); + this._protos = this._gaxGrpc.loadProto( + opts.fallback + ? // eslint-disable-next-line @typescript-eslint/no-var-requires + require('../../protos/protos.json') + : nodejsProtoPath + ); + + // This API contains "path templates"; forward-slash-separated + // identifiers to uniquely identify resources within the API. + // Create useful helper objects for these. + this.pathTemplates = { + findingPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/findings/{finding}' + ), + organizationPathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}' + ), + organizationDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/deidentifyTemplates/{deidentify_template}' + ), + organizationInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/inspectTemplates/{inspect_template}' + ), + organizationLocationDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/locations/{location}/deidentifyTemplates/{deidentify_template}' + ), + organizationLocationInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/locations/{location}/inspectTemplates/{inspect_template}' + ), + organizationLocationStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/locations/{location}/storedInfoTypes/{stored_info_type}' + ), + organizationStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/storedInfoTypes/{stored_info_type}' + ), + projectPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}' + ), + projectDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/deidentifyTemplates/{deidentify_template}' + ), + projectDlpContentPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/dlpContent' + ), + projectDlpJobPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/dlpJobs/{dlp_job}' + ), + projectInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/inspectTemplates/{inspect_template}' + ), + projectJobTriggerPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/jobTriggers/{job_trigger}' + ), + projectLocationDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/deidentifyTemplates/{deidentify_template}' + ), + projectLocationDlpJobPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/dlpJobs/{dlp_job}' + ), + projectLocationInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/inspectTemplates/{inspect_template}' + ), + projectLocationJobTriggerPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/jobTriggers/{job_trigger}' + ), + projectLocationStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/locations/{location}/storedInfoTypes/{stored_info_type}' + ), + projectStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/storedInfoTypes/{stored_info_type}' + ), + }; + + // Some of the methods on this service return "paged" results, + // (e.g. 50 results at a time, with tokens to get subsequent + // pages). Denote the keys used for pagination and results. + this.descriptors.page = { + listInspectTemplates: new this._gaxModule.PageDescriptor( + 'pageToken', + 'nextPageToken', + 'inspectTemplates' + ), + listDeidentifyTemplates: new this._gaxModule.PageDescriptor( + 'pageToken', + 'nextPageToken', + 'deidentifyTemplates' + ), + listJobTriggers: new this._gaxModule.PageDescriptor( + 'pageToken', + 'nextPageToken', + 'jobTriggers' + ), + listDlpJobs: new this._gaxModule.PageDescriptor( + 'pageToken', + 'nextPageToken', + 'jobs' + ), + listStoredInfoTypes: new this._gaxModule.PageDescriptor( + 'pageToken', + 'nextPageToken', + 'storedInfoTypes' + ), + }; + + // Put together the default options sent with requests. + this._defaults = this._gaxGrpc.constructSettings( + 'google.privacy.dlp.v2.DlpService', + gapicConfig as gax.ClientConfig, + opts.clientConfig || {}, + {'x-goog-api-client': clientHeader.join(' ')} + ); + + // Set up a dictionary of "inner API calls"; the core implementation + // of calling the API is handled in `google-gax`, with this code + // merely providing the destination and request information. + this.innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.dlpServiceStub) { + return this.dlpServiceStub; + } + + // Put together the "service stub" for + // google.privacy.dlp.v2.DlpService. + this.dlpServiceStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( + 'google.privacy.dlp.v2.DlpService' + ) + : // eslint-disable-next-line @typescript-eslint/no-explicit-any + (this._protos as any).google.privacy.dlp.v2.DlpService, + this._opts + ) as Promise<{[method: string]: Function}>; + + // Iterate over each of the methods that the service provides + // and create an API call method for each. + const dlpServiceStubMethods = [ + 'inspectContent', + 'redactImage', + 'deidentifyContent', + 'reidentifyContent', + 'listInfoTypes', + 'createInspectTemplate', + 'updateInspectTemplate', + 'getInspectTemplate', + 'listInspectTemplates', + 'deleteInspectTemplate', + 'createDeidentifyTemplate', + 'updateDeidentifyTemplate', + 'getDeidentifyTemplate', + 'listDeidentifyTemplates', + 'deleteDeidentifyTemplate', + 'createJobTrigger', + 'updateJobTrigger', + 'hybridInspectJobTrigger', + 'getJobTrigger', + 'listJobTriggers', + 'deleteJobTrigger', + 'activateJobTrigger', + 'createDlpJob', + 'listDlpJobs', + 'getDlpJob', + 'deleteDlpJob', + 'cancelDlpJob', + 'createStoredInfoType', + 'updateStoredInfoType', + 'getStoredInfoType', + 'listStoredInfoTypes', + 'deleteStoredInfoType', + 'hybridInspectDlpJob', + 'finishDlpJob', + ]; + for (const methodName of dlpServiceStubMethods) { + const callPromise = this.dlpServiceStub.then( + stub => (...args: Array<{}>) => { + if (this._terminated) { + return Promise.reject('The client has already been closed.'); + } + const func = stub[methodName]; + return func.apply(stub, args); + }, + (err: Error | null | undefined) => () => { + throw err; + } + ); + + const descriptor = this.descriptors.page[methodName] || undefined; + const apiCall = this._gaxModule.createApiCall( + callPromise, + this._defaults[methodName], + descriptor + ); + + this.innerApiCalls[methodName] = apiCall; + } + + return this.dlpServiceStub; + } + + /** + * The DNS address for this API service. + * @returns {string} The DNS address for this service. + */ + static get servicePath() { + return 'dlp.googleapis.com'; + } + + /** + * The DNS address for this API service - same as servicePath(), + * exists for compatibility reasons. + * @returns {string} The DNS address for this service. + */ + static get apiEndpoint() { + return 'dlp.googleapis.com'; + } + + /** + * The port for this API service. + * @returns {number} The default port for this service. + */ + static get port() { + return 443; + } + + /** + * The scopes needed to make gRPC calls for every method defined + * in this service. + * @returns {string[]} List of default scopes. + */ + static get scopes() { + return ['https://www.googleapis.com/auth/cloud-platform']; + } + + getProjectId(): Promise; + getProjectId(callback: Callback): void; + /** + * Return the project ID used by this class. + * @returns {Promise} A promise that resolves to string containing the project ID. + */ + getProjectId( + callback?: Callback + ): Promise | void { + if (callback) { + this.auth.getProjectId(callback); + return; + } + return this.auth.getProjectId(); + } + + // ------------------- + // -- Service calls -- + // ------------------- + inspectContent( + request: protos.google.privacy.dlp.v2.IInspectContentRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectContentResponse, + protos.google.privacy.dlp.v2.IInspectContentRequest | undefined, + {} | undefined + ] + >; + inspectContent( + request: protos.google.privacy.dlp.v2.IInspectContentRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectContentResponse, + protos.google.privacy.dlp.v2.IInspectContentRequest | null | undefined, + {} | null | undefined + > + ): void; + inspectContent( + request: protos.google.privacy.dlp.v2.IInspectContentRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectContentResponse, + protos.google.privacy.dlp.v2.IInspectContentRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Finds potentially sensitive info in content. + * This method has limits on input size, processing time, and output size. + * + * When no InfoTypes or CustomInfoTypes are specified in this request, the + * system will automatically choose what detectors to run. By default this may + * be all types, but may change over time as detectors are updated. + * + * For how to guides, see https://cloud.google.com/dlp/docs/inspecting-images + * and https://cloud.google.com/dlp/docs/inspecting-text, + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.InspectConfig} request.inspectConfig + * Configuration for the inspector. What specified here will override + * the template referenced by the inspect_template_name argument. + * @param {google.privacy.dlp.v2.ContentItem} request.item + * The item to inspect. + * @param {string} request.inspectTemplateName + * Template to use. Any configuration directly specified in + * inspect_config will override those set in the template. Singular fields + * that are set in this request will replace their corresponding fields in the + * template. Repeated fields are appended. Singular sub-messages and groups + * are recursively merged. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [InspectContentResponse]{@link google.privacy.dlp.v2.InspectContentResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.inspectContent(request); + */ + inspectContent( + request: protos.google.privacy.dlp.v2.IInspectContentRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IInspectContentResponse, + | protos.google.privacy.dlp.v2.IInspectContentRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IInspectContentResponse, + protos.google.privacy.dlp.v2.IInspectContentRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectContentResponse, + protos.google.privacy.dlp.v2.IInspectContentRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.inspectContent(request, options, callback); + } + redactImage( + request: protos.google.privacy.dlp.v2.IRedactImageRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | undefined, + {} | undefined + ] + >; + redactImage( + request: protos.google.privacy.dlp.v2.IRedactImageRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | null | undefined, + {} | null | undefined + > + ): void; + redactImage( + request: protos.google.privacy.dlp.v2.IRedactImageRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Redacts potentially sensitive info from an image. + * This method has limits on input size, processing time, and output size. + * See https://cloud.google.com/dlp/docs/redacting-sensitive-data-images to + * learn more. + * + * When no InfoTypes or CustomInfoTypes are specified in this request, the + * system will automatically choose what detectors to run. By default this may + * be all types, but may change over time as detectors are updated. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {google.privacy.dlp.v2.InspectConfig} request.inspectConfig + * Configuration for the inspector. + * @param {number[]} request.imageRedactionConfigs + * The configuration for specifying what content to redact from images. + * @param {boolean} request.includeFindings + * Whether the response should include findings along with the redacted + * image. + * @param {google.privacy.dlp.v2.ByteContentItem} request.byteItem + * The content must be PNG, JPEG, SVG or BMP. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [RedactImageResponse]{@link google.privacy.dlp.v2.RedactImageResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.redactImage(request); + */ + redactImage( + request: protos.google.privacy.dlp.v2.IRedactImageRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IRedactImageResponse, + protos.google.privacy.dlp.v2.IRedactImageRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.redactImage(request, options, callback); + } + deidentifyContent( + request: protos.google.privacy.dlp.v2.IDeidentifyContentRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + protos.google.privacy.dlp.v2.IDeidentifyContentRequest | undefined, + {} | undefined + ] + >; + deidentifyContent( + request: protos.google.privacy.dlp.v2.IDeidentifyContentRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + protos.google.privacy.dlp.v2.IDeidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): void; + deidentifyContent( + request: protos.google.privacy.dlp.v2.IDeidentifyContentRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + protos.google.privacy.dlp.v2.IDeidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * De-identifies potentially sensitive info from a ContentItem. + * This method has limits on input size and output size. + * See https://cloud.google.com/dlp/docs/deidentify-sensitive-data to + * learn more. + * + * When no InfoTypes or CustomInfoTypes are specified in this request, the + * system will automatically choose what detectors to run. By default this may + * be all types, but may change over time as detectors are updated. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.DeidentifyConfig} request.deidentifyConfig + * Configuration for the de-identification of the content item. + * Items specified here will override the template referenced by the + * deidentify_template_name argument. + * @param {google.privacy.dlp.v2.InspectConfig} request.inspectConfig + * Configuration for the inspector. + * Items specified here will override the template referenced by the + * inspect_template_name argument. + * @param {google.privacy.dlp.v2.ContentItem} request.item + * The item to de-identify. Will be treated as text. + * @param {string} request.inspectTemplateName + * Template to use. Any configuration directly specified in + * inspect_config will override those set in the template. Singular fields + * that are set in this request will replace their corresponding fields in the + * template. Repeated fields are appended. Singular sub-messages and groups + * are recursively merged. + * @param {string} request.deidentifyTemplateName + * Template to use. Any configuration directly specified in + * deidentify_config will override those set in the template. Singular fields + * that are set in this request will replace their corresponding fields in the + * template. Repeated fields are appended. Singular sub-messages and groups + * are recursively merged. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DeidentifyContentResponse]{@link google.privacy.dlp.v2.DeidentifyContentResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deidentifyContent(request); + */ + deidentifyContent( + request: protos.google.privacy.dlp.v2.IDeidentifyContentRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + | protos.google.privacy.dlp.v2.IDeidentifyContentRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + protos.google.privacy.dlp.v2.IDeidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyContentResponse, + protos.google.privacy.dlp.v2.IDeidentifyContentRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.deidentifyContent(request, options, callback); + } + reidentifyContent( + request: protos.google.privacy.dlp.v2.IReidentifyContentRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + protos.google.privacy.dlp.v2.IReidentifyContentRequest | undefined, + {} | undefined + ] + >; + reidentifyContent( + request: protos.google.privacy.dlp.v2.IReidentifyContentRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + protos.google.privacy.dlp.v2.IReidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): void; + reidentifyContent( + request: protos.google.privacy.dlp.v2.IReidentifyContentRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + protos.google.privacy.dlp.v2.IReidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Re-identifies content that has been de-identified. + * See + * https://cloud.google.com/dlp/docs/pseudonymization#re-identification_in_free_text_code_example + * to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.DeidentifyConfig} request.reidentifyConfig + * Configuration for the re-identification of the content item. + * This field shares the same proto message type that is used for + * de-identification, however its usage here is for the reversal of the + * previous de-identification. Re-identification is performed by examining + * the transformations used to de-identify the items and executing the + * reverse. This requires that only reversible transformations + * be provided here. The reversible transformations are: + * + * - `CryptoDeterministicConfig` + * - `CryptoReplaceFfxFpeConfig` + * @param {google.privacy.dlp.v2.InspectConfig} request.inspectConfig + * Configuration for the inspector. + * @param {google.privacy.dlp.v2.ContentItem} request.item + * The item to re-identify. Will be treated as text. + * @param {string} request.inspectTemplateName + * Template to use. Any configuration directly specified in + * `inspect_config` will override those set in the template. Singular fields + * that are set in this request will replace their corresponding fields in the + * template. Repeated fields are appended. Singular sub-messages and groups + * are recursively merged. + * @param {string} request.reidentifyTemplateName + * Template to use. References an instance of `DeidentifyTemplate`. + * Any configuration directly specified in `reidentify_config` or + * `inspect_config` will override those set in the template. The + * `DeidentifyTemplate` used must include only reversible transformations. + * Singular fields that are set in this request will replace their + * corresponding fields in the template. Repeated fields are appended. + * Singular sub-messages and groups are recursively merged. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [ReidentifyContentResponse]{@link google.privacy.dlp.v2.ReidentifyContentResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.reidentifyContent(request); + */ + reidentifyContent( + request: protos.google.privacy.dlp.v2.IReidentifyContentRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + | protos.google.privacy.dlp.v2.IReidentifyContentRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + protos.google.privacy.dlp.v2.IReidentifyContentRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IReidentifyContentResponse, + protos.google.privacy.dlp.v2.IReidentifyContentRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.reidentifyContent(request, options, callback); + } + listInfoTypes( + request: protos.google.privacy.dlp.v2.IListInfoTypesRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | undefined, + {} | undefined + ] + >; + listInfoTypes( + request: protos.google.privacy.dlp.v2.IListInfoTypesRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | null | undefined, + {} | null | undefined + > + ): void; + listInfoTypes( + request: protos.google.privacy.dlp.v2.IListInfoTypesRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Returns a list of the sensitive information types that the DLP API + * supports. See https://cloud.google.com/dlp/docs/infotypes-reference to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * The parent resource name. + * + * The format of this value is as follows: + * + * locations/LOCATION_ID + * @param {string} request.languageCode + * BCP-47 language code for localized infoType friendly + * names. If omitted, or if localized strings are not available, + * en-US strings will be returned. + * @param {string} request.filter + * filter to only return infoTypes supported by certain parts of the + * API. Defaults to supported_by=INSPECT. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [ListInfoTypesResponse]{@link google.privacy.dlp.v2.ListInfoTypesResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.listInfoTypes(request); + */ + listInfoTypes( + request: protos.google.privacy.dlp.v2.IListInfoTypesRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IListInfoTypesResponse, + protos.google.privacy.dlp.v2.IListInfoTypesRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listInfoTypes(request, options, callback); + } + createInspectTemplate( + request: protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest | undefined, + {} | undefined + ] + >; + createInspectTemplate( + request: protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + createInspectTemplate( + request: protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Creates an InspectTemplate for re-using frequently used configuration + * for inspecting content, images, and storage. + * See https://cloud.google.com/dlp/docs/creating-templates to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.InspectTemplate} request.inspectTemplate + * Required. The InspectTemplate to create. + * @param {string} request.templateId + * The template id can contain uppercase and lowercase letters, + * numbers, and hyphens; that is, it must match the regular + * expression: `[a-zA-Z\d-_]+`. The maximum length is 100 + * characters. Can be empty to allow the system to generate one. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.createInspectTemplate(request); + */ + createInspectTemplate( + request: protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.ICreateInspectTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createInspectTemplate(request, options, callback); + } + updateInspectTemplate( + request: protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest | undefined, + {} | undefined + ] + >; + updateInspectTemplate( + request: protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + updateInspectTemplate( + request: protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Updates the InspectTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of organization and inspectTemplate to be updated, for + * example `organizations/433245324/inspectTemplates/432452342` or + * projects/project-id/inspectTemplates/432452342. + * @param {google.privacy.dlp.v2.InspectTemplate} request.inspectTemplate + * New InspectTemplate value. + * @param {google.protobuf.FieldMask} request.updateMask + * Mask to control which fields get updated. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.updateInspectTemplate(request); + */ + updateInspectTemplate( + request: protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.IUpdateInspectTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.updateInspectTemplate(request, options, callback); + } + getInspectTemplate( + request: protos.google.privacy.dlp.v2.IGetInspectTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.IGetInspectTemplateRequest | undefined, + {} | undefined + ] + >; + getInspectTemplate( + request: protos.google.privacy.dlp.v2.IGetInspectTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IGetInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + getInspectTemplate( + request: protos.google.privacy.dlp.v2.IGetInspectTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IGetInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Gets an InspectTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and inspectTemplate to be read, for + * example `organizations/433245324/inspectTemplates/432452342` or + * projects/project-id/inspectTemplates/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.getInspectTemplate(request); + */ + getInspectTemplate( + request: protos.google.privacy.dlp.v2.IGetInspectTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IGetInspectTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IInspectTemplate, + | protos.google.privacy.dlp.v2.IGetInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate, + protos.google.privacy.dlp.v2.IGetInspectTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getInspectTemplate(request, options, callback); + } + deleteInspectTemplate( + request: protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest | undefined, + {} | undefined + ] + >; + deleteInspectTemplate( + request: protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + deleteInspectTemplate( + request: protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Deletes an InspectTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and inspectTemplate to be deleted, for + * example `organizations/433245324/inspectTemplates/432452342` or + * projects/project-id/inspectTemplates/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deleteInspectTemplate(request); + */ + deleteInspectTemplate( + request: protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteInspectTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteInspectTemplate(request, options, callback); + } + createDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest | undefined, + {} | undefined + ] + >; + createDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + createDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Creates a DeidentifyTemplate for re-using frequently used configuration + * for de-identifying content, images, and storage. + * See https://cloud.google.com/dlp/docs/creating-templates-deid to learn + * more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.DeidentifyTemplate} request.deidentifyTemplate + * Required. The DeidentifyTemplate to create. + * @param {string} request.templateId + * The template id can contain uppercase and lowercase letters, + * numbers, and hyphens; that is, it must match the regular + * expression: `[a-zA-Z\d-_]+`. The maximum length is 100 + * characters. Can be empty to allow the system to generate one. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.createDeidentifyTemplate(request); + */ + createDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createDeidentifyTemplate( + request, + options, + callback + ); + } + updateDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest | undefined, + {} | undefined + ] + >; + updateDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + updateDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Updates the DeidentifyTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates-deid to learn + * more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of organization and deidentify template to be updated, for + * example `organizations/433245324/deidentifyTemplates/432452342` or + * projects/project-id/deidentifyTemplates/432452342. + * @param {google.privacy.dlp.v2.DeidentifyTemplate} request.deidentifyTemplate + * New DeidentifyTemplate value. + * @param {google.protobuf.FieldMask} request.updateMask + * Mask to control which fields get updated. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.updateDeidentifyTemplate(request); + */ + updateDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.updateDeidentifyTemplate( + request, + options, + callback + ); + } + getDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest | undefined, + {} | undefined + ] + >; + getDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + getDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Gets a DeidentifyTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates-deid to learn + * more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and deidentify template to be read, for + * example `organizations/433245324/deidentifyTemplates/432452342` or + * projects/project-id/deidentifyTemplates/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.getDeidentifyTemplate(request); + */ + getDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + | protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate, + protos.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getDeidentifyTemplate(request, options, callback); + } + deleteDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest | undefined, + {} | undefined + ] + >; + deleteDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + deleteDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Deletes a DeidentifyTemplate. + * See https://cloud.google.com/dlp/docs/creating-templates-deid to learn + * more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and deidentify template to be deleted, + * for example `organizations/433245324/deidentifyTemplates/432452342` or + * projects/project-id/deidentifyTemplates/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deleteDeidentifyTemplate(request); + */ + deleteDeidentifyTemplate( + request: protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteDeidentifyTemplate( + request, + options, + callback + ); + } + createJobTrigger( + request: protos.google.privacy.dlp.v2.ICreateJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.ICreateJobTriggerRequest | undefined, + {} | undefined + ] + >; + createJobTrigger( + request: protos.google.privacy.dlp.v2.ICreateJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.ICreateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + createJobTrigger( + request: protos.google.privacy.dlp.v2.ICreateJobTriggerRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.ICreateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Creates a job trigger to run DLP actions such as scanning storage for + * sensitive information on a set schedule. + * See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.JobTrigger} request.jobTrigger + * Required. The JobTrigger to create. + * @param {string} request.triggerId + * The trigger id can contain uppercase and lowercase letters, + * numbers, and hyphens; that is, it must match the regular + * expression: `[a-zA-Z\d-_]+`. The maximum length is 100 + * characters. Can be empty to allow the system to generate one. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.createJobTrigger(request); + */ + createJobTrigger( + request: protos.google.privacy.dlp.v2.ICreateJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + | protos.google.privacy.dlp.v2.ICreateJobTriggerRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.ICreateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.ICreateJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createJobTrigger(request, options, callback); + } + updateJobTrigger( + request: protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest | undefined, + {} | undefined + ] + >; + updateJobTrigger( + request: protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + updateJobTrigger( + request: protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Updates a job trigger. + * See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the project and the triggeredJob, for example + * `projects/dlp-test-project/jobTriggers/53234423`. + * @param {google.privacy.dlp.v2.JobTrigger} request.jobTrigger + * New JobTrigger value. + * @param {google.protobuf.FieldMask} request.updateMask + * Mask to control which fields get updated. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.updateJobTrigger(request); + */ + updateJobTrigger( + request: protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + | protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IUpdateJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.updateJobTrigger(request, options, callback); + } + hybridInspectJobTrigger( + request: protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IHybridInspectResponse, + protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest | undefined, + {} | undefined + ] + >; + hybridInspectJobTrigger( + request: protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): void; + hybridInspectJobTrigger( + request: protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Inspect hybrid content and store findings to a trigger. The inspection + * will be processed asynchronously. To review the findings monitor the + * jobs within the trigger. + * Early access feature is in a pre-release state and might change or have + * limited support. For more information, see + * https://cloud.google.com/products#product-launch-stages. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the trigger to execute a hybrid inspect on, for example + * `projects/dlp-test-project/jobTriggers/53234423`. + * @param {google.privacy.dlp.v2.HybridContentItem} request.hybridItem + * The item to inspect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [HybridInspectResponse]{@link google.privacy.dlp.v2.HybridInspectResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.hybridInspectJobTrigger(request); + */ + hybridInspectJobTrigger( + request: protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IHybridInspectResponse, + protos.google.privacy.dlp.v2.IHybridInspectJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.hybridInspectJobTrigger( + request, + options, + callback + ); + } + getJobTrigger( + request: protos.google.privacy.dlp.v2.IGetJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | undefined, + {} | undefined + ] + >; + getJobTrigger( + request: protos.google.privacy.dlp.v2.IGetJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + getJobTrigger( + request: protos.google.privacy.dlp.v2.IGetJobTriggerRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Gets a job trigger. + * See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the project and the triggeredJob, for example + * `projects/dlp-test-project/jobTriggers/53234423`. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.getJobTrigger(request); + */ + getJobTrigger( + request: protos.google.privacy.dlp.v2.IGetJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger, + protos.google.privacy.dlp.v2.IGetJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getJobTrigger(request, options, callback); + } + deleteJobTrigger( + request: protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest | undefined, + {} | undefined + ] + >; + deleteJobTrigger( + request: protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + deleteJobTrigger( + request: protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Deletes a job trigger. + * See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the project and the triggeredJob, for example + * `projects/dlp-test-project/jobTriggers/53234423`. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deleteJobTrigger(request); + */ + deleteJobTrigger( + request: protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteJobTrigger(request, options, callback); + } + activateJobTrigger( + request: protos.google.privacy.dlp.v2.IActivateJobTriggerRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IActivateJobTriggerRequest | undefined, + {} | undefined + ] + >; + activateJobTrigger( + request: protos.google.privacy.dlp.v2.IActivateJobTriggerRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + | protos.google.privacy.dlp.v2.IActivateJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): void; + activateJobTrigger( + request: protos.google.privacy.dlp.v2.IActivateJobTriggerRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + | protos.google.privacy.dlp.v2.IActivateJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Activate a job trigger. Causes the immediate execute of a trigger + * instead of waiting on the trigger event to occur. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the trigger to activate, for example + * `projects/dlp-test-project/jobTriggers/53234423`. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DlpJob]{@link google.privacy.dlp.v2.DlpJob}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.activateJobTrigger(request); + */ + activateJobTrigger( + request: protos.google.privacy.dlp.v2.IActivateJobTriggerRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDlpJob, + | protos.google.privacy.dlp.v2.IActivateJobTriggerRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + | protos.google.privacy.dlp.v2.IActivateJobTriggerRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IActivateJobTriggerRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.activateJobTrigger(request, options, callback); + } + createDlpJob( + request: protos.google.privacy.dlp.v2.ICreateDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | undefined, + {} | undefined + ] + >; + createDlpJob( + request: protos.google.privacy.dlp.v2.ICreateDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + createDlpJob( + request: protos.google.privacy.dlp.v2.ICreateDlpJobRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Creates a new job to inspect storage or calculate risk metrics. + * See https://cloud.google.com/dlp/docs/inspecting-storage and + * https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. + * + * When no InfoTypes or CustomInfoTypes are specified in inspect jobs, the + * system will automatically choose what detectors to run. By default this may + * be all types, but may change over time as detectors are updated. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.InspectJobConfig} request.inspectJob + * Set to control what and how to inspect. + * @param {google.privacy.dlp.v2.RiskAnalysisJobConfig} request.riskJob + * Set to choose what metric to calculate. + * @param {string} request.jobId + * The job id can contain uppercase and lowercase letters, + * numbers, and hyphens; that is, it must match the regular + * expression: `[a-zA-Z\d-_]+`. The maximum length is 100 + * characters. Can be empty to allow the system to generate one. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DlpJob]{@link google.privacy.dlp.v2.DlpJob}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.createDlpJob(request); + */ + createDlpJob( + request: protos.google.privacy.dlp.v2.ICreateDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.ICreateDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createDlpJob(request, options, callback); + } + getDlpJob( + request: protos.google.privacy.dlp.v2.IGetDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | undefined, + {} | undefined + ] + >; + getDlpJob( + request: protos.google.privacy.dlp.v2.IGetDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + getDlpJob( + request: protos.google.privacy.dlp.v2.IGetDlpJobRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Gets the latest state of a long-running DlpJob. + * See https://cloud.google.com/dlp/docs/inspecting-storage and + * https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the DlpJob resource. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [DlpJob]{@link google.privacy.dlp.v2.DlpJob}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.getDlpJob(request); + */ + getDlpJob( + request: protos.google.privacy.dlp.v2.IGetDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob, + protos.google.privacy.dlp.v2.IGetDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getDlpJob(request, options, callback); + } + deleteDlpJob( + request: protos.google.privacy.dlp.v2.IDeleteDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | undefined, + {} | undefined + ] + >; + deleteDlpJob( + request: protos.google.privacy.dlp.v2.IDeleteDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + deleteDlpJob( + request: protos.google.privacy.dlp.v2.IDeleteDlpJobRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Deletes a long-running DlpJob. This method indicates that the client is + * no longer interested in the DlpJob result. The job will be cancelled if + * possible. + * See https://cloud.google.com/dlp/docs/inspecting-storage and + * https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the DlpJob resource to be deleted. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deleteDlpJob(request); + */ + deleteDlpJob( + request: protos.google.privacy.dlp.v2.IDeleteDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteDlpJob(request, options, callback); + } + cancelDlpJob( + request: protos.google.privacy.dlp.v2.ICancelDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | undefined, + {} | undefined + ] + >; + cancelDlpJob( + request: protos.google.privacy.dlp.v2.ICancelDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + cancelDlpJob( + request: protos.google.privacy.dlp.v2.ICancelDlpJobRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Starts asynchronous cancellation on a long-running DlpJob. The server + * makes a best effort to cancel the DlpJob, but success is not + * guaranteed. + * See https://cloud.google.com/dlp/docs/inspecting-storage and + * https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the DlpJob resource to be cancelled. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.cancelDlpJob(request); + */ + cancelDlpJob( + request: protos.google.privacy.dlp.v2.ICancelDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.ICancelDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.cancelDlpJob(request, options, callback); + } + createStoredInfoType( + request: protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest | undefined, + {} | undefined + ] + >; + createStoredInfoType( + request: protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + createStoredInfoType( + request: protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Creates a pre-built stored infoType to be used for inspection. + * See https://cloud.google.com/dlp/docs/creating-stored-infotypes to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {google.privacy.dlp.v2.StoredInfoTypeConfig} request.config + * Required. Configuration of the storedInfoType to create. + * @param {string} request.storedInfoTypeId + * The storedInfoType ID can contain uppercase and lowercase letters, + * numbers, and hyphens; that is, it must match the regular + * expression: `[a-zA-Z\d-_]+`. The maximum length is 100 + * characters. Can be empty to allow the system to generate one. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.createStoredInfoType(request); + */ + createStoredInfoType( + request: protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createStoredInfoType(request, options, callback); + } + updateStoredInfoType( + request: protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest | undefined, + {} | undefined + ] + >; + updateStoredInfoType( + request: protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + updateStoredInfoType( + request: protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Updates the stored infoType by creating a new version. The existing version + * will continue to be used until the new version is ready. + * See https://cloud.google.com/dlp/docs/creating-stored-infotypes to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of organization and storedInfoType to be updated, for + * example `organizations/433245324/storedInfoTypes/432452342` or + * projects/project-id/storedInfoTypes/432452342. + * @param {google.privacy.dlp.v2.StoredInfoTypeConfig} request.config + * Updated configuration for the storedInfoType. If not provided, a new + * version of the storedInfoType will be created with the existing + * configuration. + * @param {google.protobuf.FieldMask} request.updateMask + * Mask to control which fields get updated. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.updateStoredInfoType(request); + */ + updateStoredInfoType( + request: protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.updateStoredInfoType(request, options, callback); + } + getStoredInfoType( + request: protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest | undefined, + {} | undefined + ] + >; + getStoredInfoType( + request: protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest | null | undefined, + {} | null | undefined + > + ): void; + getStoredInfoType( + request: protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Gets a stored infoType. + * See https://cloud.google.com/dlp/docs/creating-stored-infotypes to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and storedInfoType to be read, for + * example `organizations/433245324/storedInfoTypes/432452342` or + * projects/project-id/storedInfoTypes/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.getStoredInfoType(request); + */ + getStoredInfoType( + request: protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + | protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType, + protos.google.privacy.dlp.v2.IGetStoredInfoTypeRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getStoredInfoType(request, options, callback); + } + deleteStoredInfoType( + request: protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest | undefined, + {} | undefined + ] + >; + deleteStoredInfoType( + request: protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + deleteStoredInfoType( + request: protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Deletes a stored infoType. + * See https://cloud.google.com/dlp/docs/creating-stored-infotypes to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the organization and storedInfoType to be deleted, for + * example `organizations/433245324/storedInfoTypes/432452342` or + * projects/project-id/storedInfoTypes/432452342. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.deleteStoredInfoType(request); + */ + deleteStoredInfoType( + request: protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + | protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteStoredInfoType(request, options, callback); + } + hybridInspectDlpJob( + request: protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IHybridInspectResponse, + protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest | undefined, + {} | undefined + ] + >; + hybridInspectDlpJob( + request: protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest + | null + | undefined, + {} | null | undefined + > + ): void; + hybridInspectDlpJob( + request: protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest, + callback: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest + | null + | undefined, + {} | null | undefined + > + ): void; + /** + * Inspect hybrid content and store findings to a job. + * To review the findings inspect the job. Inspection will occur + * asynchronously. + * Early access feature is in a pre-release state and might change or have + * limited support. For more information, see + * https://cloud.google.com/products#product-launch-stages. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Resource name of the job to execute a hybrid inspect on, for example + * `projects/dlp-test-project/dlpJob/53234423`. + * @param {google.privacy.dlp.v2.HybridContentItem} request.hybridItem + * The item to inspect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [HybridInspectResponse]{@link google.privacy.dlp.v2.HybridInspectResponse}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.hybridInspectDlpJob(request); + */ + hybridInspectDlpJob( + request: protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.privacy.dlp.v2.IHybridInspectResponse, + | protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest + | null + | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IHybridInspectResponse, + protos.google.privacy.dlp.v2.IHybridInspectDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.hybridInspectDlpJob(request, options, callback); + } + finishDlpJob( + request: protos.google.privacy.dlp.v2.IFinishDlpJobRequest, + options?: CallOptions + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | undefined, + {} | undefined + ] + >; + finishDlpJob( + request: protos.google.privacy.dlp.v2.IFinishDlpJobRequest, + options: CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + finishDlpJob( + request: protos.google.privacy.dlp.v2.IFinishDlpJobRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | null | undefined, + {} | null | undefined + > + ): void; + /** + * Finish a running hybrid DlpJob. Triggers the finalization steps and running + * of any enabled actions that have not yet run. + * Early access feature is in a pre-release state and might change or have + * limited support. For more information, see + * https://cloud.google.com/products#product-launch-stages. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the DlpJob resource to be cancelled. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * const [response] = await client.finishDlpJob(request); + */ + finishDlpJob( + request: protos.google.privacy.dlp.v2.IFinishDlpJobRequest, + optionsOrCallback?: + | CallOptions + | Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | null | undefined, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | null | undefined, + {} | null | undefined + > + ): Promise< + [ + protos.google.protobuf.IEmpty, + protos.google.privacy.dlp.v2.IFinishDlpJobRequest | undefined, + {} | undefined + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + name: request.name || '', + }); + this.initialize(); + return this.innerApiCalls.finishDlpJob(request, options, callback); + } + + listInspectTemplates( + request: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate[], + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest | null, + protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + ] + >; + listInspectTemplates( + request: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + options: CallOptions, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + | protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IInspectTemplate + > + ): void; + listInspectTemplates( + request: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + | protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IInspectTemplate + > + ): void; + /** + * Lists InspectTemplates. + * See https://cloud.google.com/dlp/docs/creating-templates to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListInspectTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is Array of [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate}. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed and will merge results from all the pages into this array. + * Note that it can affect your quota. + * We recommend using `listInspectTemplatesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listInspectTemplates( + request: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + optionsOrCallback?: + | CallOptions + | PaginationCallback< + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + | protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IInspectTemplate + >, + callback?: PaginationCallback< + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + | protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IInspectTemplate + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IInspectTemplate[], + protos.google.privacy.dlp.v2.IListInspectTemplatesRequest | null, + protos.google.privacy.dlp.v2.IListInspectTemplatesResponse + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listInspectTemplates(request, options, callback); + } + + /** + * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListInspectTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Stream} + * An object stream which emits an object representing [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate} on 'data' event. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed. Note that it can affect your quota. + * We recommend using `listInspectTemplatesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listInspectTemplatesStream( + request?: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + options?: CallOptions + ): Transform { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listInspectTemplates.createStream( + this.innerApiCalls.listInspectTemplates as gax.GaxCall, + request, + callSettings + ); + } + + /** + * Equivalent to `listInspectTemplates`, but returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListInspectTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [InspectTemplate]{@link google.privacy.dlp.v2.InspectTemplate}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * const iterable = client.listInspectTemplatesAsync(request); + * for await (const response of iterable) { + * // process response + * } + */ + listInspectTemplatesAsync( + request?: protos.google.privacy.dlp.v2.IListInspectTemplatesRequest, + options?: CallOptions + ): AsyncIterable { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + options = options || {}; + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listInspectTemplates.asyncIterate( + this.innerApiCalls['listInspectTemplates'] as GaxCall, + (request as unknown) as RequestType, + callSettings + ) as AsyncIterable; + } + listDeidentifyTemplates( + request: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate[], + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest | null, + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + ] + >; + listDeidentifyTemplates( + request: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + options: CallOptions, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + | protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IDeidentifyTemplate + > + ): void; + listDeidentifyTemplates( + request: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + | protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IDeidentifyTemplate + > + ): void; + /** + * Lists DeidentifyTemplates. + * See https://cloud.google.com/dlp/docs/creating-templates-deid to learn + * more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListDeidentifyTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is Array of [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate}. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed and will merge results from all the pages into this array. + * Note that it can affect your quota. + * We recommend using `listDeidentifyTemplatesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listDeidentifyTemplates( + request: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + optionsOrCallback?: + | CallOptions + | PaginationCallback< + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + | protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IDeidentifyTemplate + >, + callback?: PaginationCallback< + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + | protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IDeidentifyTemplate + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDeidentifyTemplate[], + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest | null, + protos.google.privacy.dlp.v2.IListDeidentifyTemplatesResponse + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listDeidentifyTemplates( + request, + options, + callback + ); + } + + /** + * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListDeidentifyTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Stream} + * An object stream which emits an object representing [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate} on 'data' event. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed. Note that it can affect your quota. + * We recommend using `listDeidentifyTemplatesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listDeidentifyTemplatesStream( + request?: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + options?: CallOptions + ): Transform { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listDeidentifyTemplates.createStream( + this.innerApiCalls.listDeidentifyTemplates as gax.GaxCall, + request, + callSettings + ); + } + + /** + * Equivalent to `listDeidentifyTemplates`, but returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListDeidentifyTemplates`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the template was created. + * - `update_time`: corresponds to time the template was last updated. + * - `name`: corresponds to template's name. + * - `display_name`: corresponds to template's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [DeidentifyTemplate]{@link google.privacy.dlp.v2.DeidentifyTemplate}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * const iterable = client.listDeidentifyTemplatesAsync(request); + * for await (const response of iterable) { + * // process response + * } + */ + listDeidentifyTemplatesAsync( + request?: protos.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest, + options?: CallOptions + ): AsyncIterable { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + options = options || {}; + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listDeidentifyTemplates.asyncIterate( + this.innerApiCalls['listDeidentifyTemplates'] as GaxCall, + (request as unknown) as RequestType, + callSettings + ) as AsyncIterable; + } + listJobTriggers( + request: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger[], + protos.google.privacy.dlp.v2.IListJobTriggersRequest | null, + protos.google.privacy.dlp.v2.IListJobTriggersResponse + ] + >; + listJobTriggers( + request: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + options: CallOptions, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListJobTriggersRequest, + protos.google.privacy.dlp.v2.IListJobTriggersResponse | null | undefined, + protos.google.privacy.dlp.v2.IJobTrigger + > + ): void; + listJobTriggers( + request: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListJobTriggersRequest, + protos.google.privacy.dlp.v2.IListJobTriggersResponse | null | undefined, + protos.google.privacy.dlp.v2.IJobTrigger + > + ): void; + /** + * Lists job triggers. + * See https://cloud.google.com/dlp/docs/creating-job-triggers to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to ListJobTriggers. `order_by` field must not + * change for subsequent calls. + * @param {number} request.pageSize + * Size of the page, can be limited by a server. + * @param {string} request.orderBy + * Comma separated list of triggeredJob fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the JobTrigger was created. + * - `update_time`: corresponds to time the JobTrigger was last updated. + * - `last_run_time`: corresponds to the last time the JobTrigger ran. + * - `name`: corresponds to JobTrigger's name. + * - `display_name`: corresponds to JobTrigger's display name. + * - `status`: corresponds to JobTrigger's status. + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `status` - HEALTHY|PAUSED|CANCELLED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - 'last_run_time` - RFC 3339 formatted timestamp, surrounded by + * quotation marks. Nanoseconds are ignored. + * - 'error_count' - Number of errors that have occurred while running. + * * The operator must be `=` or `!=` for status and inspected_storage. + * + * Examples: + * + * * inspected_storage = cloud_storage AND status = HEALTHY + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = PAUSED OR state = HEALTHY) + * * last_run_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is Array of [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger}. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed and will merge results from all the pages into this array. + * Note that it can affect your quota. + * We recommend using `listJobTriggersAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listJobTriggers( + request: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + optionsOrCallback?: + | CallOptions + | PaginationCallback< + protos.google.privacy.dlp.v2.IListJobTriggersRequest, + | protos.google.privacy.dlp.v2.IListJobTriggersResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IJobTrigger + >, + callback?: PaginationCallback< + protos.google.privacy.dlp.v2.IListJobTriggersRequest, + protos.google.privacy.dlp.v2.IListJobTriggersResponse | null | undefined, + protos.google.privacy.dlp.v2.IJobTrigger + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IJobTrigger[], + protos.google.privacy.dlp.v2.IListJobTriggersRequest | null, + protos.google.privacy.dlp.v2.IListJobTriggersResponse + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listJobTriggers(request, options, callback); + } + + /** + * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to ListJobTriggers. `order_by` field must not + * change for subsequent calls. + * @param {number} request.pageSize + * Size of the page, can be limited by a server. + * @param {string} request.orderBy + * Comma separated list of triggeredJob fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the JobTrigger was created. + * - `update_time`: corresponds to time the JobTrigger was last updated. + * - `last_run_time`: corresponds to the last time the JobTrigger ran. + * - `name`: corresponds to JobTrigger's name. + * - `display_name`: corresponds to JobTrigger's display name. + * - `status`: corresponds to JobTrigger's status. + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `status` - HEALTHY|PAUSED|CANCELLED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - 'last_run_time` - RFC 3339 formatted timestamp, surrounded by + * quotation marks. Nanoseconds are ignored. + * - 'error_count' - Number of errors that have occurred while running. + * * The operator must be `=` or `!=` for status and inspected_storage. + * + * Examples: + * + * * inspected_storage = cloud_storage AND status = HEALTHY + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = PAUSED OR state = HEALTHY) + * * last_run_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Stream} + * An object stream which emits an object representing [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger} on 'data' event. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed. Note that it can affect your quota. + * We recommend using `listJobTriggersAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listJobTriggersStream( + request?: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + options?: CallOptions + ): Transform { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listJobTriggers.createStream( + this.innerApiCalls.listJobTriggers as gax.GaxCall, + request, + callSettings + ); + } + + /** + * Equivalent to `listJobTriggers`, but returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to ListJobTriggers. `order_by` field must not + * change for subsequent calls. + * @param {number} request.pageSize + * Size of the page, can be limited by a server. + * @param {string} request.orderBy + * Comma separated list of triggeredJob fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc,update_time, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the JobTrigger was created. + * - `update_time`: corresponds to time the JobTrigger was last updated. + * - `last_run_time`: corresponds to the last time the JobTrigger ran. + * - `name`: corresponds to JobTrigger's name. + * - `display_name`: corresponds to JobTrigger's display name. + * - `status`: corresponds to JobTrigger's status. + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `status` - HEALTHY|PAUSED|CANCELLED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - 'last_run_time` - RFC 3339 formatted timestamp, surrounded by + * quotation marks. Nanoseconds are ignored. + * - 'error_count' - Number of errors that have occurred while running. + * * The operator must be `=` or `!=` for status and inspected_storage. + * + * Examples: + * + * * inspected_storage = cloud_storage AND status = HEALTHY + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = PAUSED OR state = HEALTHY) + * * last_run_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [JobTrigger]{@link google.privacy.dlp.v2.JobTrigger}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * const iterable = client.listJobTriggersAsync(request); + * for await (const response of iterable) { + * // process response + * } + */ + listJobTriggersAsync( + request?: protos.google.privacy.dlp.v2.IListJobTriggersRequest, + options?: CallOptions + ): AsyncIterable { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + options = options || {}; + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listJobTriggers.asyncIterate( + this.innerApiCalls['listJobTriggers'] as GaxCall, + (request as unknown) as RequestType, + callSettings + ) as AsyncIterable; + } + listDlpJobs( + request: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob[], + protos.google.privacy.dlp.v2.IListDlpJobsRequest | null, + protos.google.privacy.dlp.v2.IListDlpJobsResponse + ] + >; + listDlpJobs( + request: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + options: CallOptions, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListDlpJobsRequest, + protos.google.privacy.dlp.v2.IListDlpJobsResponse | null | undefined, + protos.google.privacy.dlp.v2.IDlpJob + > + ): void; + listDlpJobs( + request: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListDlpJobsRequest, + protos.google.privacy.dlp.v2.IListDlpJobsResponse | null | undefined, + protos.google.privacy.dlp.v2.IDlpJob + > + ): void; + /** + * Lists DlpJobs that match the specified filter in the request. + * See https://cloud.google.com/dlp/docs/inspecting-storage and + * https://cloud.google.com/dlp/docs/compute-risk-analysis to learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `state` - PENDING|RUNNING|CANCELED|FINISHED|FAILED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - `trigger_name` - The resource name of the trigger that created job. + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * Supported fields for risk analysis jobs: + * - `state` - RUNNING|CANCELED|FINISHED|FAILED + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * The operator must be `=` or `!=`. + * + * Examples: + * + * * inspected_storage = cloud_storage AND state = done + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = done OR state = canceled) + * * end_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {number} request.pageSize + * The standard list page size. + * @param {string} request.pageToken + * The standard list page token. + * @param {google.privacy.dlp.v2.DlpJobType} request.type + * The type of job. Defaults to `DlpJobType.INSPECT` + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, end_time asc, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the job was created. + * - `end_time`: corresponds to time the job ended. + * - `name`: corresponds to job's name. + * - `state`: corresponds to `state` + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is Array of [DlpJob]{@link google.privacy.dlp.v2.DlpJob}. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed and will merge results from all the pages into this array. + * Note that it can affect your quota. + * We recommend using `listDlpJobsAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listDlpJobs( + request: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + optionsOrCallback?: + | CallOptions + | PaginationCallback< + protos.google.privacy.dlp.v2.IListDlpJobsRequest, + protos.google.privacy.dlp.v2.IListDlpJobsResponse | null | undefined, + protos.google.privacy.dlp.v2.IDlpJob + >, + callback?: PaginationCallback< + protos.google.privacy.dlp.v2.IListDlpJobsRequest, + protos.google.privacy.dlp.v2.IListDlpJobsResponse | null | undefined, + protos.google.privacy.dlp.v2.IDlpJob + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IDlpJob[], + protos.google.privacy.dlp.v2.IListDlpJobsRequest | null, + protos.google.privacy.dlp.v2.IListDlpJobsResponse + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listDlpJobs(request, options, callback); + } + + /** + * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `state` - PENDING|RUNNING|CANCELED|FINISHED|FAILED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - `trigger_name` - The resource name of the trigger that created job. + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * Supported fields for risk analysis jobs: + * - `state` - RUNNING|CANCELED|FINISHED|FAILED + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * The operator must be `=` or `!=`. + * + * Examples: + * + * * inspected_storage = cloud_storage AND state = done + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = done OR state = canceled) + * * end_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {number} request.pageSize + * The standard list page size. + * @param {string} request.pageToken + * The standard list page token. + * @param {google.privacy.dlp.v2.DlpJobType} request.type + * The type of job. Defaults to `DlpJobType.INSPECT` + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, end_time asc, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the job was created. + * - `end_time`: corresponds to time the job ended. + * - `name`: corresponds to job's name. + * - `state`: corresponds to `state` + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Stream} + * An object stream which emits an object representing [DlpJob]{@link google.privacy.dlp.v2.DlpJob} on 'data' event. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed. Note that it can affect your quota. + * We recommend using `listDlpJobsAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listDlpJobsStream( + request?: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + options?: CallOptions + ): Transform { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listDlpJobs.createStream( + this.innerApiCalls.listDlpJobs as gax.GaxCall, + request, + callSettings + ); + } + + /** + * Equivalent to `listDlpJobs`, but returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on whether you have [specified a + * processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.filter + * Allows filtering. + * + * Supported syntax: + * + * * Filter expressions are made up of one or more restrictions. + * * Restrictions can be combined by `AND` or `OR` logical operators. A + * sequence of restrictions implicitly uses `AND`. + * * A restriction has the form of `{field} {operator} {value}`. + * * Supported fields/values for inspect jobs: + * - `state` - PENDING|RUNNING|CANCELED|FINISHED|FAILED + * - `inspected_storage` - DATASTORE|CLOUD_STORAGE|BIGQUERY + * - `trigger_name` - The resource name of the trigger that created job. + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * Supported fields for risk analysis jobs: + * - `state` - RUNNING|CANCELED|FINISHED|FAILED + * - 'end_time` - Corresponds to time the job finished. + * - 'start_time` - Corresponds to time the job finished. + * * The operator must be `=` or `!=`. + * + * Examples: + * + * * inspected_storage = cloud_storage AND state = done + * * inspected_storage = cloud_storage OR inspected_storage = bigquery + * * inspected_storage = cloud_storage AND (state = done OR state = canceled) + * * end_time > \"2017-12-12T00:00:00+00:00\" + * + * The length of this field should be no more than 500 characters. + * @param {number} request.pageSize + * The standard list page size. + * @param {string} request.pageToken + * The standard list page token. + * @param {google.privacy.dlp.v2.DlpJobType} request.type + * The type of job. Defaults to `DlpJobType.INSPECT` + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, end_time asc, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the job was created. + * - `end_time`: corresponds to time the job ended. + * - `name`: corresponds to job's name. + * - `state`: corresponds to `state` + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [DlpJob]{@link google.privacy.dlp.v2.DlpJob}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * const iterable = client.listDlpJobsAsync(request); + * for await (const response of iterable) { + * // process response + * } + */ + listDlpJobsAsync( + request?: protos.google.privacy.dlp.v2.IListDlpJobsRequest, + options?: CallOptions + ): AsyncIterable { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + options = options || {}; + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listDlpJobs.asyncIterate( + this.innerApiCalls['listDlpJobs'] as GaxCall, + (request as unknown) as RequestType, + callSettings + ) as AsyncIterable; + } + listStoredInfoTypes( + request: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + options?: CallOptions + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType[], + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest | null, + protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + ] + >; + listStoredInfoTypes( + request: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + options: CallOptions, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + | protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IStoredInfoType + > + ): void; + listStoredInfoTypes( + request: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + callback: PaginationCallback< + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + | protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IStoredInfoType + > + ): void; + /** + * Lists stored infoTypes. + * See https://cloud.google.com/dlp/docs/creating-stored-infotypes to + * learn more. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListStoredInfoTypes`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, display_name, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the most recent version of the + * resource was created. + * - `state`: corresponds to the state of the resource. + * - `name`: corresponds to resource name. + * - `display_name`: corresponds to info type's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is Array of [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType}. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed and will merge results from all the pages into this array. + * Note that it can affect your quota. + * We recommend using `listStoredInfoTypesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listStoredInfoTypes( + request: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + optionsOrCallback?: + | CallOptions + | PaginationCallback< + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + | protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IStoredInfoType + >, + callback?: PaginationCallback< + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + | protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + | null + | undefined, + protos.google.privacy.dlp.v2.IStoredInfoType + > + ): Promise< + [ + protos.google.privacy.dlp.v2.IStoredInfoType[], + protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest | null, + protos.google.privacy.dlp.v2.IListStoredInfoTypesResponse + ] + > | void { + request = request || {}; + let options: CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } else { + options = optionsOrCallback as CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listStoredInfoTypes(request, options, callback); + } + + /** + * Equivalent to `method.name.toCamelCase()`, but returns a NodeJS Stream object. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListStoredInfoTypes`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, display_name, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the most recent version of the + * resource was created. + * - `state`: corresponds to the state of the resource. + * - `name`: corresponds to resource name. + * - `display_name`: corresponds to info type's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Stream} + * An object stream which emits an object representing [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType} on 'data' event. + * The client library will perform auto-pagination by default: it will call the API as many + * times as needed. Note that it can affect your quota. + * We recommend using `listStoredInfoTypesAsync()` + * method described below for async iteration which you can stop as needed. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + */ + listStoredInfoTypesStream( + request?: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + options?: CallOptions + ): Transform { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listStoredInfoTypes.createStream( + this.innerApiCalls.listStoredInfoTypes as gax.GaxCall, + request, + callSettings + ); + } + + /** + * Equivalent to `listStoredInfoTypes`, but returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. Parent resource name. + * + * The format of this value varies depending on the scope of the request + * (project or organization) and whether you have [specified a processing + * location](https://cloud.google.com/dlp/docs/specifying-location): + * + * + Projects scope, location specified:
+ * `projects/`PROJECT_ID`/locations/`LOCATION_ID + * + Projects scope, no location specified (defaults to global):
+ * `projects/`PROJECT_ID + * + Organizations scope, location specified:
+ * `organizations/`ORG_ID`/locations/`LOCATION_ID + * + Organizations scope, no location specified (defaults to global):
+ * `organizations/`ORG_ID + * + * The following example `parent` string specifies a parent project with the + * identifier `example-project`, and specifies the `europe-west3` location + * for processing data: + * + * parent=projects/example-project/locations/europe-west3 + * @param {string} request.pageToken + * Page token to continue retrieval. Comes from previous call + * to `ListStoredInfoTypes`. + * @param {number} request.pageSize + * Size of the page, can be limited by server. If zero server returns + * a page of max size 100. + * @param {string} request.orderBy + * Comma separated list of fields to order by, + * followed by `asc` or `desc` postfix. This list is case-insensitive, + * default sorting order is ascending, redundant space characters are + * insignificant. + * + * Example: `name asc, display_name, create_time desc` + * + * Supported fields are: + * + * - `create_time`: corresponds to time the most recent version of the + * resource was created. + * - `state`: corresponds to the state of the resource. + * - `name`: corresponds to resource name. + * - `display_name`: corresponds to info type's display name. + * @param {string} request.locationId + * Deprecated. This field has no effect. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [StoredInfoType]{@link google.privacy.dlp.v2.StoredInfoType}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * const iterable = client.listStoredInfoTypesAsync(request); + * for await (const response of iterable) { + * // process response + * } + */ + listStoredInfoTypesAsync( + request?: protos.google.privacy.dlp.v2.IListStoredInfoTypesRequest, + options?: CallOptions + ): AsyncIterable { + request = request || {}; + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + parent: request.parent || '', + }); + options = options || {}; + const callSettings = new gax.CallSettings(options); + this.initialize(); + return this.descriptors.page.listStoredInfoTypes.asyncIterate( + this.innerApiCalls['listStoredInfoTypes'] as GaxCall, + (request as unknown) as RequestType, + callSettings + ) as AsyncIterable; + } + // -------------------- + // -- Path templates -- + // -------------------- + + /** + * Return a fully-qualified finding resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} finding + * @returns {string} Resource name string. + */ + findingPath(project: string, location: string, finding: string) { + return this.pathTemplates.findingPathTemplate.render({ + project: project, + location: location, + finding: finding, + }); + } + + /** + * Parse the project from Finding resource. + * + * @param {string} findingName + * A fully-qualified path representing Finding resource. + * @returns {string} A string representing the project. + */ + matchProjectFromFindingName(findingName: string) { + return this.pathTemplates.findingPathTemplate.match(findingName).project; + } + + /** + * Parse the location from Finding resource. + * + * @param {string} findingName + * A fully-qualified path representing Finding resource. + * @returns {string} A string representing the location. + */ + matchLocationFromFindingName(findingName: string) { + return this.pathTemplates.findingPathTemplate.match(findingName).location; + } + + /** + * Parse the finding from Finding resource. + * + * @param {string} findingName + * A fully-qualified path representing Finding resource. + * @returns {string} A string representing the finding. + */ + matchFindingFromFindingName(findingName: string) { + return this.pathTemplates.findingPathTemplate.match(findingName).finding; + } + + /** + * Return a fully-qualified organization resource name string. + * + * @param {string} organization + * @returns {string} Resource name string. + */ + organizationPath(organization: string) { + return this.pathTemplates.organizationPathTemplate.render({ + organization: organization, + }); + } + + /** + * Parse the organization from Organization resource. + * + * @param {string} organizationName + * A fully-qualified path representing Organization resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationName(organizationName: string) { + return this.pathTemplates.organizationPathTemplate.match(organizationName) + .organization; + } + + /** + * Return a fully-qualified organizationDeidentifyTemplate resource name string. + * + * @param {string} organization + * @param {string} deidentify_template + * @returns {string} Resource name string. + */ + organizationDeidentifyTemplatePath( + organization: string, + deidentifyTemplate: string + ) { + return this.pathTemplates.organizationDeidentifyTemplatePathTemplate.render( + { + organization: organization, + deidentify_template: deidentifyTemplate, + } + ); + } + + /** + * Parse the organization from OrganizationDeidentifyTemplate resource. + * + * @param {string} organizationDeidentifyTemplateName + * A fully-qualified path representing organization_deidentify_template resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationDeidentifyTemplateName( + organizationDeidentifyTemplateName: string + ) { + return this.pathTemplates.organizationDeidentifyTemplatePathTemplate.match( + organizationDeidentifyTemplateName + ).organization; + } + + /** + * Parse the deidentify_template from OrganizationDeidentifyTemplate resource. + * + * @param {string} organizationDeidentifyTemplateName + * A fully-qualified path representing organization_deidentify_template resource. + * @returns {string} A string representing the deidentify_template. + */ + matchDeidentifyTemplateFromOrganizationDeidentifyTemplateName( + organizationDeidentifyTemplateName: string + ) { + return this.pathTemplates.organizationDeidentifyTemplatePathTemplate.match( + organizationDeidentifyTemplateName + ).deidentify_template; + } + + /** + * Return a fully-qualified organizationInspectTemplate resource name string. + * + * @param {string} organization + * @param {string} inspect_template + * @returns {string} Resource name string. + */ + organizationInspectTemplatePath( + organization: string, + inspectTemplate: string + ) { + return this.pathTemplates.organizationInspectTemplatePathTemplate.render({ + organization: organization, + inspect_template: inspectTemplate, + }); + } + + /** + * Parse the organization from OrganizationInspectTemplate resource. + * + * @param {string} organizationInspectTemplateName + * A fully-qualified path representing organization_inspect_template resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationInspectTemplateName( + organizationInspectTemplateName: string + ) { + return this.pathTemplates.organizationInspectTemplatePathTemplate.match( + organizationInspectTemplateName + ).organization; + } + + /** + * Parse the inspect_template from OrganizationInspectTemplate resource. + * + * @param {string} organizationInspectTemplateName + * A fully-qualified path representing organization_inspect_template resource. + * @returns {string} A string representing the inspect_template. + */ + matchInspectTemplateFromOrganizationInspectTemplateName( + organizationInspectTemplateName: string + ) { + return this.pathTemplates.organizationInspectTemplatePathTemplate.match( + organizationInspectTemplateName + ).inspect_template; + } + + /** + * Return a fully-qualified organizationLocationDeidentifyTemplate resource name string. + * + * @param {string} organization + * @param {string} location + * @param {string} deidentify_template + * @returns {string} Resource name string. + */ + organizationLocationDeidentifyTemplatePath( + organization: string, + location: string, + deidentifyTemplate: string + ) { + return this.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.render( + { + organization: organization, + location: location, + deidentify_template: deidentifyTemplate, + } + ); + } + + /** + * Parse the organization from OrganizationLocationDeidentifyTemplate resource. + * + * @param {string} organizationLocationDeidentifyTemplateName + * A fully-qualified path representing organization_location_deidentify_template resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationLocationDeidentifyTemplateName( + organizationLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.match( + organizationLocationDeidentifyTemplateName + ).organization; + } + + /** + * Parse the location from OrganizationLocationDeidentifyTemplate resource. + * + * @param {string} organizationLocationDeidentifyTemplateName + * A fully-qualified path representing organization_location_deidentify_template resource. + * @returns {string} A string representing the location. + */ + matchLocationFromOrganizationLocationDeidentifyTemplateName( + organizationLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.match( + organizationLocationDeidentifyTemplateName + ).location; + } + + /** + * Parse the deidentify_template from OrganizationLocationDeidentifyTemplate resource. + * + * @param {string} organizationLocationDeidentifyTemplateName + * A fully-qualified path representing organization_location_deidentify_template resource. + * @returns {string} A string representing the deidentify_template. + */ + matchDeidentifyTemplateFromOrganizationLocationDeidentifyTemplateName( + organizationLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.match( + organizationLocationDeidentifyTemplateName + ).deidentify_template; + } + + /** + * Return a fully-qualified organizationLocationInspectTemplate resource name string. + * + * @param {string} organization + * @param {string} location + * @param {string} inspect_template + * @returns {string} Resource name string. + */ + organizationLocationInspectTemplatePath( + organization: string, + location: string, + inspectTemplate: string + ) { + return this.pathTemplates.organizationLocationInspectTemplatePathTemplate.render( + { + organization: organization, + location: location, + inspect_template: inspectTemplate, + } + ); + } + + /** + * Parse the organization from OrganizationLocationInspectTemplate resource. + * + * @param {string} organizationLocationInspectTemplateName + * A fully-qualified path representing organization_location_inspect_template resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationLocationInspectTemplateName( + organizationLocationInspectTemplateName: string + ) { + return this.pathTemplates.organizationLocationInspectTemplatePathTemplate.match( + organizationLocationInspectTemplateName + ).organization; + } + + /** + * Parse the location from OrganizationLocationInspectTemplate resource. + * + * @param {string} organizationLocationInspectTemplateName + * A fully-qualified path representing organization_location_inspect_template resource. + * @returns {string} A string representing the location. + */ + matchLocationFromOrganizationLocationInspectTemplateName( + organizationLocationInspectTemplateName: string + ) { + return this.pathTemplates.organizationLocationInspectTemplatePathTemplate.match( + organizationLocationInspectTemplateName + ).location; + } + + /** + * Parse the inspect_template from OrganizationLocationInspectTemplate resource. + * + * @param {string} organizationLocationInspectTemplateName + * A fully-qualified path representing organization_location_inspect_template resource. + * @returns {string} A string representing the inspect_template. + */ + matchInspectTemplateFromOrganizationLocationInspectTemplateName( + organizationLocationInspectTemplateName: string + ) { + return this.pathTemplates.organizationLocationInspectTemplatePathTemplate.match( + organizationLocationInspectTemplateName + ).inspect_template; + } + + /** + * Return a fully-qualified organizationLocationStoredInfoType resource name string. + * + * @param {string} organization + * @param {string} location + * @param {string} stored_info_type + * @returns {string} Resource name string. + */ + organizationLocationStoredInfoTypePath( + organization: string, + location: string, + storedInfoType: string + ) { + return this.pathTemplates.organizationLocationStoredInfoTypePathTemplate.render( + { + organization: organization, + location: location, + stored_info_type: storedInfoType, + } + ); + } + + /** + * Parse the organization from OrganizationLocationStoredInfoType resource. + * + * @param {string} organizationLocationStoredInfoTypeName + * A fully-qualified path representing organization_location_stored_info_type resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationLocationStoredInfoTypeName( + organizationLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.organizationLocationStoredInfoTypePathTemplate.match( + organizationLocationStoredInfoTypeName + ).organization; + } + + /** + * Parse the location from OrganizationLocationStoredInfoType resource. + * + * @param {string} organizationLocationStoredInfoTypeName + * A fully-qualified path representing organization_location_stored_info_type resource. + * @returns {string} A string representing the location. + */ + matchLocationFromOrganizationLocationStoredInfoTypeName( + organizationLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.organizationLocationStoredInfoTypePathTemplate.match( + organizationLocationStoredInfoTypeName + ).location; + } + + /** + * Parse the stored_info_type from OrganizationLocationStoredInfoType resource. + * + * @param {string} organizationLocationStoredInfoTypeName + * A fully-qualified path representing organization_location_stored_info_type resource. + * @returns {string} A string representing the stored_info_type. + */ + matchStoredInfoTypeFromOrganizationLocationStoredInfoTypeName( + organizationLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.organizationLocationStoredInfoTypePathTemplate.match( + organizationLocationStoredInfoTypeName + ).stored_info_type; + } + + /** + * Return a fully-qualified organizationStoredInfoType resource name string. + * + * @param {string} organization + * @param {string} stored_info_type + * @returns {string} Resource name string. + */ + organizationStoredInfoTypePath(organization: string, storedInfoType: string) { + return this.pathTemplates.organizationStoredInfoTypePathTemplate.render({ + organization: organization, + stored_info_type: storedInfoType, + }); + } + + /** + * Parse the organization from OrganizationStoredInfoType resource. + * + * @param {string} organizationStoredInfoTypeName + * A fully-qualified path representing organization_stored_info_type resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationStoredInfoTypeName( + organizationStoredInfoTypeName: string + ) { + return this.pathTemplates.organizationStoredInfoTypePathTemplate.match( + organizationStoredInfoTypeName + ).organization; + } + + /** + * Parse the stored_info_type from OrganizationStoredInfoType resource. + * + * @param {string} organizationStoredInfoTypeName + * A fully-qualified path representing organization_stored_info_type resource. + * @returns {string} A string representing the stored_info_type. + */ + matchStoredInfoTypeFromOrganizationStoredInfoTypeName( + organizationStoredInfoTypeName: string + ) { + return this.pathTemplates.organizationStoredInfoTypePathTemplate.match( + organizationStoredInfoTypeName + ).stored_info_type; + } + + /** + * Return a fully-qualified project resource name string. + * + * @param {string} project + * @returns {string} Resource name string. + */ + projectPath(project: string) { + return this.pathTemplates.projectPathTemplate.render({ + project: project, + }); + } + + /** + * Parse the project from Project resource. + * + * @param {string} projectName + * A fully-qualified path representing Project resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectName(projectName: string) { + return this.pathTemplates.projectPathTemplate.match(projectName).project; + } + + /** + * Return a fully-qualified projectDeidentifyTemplate resource name string. + * + * @param {string} project + * @param {string} deidentify_template + * @returns {string} Resource name string. + */ + projectDeidentifyTemplatePath(project: string, deidentifyTemplate: string) { + return this.pathTemplates.projectDeidentifyTemplatePathTemplate.render({ + project: project, + deidentify_template: deidentifyTemplate, + }); + } + + /** + * Parse the project from ProjectDeidentifyTemplate resource. + * + * @param {string} projectDeidentifyTemplateName + * A fully-qualified path representing project_deidentify_template resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectDeidentifyTemplateName( + projectDeidentifyTemplateName: string + ) { + return this.pathTemplates.projectDeidentifyTemplatePathTemplate.match( + projectDeidentifyTemplateName + ).project; + } + + /** + * Parse the deidentify_template from ProjectDeidentifyTemplate resource. + * + * @param {string} projectDeidentifyTemplateName + * A fully-qualified path representing project_deidentify_template resource. + * @returns {string} A string representing the deidentify_template. + */ + matchDeidentifyTemplateFromProjectDeidentifyTemplateName( + projectDeidentifyTemplateName: string + ) { + return this.pathTemplates.projectDeidentifyTemplatePathTemplate.match( + projectDeidentifyTemplateName + ).deidentify_template; + } + + /** + * Return a fully-qualified projectDlpContent resource name string. + * + * @param {string} project + * @returns {string} Resource name string. + */ + projectDlpContentPath(project: string) { + return this.pathTemplates.projectDlpContentPathTemplate.render({ + project: project, + }); + } + + /** + * Parse the project from ProjectDlpContent resource. + * + * @param {string} projectDlpContentName + * A fully-qualified path representing project_dlpContent resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectDlpContentName(projectDlpContentName: string) { + return this.pathTemplates.projectDlpContentPathTemplate.match( + projectDlpContentName + ).project; + } + + /** + * Return a fully-qualified projectDlpJob resource name string. + * + * @param {string} project + * @param {string} dlp_job + * @returns {string} Resource name string. + */ + projectDlpJobPath(project: string, dlpJob: string) { + return this.pathTemplates.projectDlpJobPathTemplate.render({ + project: project, + dlp_job: dlpJob, + }); + } + + /** + * Parse the project from ProjectDlpJob resource. + * + * @param {string} projectDlpJobName + * A fully-qualified path representing project_dlp_job resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectDlpJobName(projectDlpJobName: string) { + return this.pathTemplates.projectDlpJobPathTemplate.match(projectDlpJobName) + .project; + } + + /** + * Parse the dlp_job from ProjectDlpJob resource. + * + * @param {string} projectDlpJobName + * A fully-qualified path representing project_dlp_job resource. + * @returns {string} A string representing the dlp_job. + */ + matchDlpJobFromProjectDlpJobName(projectDlpJobName: string) { + return this.pathTemplates.projectDlpJobPathTemplate.match(projectDlpJobName) + .dlp_job; + } + + /** + * Return a fully-qualified projectInspectTemplate resource name string. + * + * @param {string} project + * @param {string} inspect_template + * @returns {string} Resource name string. + */ + projectInspectTemplatePath(project: string, inspectTemplate: string) { + return this.pathTemplates.projectInspectTemplatePathTemplate.render({ + project: project, + inspect_template: inspectTemplate, + }); + } + + /** + * Parse the project from ProjectInspectTemplate resource. + * + * @param {string} projectInspectTemplateName + * A fully-qualified path representing project_inspect_template resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectInspectTemplateName( + projectInspectTemplateName: string + ) { + return this.pathTemplates.projectInspectTemplatePathTemplate.match( + projectInspectTemplateName + ).project; + } + + /** + * Parse the inspect_template from ProjectInspectTemplate resource. + * + * @param {string} projectInspectTemplateName + * A fully-qualified path representing project_inspect_template resource. + * @returns {string} A string representing the inspect_template. + */ + matchInspectTemplateFromProjectInspectTemplateName( + projectInspectTemplateName: string + ) { + return this.pathTemplates.projectInspectTemplatePathTemplate.match( + projectInspectTemplateName + ).inspect_template; + } + + /** + * Return a fully-qualified projectJobTrigger resource name string. + * + * @param {string} project + * @param {string} job_trigger + * @returns {string} Resource name string. + */ + projectJobTriggerPath(project: string, jobTrigger: string) { + return this.pathTemplates.projectJobTriggerPathTemplate.render({ + project: project, + job_trigger: jobTrigger, + }); + } + + /** + * Parse the project from ProjectJobTrigger resource. + * + * @param {string} projectJobTriggerName + * A fully-qualified path representing project_job_trigger resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectJobTriggerName(projectJobTriggerName: string) { + return this.pathTemplates.projectJobTriggerPathTemplate.match( + projectJobTriggerName + ).project; + } + + /** + * Parse the job_trigger from ProjectJobTrigger resource. + * + * @param {string} projectJobTriggerName + * A fully-qualified path representing project_job_trigger resource. + * @returns {string} A string representing the job_trigger. + */ + matchJobTriggerFromProjectJobTriggerName(projectJobTriggerName: string) { + return this.pathTemplates.projectJobTriggerPathTemplate.match( + projectJobTriggerName + ).job_trigger; + } + + /** + * Return a fully-qualified projectLocationDeidentifyTemplate resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} deidentify_template + * @returns {string} Resource name string. + */ + projectLocationDeidentifyTemplatePath( + project: string, + location: string, + deidentifyTemplate: string + ) { + return this.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.render( + { + project: project, + location: location, + deidentify_template: deidentifyTemplate, + } + ); + } + + /** + * Parse the project from ProjectLocationDeidentifyTemplate resource. + * + * @param {string} projectLocationDeidentifyTemplateName + * A fully-qualified path representing project_location_deidentify_template resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectLocationDeidentifyTemplateName( + projectLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.match( + projectLocationDeidentifyTemplateName + ).project; + } + + /** + * Parse the location from ProjectLocationDeidentifyTemplate resource. + * + * @param {string} projectLocationDeidentifyTemplateName + * A fully-qualified path representing project_location_deidentify_template resource. + * @returns {string} A string representing the location. + */ + matchLocationFromProjectLocationDeidentifyTemplateName( + projectLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.match( + projectLocationDeidentifyTemplateName + ).location; + } + + /** + * Parse the deidentify_template from ProjectLocationDeidentifyTemplate resource. + * + * @param {string} projectLocationDeidentifyTemplateName + * A fully-qualified path representing project_location_deidentify_template resource. + * @returns {string} A string representing the deidentify_template. + */ + matchDeidentifyTemplateFromProjectLocationDeidentifyTemplateName( + projectLocationDeidentifyTemplateName: string + ) { + return this.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.match( + projectLocationDeidentifyTemplateName + ).deidentify_template; + } + + /** + * Return a fully-qualified projectLocationDlpJob resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} dlp_job + * @returns {string} Resource name string. + */ + projectLocationDlpJobPath(project: string, location: string, dlpJob: string) { + return this.pathTemplates.projectLocationDlpJobPathTemplate.render({ + project: project, + location: location, + dlp_job: dlpJob, + }); + } + + /** + * Parse the project from ProjectLocationDlpJob resource. + * + * @param {string} projectLocationDlpJobName + * A fully-qualified path representing project_location_dlp_job resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectLocationDlpJobName(projectLocationDlpJobName: string) { + return this.pathTemplates.projectLocationDlpJobPathTemplate.match( + projectLocationDlpJobName + ).project; + } + + /** + * Parse the location from ProjectLocationDlpJob resource. + * + * @param {string} projectLocationDlpJobName + * A fully-qualified path representing project_location_dlp_job resource. + * @returns {string} A string representing the location. + */ + matchLocationFromProjectLocationDlpJobName( + projectLocationDlpJobName: string + ) { + return this.pathTemplates.projectLocationDlpJobPathTemplate.match( + projectLocationDlpJobName + ).location; + } + + /** + * Parse the dlp_job from ProjectLocationDlpJob resource. + * + * @param {string} projectLocationDlpJobName + * A fully-qualified path representing project_location_dlp_job resource. + * @returns {string} A string representing the dlp_job. + */ + matchDlpJobFromProjectLocationDlpJobName(projectLocationDlpJobName: string) { + return this.pathTemplates.projectLocationDlpJobPathTemplate.match( + projectLocationDlpJobName + ).dlp_job; + } + + /** + * Return a fully-qualified projectLocationInspectTemplate resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} inspect_template + * @returns {string} Resource name string. + */ + projectLocationInspectTemplatePath( + project: string, + location: string, + inspectTemplate: string + ) { + return this.pathTemplates.projectLocationInspectTemplatePathTemplate.render( + { + project: project, + location: location, + inspect_template: inspectTemplate, + } + ); + } + + /** + * Parse the project from ProjectLocationInspectTemplate resource. + * + * @param {string} projectLocationInspectTemplateName + * A fully-qualified path representing project_location_inspect_template resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectLocationInspectTemplateName( + projectLocationInspectTemplateName: string + ) { + return this.pathTemplates.projectLocationInspectTemplatePathTemplate.match( + projectLocationInspectTemplateName + ).project; + } + + /** + * Parse the location from ProjectLocationInspectTemplate resource. + * + * @param {string} projectLocationInspectTemplateName + * A fully-qualified path representing project_location_inspect_template resource. + * @returns {string} A string representing the location. + */ + matchLocationFromProjectLocationInspectTemplateName( + projectLocationInspectTemplateName: string + ) { + return this.pathTemplates.projectLocationInspectTemplatePathTemplate.match( + projectLocationInspectTemplateName + ).location; + } + + /** + * Parse the inspect_template from ProjectLocationInspectTemplate resource. + * + * @param {string} projectLocationInspectTemplateName + * A fully-qualified path representing project_location_inspect_template resource. + * @returns {string} A string representing the inspect_template. + */ + matchInspectTemplateFromProjectLocationInspectTemplateName( + projectLocationInspectTemplateName: string + ) { + return this.pathTemplates.projectLocationInspectTemplatePathTemplate.match( + projectLocationInspectTemplateName + ).inspect_template; + } + + /** + * Return a fully-qualified projectLocationJobTrigger resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} job_trigger + * @returns {string} Resource name string. + */ + projectLocationJobTriggerPath( + project: string, + location: string, + jobTrigger: string + ) { + return this.pathTemplates.projectLocationJobTriggerPathTemplate.render({ + project: project, + location: location, + job_trigger: jobTrigger, + }); + } + + /** + * Parse the project from ProjectLocationJobTrigger resource. + * + * @param {string} projectLocationJobTriggerName + * A fully-qualified path representing project_location_job_trigger resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectLocationJobTriggerName( + projectLocationJobTriggerName: string + ) { + return this.pathTemplates.projectLocationJobTriggerPathTemplate.match( + projectLocationJobTriggerName + ).project; + } + + /** + * Parse the location from ProjectLocationJobTrigger resource. + * + * @param {string} projectLocationJobTriggerName + * A fully-qualified path representing project_location_job_trigger resource. + * @returns {string} A string representing the location. + */ + matchLocationFromProjectLocationJobTriggerName( + projectLocationJobTriggerName: string + ) { + return this.pathTemplates.projectLocationJobTriggerPathTemplate.match( + projectLocationJobTriggerName + ).location; + } + + /** + * Parse the job_trigger from ProjectLocationJobTrigger resource. + * + * @param {string} projectLocationJobTriggerName + * A fully-qualified path representing project_location_job_trigger resource. + * @returns {string} A string representing the job_trigger. + */ + matchJobTriggerFromProjectLocationJobTriggerName( + projectLocationJobTriggerName: string + ) { + return this.pathTemplates.projectLocationJobTriggerPathTemplate.match( + projectLocationJobTriggerName + ).job_trigger; + } + + /** + * Return a fully-qualified projectLocationStoredInfoType resource name string. + * + * @param {string} project + * @param {string} location + * @param {string} stored_info_type + * @returns {string} Resource name string. + */ + projectLocationStoredInfoTypePath( + project: string, + location: string, + storedInfoType: string + ) { + return this.pathTemplates.projectLocationStoredInfoTypePathTemplate.render({ + project: project, + location: location, + stored_info_type: storedInfoType, + }); + } + + /** + * Parse the project from ProjectLocationStoredInfoType resource. + * + * @param {string} projectLocationStoredInfoTypeName + * A fully-qualified path representing project_location_stored_info_type resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectLocationStoredInfoTypeName( + projectLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.projectLocationStoredInfoTypePathTemplate.match( + projectLocationStoredInfoTypeName + ).project; + } + + /** + * Parse the location from ProjectLocationStoredInfoType resource. + * + * @param {string} projectLocationStoredInfoTypeName + * A fully-qualified path representing project_location_stored_info_type resource. + * @returns {string} A string representing the location. + */ + matchLocationFromProjectLocationStoredInfoTypeName( + projectLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.projectLocationStoredInfoTypePathTemplate.match( + projectLocationStoredInfoTypeName + ).location; + } + + /** + * Parse the stored_info_type from ProjectLocationStoredInfoType resource. + * + * @param {string} projectLocationStoredInfoTypeName + * A fully-qualified path representing project_location_stored_info_type resource. + * @returns {string} A string representing the stored_info_type. + */ + matchStoredInfoTypeFromProjectLocationStoredInfoTypeName( + projectLocationStoredInfoTypeName: string + ) { + return this.pathTemplates.projectLocationStoredInfoTypePathTemplate.match( + projectLocationStoredInfoTypeName + ).stored_info_type; + } + + /** + * Return a fully-qualified projectStoredInfoType resource name string. + * + * @param {string} project + * @param {string} stored_info_type + * @returns {string} Resource name string. + */ + projectStoredInfoTypePath(project: string, storedInfoType: string) { + return this.pathTemplates.projectStoredInfoTypePathTemplate.render({ + project: project, + stored_info_type: storedInfoType, + }); + } + + /** + * Parse the project from ProjectStoredInfoType resource. + * + * @param {string} projectStoredInfoTypeName + * A fully-qualified path representing project_stored_info_type resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectStoredInfoTypeName(projectStoredInfoTypeName: string) { + return this.pathTemplates.projectStoredInfoTypePathTemplate.match( + projectStoredInfoTypeName + ).project; + } + + /** + * Parse the stored_info_type from ProjectStoredInfoType resource. + * + * @param {string} projectStoredInfoTypeName + * A fully-qualified path representing project_stored_info_type resource. + * @returns {string} A string representing the stored_info_type. + */ + matchStoredInfoTypeFromProjectStoredInfoTypeName( + projectStoredInfoTypeName: string + ) { + return this.pathTemplates.projectStoredInfoTypePathTemplate.match( + projectStoredInfoTypeName + ).stored_info_type; + } + + /** + * Terminate the gRPC channel and close the client. + * + * The client will no longer be usable and all future behavior is undefined. + * @returns {Promise} A promise that resolves when the client is closed. + */ + close(): Promise { + this.initialize(); + if (!this._terminated) { + return this.dlpServiceStub!.then(stub => { + this._terminated = true; + stub.close(); + }); + } + return Promise.resolve(); + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client_config.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client_config.json new file mode 100644 index 000000000..bcdbe63fe --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_client_config.json @@ -0,0 +1,196 @@ +{ + "interfaces": { + "google.privacy.dlp.v2.DlpService": { + "retry_codes": { + "non_idempotent": [], + "idempotent": [ + "DEADLINE_EXCEEDED", + "UNAVAILABLE" + ] + }, + "retry_params": { + "default": { + "initial_retry_delay_millis": 100, + "retry_delay_multiplier": 1.3, + "max_retry_delay_millis": 60000, + "initial_rpc_timeout_millis": 60000, + "rpc_timeout_multiplier": 1, + "max_rpc_timeout_millis": 60000, + "total_timeout_millis": 600000 + } + }, + "methods": { + "InspectContent": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "RedactImage": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeidentifyContent": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ReidentifyContent": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ListInfoTypes": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "CreateInspectTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "UpdateInspectTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "GetInspectTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ListInspectTemplates": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeleteInspectTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "CreateDeidentifyTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "UpdateDeidentifyTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "GetDeidentifyTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ListDeidentifyTemplates": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeleteDeidentifyTemplate": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "CreateJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "UpdateJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "HybridInspectJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "GetJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ListJobTriggers": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeleteJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ActivateJobTrigger": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "CreateDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "ListDlpJobs": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "GetDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeleteDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "CancelDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "CreateStoredInfoType": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "UpdateStoredInfoType": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "GetStoredInfoType": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "ListStoredInfoTypes": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "DeleteStoredInfoType": { + "timeout_millis": 300000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + }, + "HybridInspectDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "FinishDlpJob": { + "timeout_millis": 300000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + } + } + } + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_proto_list.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_proto_list.json new file mode 100644 index 000000000..482924bde --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/dlp_service_proto_list.json @@ -0,0 +1,4 @@ +[ + "../../protos/google/privacy/dlp/v2/dlp.proto", + "../../protos/google/privacy/dlp/v2/storage.proto" +] diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/gapic_metadata.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/gapic_metadata.json new file mode 100644 index 000000000..e82d006d6 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/gapic_metadata.json @@ -0,0 +1,383 @@ +{ + "schema": "1.0", + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "typescript", + "protoPackage": "google.privacy.dlp.v2", + "libraryPackage": "@google-cloud/dlp", + "services": { + "DlpService": { + "clients": { + "grpc": { + "libraryClient": "DlpServiceClient", + "rpcs": { + "InspectContent": { + "methods": [ + "inspectContent" + ] + }, + "RedactImage": { + "methods": [ + "redactImage" + ] + }, + "DeidentifyContent": { + "methods": [ + "deidentifyContent" + ] + }, + "ReidentifyContent": { + "methods": [ + "reidentifyContent" + ] + }, + "ListInfoTypes": { + "methods": [ + "listInfoTypes" + ] + }, + "CreateInspectTemplate": { + "methods": [ + "createInspectTemplate" + ] + }, + "UpdateInspectTemplate": { + "methods": [ + "updateInspectTemplate" + ] + }, + "GetInspectTemplate": { + "methods": [ + "getInspectTemplate" + ] + }, + "DeleteInspectTemplate": { + "methods": [ + "deleteInspectTemplate" + ] + }, + "CreateDeidentifyTemplate": { + "methods": [ + "createDeidentifyTemplate" + ] + }, + "UpdateDeidentifyTemplate": { + "methods": [ + "updateDeidentifyTemplate" + ] + }, + "GetDeidentifyTemplate": { + "methods": [ + "getDeidentifyTemplate" + ] + }, + "DeleteDeidentifyTemplate": { + "methods": [ + "deleteDeidentifyTemplate" + ] + }, + "CreateJobTrigger": { + "methods": [ + "createJobTrigger" + ] + }, + "UpdateJobTrigger": { + "methods": [ + "updateJobTrigger" + ] + }, + "HybridInspectJobTrigger": { + "methods": [ + "hybridInspectJobTrigger" + ] + }, + "GetJobTrigger": { + "methods": [ + "getJobTrigger" + ] + }, + "DeleteJobTrigger": { + "methods": [ + "deleteJobTrigger" + ] + }, + "ActivateJobTrigger": { + "methods": [ + "activateJobTrigger" + ] + }, + "CreateDlpJob": { + "methods": [ + "createDlpJob" + ] + }, + "GetDlpJob": { + "methods": [ + "getDlpJob" + ] + }, + "DeleteDlpJob": { + "methods": [ + "deleteDlpJob" + ] + }, + "CancelDlpJob": { + "methods": [ + "cancelDlpJob" + ] + }, + "CreateStoredInfoType": { + "methods": [ + "createStoredInfoType" + ] + }, + "UpdateStoredInfoType": { + "methods": [ + "updateStoredInfoType" + ] + }, + "GetStoredInfoType": { + "methods": [ + "getStoredInfoType" + ] + }, + "DeleteStoredInfoType": { + "methods": [ + "deleteStoredInfoType" + ] + }, + "HybridInspectDlpJob": { + "methods": [ + "hybridInspectDlpJob" + ] + }, + "FinishDlpJob": { + "methods": [ + "finishDlpJob" + ] + }, + "ListInspectTemplates": { + "methods": [ + "listInspectTemplates", + "listInspectTemplatesStream", + "listInspectTemplatesAsync" + ] + }, + "ListDeidentifyTemplates": { + "methods": [ + "listDeidentifyTemplates", + "listDeidentifyTemplatesStream", + "listDeidentifyTemplatesAsync" + ] + }, + "ListJobTriggers": { + "methods": [ + "listJobTriggers", + "listJobTriggersStream", + "listJobTriggersAsync" + ] + }, + "ListDlpJobs": { + "methods": [ + "listDlpJobs", + "listDlpJobsStream", + "listDlpJobsAsync" + ] + }, + "ListStoredInfoTypes": { + "methods": [ + "listStoredInfoTypes", + "listStoredInfoTypesStream", + "listStoredInfoTypesAsync" + ] + } + } + }, + "grpc-fallback": { + "libraryClient": "DlpServiceClient", + "rpcs": { + "InspectContent": { + "methods": [ + "inspectContent" + ] + }, + "RedactImage": { + "methods": [ + "redactImage" + ] + }, + "DeidentifyContent": { + "methods": [ + "deidentifyContent" + ] + }, + "ReidentifyContent": { + "methods": [ + "reidentifyContent" + ] + }, + "ListInfoTypes": { + "methods": [ + "listInfoTypes" + ] + }, + "CreateInspectTemplate": { + "methods": [ + "createInspectTemplate" + ] + }, + "UpdateInspectTemplate": { + "methods": [ + "updateInspectTemplate" + ] + }, + "GetInspectTemplate": { + "methods": [ + "getInspectTemplate" + ] + }, + "DeleteInspectTemplate": { + "methods": [ + "deleteInspectTemplate" + ] + }, + "CreateDeidentifyTemplate": { + "methods": [ + "createDeidentifyTemplate" + ] + }, + "UpdateDeidentifyTemplate": { + "methods": [ + "updateDeidentifyTemplate" + ] + }, + "GetDeidentifyTemplate": { + "methods": [ + "getDeidentifyTemplate" + ] + }, + "DeleteDeidentifyTemplate": { + "methods": [ + "deleteDeidentifyTemplate" + ] + }, + "CreateJobTrigger": { + "methods": [ + "createJobTrigger" + ] + }, + "UpdateJobTrigger": { + "methods": [ + "updateJobTrigger" + ] + }, + "HybridInspectJobTrigger": { + "methods": [ + "hybridInspectJobTrigger" + ] + }, + "GetJobTrigger": { + "methods": [ + "getJobTrigger" + ] + }, + "DeleteJobTrigger": { + "methods": [ + "deleteJobTrigger" + ] + }, + "ActivateJobTrigger": { + "methods": [ + "activateJobTrigger" + ] + }, + "CreateDlpJob": { + "methods": [ + "createDlpJob" + ] + }, + "GetDlpJob": { + "methods": [ + "getDlpJob" + ] + }, + "DeleteDlpJob": { + "methods": [ + "deleteDlpJob" + ] + }, + "CancelDlpJob": { + "methods": [ + "cancelDlpJob" + ] + }, + "CreateStoredInfoType": { + "methods": [ + "createStoredInfoType" + ] + }, + "UpdateStoredInfoType": { + "methods": [ + "updateStoredInfoType" + ] + }, + "GetStoredInfoType": { + "methods": [ + "getStoredInfoType" + ] + }, + "DeleteStoredInfoType": { + "methods": [ + "deleteStoredInfoType" + ] + }, + "HybridInspectDlpJob": { + "methods": [ + "hybridInspectDlpJob" + ] + }, + "FinishDlpJob": { + "methods": [ + "finishDlpJob" + ] + }, + "ListInspectTemplates": { + "methods": [ + "listInspectTemplates", + "listInspectTemplatesStream", + "listInspectTemplatesAsync" + ] + }, + "ListDeidentifyTemplates": { + "methods": [ + "listDeidentifyTemplates", + "listDeidentifyTemplatesStream", + "listDeidentifyTemplatesAsync" + ] + }, + "ListJobTriggers": { + "methods": [ + "listJobTriggers", + "listJobTriggersStream", + "listJobTriggersAsync" + ] + }, + "ListDlpJobs": { + "methods": [ + "listDlpJobs", + "listDlpJobsStream", + "listDlpJobsAsync" + ] + }, + "ListStoredInfoTypes": { + "methods": [ + "listStoredInfoTypes", + "listStoredInfoTypesStream", + "listStoredInfoTypesAsync" + ] + } + } + } + } + } + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/index.ts b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/index.ts new file mode 100644 index 000000000..2e558b1cf --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/esm/src/v2/index.ts @@ -0,0 +1,19 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +export {DlpServiceClient} from './dlp_service_client'; diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/linkinator.config.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/linkinator.config.json new file mode 100644 index 000000000..29a223b6d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/linkinator.config.json @@ -0,0 +1,10 @@ +{ + "recurse": true, + "skip": [ + "https://codecov.io/gh/googleapis/", + "www.googleapis.com", + "img.shields.io" + ], + "silent": true, + "concurrency": 10 +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/package.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/package.json new file mode 100644 index 000000000..86aa08d85 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/package.json @@ -0,0 +1,72 @@ +{ + "name": "@google-cloud/dlp", + "description": "DLP API client for Node.js", + "version": "3.1.0", + "license": "Apache-2.0", + "author": "Google Inc", + "engines": { + "node": ">=10" + }, + "repository": "googleapis/nodejs-dlp", + "main": "build/src/index.js", + "files": [ + "build/protos", + "build/src" + ], + "keywords": [ + "google apis client", + "google api client", + "google apis", + "google api", + "google", + "google cloud platform", + "google cloud", + "cloud", + "google dlp", + "dlp", + "DLP API" + ], + "scripts": { + "test": "c8 mocha build/test", + "samples-test": "cd samples/ && npm link ../ && npm install && npm test && cd ../", + "system-test": "mocha build/system-test", + "docs": "jsdoc -c .jsdoc.js", + "lint": "gts check", + "fix": "gts fix", + "docs-test": "linkinator docs", + "clean": "gts clean", + "compile": "tsc -p . && cp -r protos build/", + "compile-protos": "compileProtos src", + "predocs-test": "npm run docs", + "prepare": "npm run compile-protos && npm run compile", + "prelint": "cd samples; npm link ../; npm install", + "precompile": "gts clean", + "api-extractor": "api-extractor run --local", + "api-documenter": "api-documenter yaml --input-folder=temp" + }, + "dependencies": { + "google-gax": "^2.9.2", + "protobufjs": "^6.8.0" + }, + "devDependencies": { + "@types/mocha": "^8.0.0", + "@types/node": "^12.0.0", + "@types/sinon": "^9.0.0", + "c8": "^7.0.0", + "gts": "^2.0.0", + "jsdoc": "^3.5.5", + "jsdoc-fresh": "^1.0.1", + "jsdoc-region-tag": "^1.0.2", + "linkinator": "^2.0.0", + "mocha": "^8.0.0", + "null-loader": "^4.0.0", + "pack-n-play": "^1.0.0-2", + "sinon": "^14.0.0", + "ts-loader": "^9.0.0", + "typescript": "^3.8.3", + "webpack": "^5.0.0", + "webpack-cli": "^4.0.0", + "@microsoft/api-documenter": "^7.8.10", + "@microsoft/api-extractor": "^7.8.10" + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/renovate.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/renovate.json new file mode 100644 index 000000000..9518bf36f --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/renovate.json @@ -0,0 +1,19 @@ +{ + "extends": [ + "config:base", + "docker:disable" + ], + "pinVersions": false, + "rebaseStalePrs": true, + "schedule": [ + "after 9am and before 3pm" + ], + "gitAuthor": null, + "packageRules": [ + { + "extends": "packages:linters", + "groupName": "linters" + } + ], + "ignoreDeps": ["typescript"] +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.eslintrc.yml b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.eslintrc.yml new file mode 100644 index 000000000..b9e0cca8b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.eslintrc.yml @@ -0,0 +1,5 @@ +--- +rules: + no-console: off + no-warning-comments: off + node/no-missing-require: off diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.gitignore b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.gitignore new file mode 100644 index 000000000..df1525596 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/.gitignore @@ -0,0 +1,3 @@ +# Test outputs +*.actual.png +*.actual.csv diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/README.md b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/README.md new file mode 100644 index 000000000..4a08fe0d3 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/README.md @@ -0,0 +1,574 @@ +[//]: # "This README.md file is auto-generated, all changes to this file will be lost." +[//]: # "To regenerate it, use `python -m synthtool`." +Google Cloud Platform logo + +# [Cloud Data Loss Prevention: Node.js Samples](https://github.com/googleapis/nodejs-dlp) + +[![Open in Cloud Shell][shell_img]][shell_link] + +The [Data Loss Prevention API](https://cloud.google.com/dlp/docs/) provides programmatic access to a +powerful detection engine for personally identifiable information and other privacy-sensitive +data in unstructured data streams. + +## Table of Contents + +* [Before you begin](#before-you-begin) +* [Samples](#samples) + * [Categorical Risk Analysis](#categorical-risk-analysis) + * [Inspect Templates](#inspect-templates) + * [Job Triggers](#job-triggers) + * [Deidentify with Date Shift](#deidentify-with-date-shift) + * [Deidentify with FPE](#deidentify-with-fpe) + * [Deidentify with Mask](#deidentify-with-mask) + * [Deidentify with Replacement](#deidentify-with-replacement) + * [Delete Inspect Templates](#delete-inspect-templates) + * [Delete Job](#delete-job) + * [Delete Trigger](#delete-trigger) + * [Inspect Bigquery](#inspect-bigquery) + * [Inspect Datastore](#inspect-datastore) + * [Inspect File](#inspect-file) + * [Inspect GCS File](#inspect-gcs-file) + * [Inspects strings](#inspects-strings) + * [kAnonymity Analysis](#kanonymity-analysis) + * [kMap Estimation Analysis](#kmap-estimation-analysis) + * [l Diversity Analysis](#l-diversity-analysis) + * [List Inspect Templates](#list-inspect-templates) + * [List jobs](#list-jobs) + * [List Triggers](#list-triggers) + * [Metadata](#metadata) + * [Numerical Risk Analysis](#numerical-risk-analysis) + * [Quickstart](#quickstart) + * [Redact Image](#redact-image) + * [Redact Text](#redact-text) + * [Reidentify with FPE](#reidentify-with-fpe) + +## Before you begin + +Before running the samples, make sure you've followed the steps outlined in +[Using the client library](https://github.com/googleapis/nodejs-dlp#using-the-client-library). + +`cd samples` + +`npm install` + +`cd ..` + +## Samples + + + +### Categorical Risk Analysis + +Computes risk metrics of a column of data in a Google BigQuery table. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/categoricalRiskAnalysis.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/categoricalRiskAnalysis.js,samples/README.md) + +__Usage:__ + + +`node categoricalRiskAnalysis.js my-project nhtsa_traffic_fatalities accident_2015 state_name my-topic my-subscription bigquery-public-data` + + +----- + + + + +### Inspect Templates + +Create a new DLP inspection configuration template. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/createInspectTemplate.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/createInspectTemplate.js,samples/README.md) + +__Usage:__ + + +`node createInspectTemplate.js my-project VERY_LIKELY PERSON_NAME 5 false my-template-id` + + +----- + + + + +### Job Triggers + +Create a Data Loss Prevention API job trigger. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/createTrigger.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/createTrigger.js,samples/README.md) + +__Usage:__ + + +`node createTrigger.js my-project triggerId displayName description bucketName autoPopulateTimespan scanPeriod infoTypes minLikelihood maxFindings` + + +----- + + + + +### Deidentify with Date Shift + +Deidentify dates in a CSV file by pseudorandomly shifting them. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithDateShift.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithDateShift.js,samples/README.md) + +__Usage:__ + + +`node deidentifyWithDateShift.js my-project dates.csv dates-shifted.csv 30 30 birth_date register_date [ projects/my-project/locations/global/keyrings/my-keyring]` + + +----- + + + + +### Deidentify with FPE + +Deidentify sensitive data in a string using Format Preserving Encryption (FPE). + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithFpe.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithFpe.js,samples/README.md) + +__Usage:__ + + +`node deidentifyWithFpe.js my-project "My SSN is 372819127" projects/my-project/locations/global/keyrings/my-keyring SSN_TOKEN` + + +----- + + + + +### Deidentify with Mask + +Deidentify sensitive data in a string by masking it with a character. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithMask.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithMask.js,samples/README.md) + +__Usage:__ + + +`node deidentifyWithMask.js my-project string maskingCharacter numberToMask` + + +----- + + + + +### Deidentify with Replacement + +Deidentify sensitive data in a string by replacing it with a given replacement string. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deidentifyWithReplacement.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deidentifyWithReplacement.js,samples/README.md) + +__Usage:__ + + +`node deidentifyWithMask.js my-project string replacement` + + +----- + + + + +### Delete Inspect Templates + +Delete the DLP inspection configuration template with the specified name. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteInspectTemplate.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteInspectTemplate.js,samples/README.md) + +__Usage:__ + + +`node deleteInspectTemplates.js my-project projects/my-project/inspectTemplates/` + + +----- + + + + +### Delete Job + +Delete results of a Data Loss Prevention API job. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteJob.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteJob.js,samples/README.md) + +__Usage:__ + + +`node deleteJob.js my-project projects/YOUR_GCLOUD_PROJECT/dlpJobs/X-` + + +----- + + + + +### Delete Trigger + +Delete results of a Data Loss Prevention API job. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/deleteTrigger.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/deleteTrigger.js,samples/README.md) + +__Usage:__ + + +`node deleteTrigger.js my-rpoject projects/my-project/jobTriggers/my-trigger` + + +----- + + + + +### Inspect Bigquery + +Inspects a BigQuery table using the Data Loss Prevention API using Pub/Sub for job notifications. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectBigQuery.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectBigQuery.js,samples/README.md) + +__Usage:__ + + +`node inspectBigQuery.js my-project dataProjectId datasetId tableId topicId subscriptionId minLikelihood maxFindings infoTypes customInfoTypes` + + +----- + + + + +### Inspect Datastore + +Inspect a Datastore instance using the Data Loss Prevention API using Pub/Sub for job notifications. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectDatastore.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectDatastore.js,samples/README.md) + +__Usage:__ + + +`node inspectDatastore.js my-project dataProjectId namespaceId kind topicId subscriptionId minLikelihood maxFindings infoTypes customInfoTypes` + + +----- + + + + +### Inspect File + +Inspects a local text, PNG, or JPEG file using the Data Loss Prevention API. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectFile.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectFile.js,samples/README.md) + +__Usage:__ + + +`node inspectFile.js my-project filepath minLikelihood maxFindings infoTypes customInfoTypes includeQuote` + + +----- + + + + +### Inspect GCS File + +Inspects a text file stored on Google Cloud Storage with the Data Loss Prevention API, using Pub/Sub for job notifications. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectGCSFile.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectGCSFile.js,samples/README.md) + +__Usage:__ + + +`node inspectGCSFile.js my-project filepath minLikelihood maxFindings infoTypes customInfoTypes includeQuote` + + +----- + + + + +### Inspects strings + +Inspect a string using the Data Loss Prevention API. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/inspectString.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/inspectString.js,samples/README.md) + +__Usage:__ + + +`node inspectString.js my-project string minLikelihood maxFindings infoTypes customInfoTypes includeQuote` + + +----- + + + + +### kAnonymity Analysis + +Computes the k-anonymity of a column set in a Google BigQuery table + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/kAnonymityAnalysis.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/kAnonymityAnalysis.js,samples/README.md) + +__Usage:__ + + +`node kAnonymityAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId quasiIds` + + +----- + + + + +### kMap Estimation Analysis + +Computes the k-map risk estimation of a column set in a Google BigQuery table. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/kMapEstimationAnalysis.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/kMapEstimationAnalysis.js,samples/README.md) + +__Usage:__ + + +`node kMapEstimationAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId regionCode quasiIds` + + +----- + + + + +### l Diversity Analysis + +Computes the l-diversity of a column set in a Google BigQuery table. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/lDiversityAnalysis.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/lDiversityAnalysis.js,samples/README.md) + +__Usage:__ + + +`node lDiversityAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId sensitiveAttribute quasiIds` + + +----- + + + + +### List Inspect Templates + +List DLP inspection configuration templates. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listInspectTemplates.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listInspectTemplates.js,samples/README.md) + +__Usage:__ + + +`node listInspectTemplates.js my-project` + + +----- + + + + +### List jobs + +List Data Loss Prevention API jobs corresponding to a given filter. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listJobs.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listJobs.js,samples/README.md) + +__Usage:__ + + +`node listJobs.js my-project filter jobType` + + +----- + + + + +### List Triggers + +List Data Loss Prevention API job triggers. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/listTriggers.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/listTriggers.js,samples/README.md) + +__Usage:__ + + +`node listTriggers.js my-project` + + +----- + + + + +### Metadata + +List the types of sensitive information the DLP API supports + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/metadata.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/metadata.js,samples/README.md) + +__Usage:__ + + +`node metadata.js my-project langaugeCode filter` + + +----- + + + + +### Numerical Risk Analysis + +Computes risk metrics of a column of numbers in a Google BigQuery table. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/numericalRiskAnalysis.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/numericalRiskAnalysis.js,samples/README.md) + +__Usage:__ + + +`node numericalRiskAnalysis.js my-project tableProjectId datasetId tableId columnName topicId subscriptionId` + + +----- + + + + +### Quickstart + +Inspects and assesses a string. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/quickstart.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/quickstart.js,samples/README.md) + +__Usage:__ + + +`node quickstart.js my-project` + + +----- + + + + +### Redact Image + +Redact sensitive data from an image using the Data Loss Prevention API. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/redactImage.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/redactImage.js,samples/README.md) + +__Usage:__ + + +`node redactImage.js my-project filepath minLikelihood infoTypes outputPath` + + +----- + + + + +### Redact Text + +Redact sensitive data from text using the Data Loss Prevention API. + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/redactText.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/redactText.js,samples/README.md) + +__Usage:__ + + +`node redactText.js my-project string minLikelihood infoTypes` + + +----- + + + + +### Reidentify with FPE + +Reidentify sensitive data in a string using Format Preserving Encryption (FPE). + +View the [source code](https://github.com/googleapis/nodejs-dlp/blob/master/samples/reidentifyWithFpe.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/reidentifyWithFpe.js,samples/README.md) + +__Usage:__ + + +`node reidentifyWithFpe.js my-project string alphabet surrogateType keyName wrappedKey` + + + + + + +[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png +[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-dlp&page=editor&open_in_editor=samples/README.md +[product-docs]: https://cloud.google.com/dlp/docs/ diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/categoricalRiskAnalysis.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/categoricalRiskAnalysis.js new file mode 100644 index 000000000..01243ca1c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/categoricalRiskAnalysis.js @@ -0,0 +1,160 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Categorical Risk Analysis +// description: Computes risk metrics of a column of data in a Google BigQuery table. +// usage: node categoricalRiskAnalysis.js my-project nhtsa_traffic_fatalities accident_2015 state_name my-topic my-subscription bigquery-public-data + +function main( + projectId, + tableProjectId, + datasetId, + tableId, + columnName, + topicId, + subscriptionId +) { + // [START dlp_categorical_stats] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const tableProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + // The name of the column to compute risk metrics for, e.g. 'firstName' + // const columnName = 'firstName'; + async function categoricalRiskAnalysis() { + const sourceTable = { + projectId: tableProjectId, + datasetId: datasetId, + tableId: tableId, + }; + + // Construct request for creating a risk analysis job + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + categoricalStatsConfig: { + field: { + name: columnName, + }, + }, + }, + sourceTable: sourceTable, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Create helper function for unpacking values + const getValue = obj => obj[Object.keys(obj)[0]]; + + // Run risk analysis job + const [topicResponse] = await pubsub.topic(topicId).get(); + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + setTimeout(() => { + console.log(' Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + const histogramBuckets = + job.riskDetails.categoricalStatsResult.valueFrequencyHistogramBuckets; + histogramBuckets.forEach((histogramBucket, histogramBucketIdx) => { + console.log(`Bucket ${histogramBucketIdx}:`); + + // Print bucket stats + console.log( + ` Most common value occurs ${histogramBucket.valueFrequencyUpperBound} time(s)` + ); + console.log( + ` Least common value occurs ${histogramBucket.valueFrequencyLowerBound} time(s)` + ); + + // Print bucket values + console.log(`${histogramBucket.bucketSize} unique values total.`); + histogramBucket.bucketValues.forEach(valueBucket => { + console.log( + ` Value ${getValue(valueBucket.value)} occurs ${ + valueBucket.count + } time(s).` + ); + }); + }); + } + + categoricalRiskAnalysis(); + // [END dlp_categorical_stats] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createInspectTemplate.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createInspectTemplate.js new file mode 100644 index 000000000..5e13e694c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createInspectTemplate.js @@ -0,0 +1,102 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Inspect Templates +// description: Create a new DLP inspection configuration template. +// usage: node createInspectTemplate.js my-project VERY_LIKELY PERSON_NAME 5 false my-template-id + +function main( + projectId, + templateId, + displayName, + infoTypes, + includeQuote, + minLikelihood, + maxFindings +) { + infoTypes = transformCLI(infoTypes); + // [START dlp_create_inspect_template] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // Whether to include the matching string + // const includeQuote = true; + + // (Optional) The name of the template to be created. + // const templateId = 'my-template'; + + // (Optional) The human-readable name to give the template + // const displayName = 'My template'; + + async function createInspectTemplate() { + // Construct the inspection configuration for the template + const inspectConfig = { + infoTypes: infoTypes, + minLikelihood: minLikelihood, + includeQuote: includeQuote, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }; + + // Construct template-creation request + const request = { + parent: `projects/${projectId}/locations/global`, + inspectTemplate: { + inspectConfig: inspectConfig, + displayName: displayName, + }, + templateId: templateId, + }; + + const [response] = await dlp.createInspectTemplate(request); + const templateName = response.name; + console.log(`Successfully created template ${templateName}.`); + } + createInspectTemplate(); + // [END dlp_create_inspect_template] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + return infoTypes; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createTrigger.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createTrigger.js new file mode 100644 index 000000000..f4f338d4f --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/createTrigger.js @@ -0,0 +1,138 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Job Triggers +// description: Create a Data Loss Prevention API job trigger. +// usage: node createTrigger.js my-project triggerId displayName description bucketName autoPopulateTimespan scanPeriod infoTypes minLikelihood maxFindings + +function main( + projectId, + triggerId, + displayName, + description, + bucketName, + autoPopulateTimespan, + scanPeriod, + infoTypes, + minLikelihood, + maxFindings +) { + infoTypes = transformCLI(infoTypes); + // [START dlp_create_trigger] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // (Optional) The name of the trigger to be created. + // const triggerId = 'my-trigger'; + + // (Optional) A display name for the trigger to be created + // const displayName = 'My Trigger'; + + // (Optional) A description for the trigger to be created + // const description = "This is a sample trigger."; + + // The name of the bucket to scan. + // const bucketName = 'YOUR-BUCKET'; + + // Limit scan to new content only. + // const autoPopulateTimespan = true; + + // How often to wait between scans, in days (minimum = 1 day) + // const scanPeriod = 1; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + async function createTrigger() { + // Get reference to the bucket to be inspected + const storageItem = { + cloudStorageOptions: { + fileSet: {url: `gs://${bucketName}/*`}, + }, + timeSpanConfig: { + enableAutoPopulationOfTimespanConfig: autoPopulateTimespan, + }, + }; + + // Construct job to be triggered + const job = { + inspectConfig: { + infoTypes: infoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + storageConfig: storageItem, + }; + + // Construct trigger creation request + const request = { + parent: `projects/${projectId}/locations/global`, + jobTrigger: { + inspectJob: job, + displayName: displayName, + description: description, + triggers: [ + { + schedule: { + recurrencePeriodDuration: { + seconds: scanPeriod * 60 * 60 * 24, // Trigger the scan daily + }, + }, + }, + ], + status: 'HEALTHY', + }, + triggerId: triggerId, + }; + + // Run trigger creation request + const [trigger] = await dlp.createJobTrigger(request); + console.log(`Successfully created trigger ${trigger.name}.`); + } + + createTrigger(); + // [END dlp_create_trigger] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + return infoTypes; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithDateShift.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithDateShift.js new file mode 100644 index 000000000..e13d96425 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithDateShift.js @@ -0,0 +1,191 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Deidentify with Date Shift +// description: Deidentify dates in a CSV file by pseudorandomly shifting them. +// usage: node deidentifyWithDateShift.js my-project dates.csv dates-shifted.csv 30 30 birth_date register_date [ projects/my-project/locations/global/keyrings/my-keyring] + +function main( + projectId, + inputCsvFile, + outputCsvFile, + dateFields, + lowerBoundDays, + upperBoundDays, + contextFieldId, + wrappedKey, + keyName +) { + dateFields = transformCLI(dateFields); + // [START dlp_deidentify_date_shift] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // Import other required libraries + const fs = require('fs'); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The path to the CSV file to deidentify + // The first row of the file must specify column names, and all other rows + // must contain valid values + // const inputCsvFile = '/path/to/input/file.csv'; + + // The path to save the date-shifted CSV file to + // const outputCsvFile = '/path/to/output/file.csv'; + + // The list of (date) fields in the CSV file to date shift + // const dateFields = [{ name: 'birth_date'}, { name: 'register_date' }]; + + // The maximum number of days to shift a date backward + // const lowerBoundDays = 1; + + // The maximum number of days to shift a date forward + // const upperBoundDays = 1; + + // (Optional) The column to determine date shift amount based on + // If this is not specified, a random shift amount will be used for every row + // If this is specified, then 'wrappedKey' and 'keyName' must also be set + // const contextFieldId = [{ name: 'user_id' }]; + + // (Optional) The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key + // If this is specified, then 'wrappedKey' and 'contextFieldId' must also be set + // const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'; + + // (Optional) The encrypted ('wrapped') AES-256 key to use when shifting dates + // This key should be encrypted using the Cloud KMS key specified above + // If this is specified, then 'keyName' and 'contextFieldId' must also be set + // const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY' + + // Helper function for converting CSV rows to Protobuf types + const rowToProto = row => { + const values = row.split(','); + const convertedValues = values.map(value => { + if (Date.parse(value)) { + const date = new Date(value); + return { + dateValue: { + year: date.getFullYear(), + month: date.getMonth() + 1, + day: date.getDate(), + }, + }; + } else { + // Convert all non-date values to strings + return {stringValue: value.toString()}; + } + }); + return {values: convertedValues}; + }; + + async function deidentifyWithDateShift() { + // Read and parse a CSV file + const csvLines = fs + .readFileSync(inputCsvFile) + .toString() + .split('\n') + .filter(line => line.includes(',')); + const csvHeaders = csvLines[0].split(','); + const csvRows = csvLines.slice(1); + + // Construct the table object + const tableItem = { + table: { + headers: csvHeaders.map(header => { + return {name: header}; + }), + rows: csvRows.map(row => rowToProto(row)), + }, + }; + + // Construct DateShiftConfig + const dateShiftConfig = { + lowerBoundDays: lowerBoundDays, + upperBoundDays: upperBoundDays, + }; + + if (contextFieldId && keyName && wrappedKey) { + dateShiftConfig.context = {name: contextFieldId}; + dateShiftConfig.cryptoKey = { + kmsWrapped: { + wrappedKey: wrappedKey, + cryptoKeyName: keyName, + }, + }; + } else if (contextFieldId || keyName || wrappedKey) { + throw new Error( + 'You must set either ALL or NONE of {contextFieldId, keyName, wrappedKey}!' + ); + } + + // Construct deidentification request + const request = { + parent: `projects/${projectId}/locations/global`, + deidentifyConfig: { + recordTransformations: { + fieldTransformations: [ + { + fields: dateFields, + primitiveTransformation: { + dateShiftConfig: dateShiftConfig, + }, + }, + ], + }, + }, + item: tableItem, + }; + + // Run deidentification request + const [response] = await dlp.deidentifyContent(request); + const tableRows = response.item.table.rows; + + // Write results to a CSV file + tableRows.forEach((row, rowIndex) => { + const rowValues = row.values.map( + value => + value.stringValue || + `${value.dateValue.month}/${value.dateValue.day}/${value.dateValue.year}` + ); + csvLines[rowIndex + 1] = rowValues.join(','); + }); + csvLines.push(''); + fs.writeFileSync(outputCsvFile, csvLines.join('\n')); + + // Print status + console.log(`Successfully saved date-shift output to ${outputCsvFile}`); + } + + deidentifyWithDateShift(); + // [END dlp_deidentify_date_shift] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(dateFields) { + return (dateFields = dateFields.split(',').map(type => { + return {name: type}; + })); +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithFpe.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithFpe.js new file mode 100644 index 000000000..015b24d7a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithFpe.js @@ -0,0 +1,101 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Deidentify with FPE +// description: Deidentify sensitive data in a string using Format Preserving Encryption (FPE). +// usage: node deidentifyWithFpe.js my-project "My SSN is 372819127" projects/my-project/locations/global/keyrings/my-keyring SSN_TOKEN + +function main(projectId, string, alphabet, keyName, wrappedKey, surrogateType) { + // [START dlp_deidentify_fpe] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The string to deidentify + // const string = 'My SSN is 372819127'; + + // The set of characters to replace sensitive ones with + // For more information, see https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#ffxcommonnativealphabet + // const alphabet = 'ALPHA_NUMERIC'; + + // The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key + // const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'; + + // The encrypted ('wrapped') AES-256 key to use + // This key should be encrypted using the Cloud KMS key specified above + // const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY' + + // (Optional) The name of the surrogate custom info type to use + // Only necessary if you want to reverse the deidentification process + // Can be essentially any arbitrary string, as long as it doesn't appear + // in your dataset otherwise. + // const surrogateType = 'SOME_INFO_TYPE_DEID'; + + async function deidentifyWithFpe() { + // Construct FPE config + const cryptoReplaceFfxFpeConfig = { + cryptoKey: { + kmsWrapped: { + wrappedKey: wrappedKey, + cryptoKeyName: keyName, + }, + }, + commonAlphabet: alphabet, + }; + if (surrogateType) { + cryptoReplaceFfxFpeConfig.surrogateInfoType = { + name: surrogateType, + }; + } + + // Construct deidentification request + const item = {value: string}; + const request = { + parent: `projects/${projectId}/locations/global`, + deidentifyConfig: { + infoTypeTransformations: { + transformations: [ + { + primitiveTransformation: { + cryptoReplaceFfxFpeConfig: cryptoReplaceFfxFpeConfig, + }, + }, + ], + }, + }, + item: item, + }; + + // Run deidentification request + const [response] = await dlp.deidentifyContent(request); + const deidentifiedItem = response.item; + console.log(deidentifiedItem.value); + } + deidentifyWithFpe(); + // [END dlp_deidentify_fpe] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithMask.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithMask.js new file mode 100644 index 000000000..6e6df7e7e --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithMask.js @@ -0,0 +1,80 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Deidentify with Mask +// description: Deidentify sensitive data in a string by masking it with a character. +// usage: node deidentifyWithMask.js my-project string maskingCharacter numberToMask + +function main(projectId, string, maskingCharacter, numberToMask) { + // [START dlp_deidentify_masking] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project-id'; + + // The string to deidentify + // const string = 'My SSN is 372819127'; + + // (Optional) The maximum number of sensitive characters to mask in a match + // If omitted from the request or set to 0, the API will mask any matching characters + // const numberToMask = 5; + + // (Optional) The character to mask matching sensitive data with + // const maskingCharacter = 'x'; + + // Construct deidentification request + const item = {value: string}; + + async function deidentifyWithMask() { + const request = { + parent: `projects/${projectId}/locations/global`, + deidentifyConfig: { + infoTypeTransformations: { + transformations: [ + { + primitiveTransformation: { + characterMaskConfig: { + maskingCharacter: maskingCharacter, + numberToMask: numberToMask, + }, + }, + }, + ], + }, + }, + item: item, + }; + + // Run deidentification request + const [response] = await dlp.deidentifyContent(request); + const deidentifiedItem = response.item; + console.log(deidentifiedItem.value); + } + + deidentifyWithMask(); + // [END dlp_deidentify_masking] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithReplacement.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithReplacement.js new file mode 100644 index 000000000..c3e5f0de7 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deidentifyWithReplacement.js @@ -0,0 +1,76 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Deidentify with Replacement +// description: Deidentify sensitive data in a string by replacing it with a given replacement string. +// usage: node deidentifyWithMask.js my-project string replacement + +function main(projectId, string, replacement) { + // [START dlp_deidentify_replacement] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The string to deidentify + // const string = 'My SSN is 372819127'; + + // The string to replace sensitive information with + // const replacement = "[REDACTED]" + + async function deidentifyWithReplacement() { + // Construct deidentification request + const item = {value: string}; + const request = { + parent: `projects/${projectId}/locations/global`, + deidentifyConfig: { + infoTypeTransformations: { + transformations: [ + { + primitiveTransformation: { + replaceConfig: { + newValue: { + stringValue: replacement, + }, + }, + }, + }, + ], + }, + }, + item: item, + }; + + // Run deidentification request + const [response] = await dlp.deidentifyContent(request); + const deidentifiedItem = response.item; + console.log(deidentifiedItem.value); + } + + deidentifyWithReplacement(); + // [END dlp_deidentify_replacement] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteInspectTemplate.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteInspectTemplate.js new file mode 100644 index 000000000..61a802115 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteInspectTemplate.js @@ -0,0 +1,55 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Delete Inspect Templates +// description: Delete the DLP inspection configuration template with the specified name. +// usage: node deleteInspectTemplates.js my-project projects/my-project/inspectTemplates/##### + +function main(projectId, templateName) { + // [START dlp_delete_inspect_template] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The name of the template to delete + // Parent project ID is automatically extracted from this parameter + // const templateName = 'projects/YOUR_PROJECT_ID/inspectTemplates/#####' + async function deleteInspectTemplate() { + // Construct template-deletion request + const request = { + name: templateName, + }; + + // Run template-deletion request + await dlp.deleteInspectTemplate(request); + console.log(`Successfully deleted template ${templateName}.`); + } + + deleteInspectTemplate(); + // [END dlp_delete_inspect_template] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteJob.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteJob.js new file mode 100644 index 000000000..78202468e --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteJob.js @@ -0,0 +1,59 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Delete Job +// description: Delete results of a Data Loss Prevention API job. +// usage: node deleteJob.js my-project projects/YOUR_GCLOUD_PROJECT/dlpJobs/X-##### + +function main(projectId, jobName) { + // [START dlp_delete_job] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The name of the job whose results should be deleted + // Parent project ID is automatically extracted from this parameter + // const jobName = 'projects/my-project/dlpJobs/X-#####' + + function deleteJob() { + // Construct job deletion request + const request = { + name: jobName, + }; + + // Run job deletion request + dlp + .deleteDlpJob(request) + .then(() => { + console.log(`Successfully deleted job ${jobName}.`); + }) + .catch(err => { + console.log(`Error in deleteJob: ${err.message || err}`); + }); + } + + deleteJob(); + // [END dlp_delete_job] +} +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteTrigger.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteTrigger.js new file mode 100644 index 000000000..9fca52f79 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/deleteTrigger.js @@ -0,0 +1,54 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Delete Trigger +// description: Delete results of a Data Loss Prevention API job. +// usage: node deleteTrigger.js my-rpoject projects/my-project/jobTriggers/my-trigger + +function main(projectId, triggerId) { + // [START dlp_delete_trigger] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project' + + // The name of the trigger to be deleted + // Parent project ID is automatically extracted from this parameter + // const triggerId = 'projects/my-project/triggers/my-trigger'; + + async function deleteTrigger() { + // Construct trigger deletion request + const request = { + name: triggerId, + }; + + // Run trigger deletion request + await dlp.deleteJobTrigger(request); + console.log(`Successfully deleted trigger ${triggerId}.`); + } + + deleteTrigger(); + // [END dlp_delete_trigger] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectBigQuery.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectBigQuery.js new file mode 100644 index 000000000..32d2950af --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectBigQuery.js @@ -0,0 +1,195 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Inspect Bigquery +// description: Inspects a BigQuery table using the Data Loss Prevention API using Pub/Sub for job notifications. +// usage: node inspectBigQuery.js my-project dataProjectId datasetId tableId topicId subscriptionId minLikelihood maxFindings infoTypes customInfoTypes + +function main( + projectId, + dataProjectId, + datasetId, + tableId, + topicId, + subscriptionId, + minLikelihood, + maxFindings, + infoTypes, + customInfoTypes +) { + [infoTypes, customInfoTypes] = transformCLI(infoTypes, customInfoTypes); + + // [START dlp_inspect_bigquery] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const dataProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The customInfoTypes of information to match + // const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}}, + // { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}]; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + async function inspectBigquery() { + // Construct item to be inspected + const storageItem = { + bigQueryOptions: { + tableReference: { + projectId: dataProjectId, + datasetId: datasetId, + tableId: tableId, + }, + }, + }; + + // Construct request for creating an inspect job + const request = { + parent: `projects/${projectId}/locations/global`, + inspectJob: { + inspectConfig: { + infoTypes: infoTypes, + customInfoTypes: customInfoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + storageConfig: storageItem, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Run inspect-job creation request + const [topicResponse] = await pubsub.topic(topicId).get(); + // Verify the Pub/Sub topic and listen for job notifications via an + // existing subscription. + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + // Wait for DLP job to fully complete + setTimeout(() => { + console.log('Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + console.log(`Job ${job.name} status: ${job.state}`); + + const infoTypeStats = job.inspectDetails.result.infoTypeStats; + if (infoTypeStats.length > 0) { + infoTypeStats.forEach(infoTypeStat => { + console.log( + ` Found ${infoTypeStat.count} instance(s) of infoType ${infoTypeStat.infoType.name}.` + ); + }); + } else { + console.log('No findings.'); + } + } + + inspectBigquery(); + // [END dlp_inspect_bigquery] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes, customInfoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + + if (customInfoTypes) { + customInfoTypes = customInfoTypes.includes(',') + ? customInfoTypes.split(',').map((dict, idx) => { + return { + infoType: {name: 'CUSTOM_DICT_'.concat(idx.toString())}, + dictionary: {wordList: {words: dict.split(',')}}, + }; + }) + : customInfoTypes.split(',').map((rgx, idx) => { + return { + infoType: {name: 'CUSTOM_REGEX_'.concat(idx.toString())}, + regex: {pattern: rgx}, + }; + }); + } + + return [infoTypes, customInfoTypes]; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectDatastore.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectDatastore.js new file mode 100644 index 000000000..e6674332d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectDatastore.js @@ -0,0 +1,198 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Inspect Datastore +// description: Inspect a Datastore instance using the Data Loss Prevention API using Pub/Sub for job notifications. +// usage: node inspectDatastore.js my-project dataProjectId namespaceId kind topicId subscriptionId minLikelihood maxFindings infoTypes customInfoTypes + +function main( + projectId, + dataProjectId, + namespaceId, + kind, + topicId, + subscriptionId, + minLikelihood, + maxFindings, + infoTypes, + customInfoTypes +) { + [infoTypes, customInfoTypes] = transformCLI(infoTypes, customInfoTypes); + + // [START dlp_inspect_datastore] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the target Datastore is stored under + // This may or may not equal the calling project ID + // const dataProjectId = 'my-project'; + + // (Optional) The ID namespace of the Datastore document to inspect. + // To ignore Datastore namespaces, set this to an empty string ('') + // const namespaceId = ''; + + // The kind of the Datastore entity to inspect. + // const kind = 'Person'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The customInfoTypes of information to match + // const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}}, + // { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}]; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + async function inspectDatastore() { + // Construct items to be inspected + const storageItems = { + datastoreOptions: { + partitionId: { + projectId: dataProjectId, + namespaceId: namespaceId, + }, + kind: { + name: kind, + }, + }, + }; + + // Construct request for creating an inspect job + const request = { + parent: `projects/${projectId}/locations/global`, + inspectJob: { + inspectConfig: { + infoTypes: infoTypes, + customInfoTypes: customInfoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + storageConfig: storageItems, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + // Run inspect-job creation request + const [topicResponse] = await pubsub.topic(topicId).get(); + // Verify the Pub/Sub topic and listen for job notifications via an + // existing subscription. + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + // Wait for DLP job to fully complete + setTimeout(() => { + console.log('Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + console.log(`Job ${job.name} status: ${job.state}`); + + const infoTypeStats = job.inspectDetails.result.infoTypeStats; + if (infoTypeStats.length > 0) { + infoTypeStats.forEach(infoTypeStat => { + console.log( + ` Found ${infoTypeStat.count} instance(s) of infoType ${infoTypeStat.infoType.name}.` + ); + }); + } else { + console.log('No findings.'); + } + } + inspectDatastore(); + // [END dlp_inspect_datastore] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes, customInfoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + + if (customInfoTypes) { + customInfoTypes = customInfoTypes.includes(',') + ? customInfoTypes.split(',').map((dict, idx) => { + return { + infoType: {name: 'CUSTOM_DICT_'.concat(idx.toString())}, + dictionary: {wordList: {words: dict.split(',')}}, + }; + }) + : customInfoTypes.split(',').map((rgx, idx) => { + return { + infoType: {name: 'CUSTOM_REGEX_'.concat(idx.toString())}, + regex: {pattern: rgx}, + }; + }); + } + + return [infoTypes, customInfoTypes]; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectFile.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectFile.js new file mode 100644 index 000000000..26da96e5a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectFile.js @@ -0,0 +1,143 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Inspect File +// description: Inspects a local text, PNG, or JPEG file using the Data Loss Prevention API. +// usage: node inspectFile.js my-project filepath minLikelihood maxFindings infoTypes customInfoTypes includeQuote + +function main( + projectId, + filepath, + minLikelihood, + maxFindings, + infoTypes, + customInfoTypes, + includeQuote +) { + [infoTypes, customInfoTypes] = transformCLI(infoTypes, customInfoTypes); + + // [START dlp_inspect_file] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Import other required libraries + const fs = require('fs'); + const mime = require('mime'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The path to a local file to inspect. Can be a text, JPG, or PNG file. + // const filepath = 'path/to/image.png'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The customInfoTypes of information to match + // const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}}, + // { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}]; + + // Whether to include the matching string + // const includeQuote = true; + + async function inspectFile() { + // Construct file data to inspect + const fileTypeConstant = + ['image/jpeg', 'image/bmp', 'image/png', 'image/svg'].indexOf( + mime.getType(filepath) + ) + 1; + const fileBytes = Buffer.from(fs.readFileSync(filepath)).toString('base64'); + const item = { + byteItem: { + type: fileTypeConstant, + data: fileBytes, + }, + }; + + // Construct request + const request = { + parent: `projects/${projectId}/locations/global`, + inspectConfig: { + infoTypes: infoTypes, + customInfoTypes: customInfoTypes, + minLikelihood: minLikelihood, + includeQuote: includeQuote, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + item: item, + }; + + // Run request + const [response] = await dlp.inspectContent(request); + const findings = response.result.findings; + if (findings.length > 0) { + console.log('Findings:'); + findings.forEach(finding => { + if (includeQuote) { + console.log(`\tQuote: ${finding.quote}`); + } + console.log(`\tInfo type: ${finding.infoType.name}`); + console.log(`\tLikelihood: ${finding.likelihood}`); + }); + } else { + console.log('No findings.'); + } + } + // [END dlp_inspect_file] + inspectFile(); +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes, customInfoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + + if (customInfoTypes) { + customInfoTypes = customInfoTypes.includes(',') + ? customInfoTypes.split(',').map((dict, idx) => { + return { + infoType: {name: 'CUSTOM_DICT_'.concat(idx.toString())}, + dictionary: {wordList: {words: dict.split(',')}}, + }; + }) + : customInfoTypes.split(',').map((rgx, idx) => { + return { + infoType: {name: 'CUSTOM_REGEX_'.concat(idx.toString())}, + regex: {pattern: rgx}, + }; + }); + } + + return [infoTypes, customInfoTypes]; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectGCSFile.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectGCSFile.js new file mode 100644 index 000000000..19e6eff17 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectGCSFile.js @@ -0,0 +1,187 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Inspect GCS File +// description: Inspects a text file stored on Google Cloud Storage with the Data Loss Prevention API, using Pub/Sub for job notifications. +// usage: node inspectGCSFile.js my-project filepath minLikelihood maxFindings infoTypes customInfoTypes includeQuote + +function main( + projectId, + bucketName, + fileName, + topicId, + subscriptionId, + minLikelihood, + maxFindings, + infoTypes, + customInfoTypes +) { + [infoTypes, customInfoTypes] = transformCLI(infoTypes, customInfoTypes); + + // [START dlp_inspect_gcs] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The name of the bucket where the file resides. + // const bucketName = 'YOUR-BUCKET'; + + // The path to the file within the bucket to inspect. + // Can contain wildcards, e.g. "my-image.*" + // const fileName = 'my-image.png'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The customInfoTypes of information to match + // const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}}, + // { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}]; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + async function inspectGCSFile() { + // Get reference to the file to be inspected + const storageItem = { + cloudStorageOptions: { + fileSet: {url: `gs://${bucketName}/${fileName}`}, + }, + }; + + // Construct request for creating an inspect job + const request = { + parent: `projects/${projectId}/locations/global`, + inspectJob: { + inspectConfig: { + infoTypes: infoTypes, + customInfoTypes: customInfoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + storageConfig: storageItem, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Create a GCS File inspection job and wait for it to complete + const [topicResponse] = await pubsub.topic(topicId).get(); + // Verify the Pub/Sub topic and listen for job notifications via an + // existing subscription. + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + // Get the job's ID + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + + setTimeout(() => { + console.log('Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + console.log(`Job ${job.name} status: ${job.state}`); + + const infoTypeStats = job.inspectDetails.result.infoTypeStats; + if (infoTypeStats.length > 0) { + infoTypeStats.forEach(infoTypeStat => { + console.log( + ` Found ${infoTypeStat.count} instance(s) of infoType ${infoTypeStat.infoType.name}.` + ); + }); + } else { + console.log('No findings.'); + } + } + inspectGCSFile(); + // [END dlp_inspect_gcs] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes, customInfoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + + if (customInfoTypes) { + customInfoTypes = customInfoTypes.includes(',') + ? customInfoTypes.split(',').map((dict, idx) => { + return { + infoType: {name: 'CUSTOM_DICT_'.concat(idx.toString())}, + dictionary: {wordList: {words: dict.split(',')}}, + }; + }) + : customInfoTypes.split(',').map((rgx, idx) => { + return { + infoType: {name: 'CUSTOM_REGEX_'.concat(idx.toString())}, + regex: {pattern: rgx}, + }; + }); + } + + return [infoTypes, customInfoTypes]; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectString.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectString.js new file mode 100644 index 000000000..081cb57bf --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/inspectString.js @@ -0,0 +1,134 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Inspects strings +// description: Inspect a string using the Data Loss Prevention API. +// usage: node inspectString.js my-project string minLikelihood maxFindings infoTypes customInfoTypes includeQuote + +function main( + projectId, + string, + minLikelihood, + maxFindings, + infoTypes, + customInfoTypes, + includeQuote +) { + [infoTypes, customInfoTypes] = transformCLI(infoTypes, customInfoTypes); + + // [START dlp_inspect_string] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The string to inspect + // const string = 'My name is Gary and my email is gary@example.com'; + + // The minimum likelihood required before returning a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report per request (0 = server maximum) + // const maxFindings = 0; + + // The infoTypes of information to match + // const infoTypes = [{ name: 'PHONE_NUMBER' }, { name: 'EMAIL_ADDRESS' }, { name: 'CREDIT_CARD_NUMBER' }]; + + // The customInfoTypes of information to match + // const customInfoTypes = [{ infoType: { name: 'DICT_TYPE' }, dictionary: { wordList: { words: ['foo', 'bar', 'baz']}}}, + // { infoType: { name: 'REGEX_TYPE' }, regex: {pattern: '\\(\\d{3}\\) \\d{3}-\\d{4}'}}]; + + // Whether to include the matching string + // const includeQuote = true; + + async function inspectString() { + // Construct item to inspect + const item = {value: string}; + + // Construct request + const request = { + parent: `projects/${projectId}/locations/global`, + inspectConfig: { + infoTypes: infoTypes, + customInfoTypes: customInfoTypes, + minLikelihood: minLikelihood, + includeQuote: includeQuote, + limits: { + maxFindingsPerRequest: maxFindings, + }, + }, + item: item, + }; + + console.log(request.inspectConfig.infoTypes); + console.log(Array.isArray(request.inspectConfig.infoTypes)); + + // Run request + const [response] = await dlp.inspectContent(request); + const findings = response.result.findings; + if (findings.length > 0) { + console.log('Findings:'); + findings.forEach(finding => { + if (includeQuote) { + console.log(`\tQuote: ${finding.quote}`); + } + console.log(`\tInfo type: ${finding.infoType.name}`); + console.log(`\tLikelihood: ${finding.likelihood}`); + }); + } else { + console.log('No findings.'); + } + } + inspectString(); + // [END dlp_inspect_string] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes, customInfoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + + if (customInfoTypes) { + customInfoTypes = customInfoTypes.includes(',') + ? customInfoTypes.split(',').map((dict, idx) => { + return { + infoType: {name: 'CUSTOM_DICT_'.concat(idx.toString())}, + dictionary: {wordList: {words: dict.split(',')}}, + }; + }) + : customInfoTypes.split(',').map((rgx, idx) => { + return { + infoType: {name: 'CUSTOM_REGEX_'.concat(idx.toString())}, + regex: {pattern: rgx}, + }; + }); + } + + return [infoTypes, customInfoTypes]; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kAnonymityAnalysis.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kAnonymityAnalysis.js new file mode 100644 index 000000000..b604c0499 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kAnonymityAnalysis.js @@ -0,0 +1,165 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: kAnonymity Analysis +// description: Computes the k-anonymity of a column set in a Google BigQuery table +// usage: node kAnonymityAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId quasiIds + +function main( + projectId, + tableProjectId, + datasetId, + tableId, + topicId, + subscriptionId, + quasiIds +) { + quasiIds = transformCLI(quasiIds); + + // [START dlp_k_anonymity] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const tableProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + // A set of columns that form a composite key ('quasi-identifiers') + // const quasiIds = [{ name: 'age' }, { name: 'city' }]; + async function kAnonymityAnalysis() { + const sourceTable = { + projectId: tableProjectId, + datasetId: datasetId, + tableId: tableId, + }; + // Construct request for creating a risk analysis job + + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + kAnonymityConfig: { + quasiIds: quasiIds, + }, + }, + sourceTable: sourceTable, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Create helper function for unpacking values + const getValue = obj => obj[Object.keys(obj)[0]]; + + // Run risk analysis job + const [topicResponse] = await pubsub.topic(topicId).get(); + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + setTimeout(() => { + console.log(' Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + const histogramBuckets = + job.riskDetails.kAnonymityResult.equivalenceClassHistogramBuckets; + + histogramBuckets.forEach((histogramBucket, histogramBucketIdx) => { + console.log(`Bucket ${histogramBucketIdx}:`); + console.log( + ` Bucket size range: [${histogramBucket.equivalenceClassSizeLowerBound}, ${histogramBucket.equivalenceClassSizeUpperBound}]` + ); + + histogramBucket.bucketValues.forEach(valueBucket => { + const quasiIdValues = valueBucket.quasiIdsValues + .map(getValue) + .join(', '); + console.log(` Quasi-ID values: {${quasiIdValues}}`); + console.log(` Class size: ${valueBucket.equivalenceClassSize}`); + }); + }); + } + kAnonymityAnalysis(); + // [END dlp_k_anonymity] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(quasiIds) { + quasiIds = quasiIds + ? quasiIds.split(',').map((name, idx) => { + return { + name: name, + infoType: { + name: idx, + }, + }; + }) + : undefined; + return quasiIds; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kMapEstimationAnalysis.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kMapEstimationAnalysis.js new file mode 100644 index 000000000..204350d27 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/kMapEstimationAnalysis.js @@ -0,0 +1,179 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: kMap Estimation Analysis +// description: Computes the k-map risk estimation of a column set in a Google BigQuery table. +// usage: node kMapEstimationAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId regionCode quasiIds + +function main( + projectId, + tableProjectId, + datasetId, + tableId, + topicId, + subscriptionId, + regionCode, + quasiIds, + infoTypes +) { + quasiIds = transformCLI(quasiIds, infoTypes); + + // [START dlp_k_map] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const tableProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + // The ISO 3166-1 region code that the data is representative of + // Can be omitted if using a region-specific infoType (such as US_ZIP_5) + // const regionCode = 'USA'; + + // A set of columns that form a composite key ('quasi-identifiers'), and + // optionally their reidentification distributions + // const quasiIds = [{ field: { name: 'age' }, infoType: { name: 'AGE' }}]; + async function kMapEstimationAnalysis() { + const sourceTable = { + projectId: tableProjectId, + datasetId: datasetId, + tableId: tableId, + }; + + // Construct request for creating a risk analysis job + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + kMapEstimationConfig: { + quasiIds: quasiIds, + regionCode: regionCode, + }, + }, + sourceTable: sourceTable, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + // Create helper function for unpacking values + const getValue = obj => obj[Object.keys(obj)[0]]; + + // Run risk analysis job + const [topicResponse] = await pubsub.topic(topicId).get(); + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + setTimeout(() => { + console.log(' Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + + const histogramBuckets = + job.riskDetails.kMapEstimationResult.kMapEstimationHistogram; + + histogramBuckets.forEach((histogramBucket, histogramBucketIdx) => { + console.log(`Bucket ${histogramBucketIdx}:`); + console.log( + ` Anonymity range: [${histogramBucket.minAnonymity}, ${histogramBucket.maxAnonymity}]` + ); + console.log(` Size: ${histogramBucket.bucketSize}`); + histogramBucket.bucketValues.forEach(valueBucket => { + const values = valueBucket.quasiIdsValues.map(value => getValue(value)); + console.log(` Values: ${values.join(' ')}`); + console.log( + ` Estimated k-map anonymity: ${valueBucket.estimatedAnonymity}` + ); + }); + }); + } + + kMapEstimationAnalysis(); + // [END dlp_k_map] +} +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(quasiIds, infoTypes) { + infoTypes = infoTypes ? infoTypes.split(',') : null; + + quasiIds = quasiIds + ? quasiIds.split(',').map((name, index) => { + return { + field: { + name: name, + }, + infoType: { + name: infoTypes[index], + }, + }; + }) + : undefined; + + return quasiIds; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/lDiversityAnalysis.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/lDiversityAnalysis.js new file mode 100644 index 000000000..7ca245d2d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/lDiversityAnalysis.js @@ -0,0 +1,180 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: l Diversity Analysis +// description: Computes the l-diversity of a column set in a Google BigQuery table. +// usage: node lDiversityAnalysis.js my-project tableProjectId datasetId tableId topicId subscriptionId sensitiveAttribute quasiIds + +function main( + projectId, + tableProjectId, + datasetId, + tableId, + topicId, + subscriptionId, + sensitiveAttribute, + quasiIds +) { + quasiIds = transformCLI(quasiIds); + // [START dlp_l_diversity] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const tableProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + // The column to measure l-diversity relative to, e.g. 'firstName' + // const sensitiveAttribute = 'name'; + + // A set of columns that form a composite key ('quasi-identifiers') + // const quasiIds = [{ name: 'age' }, { name: 'city' }]; + + async function lDiversityAnalysis() { + const sourceTable = { + projectId: tableProjectId, + datasetId: datasetId, + tableId: tableId, + }; + + // Construct request for creating a risk analysis job + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + lDiversityConfig: { + quasiIds: quasiIds, + sensitiveAttribute: { + name: sensitiveAttribute, + }, + }, + }, + sourceTable: sourceTable, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Create helper function for unpacking values + const getValue = obj => obj[Object.keys(obj)[0]]; + + // Run risk analysis job + const [topicResponse] = await pubsub.topic(topicId).get(); + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + setTimeout(() => { + console.log(' Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + const histogramBuckets = + job.riskDetails.lDiversityResult.sensitiveValueFrequencyHistogramBuckets; + + histogramBuckets.forEach((histogramBucket, histogramBucketIdx) => { + console.log(`Bucket ${histogramBucketIdx}:`); + + console.log( + `Bucket size range: [${histogramBucket.sensitiveValueFrequencyLowerBound}, ${histogramBucket.sensitiveValueFrequencyUpperBound}]` + ); + histogramBucket.bucketValues.forEach(valueBucket => { + const quasiIdValues = valueBucket.quasiIdsValues + .map(getValue) + .join(', '); + console.log(` Quasi-ID values: {${quasiIdValues}}`); + console.log(` Class size: ${valueBucket.equivalenceClassSize}`); + valueBucket.topSensitiveValues.forEach(valueObj => { + console.log( + ` Sensitive value ${getValue(valueObj.value)} occurs ${ + valueObj.count + } time(s).` + ); + }); + }); + }); + } + + lDiversityAnalysis(); + // [END dlp_l_diversity] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(quasiIds) { + quasiIds = quasiIds + ? quasiIds.split(',').map((name, idx) => { + return { + name: name, + infoType: { + name: idx, + }, + }; + }) + : undefined; + return quasiIds; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listInspectTemplates.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listInspectTemplates.js new file mode 100644 index 000000000..73e41aaeb --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listInspectTemplates.js @@ -0,0 +1,74 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: List Inspect Templates +// description: List DLP inspection configuration templates. +// usage: node listInspectTemplates.js my-project + +function main(projectId) { + // [START dlp_list_inspect_templates] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // Helper function to pretty-print dates + const formatDate = date => { + const msSinceEpoch = parseInt(date.seconds, 10) * 1000; + return new Date(msSinceEpoch).toLocaleString('en-US'); + }; + + async function listInspectTemplates() { + // Construct template-listing request + const request = { + parent: `projects/${projectId}/locations/global`, + }; + + // Run template-deletion request + const [templates] = await dlp.listInspectTemplates(request); + + templates.forEach(template => { + console.log(`Template ${template.name}`); + if (template.displayName) { + console.log(` Display name: ${template.displayName}`); + } + + console.log(` Created: ${formatDate(template.createTime)}`); + console.log(` Updated: ${formatDate(template.updateTime)}`); + + const inspectConfig = template.inspectConfig; + const infoTypes = inspectConfig.infoTypes.map(x => x.name); + console.log(' InfoTypes:', infoTypes.join(' ')); + console.log(' Minimum likelihood:', inspectConfig.minLikelihood); + console.log(' Include quotes:', inspectConfig.includeQuote); + + const limits = inspectConfig.limits; + console.log(' Max findings per request:', limits.maxFindingsPerRequest); + }); + } + + listInspectTemplates(); + // [END dlp_list_inspect_templates] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listJobs.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listJobs.js new file mode 100644 index 000000000..41469ed25 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listJobs.js @@ -0,0 +1,62 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: List jobs +// description: List Data Loss Prevention API jobs corresponding to a given filter. +// usage: node listJobs.js my-project filter jobType + +function main(projectId, filter, jobType) { + // [START dlp_list_jobs] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The filter expression to use + // For more information and filter syntax, see https://cloud.google.com/dlp/docs/reference/rest/v2/projects.dlpJobs/list + // const filter = `state=DONE`; + + // The type of job to list (either 'INSPECT_JOB' or 'RISK_ANALYSIS_JOB') + // const jobType = 'INSPECT_JOB'; + async function listJobs() { + // Construct request for listing DLP scan jobs + const request = { + parent: `projects/${projectId}/locations/global`, + filter: filter, + type: jobType, + }; + + // Run job-listing request + const [jobs] = await dlp.listDlpJobs(request); + jobs.forEach(job => { + console.log(`Job ${job.name} status: ${job.state}`); + }); + } + + listJobs(); + // [END dlp_list_jobs] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listTriggers.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listTriggers.js new file mode 100644 index 000000000..9d09c7772 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/listTriggers.js @@ -0,0 +1,69 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: List Triggers +// description: List Data Loss Prevention API job triggers. +// usage: node listTriggers.js my-project + +function main(projectId) { + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project' + + async function listTriggers() { + // Construct trigger listing request + const request = { + parent: `projects/${projectId}/locations/global`, + }; + + // Helper function to pretty-print dates + const formatDate = date => { + const msSinceEpoch = parseInt(date.seconds, 10) * 1000; + return new Date(msSinceEpoch).toLocaleString('en-US'); + }; + + // Run trigger listing request + const [triggers] = await dlp.listJobTriggers(request); + triggers.forEach(trigger => { + // Log trigger details + console.log(`Trigger ${trigger.name}:`); + console.log(` Created: ${formatDate(trigger.createTime)}`); + console.log(` Updated: ${formatDate(trigger.updateTime)}`); + if (trigger.displayName) { + console.log(` Display Name: ${trigger.displayName}`); + } + if (trigger.description) { + console.log(` Description: ${trigger.description}`); + } + console.log(` Status: ${trigger.status}`); + console.log(` Error count: ${trigger.errors.length}`); + }); + } + + listTriggers(); +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/metadata.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/metadata.js new file mode 100644 index 000000000..02cf40466 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/metadata.js @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; +// sample-metadata: +// title: Metadata +// description: List the types of sensitive information the DLP API supports +// usage: node metadata.js my-project langaugeCode filter + +function main(projectId, languageCode, filter) { + // [START dlp_list_info_types] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The BCP-47 language code to use, e.g. 'en-US' + // const languageCode = 'en-US'; + + // The filter to use + // const filter = 'supported_by=INSPECT' + + async function listInfoTypes() { + const [response] = await dlp.listInfoTypes({ + languageCode: languageCode, + filter: filter, + }); + const infoTypes = response.infoTypes; + console.log('Info types:'); + infoTypes.forEach(infoType => { + console.log(`\t${infoType.name} (${infoType.displayName})`); + }); + } + + listInfoTypes(); + // [END dlp_list_info_types] +} + +module.exports.main = main; + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/numericalRiskAnalysis.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/numericalRiskAnalysis.js new file mode 100644 index 000000000..2e404c7ea --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/numericalRiskAnalysis.js @@ -0,0 +1,161 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Numerical Risk Analysis +// description: Computes risk metrics of a column of numbers in a Google BigQuery table. +// usage: node numericalRiskAnalysis.js my-project tableProjectId datasetId tableId columnName topicId subscriptionId + +function main( + projectId, + tableProjectId, + datasetId, + tableId, + columnName, + topicId, + subscriptionId +) { + // [START dlp_numerical_stats] + // Import the Google Cloud client libraries + const DLP = require('@google-cloud/dlp'); + const {PubSub} = require('@google-cloud/pubsub'); + + // Instantiates clients + const dlp = new DLP.DlpServiceClient(); + const pubsub = new PubSub(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The project ID the table is stored under + // This may or (for public datasets) may not equal the calling project ID + // const tableProjectId = 'my-project'; + + // The ID of the dataset to inspect, e.g. 'my_dataset' + // const datasetId = 'my_dataset'; + + // The ID of the table to inspect, e.g. 'my_table' + // const tableId = 'my_table'; + + // The name of the column to compute risk metrics for, e.g. 'age' + // Note that this column must be a numeric data type + // const columnName = 'firstName'; + + // The name of the Pub/Sub topic to notify once the job completes + // TODO(developer): create a Pub/Sub topic to use for this + // const topicId = 'MY-PUBSUB-TOPIC' + + // The name of the Pub/Sub subscription to use when listening for job + // completion notifications + // TODO(developer): create a Pub/Sub subscription to use for this + // const subscriptionId = 'MY-PUBSUB-SUBSCRIPTION' + + async function numericalRiskAnalysis() { + const sourceTable = { + projectId: tableProjectId, + datasetId: datasetId, + tableId: tableId, + }; + + // Construct request for creating a risk analysis job + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + numericalStatsConfig: { + field: { + name: columnName, + }, + }, + }, + sourceTable: sourceTable, + actions: [ + { + pubSub: { + topic: `projects/${projectId}/topics/${topicId}`, + }, + }, + ], + }, + }; + + // Create helper function for unpacking values + const getValue = obj => obj[Object.keys(obj)[0]]; + + // Run risk analysis job + const [topicResponse] = await pubsub.topic(topicId).get(); + const subscription = await topicResponse.subscription(subscriptionId); + const [jobsResponse] = await dlp.createDlpJob(request); + const jobName = jobsResponse.name; + // Watch the Pub/Sub topic until the DLP job finishes + await new Promise((resolve, reject) => { + const messageHandler = message => { + if (message.attributes && message.attributes.DlpJobName === jobName) { + message.ack(); + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + resolve(jobName); + } else { + message.nack(); + } + }; + + const errorHandler = err => { + subscription.removeListener('message', messageHandler); + subscription.removeListener('error', errorHandler); + reject(err); + }; + + subscription.on('message', messageHandler); + subscription.on('error', errorHandler); + }); + setTimeout(() => { + console.log(' Waiting for DLP job to fully complete'); + }, 500); + const [job] = await dlp.getDlpJob({name: jobName}); + const results = job.riskDetails.numericalStatsResult; + + console.log( + `Value Range: [${getValue(results.minValue)}, ${getValue( + results.maxValue + )}]` + ); + + // Print unique quantile values + let tempValue = null; + results.quantileValues.forEach((result, percent) => { + const value = getValue(result); + + // Only print new values + if ( + tempValue !== value && + !(tempValue && tempValue.equals && tempValue.equals(value)) + ) { + console.log(`Value at ${percent}% quantile: ${value}`); + tempValue = value; + } + }); + } + + numericalRiskAnalysis(); + // [END dlp_numerical_stats] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/package.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/package.json new file mode 100644 index 000000000..c09cc4574 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/package.json @@ -0,0 +1,30 @@ +{ + "name": "dlp-samples", + "description": "Code samples for Google Cloud Platform's Data Loss Prevention API", + "private": true, + "license": "Apache-2.0", + "author": "Google Inc.", + "repository": "googleapis/nodejs-dlp", + "files": [ + "*.js" + ], + "engines": { + "node": ">=8" + }, + "scripts": { + "test": "mocha system-test/*.test.js --timeout=600000" + }, + "dependencies": { + "@google-cloud/dlp": "^3.1.0", + "@google-cloud/pubsub": "^2.0.0", + "mime": "^2.3.1", + "yargs": "^16.0.0" + }, + "devDependencies": { + "chai": "^4.2.0", + "mocha": "^8.0.0", + "pixelmatch": "^5.0.0", + "pngjs": "^6.0.0", + "uuid": "^9.0.0" + } +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/quickstart.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/quickstart.js new file mode 100644 index 000000000..0d60c0e43 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/quickstart.js @@ -0,0 +1,91 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Quickstart +// description: Inspects and assesses a string. +// usage: node quickstart.js my-project + +function main(projectId) { + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // [START dlp_quickstart] + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The string to inspect + const string = 'Robert Frost'; + + // The project ID to run the API call under + // const projectId = 'my-project'; + + async function quickStart() { + // The minimum likelihood required before returning a match + const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The maximum number of findings to report (0 = server maximum) + const maxFindings = 0; + + // The infoTypes of information to match + const infoTypes = [{name: 'PERSON_NAME'}, {name: 'US_STATE'}]; + + // Whether to include the matching string + const includeQuote = true; + + // Construct item to inspect + const item = {value: string}; + + // Construct request + const request = { + parent: `projects/${projectId}/locations/global`, + inspectConfig: { + infoTypes: infoTypes, + minLikelihood: minLikelihood, + limits: { + maxFindingsPerRequest: maxFindings, + }, + includeQuote: includeQuote, + }, + item: item, + }; + + // Run request + const [response] = await dlp.inspectContent(request); + const findings = response.result.findings; + if (findings.length > 0) { + console.log('Findings:'); + findings.forEach(finding => { + if (includeQuote) { + console.log(`\tQuote: ${finding.quote}`); + } + console.log(`\tInfo type: ${finding.infoType.name}`); + console.log(`\tLikelihood: ${finding.likelihood}`); + }); + } else { + console.log('No findings.'); + } + } + quickStart(); + // [END dlp_quickstart] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactImage.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactImage.js new file mode 100644 index 000000000..da893c2e8 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactImage.js @@ -0,0 +1,96 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Redact Image +// description: Redact sensitive data from an image using the Data Loss Prevention API. +// usage: node redactImage.js my-project filepath minLikelihood infoTypes outputPath + +function main(projectId, filepath, minLikelihood, infoTypes, outputPath) { + infoTypes = transformCLI(infoTypes); + // [START dlp_redact_image] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Imports required Node.js libraries + const mime = require('mime'); + const fs = require('fs'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The path to a local file to inspect. Can be a JPG or PNG image file. + // const filepath = 'path/to/image.png'; + + // The minimum likelihood required before redacting a match + // const minLikelihood = 'LIKELIHOOD_UNSPECIFIED'; + + // The infoTypes of information to redact + // const infoTypes = [{ name: 'EMAIL_ADDRESS' }, { name: 'PHONE_NUMBER' }]; + + // The local path to save the resulting image to. + // const outputPath = 'result.png'; + async function redactImage() { + const imageRedactionConfigs = infoTypes.map(infoType => { + return {infoType: infoType}; + }); + + // Load image + const fileTypeConstant = + ['image/jpeg', 'image/bmp', 'image/png', 'image/svg'].indexOf( + mime.getType(filepath) + ) + 1; + const fileBytes = Buffer.from(fs.readFileSync(filepath)).toString('base64'); + + // Construct image redaction request + const request = { + parent: `projects/${projectId}/locations/global`, + byteItem: { + type: fileTypeConstant, + data: fileBytes, + }, + inspectConfig: { + minLikelihood: minLikelihood, + infoTypes: infoTypes, + }, + imageRedactionConfigs: imageRedactionConfigs, + }; + + // Run image redaction request + const [response] = await dlp.redactImage(request); + const image = response.redactedImage; + fs.writeFileSync(outputPath, image); + console.log(`Saved image redaction results to path: ${outputPath}`); + } + redactImage(); + // [END dlp_redact_image] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + return infoTypes; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactText.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactText.js new file mode 100644 index 000000000..305dcd44b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/redactText.js @@ -0,0 +1,80 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Redact Text +// description: Redact sensitive data from text using the Data Loss Prevention API. +// usage: node redactText.js my-project string minLikelihood infoTypes + +function main(projectId, string, minLikelihood, infoTypes) { + infoTypes = transformCLI(infoTypes); + // [START dlp_redact_text] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // Construct transformation config which replaces sensitive info with its info type. + // E.g., "Her email is xxx@example.com" => "Her email is [EMAIL_ADDRESS]" + const replaceWithInfoTypeTransformation = { + primitiveTransformation: { + replaceWithInfoTypeConfig: {}, + }, + }; + + async function redactText() { + // Construct redaction request + const request = { + parent: `projects/${projectId}/locations/global`, + item: { + value: string, + }, + deidentifyConfig: { + infoTypeTransformations: { + transformations: [replaceWithInfoTypeTransformation], + }, + }, + inspectConfig: { + minLikelihood: minLikelihood, + infoTypes: infoTypes, + }, + }; + + // Run string redaction + const [response] = await dlp.deidentifyContent(request); + const resultString = response.item.value; + console.log(`Redacted text: ${resultString}`); + } + redactText(); + // [END dlp_redact_text] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); + +function transformCLI(infoTypes) { + infoTypes = infoTypes + ? infoTypes.split(',').map(type => { + return {name: type}; + }) + : undefined; + return infoTypes; +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/reidentifyWithFpe.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/reidentifyWithFpe.js new file mode 100644 index 000000000..0fe8e1413 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/reidentifyWithFpe.js @@ -0,0 +1,103 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// sample-metadata: +// title: Reidentify with FPE +// description: Reidentify sensitive data in a string using Format Preserving Encryption (FPE). +// usage: node reidentifyWithFpe.js my-project string alphabet surrogateType keyName wrappedKey + +function main(projectId, string, alphabet, surrogateType, keyName, wrappedKey) { + // [START dlp_reidentify_fpe] + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = new DLP.DlpServiceClient(); + + // The project ID to run the API call under + // const projectId = 'my-project'; + + // The string to reidentify + // const string = 'My SSN is PHONE_TOKEN(9):#########'; + + // The set of characters to replace sensitive ones with + // For more information, see https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#ffxcommonnativealphabet + // const alphabet = 'ALPHA_NUMERIC'; + + // The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key + // const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'; + + // The encrypted ('wrapped') AES-256 key to use + // This key should be encrypted using the Cloud KMS key specified above + // const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY' + + // The name of the surrogate custom info type to use when reidentifying data + // const surrogateType = 'SOME_INFO_TYPE_DEID'; + + async function reidentifyWithFpe() { + // Construct deidentification request + const item = {value: string}; + const request = { + parent: `projects/${projectId}/locations/global`, + reidentifyConfig: { + infoTypeTransformations: { + transformations: [ + { + primitiveTransformation: { + cryptoReplaceFfxFpeConfig: { + cryptoKey: { + kmsWrapped: { + wrappedKey: wrappedKey, + cryptoKeyName: keyName, + }, + }, + commonAlphabet: alphabet, + surrogateInfoType: { + name: surrogateType, + }, + }, + }, + }, + ], + }, + }, + inspectConfig: { + customInfoTypes: [ + { + infoType: { + name: surrogateType, + }, + surrogateType: {}, + }, + ], + }, + item: item, + }; + + // Run reidentification request + const [response] = await dlp.reidentifyContent(request); + const reidentifiedItem = response.item; + console.log(reidentifiedItem.value); + } + reidentifyWithFpe(); + // [END dlp_reidentify_fpe] +} + +main(...process.argv.slice(2)); +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/accounts.txt b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/accounts.txt new file mode 100644 index 000000000..2763cd0ab --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/accounts.txt @@ -0,0 +1 @@ +My credit card number is 1234 5678 9012 3456, and my CVV is 789. \ No newline at end of file diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/dates.csv b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/dates.csv new file mode 100644 index 000000000..6a80d40a4 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/dates.csv @@ -0,0 +1,5 @@ +name,birth_date,register_date,credit_card +Ann,01/01/1980,07/21/1996,4532908762519852 +James,03/06/1988,04/09/2001,4301261899725540 +Dan,08/14/1945,11/15/2011,4620761856015295 +Laura,11/03/1992,01/04/2017,4564981067258901 diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/harmless.txt b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/harmless.txt new file mode 100644 index 000000000..5666de37a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/harmless.txt @@ -0,0 +1 @@ +This file is mostly harmless. diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/test.png b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/resources/test.png new file mode 100644 index 0000000000000000000000000000000000000000..137e14cd2c25e9642f9f8747abb1061bf34f2167 GIT binary patch literal 31282 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 au)u#F=Z}++E;=6o0000 cp.execSync(cmd, {encoding: 'utf-8'}); + +const harmfulString = 'My SSN is 372819127'; +const harmlessString = 'My favorite color is blue'; +const surrogateType = 'SSN_TOKEN'; +const csvFile = 'resources/dates.csv'; +const tempOutputFile = path.join(__dirname, 'temp.result.csv'); +const dateShiftAmount = 30; +const dateFields = 'birth_date,register_date'; + +const client = new DLP.DlpServiceClient(); +describe('deid', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + // deidentify_masking + it('should mask sensitive data in a string', () => { + const output = execSync( + `node deidentifyWithMask.js ${projectId} "${harmfulString}" x 5` + ); + assert.include(output, 'My SSN is xxxxx9127'); + }); + + it('should ignore insensitive data when masking a string', () => { + const output = execSync( + `node deidentifyWithMask.js ${projectId} "${harmlessString}"` + ); + assert.include(output, harmlessString); + }); + + it('should handle masking errors', () => { + let output; + try { + output = cp.execSync( + `node deidentifyWithMask.js ${projectId} "${harmfulString}" 'a' '-1'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // deidentify_fpe + it('should handle FPE encryption errors', () => { + let output; + try { + output = execSync( + `node deidentifyWithFpe.js ${projectId} "${harmfulString}" '[0-9A-Za-z]' 'BAD_KEY_NAME' 'BAD_KEY_NAME'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'invalid encoding'); + }); + + // reidentify_fpe + it('should handle FPE decryption errors', () => { + let output; + try { + output = execSync( + `node reidentifyWithFpe.js ${projectId} "${harmfulString}" '[0-9A-Za-z]' ${surrogateType} 'BAD_KEY_NAME' 'BAD_KEY_NAME NUMERIC'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'invalid encoding'); + }); + + // deidentify_date_shift + it('should date-shift a CSV file', () => { + const outputCsvFile = 'dates.actual.csv'; + const output = execSync( + `node deidentifyWithDateShift.js ${projectId} "${csvFile}" "${outputCsvFile}" ${dateFields} ${dateShiftAmount} ${dateShiftAmount}` + ); + assert.include( + output, + `Successfully saved date-shift output to ${outputCsvFile}` + ); + assert.notInclude( + fs.readFileSync(outputCsvFile).toString(), + fs.readFileSync(csvFile).toString() + ); + }); + + it('should handle date-shift errors', () => { + let output; + try { + output = execSync( + `node deidentifyWithDateShift.js ${projectId} "${csvFile}" "${tempOutputFile}" ${dateShiftAmount} ${dateShiftAmount}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/inspect.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/inspect.test.js new file mode 100644 index 000000000..608169e0a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/inspect.test.js @@ -0,0 +1,282 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before, after} = require('mocha'); +const cp = require('child_process'); +const {PubSub} = require('@google-cloud/pubsub'); +const pubsub = new PubSub(); +const uuid = require('uuid'); +const DLP = require('@google-cloud/dlp'); + +const bucket = 'nodejs-docs-samples-dlp'; +const dataProject = 'nodejs-docs-samples'; + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const client = new DLP.DlpServiceClient(); +describe('inspect', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + let topic, subscription; + const topicName = `dlp-inspect-topic-${uuid.v4()}`; + const subscriptionName = `dlp-inspect-subscription-${uuid.v4()}`; + before(async () => { + [topic] = await pubsub.createTopic(topicName); + [subscription] = await topic.createSubscription(subscriptionName); + }); + + // Delete custom topic/subscription + after(async () => { + await subscription.delete(); + await topic.delete(); + }); + + // inspect_string + it('should inspect a string', () => { + const output = execSync( + `node inspectString.js ${projectId} "I'm Gary and my email is gary@example.com"` + ); + assert.match(output, /Info type: EMAIL_ADDRESS/); + }); + + it('should inspect a string with custom dictionary', () => { + const output = execSync( + `node inspectString.js ${projectId} "I'm Gary and my email is gary@example.com" 'LIKELIHOOD_UNSPECIFIED' '0' 'PHONE_NUMBER' "Gary,email"` + ); + assert.match(output, /Info type: CUSTOM_DICT_0/); + }); + + it('should inspect a string with custom regex', () => { + const output = execSync( + `node inspectString.js ${projectId} "I'm Gary and my email is gary@example.com" 'LIKELIHOOD_UNSPECIFIED' '0' 'PHONE_NUMBER' "gary@example\\.com"` + ); + assert.match(output, /Info type: CUSTOM_REGEX_0/); + }); + + it('should handle a string with no sensitive data', () => { + const output = execSync(`node inspectString.js ${projectId} string "foo"`); + assert.include(output, 'No findings.'); + }); + + it('should report string inspection handling errors', () => { + let output; + try { + output = execSync( + `node inspectString.js ${projectId} "I'm Gary and my email is gary@example.com" 'LIKELIHOOD_UNSPECIFIED' '0' BAD_TYPE` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'BAD_TYPE'); + }); + + // inspect_file + it('should inspect a local text file', () => { + const output = execSync( + `node inspectFile.js ${projectId} resources/test.txt` + ); + assert.match(output, /Info type: PHONE_NUMBER/); + assert.match(output, /Info type: EMAIL_ADDRESS/); + }); + + it('should inspect a local text file with custom dictionary', () => { + const output = execSync( + `node inspectFile.js ${projectId} resources/test.txt 'LIKELIHOOD_UNSPECIFIED' '0' 'PHONE_NUMBER' "Gary,email"` + ); + assert.match(output, /Info type: CUSTOM_DICT_0/); + }); + + it('should inspect a local text file with custom regex', () => { + const output = execSync( + `node inspectFile.js ${projectId} resources/test.txt 'LIKELIHOOD_UNSPECIFIED' '0' 'PHONE_NUMBER' "\\(\\d{3}\\) \\d{3}-\\d{4}"` + ); + assert.match(output, /Info type: CUSTOM_REGEX_0/); + }); + + it('should inspect a local image file', () => { + const output = execSync( + `node inspectFile.js ${projectId} resources/test.png` + ); + assert.match(output, /Info type: EMAIL_ADDRESS/); + }); + + it('should handle a local file with no sensitive data', () => { + const output = execSync( + `node inspectFile.js ${projectId} resources/harmless.txt` + ); + assert.match(output, /No findings/); + }); + + it('should report local file handling errors', () => { + let output; + try { + output = execSync( + `node inspectFile.js ${projectId} resources/harmless.txt 'LIKELIHOOD_UNSPECIFIED' '0' 'BAD_TYPE'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // inspect_gcs_file_promise + it.skip('should inspect a GCS text file', () => { + const output = execSync( + `node inspectGCSFile.js ${projectId} ${bucket} test.txt ${topicName} ${subscriptionName}` + ); + assert.match(output, /Found \d instance\(s\) of infoType PHONE_NUMBER/); + assert.match(output, /Found \d instance\(s\) of infoType EMAIL_ADDRESS/); + }); + + it.skip('should inspect multiple GCS text files', () => { + const output = execSync( + `node inspectGCSFile.js ${projectId} ${bucket} "*.txt" ${topicName} ${subscriptionName}` + ); + assert.match(output, /Found \d instance\(s\) of infoType PHONE_NUMBER/); + assert.match(output, /Found \d instance\(s\) of infoType EMAIL_ADDRESS/); + }); + + it.skip('should handle a GCS file with no sensitive data', () => { + const output = execSync( + `node inspectGCSFile.js ${projectId} ${bucket} harmless.txt ${topicName} ${subscriptionName}` + ); + assert.match(output, /No findings/); + }); + + it('should report GCS file handling errors', () => { + let output; + try { + output = execSync( + `node inspectGCSFile.js ${projectId} ${bucket} harmless.txt ${topicName} ${subscriptionName} 'LIKELIHOOD_UNSPECIFIED' '0' 'BAD_TYPE'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // inspect_datastore + it.skip('should inspect Datastore', () => { + const output = execSync( + `node inspectDatastore.js ${projectId} Person ${topicName} ${subscriptionName} --namespaceId DLP -p ${dataProject}` + ); + assert.match(output, /Found \d instance\(s\) of infoType EMAIL_ADDRESS/); + }); + + it.skip('should handle Datastore with no sensitive data', () => { + const output = execSync( + `node inspectDatastore.js ${projectId} Harmless ${topicName} ${subscriptionName} --namespaceId DLP -p ${dataProject}` + ); + assert.match(output, /No findings/); + }); + + it('should report Datastore errors', () => { + let output; + try { + output = execSync( + `node inspectDatastore.js ${projectId} ${projectId} 'DLP' 'Person' ${topicName} ${subscriptionName} 'LIKELIHOOD_UNSPECIFIED' '0' 'BAD_TYPE'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // inspect_bigquery + it.skip('should inspect a Bigquery table', () => { + const output = execSync( + `node inspectBigQuery.js ${projectId} integration_tests_dlp harmful ${topicName} ${subscriptionName} -p ${dataProject}` + ); + assert.match(output, /Found \d instance\(s\) of infoType PHONE_NUMBER/); + }); + + it.skip('should handle a Bigquery table with no sensitive data', () => { + const output = execSync( + `node inspectBigQuery.js ${projectId} integration_tests_dlp harmless ${topicName} ${subscriptionName} -p ${dataProject}` + ); + assert.match(output, /No findings/); + }); + + it('should report Bigquery table handling errors', () => { + let output; + try { + output = execSync( + `node inspectBigQuery.js ${projectId} ${dataProject} integration_tests_dlp harmless ${topicName} ${subscriptionName} 'LIKELIHOOD_UNSPECIFIED' '0' 'BAD_TYPE'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // CLI options + // This test is potentially flaky, possibly because of model changes. + it('should have a minLikelihood option', () => { + const outputA = execSync( + `node inspectString.js ${projectId} "My phone number is (123) 456-7890." VERY_LIKELY` + ); + const outputB = execSync( + `node inspectString.js ${projectId} "My phone number is (123) 456-7890." UNLIKELY` + ); + assert.ok(outputA); + assert.notMatch(outputA, /PHONE_NUMBER/); + assert.match(outputB, /PHONE_NUMBER/); + }); + + it('should have a maxFindings option', () => { + const outputA = execSync( + `node inspectString.js ${projectId} "My email is gary@example.com and my phone number is (223) 456-7890." LIKELIHOOD_UNSPECIFIED 2` + ); + const outputB = execSync( + `node inspectString.js ${projectId} "My email is gary@example.com and my phone number is (223) 456-7890." LIKELIHOOD_UNSPECIFIED 3` + ); + assert.notStrictEqual( + outputA.includes('PHONE_NUMBER'), + outputA.includes('EMAIL_ADDRESS') + ); // Exactly one of these should be included + assert.match(outputB, /PHONE_NUMBER/); + assert.match(outputB, /EMAIL_ADDRESS/); + }); + + it('should have an option to include quotes', () => { + const outputA = execSync( + `node inspectString.js ${projectId} "My phone number is (223) 456-7890." '' '' '' '' false` + ); + const outputB = execSync( + `node inspectString.js ${projectId} "My phone number is (223) 456-7890." '' '' '' '' ` + ); + assert.ok(outputA); + assert.notMatch(outputB, /\(223\) 456-7890/); + assert.match(outputA, /\(223\) 456-7890/); + }); + + it('should have an option to filter results by infoType', () => { + const outputA = execSync( + `node inspectString.js ${projectId} "My email is gary@example.com and my phone number is (223) 456-7890."` + ); + const outputB = execSync( + `node inspectString.js ${projectId} "My email is gary@example.com and my phone number is (223) 456-7890." LIKELIHOOD_UNSPECIFIED 0 PHONE_NUMBER` + ); + assert.match(outputA, /EMAIL_ADDRESS/); + assert.match(outputA, /PHONE_NUMBER/); + assert.notMatch(outputB, /EMAIL_ADDRESS/); + assert.match(outputB, /PHONE_NUMBER/); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/jobs.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/jobs.test.js new file mode 100644 index 000000000..c3f38a531 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/jobs.test.js @@ -0,0 +1,158 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const cp = require('child_process'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const badJobName = 'projects/not-a-project/dlpJobs/i-123456789'; + +const testTableProjectId = 'bigquery-public-data'; +const testDatasetId = 'san_francisco'; +const testTableId = 'bikeshare_trips'; +const testColumnName = 'zip_code'; + +const client = new DLP.DlpServiceClient(); + +// createTestJob needs time to finish creating a DLP job, before listing +// tests will succeed. +const delay = async test => { + const retries = test.currentRetry(); + if (retries === 0) return; // no retry on the first failure. + // see: https://cloud.google.com/storage/docs/exponential-backoff: + const ms = Math.pow(2, retries) * 1000 + Math.random() * 2000; + return new Promise(done => { + console.info(`retrying "${test.title}" in ${ms}ms`); + setTimeout(done, ms); + }); +}; + +describe('test', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + // Helper function for creating test jobs + const createTestJob = async () => { + // Initialize client library + const DLP = require('@google-cloud/dlp').v2; + const dlp = new DLP.DlpServiceClient(); + + // Construct job request + const request = { + parent: `projects/${projectId}/locations/global`, + riskJob: { + privacyMetric: { + categoricalStatsConfig: { + field: { + name: testColumnName, + }, + }, + }, + sourceTable: { + projectId: testTableProjectId, + datasetId: testDatasetId, + tableId: testTableId, + }, + }, + }; + + // Create job + return dlp.createDlpJob(request).then(response => { + return response[0].name; + }); + }; + + // Create a test job + let testJobName; + before(async () => { + testJobName = await createTestJob(); + await deleteStaleJobs(); + }); + + async function deleteStaleJobs() { + const dlp = new DLP.DlpServiceClient(); + const request = { + parent: `projects/${projectId}/locations/global`, + filter: 'state=DONE', + type: 'RISK_ANALYSIS_JOB', + }; + const [jobs] = await dlp.listDlpJobs(request); + for (const job of jobs) { + const TEN_HOURS_MS = 1000 * 60 * 60 * 10; + const created = Number(job.createTime.seconds) * 1000; + const now = Date.now(); + if (now - created > TEN_HOURS_MS) { + console.info(`delete ${job.name}`); + await dlp.deleteDlpJob({name: job.name}); + } + } + } + + // dlp_list_jobs + it('should list jobs', async function () { + this.retries(5); + await delay(this.test); + const output = execSync(`node listJobs.js ${projectId} 'state=DONE'`); + assert.match( + output, + /Job projects\/(\w|-)+\/locations\/global\/dlpJobs\/\w-\d+ status: DONE/ + ); + }); + + it('should list jobs of a given type', async function () { + this.retries(5); + await delay(this.test); + const output = execSync( + `node listJobs.js ${projectId} 'state=DONE' RISK_ANALYSIS_JOB` + ); + assert.match( + output, + /Job projects\/(\w|-)+\/locations\/global\/dlpJobs\/r-\d+ status: DONE/ + ); + }); + + it('should handle job listing errors', () => { + let output; + try { + output = execSync(`node listJobs.js ${projectId} 'state=NOPE'`); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // dlp_delete_job + it('should delete job', () => { + const output = execSync(`node deleteJob.js ${projectId} ${testJobName}`); + assert.include(output, `Successfully deleted job ${testJobName}.`); + }); + + it('should handle job deletion errors', () => { + let output; + try { + output = execSync(`node deleteJob.js ${projectId} ${badJobName}`); + } catch (err) { + output = err.message; + } + console.log(output); + assert.match(output, /Error in deleteJob/); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/metadata.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/metadata.test.js new file mode 100644 index 000000000..c8ec161ea --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/metadata.test.js @@ -0,0 +1,42 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const cp = require('child_process'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const client = new DLP.DlpServiceClient(); +describe('metadata', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + it('should list info types', () => { + const output = execSync(`node metadata.js ${projectId} infoTypes`); + assert.match(output, /US_DRIVERS_LICENSE_NUMBER/); + }); + + it('should filter listed info types', () => { + const output = execSync( + `node metadata.js ${projectId} infoTypes "supported_by=RISK_ANALYSIS"` + ); + assert.notMatch(output, /US_DRIVERS_LICENSE_NUMBER/); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/quickstart.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/quickstart.test.js new file mode 100644 index 000000000..2e000674b --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/quickstart.test.js @@ -0,0 +1,35 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const cp = require('child_process'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const client = new DLP.DlpServiceClient(); +describe('quickstart', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + it('should run', () => { + const output = execSync(`node quickstart.js ${projectId}`); + assert.match(output, /Info type: PERSON_NAME/); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/redact.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/redact.test.js new file mode 100644 index 000000000..5590a26ed --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/redact.test.js @@ -0,0 +1,135 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const fs = require('fs'); +const cp = require('child_process'); +const {PNG} = require('pngjs'); +const pixelmatch = require('pixelmatch'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const testImage = 'resources/test.png'; +const testResourcePath = 'system-test/resources'; + +const client = new DLP.DlpServiceClient(); + +async function readImage(filePath) { + return new Promise((resolve, reject) => { + fs.createReadStream(filePath) + .pipe(new PNG()) + .on('error', reject) + .on('parsed', function () { + resolve(this); + }); + }); +} + +async function getImageDiffPercentage(image1Path, image2Path) { + const image1 = await readImage(image1Path); + const image2 = await readImage(image2Path); + const diff = new PNG({width: image1.width, height: image1.height}); + + const diffPixels = pixelmatch( + image1.data, + image2.data, + diff.data, + image1.width, + image1.height + ); + return diffPixels / (diff.width * diff.height); +} +describe('redact', () => { + let projectId; + + before(async () => { + projectId = await client.getProjectId(); + }); + // redact_text + it('should redact a single sensitive data type from a string', () => { + const output = execSync( + `node redactText.js ${projectId} "My email is jenny@example.com" -t EMAIL_ADDRESS` + ); + assert.match(output, /My email is \[EMAIL_ADDRESS\]/); + }); + + it('should redact multiple sensitive data types from a string', () => { + const output = execSync( + `node redactText.js ${projectId} "I am 29 years old and my email is jenny@example.com" LIKELIHOOD_UNSPECIFIED 'EMAIL_ADDRESS,AGE'` + ); + assert.match(output, /I am \[AGE\] and my email is \[EMAIL_ADDRESS\]/); + }); + + it('should handle string with no sensitive data', () => { + const output = execSync( + `node redactText.js ${projectId} "No sensitive data to redact here" LIKELIHOOD_UNSPECIFIED 'EMAIL_ADDRESS,AGE'` + ); + assert.match(output, /No sensitive data to redact here/); + }); + + // redact_image + it('should redact a single sensitive data type from an image', async () => { + const testName = 'redact-single-type'; + const output = execSync( + `node redactImage.js ${projectId} ${testImage} 'LIKELIHOOD_UNSPECIFIED' 'PHONE_NUMBER' ${testName}.actual.png` + ); + assert.match(output, /Saved image redaction results to path/); + const difference = await getImageDiffPercentage( + `${testName}.actual.png`, + `${testResourcePath}/${testName}.expected.png` + ); + assert.isBelow(difference, 0.1); + }); + + it('should redact multiple sensitive data types from an image', async () => { + const testName = 'redact-multiple-types'; + const output = execSync( + `node redactImage.js ${projectId} ${testImage} LIKELIHOOD_UNSPECIFIED 'PHONE_NUMBER,EMAIL_ADDRESS' ${testName}.actual.png` + ); + assert.match(output, /Saved image redaction results to path/); + const difference = await getImageDiffPercentage( + `${testName}.actual.png`, + `${testResourcePath}/${testName}.expected.png` + ); + assert.isBelow(difference, 0.1); + }); + + it('should report info type errors', () => { + let output; + try { + output = execSync( + `node redactText.js ${projectId} "My email is jenny@example.com" LIKELIHOOD_UNSPECIFIED 'NONEXISTENT'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + it('should report image redaction handling errors', () => { + let output; + try { + output = execSync( + `node redactImage.js ${projectId} ${testImage} output.png BAD_TYPE` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/date-shift-context.expected.csv b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/date-shift-context.expected.csv new file mode 100644 index 000000000..2329cb63c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/date-shift-context.expected.csv @@ -0,0 +1,5 @@ +name,birth_date,register_date,credit_card +Ann,1/31/1980,8/20/1996,4532908762519852 +James,4/5/1988,5/9/2001,4301261899725540 +Dan,9/13/1945,12/15/2011,4620761856015295 +Laura,12/3/1992,2/3/2017,4564981067258901 diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/redact-multiple-types.expected.png b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/resources/redact-multiple-types.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0ef54c3822441792ec192bdafd987ab4ad8e99 GIT binary patch literal 15869 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

Z!Z-kTnfgeW_s245NH%^shrfSp0k6DSK zSq^xF#5($O5#HdAX#?ByU`VA*0iGb$n{h-gRv$1;zz83;CT{iMgQ^zhVE7tO`XiSX z!jI>FdIY?py}N&Neb}CFXr(yBydG+h2!9Rw_O|oIWk>iyacNagptrGr_7Xj9R_(>4 zf}$^F1d`2YyAu{L6YWI*4q3eq1dvd)QCT^%VsN`Y4c#hw<%xgC%5@uagb;5dX1P#; zoSN+g%$%yVcdK>g8L_?yM3Y4Vb)!{YZXYoS;c4LxM=`k0qTpvj9l-$_3$5b8)NLp- zlxC8dtROYNZc)T*39vp2?c(a0wLYj2h>TrwG>~J1PP<|v>N@9Fiy6a#%FQ+5DO_u+ zg$4zGVX&U<(i#o4*gP?+XL-naFAtml93xJen>36RvU;8abiCwzJ2@=-aFQhm)B*!@ zg{FD{^kq0YGSzoo;ttC;6n+scG~0WpoH&(Xa;fBQ@Bk5)cZ!vd`UxrPPofX zGj09xSh7fB4DaXWEV=kAZ^p4WL_xl3H}c`r7kEdu)P) zKudYaFdiJjM>U6!2UrIMMNYsXvU|m<5Chs=>O6TV+=;67QeJm9JyJr?7%uR;!XJV- zo@CaReT`CyOUk?xHjv6{cqf#&=T*(U8X=dklxfjf{A?DX@4(DG;3xm`(np-j@Lfv8 zOA8MxMXqP0ERVpX(qg_slbNC07K4mN_VhtWb`(m4792IT(SjumFGO@xxu3@JtZP!lxmg%o=4A`nPm9D{ z9G4Cks!7LaQ>>ZU|2_8nf8*p2Fk#0ScnZC#S2>nLyg>ZT* z=XuE!3G>YF&(%A|qSVO8=U>J)c7C~p3_ZzPO`fpJxCL--$ISZ|8hPGVUSDIQ%0&b$It+%L8*1ZypGG~m2jOqlsd(anu6>|TF+)zGItRn zAhWVVyF=rYfklhDBoXLhB!y@O;6BdkY@W(#I2McKG98N>9gwxpISi~ZlKcH|$B1~b zR}&;6xL3NlUaTZ6D4%i7?ajRlUljDCoyNgapeYC3e9KxHm1# z-`ZV}jMQ?UBETMvSb=jTqMsp%o0eFyY>6bgv9b?w0}SSiYFS5e640ZJ_chiht|~K$Fc+2l@*}@ z6~2BNSFr>lDeicWj%obu1c7NRl^HFJEe+QyOR(j?+8DAGLfRCRupx6P& z7B{FbLbk08?5p2g)_)SYdHdxUCEN!Q8`}!q@@2MwzAGr!mk zJ(&=Y1Cxx50u?_QCncX2suKbxq+`}DI{&E&samyh=_s|HxZwC-M2VP{hvn}hocyoc z{ohEOSq6tupOD>?Y7#?5Auu6sf_;G5%%FZ;rWyNUFTrF8r7}Gxh(E4a-HIAYQF$n! z_SFnTkt@Ak?ExrLFAd+4@Do=@lHDh$5!%jlbdup2?52+KwbEH{Yj6qgo=khki7LKr zS;l+f;BAAEXBeX^8zbchVc_TQh>X^$IE2epb}i31CeaJ&iR0^O z+`uT>Z3u>+hMU!Q*%FXPlUKrWLneQ0SZSg9GWBni^B&)5bMqrCrd~!P+4xSxO-9)G z1bJ8JI+lIC9n#P8m3mYq;qjXmIObS?ffj3r#_)ZtFu|#vdm5?l-3(6GdiZ@o^m02J zRCzkh^z^{!#O$u8$z=aw@*KRNX2bfi0dtC2nHQ5%usuCO^l3_4@73ep(3u<9>W-2% zvLfrlgIeM?8I$xsQ_EAwEzFWe~j(_fo}f|cqjT$9b@ST0{f&k3FWK*{iOeQ zz!QH$#oj5lCPH(-PRdJ7ZtTx7ETsX(V_udy=`ebiww_jonw8 z`l)@R8vU59|5PD`N2{8Kx96I2M~K-iF==*#j$=+Cn+M~%X`HtodYtKChg_at7o+?e=U|8tApjX=2Zz+bFge` zhr-xCM6o1_BK6V82QQY&>JgS~=iHR#ee?IElAbkAw+9FQH;u2C^Ew#EuBYo;YqJCC zB}UU#SJhq>#Ymosy;rTEV7a-RXEqS1`pe?vn*qO9h^@52#7g-;Zc(|GW+M z;_&u8m+ZepoI6$0Ht7DlL-|CB8-Hx($58H(T0(-o|BSd}kzYlaP}E#?{@l5v3LD8CKrncLTPuDR|gPL5qh&d=hueCRB!G^XWorsZ>Me$ z^M7b(QG-4A2fCFze3J4HdEjhU6gCb8&%Tb~kIGv3YZpiRc4GU}U*?NGrOY}!t@rlZm^bS^qPl*r zERr)U4EPUyswcBDx(rcYtUU?!&v=KIb0ldcxOwhp`yUI$(i#KfXRSR&GAG3=h-3|V znd5x&+5jO{fO4|T-NmR|<}sF8d!u(Fd#@JHT31kL4QHGl$!(SzeApE__tuMdFjwa0 z82$bqo^z3T3KRlT*`@eW$zZzAZk7pTX9up->1?|gx9q}m-}cZATj<;liHyE!4Q5+O zec0d>+KM%6vEk)u-;+Og4_f!%VPWWbSNNHK{cVGYjHttDzh;QX)3bTcEZfxyd|NER zX0C6|2|DcOKXsorvKI}_ac}uk5M!*?c{PR)(5bHy>;dvvXfX{GC~eUaeBKYM`!~hS zn$U3mTdXRkM16pc!3ElcJ@A;Fi!D1_4bvtWEG(+qm`q*fYTRt{ZMnPIW7d#9nZ)~O z=MSF8MzlxJ#-DasqQ(B$wA<2eEaKrLZN*5!7K8$gc;eSVOt0*yqt=K;G~{z`ZNb*% z1KlCG8X?`f*zDrnI_lf0$ax@^$5o;=BuW2+YA*E)br*83>t`m5hiNNCvNw*r2`jMU zC@e?W@8*_y>xV(-h|OD!JFpWqCe6@Mqg>*CTyJ zMKeIhnq}x~**~3+dO`LKL6n~m{MWjy++<-({~rXMFC_^ESbAHN0SwOmakrJz`nKQ_ z-K=_yQ_1>=Rim>- zxfoz1<@W)mp#6?6GReP!&A(_W93bMz1ixb%kTfObr%w` z1uyhUyl=C034sOh^bp~~9sWv*B#A7k`X6O`zm3hb)Y;9l5LJLt-!?dh2?K!l|Zhb8jsQJU{ojic=7$-XIF!YNF3pAUuo|TxXnPAL< z3u5utu#w`@9h?0G&bl`3&@01;buG>sXIz#={b+YgmM*6&|G_TjiWVPU)pkIO@7MG( zBHg6Zgn-GyC_MwS+FD%x}joi!Lkjvj(5!5z}kTyn0}t{ zd8JcC6(-!SY#9|tpSI>!5oqRSqYy}Rx~S?TN)ggIGi{yrKoX!XEl5iG2gFk}>O z=vOyhBA311U*UY>uYx=Bk1y#b_{wY>jXJ@&)LJwx2>IHT=A6y8jsMZ>=^XHTXq)uu zY~exw4HgSc%LD_ru+XwR_{sMV(;(SQ|Ad2QSXiI6ESwgJI9oXH5qI6`!5s}+7s+Cg z=M5ei;64fc1mfLU^Uj|~l) z_-D?EKDOq``bLX&8DLT`yg&IZIm>S2=NW0tG_Q+hRa$n&FNE~2U^b~SWG2Xo`^B-Kpn*WqSZ zsvg(Q!CAJf$VjiT{6R6!DEtvDCcje(pZ=Uu)R+V5&P1X1qL9@IpBSo}hP3zj2%#rY zlk*g@N>wo$b*v9qycqEnv%oWi$HVy}Tv(<`EFfTX+>@?=F(uAfmY$ru>$XBLmV57M{&6$*w!XlrW2BP>}sh!k)>#K>LY@FZuj045CO0V61Rus6LM zedcohTJ@VzNg@xV#Eksk_9pn)W$%yTPu3^g?sO8HZkG)Qc}gOS_nj1nA~^@)Kw2&irxc!UG84aKCVE$5w&N5R;?OlOuX%hR8>VhauXH1%4|RHDcrRn1 zge8vaRGfF%uo%pbqI1~~f6F3BL>q3Dz1qIuv6IZk6|F366+j-Q7YVm zHY^v~995%yOdQ@**6o51xI&h3nP=6wb$lkeJx^3J3Wqko*;3gRJ7*f%%q>Xrvze>NR}<(fa;o zOMCPIo(f=k2{V*Ze(NCWPb91sRW&9N934%nhRRqX)Rq(7JGdpJIOe7fd*%MAf%Q?4z zt1+nX-bX>l=cZg1&_-+(K#ZS4cCZL|-*jJchxnY($$iyc4Rb|=XpifIbLuP=-DQMB zghjHJUWk17E}V=bT02vewC!9UrIRFq70Y-1OYb-$CU&?H}_7E4^T`O`32wQZ9c25ld{{RCjao2H-HO zNyr@DIR)~Gh49&E7TDMcM2T?XkBskx5+WMJdH}TfY1{KaK=f!kUa0Q67kxxN)r#x z9?L8h|9uk*iWgaHAvuuP0r?Nqy@Uv1Qn|ox6iCPTJ&(QMx0C|M`o(~4r1nKaj^=OF zNQ`0u0g5oD;anFk)j{+?B|*s1NGFQXbHM680!s( zJO{0AGPB?h!IT~Wm0tt5?8FNA?Uaa-WnZ0Xb53v&Ta>fHArMnq=CWfvWk-&iAwLk} zH8CIYoxKpQLlFdxhB!|QA_Reo`ZVcLwx4{* z+k*nQ4rmcoFWH8It2GEA;VDxu497+=9pRSzl*0d2ue2!tg8r`YM0CB1NNJE9CW*7k zK-PeCFy;91hP2S0bUeafJGpUv)T1$5`j3joQZ=$2UGRFgu5kT%j#kzsGt;m-YkXWb z^?Q~X>~ZU*9fb$GTwDUGG0dak`&pW4*2j_h1%2g`bne1{n6Q@tmF$D!Gw<-pH? zVvVeBDZJl&n}eRBC584i&-pT|r_+66BVt8&wd5pobjx%DSARy5P4N01`64s&Yqo5$ z@5TuHMGK&L6}=_=e*0M2%vP`HS+zAcOEIQa;BzkI0X=ES2w~jct$rF-;SozZ_rSE! z&mMzdts;5^TO7Jvh4hp!3^KTJ?gEsbik!+l@@;2y@8&4)-{ksYn1P5BiAydP$@Ab& zVo0vX3DEIqhFSRU_W9Y)d9?j<$fS)L71@#5EOnf4qMvTqZsdA8chj@!^^06T8FDlS zv{I+l%B{#VN#RmAUw9kUNtpar;LpJ#dQvYP?vrTV!O&5}gsAzGJpK8HH+!HDK<}>H zsR~w6PW_Ex%vv#FNgMb%V9RTe7A4xNJzxNCRD|_riakdX#HSTJdp1nMgoKMGPAgnm zoeTP!!IGAB02FchHy!s5Rp=N??lVP{XO6GpJw6C@HZzhjEF5rD6$_qR)?Jtu*8o|_ znMRmdhx)!F*hJy77+a=6jc3f1RzVy_u7oul&H2BUsB$nLk5x!C9< z2K&l#FHb~0>Cjp$E`hx`JP)VYiSLg18oq%VNr&}Gx!`GGBpg>>hF#>%#tu%}T&3?rb+LSv}+qK81wuC(J@s8OvWsm71b<;K%4(&e=y(~nJ@ z;EwPER#Tv#*~_Ons_M(dnFq;GHC8=cQk`zBK97K|OD_?tX56$j!U1ZX z5)bG|!8^va=-J;)5s?~&&p0CnL{Ez9=k-Mqf8yWt%f z&W-8`*I<>qtwq2VvHa0?Xwa*crUHMHee~SUXd+Gt>Om_R^ISO(DC|2OFdxq&3 zG5?TgKaoTK{oCyULV*P6mEBt0fs_K58F}j1YWHHBcpS+GIGQ?3FA(0DoGhw2T+V)u zsNdk~cVm}^F^4q;N=C#?NfhnIrhporIg#7?>AK9Ke$^jmD0TH`qpAt7^PAuC|1mS5 zjN8zbP8aQ--okhkKMdvOt~lu&cvRBb7&80NBKY8$xp%5*Yfi0zKckDem7K&5;6n=5 z4&!I~r=hVwIDKknwO>cHMcTOrzO&t|JbP+9wWwp#_4lTBd?CbiQ`6-`y|v=wtT#cU zbRwr$nAcoc`2lPBNxR+m#k01FBFCC98-K!{geIFk3o=~Wu}U@8>mg&9-ifdB9$qwD znmcm_H^==tUBiUid$z@(5;XtDtQS$bWF*@U-s*&RulolYwCvH(d{>-nb3#Y$A#|(g7VtgWkvxv( z;oV{qnD6)rY*2^e&wjbo&_PDT>LgRJP}iMZ{3wQ6jVk8H#>cvsw^np4fW-T1`aQpI z@uW7*q>4z!%COgf9V4#S_ZM($sEbjhjbFAuO@qI~Ck7^LQ0zMj&Z@uC-ozzCUxLv& z!cUa9JFk%!E``Y&oGP7;@=GG2KuvstO?!CNkWn}=FQeG)sQ6{SO zO(re=Tdcbi8ZXUg>L-SbJfjJ%TF?5(2{iP0Zsk|(D8-vi!mlvM^&zFtX`-ud9Y6?E zpPO))nmjF*v8(WsX*aK+k0w=~8hoQJtzsy!rgq5pBi%L!-CEEaq}>@-XOPxUJoJo{ zg`tl#J%&Nc;89uSdU-PxJv0UZB)guPk>5yjaw^!ATkYzQXyAziMo$y10FAyN;4wuKGdc+Zj5S-$pdboXnQUbV)M|f1zJH4Pzxb3s%Ec@E5 zq4Isl*I4h80f+17E?x$QQ{hiXs~yW}biqVlclYpm*fYFMNO{huI_pe2;|X3zNjoCM zvq>kZo$v;xJ=R*HB{FMnPnl%uKO8d=5B)-{e8$TI8j0Sx%fqr z2lT}6qrC>yINd=V+(nz>Xy>q=L=sVR|LHd)5cuiq_1ESyNWLf!u#oPF1q$qdr|%#% zdZ6NHfDs!!f89Cp8TuFwf(R48tnF7SJ4zYAB~OO1lo79$xMj9ujk7ejnOym1l$+-B zVe9eexsbI&mg6SJ#r=+H%}g`qF9)BLcpSAiJXpJ)vt;)$F`*wm?S!IRmwz301AAn6 zk~JS|7Xijz^?#?Rfh$r$eo4M|9~}hp{V1t1cS=<7Z}3<5erg@H_h?QEoUHk5B#uM1 z6_yaxe%~3VeOntl}8i#zyBC4+A z+x`kHA>)WwyyRfFE|B;wnM<8H3=&rO*(_@b@r2V4^cjBktlO#i)DL^?>QRnp)4?vO zO+MF44f*pEOELf$k4_bOzLIrml)G_Ft(1k5qOAs_yuZBO4SeY-ya@Ve92Z5M1IR0jI;C!jM z=LHmJ?Y6g7nB))g%pNO^Kt*^(LnWg7x1+Yc_)i5Xug3jSJ)+lKvnkGPts*?{Tvs0M zm@ac2EZ~cGJz$%!-Lq_TU!`n2Y%1Dv~4A*KcBWa^%o%9Q>fKKU?^DeNUc9<;UYO0aqNW>>>ltr8ME zQRQx^f4lUQAZbcJT;;yQSRT^(m#;yb%##>8Bn<+M_491b6SjDt-*#62s9pV-+1x*p z*tBb)u6XnI`JRN!&*25vT@5^CXH25XPy=dsu?nB5h{nv=7?q=-dxS#(&mgFHe}6_T zJQ(degV25O)HsE?5hXhB_tOmT&xCN5Gg+a;j}#Ui?1iS*z;bl6x}9udFw|s^XI9Xe zCA&KaDStc_9>u4_Okly~*gjZz)01bR?`)fVQ<>Q+x_XQFJuBKdC)dabo5XoLxNOI7 zvh4S*xJ=RoIbNOS%~0FI9fb#HY>(kt^rLn4zg$50Y))X zST_6SAN|BUKjS+nc`v+{;lzaxPrKoFdw-_EuUx`o>G(<-UHI^mxk!qV@%q!|x6_Bp zcC5RMXXY7sIZ2{vef=LEa=HIJU{MQMdG`R@ikE11L}g=?Yh>^v7R)qL9Fh4fxRkOd z)5dgKjN8*un0%HdNf^WX#v*wE1gMCkC`0!8!=-qVFO^eH%)aNn>qoz;tO{}2Cat;rG zOM}1c^7@Pzf%bbzkO9m0KTEF@J!#IbnJieHpRp5O z=l<5$|2SKl*b=#^WLwwhhiQVTd?eYaieVcv!^I=&wSLOQZ0uKb0pZm_d`@9?W1OBj z`y0vu|EroZJ<+rJvI3^pqS8(i7Or?Ldy~w5f5&P1{M*TOnQW4y(b>21gKxC9<3<*# zHJn3!ww*F8*%MIkkgY!jfG~ zd3auun|rjd&#E(>kX9TRZXQfXB3NgbrJR#20z) zzDfLzs+1MdX!-rB8oh(XlP)ooJ&DMwaIc^sbLq&m^;MH%3zKHmC3pp-s+F4~A)m9T z`c6A{tm7kfgH7;6Vv_EUq^CziB6AvKwrlYU#FFyI9px06)L`DC3aU3h?|o^W8=-)3 z=KcO%#m?a(Pdr!u3ygFVGYl-MMfSTiU94x-OMik=>*}`cP>(+dHYmDDnuwsF`pLm0 z!Cm<)uyd$Y+oXf%$TB53!~sg;uC@S9UfOZ>o`1K$Jk zs40B4+&3GMvC=7*rRs-k%6@D9#mpH^rT8Zzc(oSNFoJ!Za0lLYDmG9?HFV1iYMcF4 z;$*x@L7RwWZ%p5d`_U=3f}}4lr{e6$z6@;K``eY`mAU7jN@r#N*TJSfNS;b@j{MuG zFb&|*KDH~4^Tp!R*TjfA?-ime!MJzQd1@gzx(wqR?YQJ`T&lz;bI=#?YYSHBz*4pN zm_F08jq6V$m}8hqCl8gGIW3@r5JE}x(JHlQL68*57F@Hsc!r-Ig+B?;I6eMZ_=tx_ zcj)SRosR;Okz)56hgnhoe$DsLZ>W6G z=2@5!qyXLeLjak&zxo{J_kLqM<$mpt7`;U4Y$k*%9fE_+u8ZUCZPziau|Nh#cIRgZ zbDU$P^Q(k397Y``k?zpyu7}AY^$ws|IY9t(RIJ+;7yt;^t-*(JW1@EsCKxC^r*ak7}Qh3-{rY%O@zd1tX|4;Yxi@pWG~(cYZ{7(vq4kmwv)l~l9_ zFlcdc@{qz@qrU*)(KZ!K_#mAN%X4ngJW555FrilnVatin@ZqIT7<@Wdv&Hn=^+y&l zKYK?HO?>uC9*9_rg;CK*G??hx$JR?uF_xhar)Uqjy5)PQkxT7VX2VyD_YVUcwhe^K z>~9m6J7Msg20}vkt1NgE&>lxm1@H)gCceZ#794w;<(IO7s7XysT9K@ zULN0yB-W}CFk~9i!N6&#tcr#&za;$W))5vky@wRnnyD)3V9#wI8}&rm zz{gbXD>hMChTBCyY%0jVs!f4@^v~Y0f?hlh>J6GGkh#bSdI7MS#&J~_`84z!Aw}`% zLE@pC1NS=HK29+Y4Q{NzV3Duo)4hCA5EuM2?NXp4X9z=?socxJ8SB%nC08~6#KI6u zORAUhG!zF+LIT8c*_WK}l#t;LU*J{3zkkfH;R8NOuyZ(Fsz3lvGKFH45FEWr{b5x* z_N5enwO!%+EVplEJz+i5=3cKJ2vTvJ%6U8k5Cy|OUu*14`9N2>sa!GP=I!O?m{i5l zeg`5HXXS>`GC?2Kj|KwyIUcQ!I)ho)d_%rf9hk%^`X&n4sy{CHK#6evy_A@fBsXZr zUPQ{(#o>zNf)cP~=&vvfZzSb%;o`v|#SUC9?WmOAs2&@7T)djGz?Osx0;$Epl%t1g z$|bmtI7&mB7oOFVC3Y#QT9LUnk0V3ZrJ<{IE(Hx2{nxKCY3o2K8DAugU{%|RNvBO` z6mvYQqhcn6U~`&%hcglXWmqAiih~;7k%8=k+++PQ#HBXIyfZ4XUFsvkZbS^rfKeO? zqhDa;9M&t@T|cyLN?IYMGK;(3l83861ea!O)D}@+1RmQz`xD_q2Zl^*dOZ(aI#9^y z2GLYjhYQ=!%QdFReVm0SU%b98d5GgofhVixP5YGUJ~+7mnh_>C24QvqAo`E*-}S&m zHXX!(VES~B9oq(!@q}Z69V$}cz)h0Veh+CYEb;?3DG9zDom9QgIp%lGy#{*kG)Z|5 zkAsNq3zGvs?jMk>YZyIOkQAy1WS(ZF<@Jw+>1m0K0x1QZYT~*x#8wQf|1dT)#BBwG zh;kuEL*uTdIQQSflBy`W^Z8e~k$jE7Z=UKSPgi5b(g%C-kN2QS+l)_j(?6TwS< zJLFR8sJ1g9yL52Z!f+F(S{F>mOrJfrwx>vVLZhTgiGaX)!0Qx(^vYD=h{Sf*9)H@Ygz&mzhhIlKTz^jPkCeA&Ig?cHr%ty^a{I=FYPl6u80XbC z!K4FN35f)zal-m_SS@26@5jOIbmIH7d^r55)gS*Fxh9bEk~a{*%{2@3JTK46>Y^Xp zV7#8I{iB1=lc;`lsS`W+3PeHAMuPgj0eJ65cwB>8tXrzd`0G-|8;`spxzFpz7oSJu z0J57&;+rjUfyZPUT`tHq#wOc|Y**ik_kT*a*`DLe8Clq)p+KNp6KWLSfThinM2xoL zKacR;>}Gn=x#2Str*Z<#*;3JqZ6R38Ib&&Q#AGE7zbZyAqLS6Pt-q2(Q+8|edBLnt#SY5P+njymw}=TG5uk5^UgBJZjBaGR1QPj8m)^Zy*n0MqI1D9Fo3*aNb(I?% z)gSD9HHlqJ#i)_y%0v>oSgWfEt!;f}+>`zvz0rLSbl}Nk^BJeBOy_y0pD>eeUVJAV zQ>A*EBnp7r!vA2me9>roTuCr%?tB%V92)RBi&q7}Mc?NGSG)4(6w4eWx9Jkzt6<|^I5A<}>nI~P;O39qP9AbMVfCD|s1x`58sBN6QQ zc2uP*Y4yK7wz^(a*>HS%rjtq6%*UxNEn9r~m6wxTGvs%@%DB*Qc8aS)o#dtrVmpyg zEu`RwG`GFhA-A{P=2_4}{|nBzL?~C><8&`kf9LXFslsueEMui)&^ZmzMNTSZ;XgLy zDeoQLj*iz2oYgknhLhI;EJ(`r%a)7&6MPMo0jrf0y%sL z8bq{y->{h;+NRnh66_sBPO6ne-HRwp|v@0YJ?27NO*s^h4RR17i z-2Wln+dSsq@aCVWWs>h}#X@*IA1He|S*Dcc{_Q@q3Gir{r#dFxlio7hHd@h4;AnRuN+;l@7r&QFj+YACM7)eUbs+-t-yWQO z@eXb=xY7dCxTR0hT9o0rqJjqeYr8b=QC6 z+0$!_c|Z25V(|uyqEy*F2^B>MnGJ^u^gm`x?n9O9DgC$hH80F@q1;-zG;Od$-`caD ze>@wcLvXFu#KGn$-yK=`^LS+6blwxTBlws*`oELg`!!INbP*fX600XkguwQijZ9W7 zOz{|PXA`gPb2nMtKbyy^_lS1A`0cTT%l6C*uZ=pWjV zaO#YwMGM6QYP2i+;1|XIxBBA@`j$Ac;muHQp)QZ?3|3x*2Y-KoKdT$@-zy>TO-|I! z*eXx@H|g!137W^xP7f#ALe7qPc;Db(Vf#OQ6MYg-o3Iv+ZPwgn*_vb_Jf^-21QUVB41BeI&L8`tM7+>Yp(1A?2LJ$6s!$~@-1j=}lSWF6 zd-gKi=L7&=QK>2^XnSL}=g1m7C(h*eBIzSZKhi`*zeFcMpYzqcz{W$<6m1hgV#&GD zY2E$lFRa5A)4Hws4xb**1ZI0&x9@s<+e#ew(Hy#L@im)r&vehKImI~6ZQjg}8J@Q4 z-Yar!Dsn8U(gD%JrryFiGAq~9E6EDRBuwa_#s8X8AQyqRr-5DaH~Vo*u7Q^`d#CNU z{%4zJx0ryTg`3l=!0S!wbE^|hN_#_#4Z8z^_RL`|K2_JcQ+ zPUEq~6vP3J2Z`IH}2|0-kk{gaU8Ry0>MR%t^-O z8r$)QE)O!Z194rk{wDBSxW1TbzlpP}-43j4^-EO;9?lcwUAM*qMitUTR z%Tf8%eXQ4R_}+p4{DfKV^ZTiC+Gv=W|7g+WFxTk^$-4HPiGZx#G`VZI@3}1gw5C;m z4W`U}Im^_%N$++nOLKcF`{trcbqC_lCpd-ag*{K{q4be!cA)=GAtX*`>_t z41Rk2S<^XC57fKMjDWpKj}|cizhUM`WXv@`IBd=ajd5m7vY(m}Jx7g-`*_VCH!obf7_jE*p%>51ZVpnrW)^NvmTZK54Oq== z9EOx3Yf+bTbbvo|>+ToVmkYN6)1Ml;7uLJ%3&2e0|f=_fl^l-uv{WP*+srl#6X>Xt_00^Sm=$nLz3Tk;w5HMNRYSwkr6$ES{%Ltcb<@eRLH@&(|Uc6XrK% zMBRGM2v3*Ob_>xsH_8Z^XKLH~u!NRs+jncfoU1Zmw79_Nb}Wo>aD1NB%p!w6jZ(h3 z!AiADZ&mjRb>*`kmn@CH(sUlu31ZkbzSRGa)EJRd35Eq;$$zi*O7-K^7pT}c6p)3s z@5i`O`tCHYy3K8xdU@j>QlEUVX z;=jciWG4?t$40>g*TTDL{4{NYnpt9slpV^(|u_!c9;TiuW0z<{Zi%41ee!M8g{)0 zUM+$a6*G`r>GFZaak*b_S7mm0y0z;jnA*>NF5U5Jct-H>fiZlebX`D%OJ98VYp9r6 zK%UQiJBEi7f~O|vl*@-Dyzw`z1#$jcR$(~DzZd{giEAqpL>9|muXo`b@!aCuoTnp) zf1lC3Sa~Bhy{jhsdh5gs8Paj3k1UQcyBJNCta+qF{lyP?)Q2-WxAB)MRKnh!6zPnC zKLt!h{r27ijf*_+kIb%?nY#Y1{SuX{cb8iS9tovzzxn^?=*b77YGllpH|3m22$QbfOey}^YO*S4E(TrfD9^If={U+N&Bc3LsF4LEIH zaDHoB_$lCGJ!amq{Hrp-&|MX_kq|q-!&fO4HRXKLLZhh7>ace5m(xY- zG5aX1SVT(d*To2Xzgyn{N7FHE@291R4Xm}x2%+=wW^$FEP5zMd>L+)hZ#IP_{FXa) zQ>O4l%L@m5-7%sX@d)4^k_1df=AGI!UKq+Nf8GO6Y$AD$w=#d)cKYS|WQO{*WmPtV zxNV}sWdd+^y&D*qwhomsm)o8@uJm#~ojV`&Vy~Znx4HChl6|vJj__6-yjC;4Tux`V zUA!EJoSL`m2XH|H^MeD|xhBi2HG-lUoZn(vvwW{sfD1bnospz>uDc=35qligJMP(+ zwO(!n$e*aJ+pAS6XS(eWRfNoS+gRq#`20#5iQHaL*Cp=1O)?td|KtLm|H6vpd=Pcx za`E3ZqMmW8fgf(4e+YiN`);b)a6!+^|Co_l#HD}BA6)Jmv%BNfe(9FlJZsZ1x9u{8 z@fm*44)*&iV1~f|!AvHJ4~RJ;iy7(CN7Y{tez~aYBxa>#b!o8Jyj3?nNRaHlYp>&b zag#RWXUhtdB6DsDtQnAWJXFqE%9lO)ZPl=HfA_J|*Po2r&l>V|I_y4m#MsK6Hchn} zwzp&tKWOQ;WD($jo^$n^6qS?3XeLrC?!OZ0K(o5ea(|29Ogk^QDdM5Y&VCnVG@B>N zY#Xq`y6_v>aJkb=t=Ej1U~wP8M9X7^*IvVZM6;FvmT>{= z+zsb>)p(I9d3At3FI2clP6ZhNuh#!$x)^cCaQ$_h@2uN<*4dn(aI`ov#_n)H$~9+9 zD*6s3X4FhEfpP5HznzszDJ19gs}SMamcs~5KTAhex7N5xZ19=ygpQu`cdD46qkjuk zEk{=r!qkMv{9<(SLWN>}FI39un(qDLJPoP;5gW7)?rm~hs^_ez-VDz55kC!%B@C0E zVzT07+Z#;GIw}Aa)WJ7t$+5}x60YUs<~(l5`(|*C>rX|$9~oHYueNXrNjf!gp!pdWu$5~n|V)o$Rr8o(_3_ThD#H|QR<}`DE)Q9R^DVk z_RLXY`0rsC@a9Wvw?E1-<6hX!@D=lPvnUf2AitW@(%)~_cfm1-;cTC-byjmG2QTNx z5cm%0z@ySVb7_e>(3>?|RD4L-J*^Lnp@Zz$=;l)mbPH03M}O#8?4kwij8z7#69fSk z_r1vEA^4K+UA%<@gr8AOBc2}oyf-E177y;i)?($-zO|mt`|3N_O&9`e*G(?MV+oNb zBl!OPM1~@l{!ABv8?Uk*w&~_mh;YI9a(V25&@Jr};%k}N^#;5q;rCS2WL@Z{$?m(D z5@f_4L^-&7)+ROqgNo<=(`-TCVXkHIqQBQK-#~V^6-=DX426qTxFpp2e2p?GN9bv# zCjAxP{?c`4+spQW`2F{LUEd+=?=MMNcbQsGgyiUL8MZ8KKZrVXD9e-+8z#LFsZ@GB zM6Cue|<;vRd z*wb_OamR|AqM!B;R{k1_I3o~p0Wqcou_p$k7*Sge9^_F?Wel1+1{jAuZQb?H@U$)b z<7;Jk<BexPBLSO>WhHwimie)^j{*R8`mMuoS$=WMxsg((P!x!qO$4wI6+}uUGkU z!N*u#Rx>+E83HZZea3zefAV1ZZggX~4{a`?7#(3jKU+He$`~=}ke&r*4-avFTm1U0 zwze(;-&5-nYE|sTojox)4w+l*K5C+fak(lzm38#G4Jlu?~e?atkG_U_rPhU>fEg!{5k&l$=!qSC#m*fNLciHqLpIb z0g3stzBdsUlO4ZXDvE`e=blrhM_N~~5^NL;X^-)NlVhj>=D}ylr0NtS?98#&Co*{i ztv#|=dtEb!1yb!49Oo+FlN2MD=`1o7N|hNbV{Pw>2@)}XD5{F^58x^SIOH^*)K$&Z zqE1CSua7>}`@5d=1t2o*(NmR4FD5<+m>cZSO0TB=k03em@hzh&$}!FaL=+1*NY-I1cN zG)Q`r;Y<-S=IYLZO1!c8c{`0`QKWJiGAV9rcaJKa1&9YT%Dex-iG3jEc0aLoLAH&K zKzi#-*B}q1O!xVUk8#mGBL1-mGZMjYy($r7ka)IWXMAXitL2SY90Cs0;xYI9VJ|=% zpOVXuOidX~2<`d1IZVzi&wlY)s*{Bxamoeev^q2HaE;VByI;I-Yh#;E$1L_gJ8@CQc0Xj}UNsi|N?g}ry zJ{|sX9YTS`m)m^*Ji$ZLA7Ff)D@|r5N~kz`S!2pZwa&gcQQub0M#|tm;`$3xQ|?2X zjvU$`hnn0_Yh#0T=)Jx-lTs=Im`60sBLVomTP=}qeo6KVUjOJH^4(w@NJjG#@!cIl z)=qu$Akio&C9`lDvCea=WmYyHw4kIk_(pQTig=zLP3$RLBr*~#I#K@J31-Am=mD=+ z<%PmrkXT=cbyl-p60MuyDXEr?V510E;wNI7q=?X+0TURZ2y>PI&A>h6=uJUuILMaa zFTH)AHvwb;k6!tRtxuudzO8BdWplle;X9h6JVf4SQ8B7#z9SAWFU+fPaR0{p+_cX- zypQ|&v6?h7u4Y~rIhoRSlj2e5xq^3A9*8W5*%Bz#aTAh~0k5C$BF%u$?GR8G67~qU zDUd~>eA}tqB)I@zpOelrvD7*BJw3D9h4cokN1el=FzS(6wdkgb zfLon1_&(UAoHt1Cbsb_>6?2bm<;z|%IjG9o3j&H0rKn!_wY75ai#LAMv~7xMU5iyROB9bjV|3~ z<~&qE^dD6{Aa1~z4r|Lv3jj8zr}Hrw*(0vH!-P1NT{PE7lgMrsrQXsNwC{b=d!|mP3E|VaERI$ku%# z{=76nT6!yO;G<3B5ip)(eY$8nw3!et@>rgP`MHCt1}0AO0RVdHl(I?@MKk6N7U^-Q zk$a^*)1g$8Sa}iB6ZCP2A|x-1yUbUgVA`c94$Mky6p3QD70z_rDfLc*x$u}>gQ0i2j$D193*?~v2N(MX!{|?vz-a+^M_#w zan1u)L&nB~kd{;^-xR7Wa}00rcGs0>`)ajf4ji8WuK#8&6dgkTL|;8di{rO5>$v>K zo6>1L@_0^5NvjxeR^@2fM$&wd_g*PqqSD)G zL2AuA-8e4-wF@PVhkvdYExD|vCdGq^*wsUxVrAhTbO53E|esQs0ty8_L5 zxH1BIWNkd57E#107$e1Rcb5^Byccc07wEi}dYY?(RhLJ_-ZR5D6(qSHlj?v(IYn0S z2VFR`E0#T3h){0;HuyUnP05g%Usv3Fyl)UQcXqMG*wXz+vUqLl9MwBPQV16?xh&Z= zeqT!*cHo<>H+^e*haj&J6Eh;Qh#^*k`{ZP z)o94vN}>L1DY;d|l2v+(=CeM3t3!ztcWFkL>H(zHPH;~v)eyZlxjI}_vGMT8inTB6 zp8D$MtL=A~30xLY3H~o$HYO4D7RSr**Wbeb4@iSNG5NnB?LQ5Kqd2^_p8j7Apm+`3 z&!_&=@E`8>zx!$WUk(5D0y-$~|A*22zwcBh9{nmVaj~&z#jq*7;aFaM{xpmF&C6kr z+;g)Haec;jyJ{YcFj>#mlnbvm=-|w+Vs`RR;wEU&TOZS7zK~DCiLd62rM29egw8&M z4jO+3552rAeaHPX_DRe7TH-sv+rh5}pZn)-!kbMkV^phQy0V+@{5(#9Xjq_b-`hvA zlG~b4vtGGBi=RJ)^e_(%Ry49A(mKN+$7}CKqm;@5h3g{j4FJ)f4c+JC9LyZl3mr;7 zVd}LFYfpHKzx{l(L7kfJ8?P%aMHipHv+;2^S)@@4$t+{z?Bh6$s?%9sjUHV$WTRr) zH5r?k zk>l8?z#eteH-+ac3OzX8QGjz@Eczy#3 zavG!>ejk#7jEvLuHqy5ImDyK+c)Q%Q4nIu}b={HK zlK1;VRuDy^o%0lTNDR}_H7GO?ZofIM5*7;_zalrr@gX294&Mn=;Rdoh$iS557@zf~ zm%qy&mq9H#;8NhdaFwTdLC3$i;-02TdORQ}^K9KTac$_jzawJ2AF1b*PPt@nRrKp0 z^tt`5zbJjnONow+^BVdGi2noQPWL6`aHrxsxDGEvaU}Y>!la)TFj_F=hZWBN;V7{g zrdDQYztXGK@i8u+&p_@EKItjPTf7-BmYdl5s|oa)ecgp4fHC##pO7d3nRu@Z8PI?E zlHLDkWIN#2J`(rs&1VOx?X!Zcsd5dc{o+GTR@XTChq0vQ&GNQ9TqT?O$EhEI zmi+Ar0Eii5)Cw|5xPtx<{*S!Lvvu$?(Jo$oi zkL}vAy;8kahu<#E+v&hRT~`6yj%G4f|48Pk)nkr1^Y>JtD)JX2U3551zoh%EY2wRL zDC-?uYQ4UfLn2!eq$JPjKlFGd8f1PpvLibAsQ$O5cfS?;7&EE(#wLzQwOX`apExS6 z;j(Tw$4zBiLiD8vlmQm#Vg~5Xpa?qZ{1<~r?)<}cMj00^6S_tc^1u}yF~j#960`%| zr&<5F*}zm2j@JCf{I<`JF$_EpL2d-(_~OPqb%FQWW17;+wSL;xITk=|@{cM~Q{#k& zjKBLKyiY9}2Ao~QjW01%?Dey6`YftiPaNDKc>H$zs?);O=~<5~rF_e{1>s$Vldl{EHs9vkbWwfv74m zw0EcFaIg!<`~HGH*08TXdxf{V)4V$$PF^7Fw?r}X14W{*c1M_un~k54y|2H zR0Y(DI-|7P?Q>Xu)14dRAO{N|=w3x#=W+vDqH+Ws@asVsQrPzPlW&5XdC<#~%4)SgX;yl20W#6Ti#M|F2@cNjQ z?|JUR8Cpt`B`x)(%4_5L3^YG1vez5;BmGkXrm zL1M^>Y|K5n-dm*R0`j*OLHsBqikM&|$$(dh6;g-*#D$<~FzAvH9e`D|rY~kJoyPlO zEV~WnI9cKYnoa||^8sWBN}%)g)PKqOyT%Piw$g>h^Y2Tw>NGgwk!a5lH5 zey$mZE+rK1TGT7Pr;mqG4s-&aTyE85&|3!M+-1Rm5X6rl0{+NdB8;^kNAZN?H!wf! zx5^6wzRZ7aNj^o^2?n#|*;WI#C8H9BOl+q=FzSsJ}?DZ`b(FjQfym2BD2w!eYMy zT|SUmcm@ps6>vtq=#+_D9cHv7mQ(aqVPI_+w95;u`U_+`F`XX_*osz+V>(5LmSg``jV>_e}i+L8=`z z{g^ERFM(RkNEA0`Psln#FyLnfP70KK>BkDn?1+!}qw?`bfbAy7=d$~Bp^YN@bGrej zwog7*TTu*6@Y=+R6_=%`qB618x(UOgUaHy{(E#@jmBe&De6WkV_|D?EpG8yd1w1uiSBu%K{H}rO~l! z*PP0#Wf)9LOi^^5*67} zA~D%#%~6~yFN?qw6ubB}J^*atylcyBUNa1M(u_C4$*l7tM3rt?>>Phoz+_zwPVr;t zV2qGL=uCc_;*8Yc&5B+0-vE4mH!d;Ti1E|01(*U$TH3&F?mZ>rG*!H;dV34pE`V|j zCJu)BX-DV6X=S!8{a`=FyOTg!2$wD9#vN-~LHs6}xpfWrAxQz4K|P2%blUGKjzMu| z{n^CgJw0@6D5RIWaH;y^tiHVyhwO4Vmmw>%gJg{Q?(h*coJ^Rbb=%o>hA`S|*y%#0 zM8|!~cb0;CC*~5bK+}KYRR+k$As^52dGvQ?y0n-DK{1y>KYLdN{%f0ekxq0MAy#X6 zBC~{xQtY)PT5sdN;N5IQfy6ew+{1M{;uv?tLDxm3E$_|MYxSKJAe7F!XC9*>59uCg zv2n%sf(f_pj?qF9_lrLDlxRg3&Ar>K$WZ>f`cCfSSd$P-1p6?jAa+^P;((CXm|GTI zU?b|B*L?N3NaHFC^##l|mZ|A*a8}`G)10)NSOnx2r($2^X;L@zb!FgV?rX3oyXN_# z^a$aNkLSExwjKv9FlR-6JdxNgyZD3prJtu-^O_Jk;&MEp=XzA+BO-p7&?E3W1@g&@ z;L&2P{DU&8YdRb3nDS%pwXPvTEk$Af{ea+Is19X+?U8a4VYQ4^eQ^cBpxW4rg_%ySxpv@ZeFSLKA?S=SEB12(?-s7!5a zR>gA^$|BV0tnyYG2#{nPF#tv@w00!uZ@%)_*%=W3fC}oicxqw-tbkBKRju3T#Xn$) zv`5)rli_1a`1p~AkZ$O{v)EUhpZdbn{5Xry%3W5R+vzXb9;*krSr#E!YrN+h;BQ-@ zR&O~3k5U_9&BIM0q;$Y8R$*IOdJ9QfKIVoZU7eb2noe&tNjRSP;$1aBf5>E z&m!y>eiK2+9)Gv}K*Ya1)Jp=j`z(J=LIC(Bc)A~W9UhIIJ?`uWQ=cL|kV^>uQ+#;~ zZV_n72)2zt?mIoIK>|M;q@=#*cbRxc&GJ5Ni{JFpE<} z*5^GB66$*a&Rb2pCSympFx+FTT?Xw_o$oA@*WMRrra@={`dAQPJ1X|$X*kR{g;73> zXeltDdh6(Aw*C`BQj71IOOoZoBXb6p%xz18;%_-y4hgj&WTbgNt6BNl2{;mydv;vY znMwf69F6qBuP4Hy)6{107&*kJYFyHw-&WIpVW4{>vajPDBtrd=#_e;7HsDIUnoOTZ z-rV8Izq=w+1|<=r6#Hc2Lv+y1n|1rn@|PFQmGV;n4WxD|+%gOQP5sf|M#G7bn&}6O zaDy3j`3nxK7#Z#16UR~yM3osF1$p;C{wmYJc5Ulj8gD$l3i3BWPVmE*CRjHU_Rr1b z8)7PAp7;r+CY$KP6}2=Z1n(2Z%igE@yzDcqM}Ne&`iPjy-90(^XU7xlXx_bL^L@nE-Uk2 z<0m*tl^Z_nzi(UhS8_~wPDdBd^we5!z~sHIhnbsMj!b|9*fYf(f6Ixw!lwiWvZ~I8 ztA3tjT#45glFJQ%p>`GWR*Ke>@B<1??~SbaCND{32?u#j4J_f(_r-DdM{R`{c%~95 z?L-0P?wD0|h;?Q?KA->nnX?!0Ib_3a;QYd>lwO6Y_}9`e>3*X{5c3esTBL%iElU~OWcP6eX%y;UpwHU-Ra7!o0c(nS+O`Cwr->o?A zQ|L5V84G=Bn+3$!zq4(du;^lJw3eVivJUE=)HCL)^hLLQr|w4mGIeS@{IGX z(>tZ^+m~RJzckVN{CCsfGU3wxP>o{LfCN%-^fah;f!ByYR5JCK?Z=m#on{K+z{c;T zZ-2?g>LwdKlz{D2DS4eY^k%Dtr;6q$!D$!V(b0Zp{I;d{9Q5u#{HsyWpjydGqj7Vvl=osq!yhFBGZBF^aWnlcdCe!qF!P?R<2qCYfj-$C#`|cJ#LcCme+95KJ zxC9g+?=5I`HjTF)2pQ^7*?8dktfhFN%AuDHl{tX%ES>V6JU<)@*TRlZCzz?lL$gww zH~jzAs~Fyt7Emql7jxb-36?e=O9BfkaK^++R(9r-(y++#&KDC7zac@GHCbW$_uA7| z4(kaMzgzA%=2d6~>JyOy3W#1Mi`E6=Y5Fh?HIl4VzDX{twMz@1eoNi2RxnzP(XCW5 z&|I`sYfc5_-$w`=8r}V-?Z`&J4~O}dw&avk9A;osm5V>AMTU&wRFfP0Eb=?OLn2mb zHG~8Z@vxPJjcrrL;D%Xh#v<4hK1Ki@w$PPE~u@zbpQxX4l!kdpp_ z*%ZMt^pN+N`baeyCr@?yfk>$|0N;G99&9L4cRkKtqbChCuhNV8L0o{bsV~Z;7u0(L z@<>_k6B|O9jaaquEkS0QQ+p`-rFl5W{zUfuq$-g~(lvC~Gs(eiEG)<#NllJ{d*U96 z?@s2hBD~%HB3?RAUKAyg_4NOdxyYt~p8MC@9y|Ld5&o@uh`=YkA=YZMHW?$N0r738 zEKglms{owG-d}1;3j29;N={ENL$cpq(N_M5byW^lgQe}H(hsPzu42;#7LCzH)b zwD?pLKqGcFrG2{!9Bb&ewR-XVrGnIP!W)Q3`;QuKjtZk%+XxF-ub?>CUG+n!4+Y!A z!(cKtQFl>c;46k_brGn~XkiRlExtf4YW1w3R=_#K*-z90p~1lb!)Hk*O2+)jpY%{W zC7@0Ob5yYYEptupxEr%tp4~zXy&m9Y_;k<~J#-~%^*jTyPJhnWDXEb@$DF+XQib2< zW$GKQu13g{sC)No*dKp~)U+)v2mio(mz~s8oK*4(U|*_j9Bu&PB4gRVFWRs=0nlBZ zFc6mbwH#3A^T^||Rp@RB<|$pG=Jb@Z7LQqnimZ8n6>Wp#^Dy=TFan18w5*c&nVt=?sAuIwf3Lbuag2)w8O29Xlbu?_*#`yQr{Yx zx2Jheo_rj9C!6DA6l}m(LuhU<-j*++ev`>L&54uwS&5x!b6!8S5+`VnU6}5cwbzmp zj0e5h3QzzhU!E7K6+ZNa=OajDD<6b^#WDPP-2|v%@OFCgC4(%-nU`(Me46UHBSDQPzNxwh zAeD|%E5GN~UQ-c0O6@#fTqU}lwgoXg-8$i|)s%^~HQwxhH@Hc3|5e}z(Q_NlRzHY* znXOSY1=K0Ye8;wZTmR)2h3`b^S>08!R}(UWX1S)C(}8?JiwT?oc@lKw7xXr|$5HXv z(zK3UE1RzkrPrR6SP_6mb1qUCan%tUy_!o=F)Qk&q=O36Lx-aHQ^S4 zD4SQELTS=VkPUM8!e762+KF`r>BF*XneO!U-EKN^OgrMc3+taOT)eh`&uiQLD#n%-VnI3oaKk=5WZP2Ctl+eZtf8rjL|KV!*=cLrt_IdbK)c9KKCh z!h)JM;mI~F){a%O0*OAZcu4(=yhrvzz{%{}$ay0Ui`7xm`k?lG zofOJGWYv6by^uft^?|-b^5z|%YsDUuS*Z}KwcO?iHDu-52fZLIQPI|X;aHE~+nIEo zAh6Q+yXMs|&8wPmqcvTYcwL%a&PCtpSxS28D6U1=bvj^dxvJEKT-t|`>ra*lv#L|R zyGgd#w1uRM{J1fZTzj|PFVjI%{J`Rdyd4CGXef;$oeka~SMS9e=C$*Me7wUDC&e1PMLKL`eviCpVjq z@SAuSAjST(cFT7{w_O0;y5>~AlSpgZR&5T9kG&tCB)v8;NzdHZLg41W@i#N7wf&z} zw!<1`A%$W>zSDj6FpsnoBj-AuzK75T7B{?*l*c$Z%`hMfQ@Sz3*X@mCcJ&`DrfD1& zp)y+6aLE?Whs*`c=ccW!yV`*|tkn|8yNO>De+*LBn4(qQnLd zaJqGRg|F@;f$l-mg#JrXvT=jEAc7dwlncE?%jAN zKm>)Czbk!nSwM;R!2B_|`_JW_8VfZLjjf^kfP|4ot{Bt5641+E_q3Z{GPeCNC}gCT z{u8guGHSh3JEqY$_-Z7przrDj+4qbq`I%Y~dg7th$UwX+E8yjCv@tkXiwUJ^gUsSD zJy#YfDJ!jdbAL{FME?;xWf?U}Zeoz^o^%qrTyx_upZ8y%LSR~RIq|kQ(Xp8fl4MUU zcuk;#mXk2eH)y;W*(>+bnI+#VDvuU2pIf!2@nWlSHLJooIAL;BrGwz@LQj|W+w@(& z!ssvJUf}AucS_{SeIydL$>ad~vsSZqtp`n3Fu^7%Yr$w3yRuwqSuhzX0LN zm_ezb#N(*6Hy3~S9;*GMKa{(5XC&Q*sfmjQQFApj)r^dSso|yVka1VxGHK+6g15*k zSrvD47`BekJY8$xK4!IHCDt+GM>(Ott;>cyT-h6d@>C@8Ut}7qhFLi`0|~~$!Br3O zES0<=3@^u#{PBls4SfOeoD3dbj)}@!ipeyll#jtCSPdXS zKwChtH64`cUcqG7q^a+=WG+liiv{3MpMq}=N-&n8BrVwJ+|zV`a79D$txBLa9R<>& z84Fx>a4~>Sd+AF5%QnWExa_}yJ&RL9wrD4O9x$={x0J!Pu}p^;T|=!~gmgdX%d?z+ zR~iP4!Il5&>th6xCu?q0+$C|`AXiJ_28fNQ z8t1++!iti}`I-9@GIr!okTK=hntXYJDy$V1;Qp?W9n;4=5>aSv+CUF;&8c+Pd#@6J zFQ5H3KSt64Nh~*HkYJ%$tk1lyh9pbpdAAiAnpOE6pC9W{A4c}KZ14VIBI9x5ZjTfp zjqRhwNin+5FpXY;Oe#)PIEbp@8eqSV-MuPFZ51DR1FrBZxd=jQ1cpH(KF3nU^ni)U zZF5iG0nMnrTT=N~Wl{0EB%_3}sO*hZ>oUCxzSJC2`5rCO+kRgpTKq!E{V?(TXYHc_ z0&l+^K>>5icGhpfJt0)`Y|loc!H7Gf6)G434yq)46@DvKK9Tn|u#YzMijiq>RE|6* z+j}`;yDQrI5x^E-vA<7{dYvRUtt+bw}h1}t_Uo63`D}(>mAPs6%5V2k#iX9+j*yw$xP%PXuGrsIPqSg$^7d00g63FWZo&-b>&4M6D zQPQZc*JPv$pmcg@or1V%92rM6ML&9gp7F(jyn^&w^9cQ53$$&G5;$P6$67H@H2zW^ z-b1fvo8VdstZm&Fc|IcW(g>3ZctA=fG>IS7qxHbNA0Zi|Z~F$AD0L0p<4f26k$Fz- zy%t_+Of1)YgWWR$y4-Q>K)LVj7CgrVBS^~VEl8mwJferqdS}lHI!q5mk24cNv{aJ8 z=rg2BqF7^IBTA(}3{6w<osd%bS76`3${kKdCHtTEI}n8ONfHwg7IDc(isaSRK6^H* z$ZXW^hk8@XbxXHWP5C{ zpeC?=&HH3AaG9~v`Aj(9Slus!DPQ&}HB&wtMDQ8z(Cz8Q8g%fR*L!5i#l4Pl6Iz7$lYb zBN1#YYmWG8Baf#ED6B6MTPxc7B5ZQu=#0PVO}TQl$1U}KiYraLQof&SBzupfgpOVZ z9v9LH?3pSia`aksAn0VT+Cf~ni>Fii1T9<5C+zNM%h9Q}QNOt%8Ivf$s9_~%XPn^j zs$I2|<={9K!7=4W=;*AT_^UVRZEXj|r8fEEzRE!G=eKK)C*u%3 zd(=MmRaralW})q)iJMa^6rhO>ysr4O_=3JD>+Jd#{jl%Rk>7%6;IL-kkfJ{o$HQ;| zD{PuyV8CgrkT&McR^wN>Y`x>)fUt4qIi@_Fz=hvBokkLW6nD2)UACSMrmu@J5;Smt zTrlNiw0GIn4K_VL0M;Wtj|-n%ut@8?Uu}K|yJ|7@Pf(~m*8(nh1ylvxlzN)>TY*6F zrb>DeBU~|;W1Sn5-=Ld5DZ?I461mM68#UZ7EIp^BTT32x_N^@q9XO%l2O z(H~d0OK%WYzYWhVC&90PV@@18n&ZZKVF4_7U10NzL1m7%PuyMpHT@`RQKb?yClxD~+gc zx=*eq z_d5yqE3_qoWT_9Wbo+B|EHRiXm$)jbT}cmh=bAX};5ykV$=Df9ht2fcnFX~?%+6U;xyn|$$|3O;s1U{rniu79fA8})a13#C{c5v5?>jKr_NdGd(gk%?iq(e$ zi!%%A>I8#OG*vsc_h!Dln2A2zEmi0AxHNUx#onKwgy(Q|7uZR?^gJk`wsx1MQNxFR zz#GCGq?}$NhROtKGUjw-N+@4;n@-)`T%bT?wJE!*<(|~84PpA3A9hX9Ro1vl)<*TD zW`E^$$PsJ~K?{BF{k_doPgL!))Gwji@#s*}vqjN_J))hpQ))5*2qCnQ&!{xTHl3#MP9Y4 z4JmoRMZ5F*4$MIyA}Z0EZV6une^;$DY8V}By-lWdoZU%`Exy=!^;Me0U2>0CUN#p^ z{z6Lmk6v9)%G6vBXBlWc_Vwv{3est0z$Ok{A3VQY9tW3;{@$yKv7c@djNdPSej7MA z=>tKM{Y&eT>`#sk($0TjD(`V#Db>bfQmzL)1T4`YnXtf^w*HgZSBR8HahL>RdxAEf zr0jh*7l6cN=)TMmiI{( zr(1rKqz79&QT5BH>9ek0@!xl=$&w5(fPYLXMLrMga$fEv$d#WE=hv16;`2d`k z-(`3pT;xUCcB<0!Y3!KfNS;F_1`>k@9Zp&{iF|>yp@(BK_SWas{IsB|6ly)McIK#l z_O!=4`$9QVLWsB1e!KT}lcsvc!KTs$JE@Aw`90|$O*nTM=lq5#S9Ae+5=#lEjX+t{ z4ywq-mC&;8qjkPD`=9yVy^q&cJ4i5wT-KV6{}0yGN>uW55P%8zQa6!pv|w{xfF(cK ziQ~gEsRs7*u0QF^2<&uioTPV03v{mU={Z8qTHi*4lzBb8IzdE+2ibO!BNF7r!lkaZ zFp#YMleGP&Hn{2Q2mFt-Re|#{mFU6md97S-F=n9*0is^G`*&-}2O>Verj4q`6tY72 zQL2PZC6Dm04l&oXXHP#~jJ0OaG{s#MJSk$lvy6yWCHtaP@mBlE{{({(eC`rLF&{|> zAaEbQ5J71uU@;IrkkTk5W@_d#xqu${wTZaiMJE_*l)wNU&yn&bTB5o7Kyo5U zCK?KG5Kwzk+z>_zoe$=esEyf;PyeKL=@$Y?3-c^SW)>Q=^e;gu?*ZOSoNhkQ{2MPfC2 z88@o|U1(@+36>FJa$3QW5MWB|1hlgxi{KWnH4FCXoU{OVy*}kd94`RoB$LHK%0cFG)R3Q1k^hg zTQGiO^E^H>20~lPVV@)tpt{i2e3=8_GY&MwA815jq#}m#=@X%9PVgxO1KhwTjWK4o z=Zyhx;3I)b$@u6abBlSsU6K6sJSDVUQBC=dZ%$KO9doVI4^fyg|(J+DMyoW|-BJyLSApu4oF^{n% zEsW`cF|}#pW5%GDxy_2|Wk~ z{bOAbLcZ5Fa53@BE$hfL<_S#*M?4{FYb?w~{G~4}5mhJT>Y@dK>ivW)9smXkKzjhG z<`pZ#Sj-Dymx2WSIYiZ5H^&4r!N)ql!}?3Z13CVt#r=;E#8aN3ef1ZQ8wZ}m2XPHN zi@x%NRl`7cJVc@BvpE!DXFYKd1UAhbUN%=Xo2vS#t5jz?&Nz@DIIUQ>X1Nd$AVu9U zk;wx_64<20q=|nD?3mghnWUHnNSP;qj$ zJ(x8PKA`(QLIMiFCB2ToF;OJ3??^fQBGrrw!(w_2o2v3A0}v%&YYTJK9WfZiM3JT` zd&%OEU~O`MIew7}4FnYnBtZpjnOK?!b7D-i#k@2J02&XbMmrzc9%C|@(I2g71HehZ zEcu-7mE_GV0|Ik_*)gHEYB^7UO5w4TRY6;c;(!<5(RgS_eWq=a)b1k(mx)fB5aD7b>0(AiV16K z6@mjK$xecknBE6~K*r2YGBGJn0@0GG9>_E|p)_C^K2c-DOkwIUhJXi9le+$9%F(zc z83ULglSqr05KOCW6M;#XQ~^N7k#ljBRbj^IzqWu8;4ncZF14ZnutpoTVZ0b#`59w# zpMEjXXkg|l)70-Q8tcI{6HSc)X<}L-L94XSRHJ2?TbR!LVk-VqO*9DY%pqn5R`;7* zVreW|i{^obBsd68X1sY~anwEH zf>PWBb4^esZ<-P#)F~YA=zYR{RKx*O$v>I}!6$u4qcE2kK z?eu}k1Q>)IO8~QCTH2SO46XGMP2A6{rgg^_|7mY73|ayZA;e_kV^=2DKl3UM!D<3h zCLwEpz@e?9#k3zV@qw9bc`thKHI=9VQf<;6G!sC_uQOJ2BydCP5)QO5ZL3|rKLM0^ z!w>w!x`d)HDgI4R)@X2DCi9aJp)eUt2IOo3T39xWqKKvEc# z38a%r8C}B9i*FWHguiFeC;|bj_r5z%g6anKCf} zgFa#qgBKz8ehkjfNU2gE%wb#@80cwWwQFf8j7sqEB~u_e64p-wOrXL203SaE*ag|@ zrgoZCPz^}K049!aWNdsPzV`u-zO?h0n~y3#!V35UGqSbnj-?H z3S<|{f{Ov9%y$}6&`exJAG7qQO+t*Dz>Uk2p1#neXa=M?H88GEO$Hf_?ve~9hq+ph z!t-K54*n!f%4ESr7)a+ZyiVjLn3~i|DNBRovlzGmRWmPA#9%Rv_AqcHX)4I;H1mS= zCE2})$x34jEY)>U_CL*HQV9=?mOu<`&3A}Ni~$J}|IfsFACMC&#vBs|qw@JoWL?N7 zF==9;BnT2XVo6}cNNe|-c!JQxWo=boqDceN9OXblW8@n3(-z@HDAMfwXhH%lX!N=% z!|%*v{{vD232^wR1a8**5>+Sh(UY~IP4h~NxgVJ7k_IqogFwo-!bl(R5vxMGS%c5V_?WRkUY8S%t!gG#9P5My7Kl$LM^UgQ0!D2BDPE4b8_i!2-W~<1iKop- zCDL05bwZ;6bBShTKt>H$QbA2G7fs_y4Zx2i*ME%S9rDs?iF*8%H zRv!o<<~hNLrmR9jmB}q=g}?D3MMGeQKIWQWB&;bBbB2eFAFohkiS>BKIQZq}3cm(` zgpkNCUe0NN{c@3UELeA!mSUD52;V_tv$7VDd&Ga&JaL?SaLG$Eu2zB&Oc3hiQ)erzTl zI0%TWlcK+gX2B3z#_JyR&E^O612FwT3w`msu^1P>hhh%m=lHmn7jOss;<3WioD(9(!L&yU zAR!O~Fmz^uN1G=gg)ZiVxtsNVRu&$%jtU?N&Lset<3?Clc!m(eyQ%Weq$Oloivnia zWBuquRvek)HHGxumZeGnJW-ejCZ_3_bS9Ug$oHRY= zVvYhF%Ol&`FcClyCNxaSd%8>37CtdXphOcsc9uc-wS=+f2{)i6r0Oz@%RJ$`oD$&uTo_7* z1r=9J{|ITc(>DUinDLFiMKfx{_$>*sh|DvdH0S!1t*8k+0<BqlG%0~#mc zV**Gz&t^ThmSw>JF&QzrHqjuH7C#WpOcEhb!}!`HL}GGB2!vzX$0=h%#_UuT|jf4?{onGC3|u|^w2L)L7X8s6`-5Bf@QBoUuV#L#5c%@mO~zGFI*oNRhdIg z!l?C`92CXurd4RZx*aPMm`SW*`+glQ?~nhT?`zHA8cnPjGWEW(nzwyMPOaISc9R7Y zccF&+Yej=9*lM5a#{Zf$P^(+iqGff9UETa0fYu;MU)e9QhDwVnbo;u&HBM1$8du=w z{tCEC*RgDs^r6zI)*h~f+xvaL*>F*pD#I`7Q>``Juc_9OJ@Jj}efhaiiQG|;W{Vc{ zl`7_A`uH6{nUpkY%(}cJrd*w*1UbfvS%(1WFmscS2b}EmoC{jhuPO*~E(}wPR%Frw zAQOU*!K~xM_-QGJNhcU0=;b?_EPbgARwt#VYSj>YWeoRKX064#D|1w!)%35rNxNo> zq>6p*SIy+;)2Jd$>LPv>I(cvURF@y>rj^WB%@(QPt*KQ#L-r>H)Kt4l!@j6^1z#Ay zGI5OrS0T}-lT{NqbJG`Is~a8a?zE~<>Uw3(Fse&b=|f+Ma;!v6<%cT3>W;ozc)lvJ zQIKMO{)e?e4t_Q-&~E%X8jPvXYnaM(wbOmdS#~L<^YO_5N0iWqZ@|>7QmY3?%qJ$2 zKo=nLZ-9{?$u1cFgb&|TyCR9KfJ(fo#cEnzO&`j5`^l-3So12!v|&G~VThU+Stq-% z*5Ci#Gh43(E7SBv!h2~RCaJ(1tJ7O8gKDYN|MdmmYFin5rCA+M-ObcnFntZA3ho|& zwcgc2dwJ{JjxB*ydiNGcpW<1o`1gg_E05KE3HAP7IR4kl3?5)B3!QV)MdE-HaH2Kp zfchg0`b`qOc~hgh+04MN`C%F`3yiPxWS(l;1Nh5bVQA1=Iq7+`S}kJ<=VK*%#%e~-RgI(R zny#r3*>p|UbWI?guIZYt38d3CT@y&BYr3Xu0_k*3*GhN&KUH?Nn|eo?_W%F@07*qo IM6N<$g0;9N9smFU literal 0 HcmV?d00001 diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/risk.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/risk.test.js new file mode 100644 index 000000000..b62d937e0 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/risk.test.js @@ -0,0 +1,208 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before, after} = require('mocha'); +const uuid = require('uuid'); +const {PubSub} = require('@google-cloud/pubsub'); +const cp = require('child_process'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => { + return cp.execSync(cmd, { + encoding: 'utf-8', + stdio: [null, null, null], + }); +}; + +const dataset = 'integration_tests_dlp'; +const uniqueField = 'Name'; +const numericField = 'Age'; +const pubsub = new PubSub(); +const client = new DLP.DlpServiceClient(); + +/* + * The tests in this file rely on a table in BigQuery entitled + * "integration_tests_dlp.harmful" with the following fields: + * + * Age NUMERIC NULLABLE + * Name STRING NULLABLE + * + * Insert into this table a few rows of Age/Name pairs. + */ +describe('risk', () => { + let projectId; + // Create new custom topic/subscription + let topic, subscription, topicName, subscriptionName; + + before(async () => { + topicName = `dlp-risk-topic-${uuid.v4()}-${Date.now()}`; + subscriptionName = `dlp-risk-subscription-${uuid.v4()}-${Date.now()}`; + projectId = await client.getProjectId(); + [topic] = await pubsub.createTopic(topicName); + [subscription] = await topic.createSubscription(subscriptionName); + await deleteOldTopics(); + }); + + async function deleteOldTopics() { + const [topics] = await pubsub.getTopics(); + const now = Date.now(); + const TEN_HOURS_MS = 1000 * 60 * 60 * 10; + for (const topic of topics) { + const created = Number(topic.name.split('-').pop()); + if ( + topic.name.includes('dlp-risk-topic') && + now - created > TEN_HOURS_MS + ) { + const [subscriptions] = await topic.getSubscriptions(); + for (const subscription of subscriptions) { + console.info(`deleting ${subscription.name}`); + await subscription.delete(); + } + console.info(`deleting ${topic.name}`); + await topic.delete(); + } + } + } + + // Delete custom topic/subscription + after(async () => { + await subscription.delete(); + await topic.delete(); + }); + + // numericalRiskAnalysis + it('should perform numerical risk analysis', () => { + const output = execSync( + `node numericalRiskAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${numericField} ${topicName} ${subscriptionName}` + ); + assert.match(output, /Value at 0% quantile:/); + assert.match(output, /Value at \d+% quantile:/); + }); + + it('should handle numerical risk analysis errors', () => { + let output; + try { + output = execSync( + `node numericalRiskAnalysis.js ${projectId} ${projectId} ${dataset} nonexistent ${numericField} ${topicName} ${subscriptionName}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'NOT_FOUND'); + }); + + // categoricalRiskAnalysis + it('should perform categorical risk analysis on a string field', () => { + const output = execSync( + `node categoricalRiskAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${uniqueField} ${topicName} ${subscriptionName}` + ); + assert.match(output, /Most common value occurs \d time\(s\)/); + }); + + it('should perform categorical risk analysis on a number field', () => { + const output = execSync( + `node categoricalRiskAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${numericField} ${topicName} ${subscriptionName}` + ); + assert.match(output, /Most common value occurs \d time\(s\)/); + }); + + it('should handle categorical risk analysis errors', () => { + let output; + try { + output = execSync( + `node categoricalRiskAnalysis.js ${projectId} ${projectId} ${dataset} nonexistent ${uniqueField} ${topicName} ${subscriptionName}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); + + // kAnonymityAnalysis + it('should perform k-anonymity analysis on a single field', () => { + const output = execSync( + `node kAnonymityAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${topicName} ${subscriptionName} ${numericField}` + ); + console.log(output); + assert.include(output, 'Quasi-ID values:'); + assert.include(output, 'Class size:'); + }); + + it('should handle k-anonymity analysis errors', () => { + let output; + try { + output = execSync( + `node kAnonymityAnalysis.js ${projectId} ${projectId} ${dataset} nonexistent ${topicName} ${subscriptionName} ${numericField}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); + + // kMapAnalysis + it('should perform k-map analysis on a single field', () => { + const output = execSync( + `node kMapEstimationAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${topicName} ${subscriptionName} 'US' ${numericField} AGE` + ); + assert.match(output, /Anonymity range: \[\d+, \d+\]/); + assert.match(output, /Size: \d/); + assert.match(output, /Values: \d{2}/); + }); + + it('should handle k-map analysis errors', () => { + let output; + try { + output = execSync( + `node kMapEstimationAnalysis.js ${projectId} ${projectId} ${dataset} nonexistent ${topicName} ${subscriptionName} ${numericField} AGE` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); + + it('should check that numbers of quasi-ids and info types are equal', () => { + assert.throws(() => { + execSync( + `node kMapEstimationAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${topicName} ${subscriptionName} 'US' 'Age,Gender' AGE` + ); + }, /3 INVALID_ARGUMENT: InfoType name cannot be empty of a TaggedField/); + }); + + // lDiversityAnalysis + it('should perform l-diversity analysis on a single field', () => { + const output = execSync( + `node lDiversityAnalysis.js ${projectId} ${projectId} ${dataset} harmful ${topicName} ${subscriptionName} ${uniqueField} ${numericField}` + ); + assert.match(output, /Quasi-ID values:/); + assert.match(output, /Class size: \d/); + assert.match(output, /Sensitive value/); + }); + + it('should handle l-diversity analysis errors', () => { + let output; + try { + output = execSync( + `node lDiversityAnalysis.js ${projectId} ${projectId} ${dataset} nonexistent ${topicName} ${subscriptionName} ${numericField}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/temp.result.csv b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/temp.result.csv new file mode 100644 index 000000000..2329cb63c --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/temp.result.csv @@ -0,0 +1,5 @@ +name,birth_date,register_date,credit_card +Ann,1/31/1980,8/20/1996,4532908762519852 +James,4/5/1988,5/9/2001,4301261899725540 +Dan,9/13/1945,12/15/2011,4620761856015295 +Laura,12/3/1992,2/3/2017,4564981067258901 diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/templates.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/templates.test.js new file mode 100644 index 000000000..16b330d9d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/templates.test.js @@ -0,0 +1,103 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const cp = require('child_process'); +const uuid = require('uuid'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const templateName = ''; +const client = new DLP.DlpServiceClient(); + +describe('templates', () => { + let projectId; + let fullTemplateName; + const INFO_TYPE = 'PERSON_NAME'; + const MIN_LIKELIHOOD = 'VERY_LIKELY'; + const MAX_FINDINGS = 5; + const INCLUDE_QUOTE = false; + const DISPLAY_NAME = `My Template ${uuid.v4()}`; + const TEMPLATE_NAME = `my-template-${uuid.v4()}`; + + before(async () => { + projectId = await client.getProjectId(); + fullTemplateName = `projects/${projectId}/locations/global/inspectTemplates/${TEMPLATE_NAME}`; + }); + + // create_inspect_template + it('should create template', () => { + const output = execSync( + `node createInspectTemplate.js ${projectId} "${TEMPLATE_NAME}" "${DISPLAY_NAME}" ${INFO_TYPE} ${INCLUDE_QUOTE} ${MIN_LIKELIHOOD} ${MAX_FINDINGS}` + ); + console.log(output); + assert.include(output, `Successfully created template ${fullTemplateName}`); + }); + + it('should handle template creation errors', () => { + let output; + try { + output = execSync( + `node createInspectTemplate.js ${projectId} invalid_template#id` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); + + // list_inspect_templates + it('should list templates', () => { + const output = execSync(`node listInspectTemplates.js ${projectId}`); + assert.include(output, `Template ${templateName}`); + assert.match(output, /Created: \d{1,2}\/\d{1,2}\/\d{4}/); + assert.match(output, /Updated: \d{1,2}\/\d{1,2}\/\d{4}/); + }); + + it('should pass creation settings to template', () => { + const output = execSync(`node listInspectTemplates.js ${projectId}`); + assert.include(output, fullTemplateName); + assert.include(output, DISPLAY_NAME); + assert.include(output, INFO_TYPE); + assert.include(output, MIN_LIKELIHOOD); + assert.include(output, MAX_FINDINGS); + }); + + // delete_inspect_template + it('should delete template', () => { + const output = execSync( + `node deleteInspectTemplate.js ${projectId} ${fullTemplateName}` + ); + assert.include( + output, + `Successfully deleted template ${fullTemplateName}.` + ); + }); + + it('should handle template deletion errors', () => { + let output; + try { + output = execSync( + `node deleteInspectTemplate.js ${projectId} BAD_TEMPLATE` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'INVALID_ARGUMENT'); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/triggers.test.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/triggers.test.js new file mode 100644 index 000000000..907b03b9d --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/samples/system-test/triggers.test.js @@ -0,0 +1,91 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it, before} = require('mocha'); +const cp = require('child_process'); +const uuid = require('uuid'); +const DLP = require('@google-cloud/dlp'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const client = new DLP.DlpServiceClient(); + +describe('triggers', () => { + let projectId; + let fullTriggerName; + const triggerName = `my-trigger-${uuid.v4()}`; + const triggerDisplayName = `My Trigger Display Name: ${uuid.v4()}`; + const triggerDescription = `My Trigger Description: ${uuid.v4()}`; + const infoType = 'PERSON_NAME'; + const minLikelihood = 'VERY_LIKELY'; + const maxFindings = 5; + const bucketName = process.env.BUCKET_NAME; + + before(async () => { + projectId = await client.getProjectId(); + fullTriggerName = `projects/${projectId}/locations/global/jobTriggers/${triggerName}`; + }); + + it('should create a trigger', () => { + const output = execSync( + `node createTrigger.js ${projectId} ${triggerName} "${triggerDisplayName}" "${triggerDescription}" ${bucketName} true '1' ${infoType} ${minLikelihood} ${maxFindings}` + ); + assert.include(output, `Successfully created trigger ${fullTriggerName}`); + }); + + it('should list triggers', () => { + const output = execSync(`node listTriggers.js ${projectId}`); + assert.include(output, `Trigger ${fullTriggerName}`); + assert.include(output, `Display Name: ${triggerDisplayName}`); + assert.include(output, `Description: ${triggerDescription}`); + assert.match(output, /Created: \d{1,2}\/\d{1,2}\/\d{4}/); + assert.match(output, /Updated: \d{1,2}\/\d{1,2}\/\d{4}/); + assert.match(output, /Status: HEALTHY/); + assert.match(output, /Error count: 0/); + }); + + it('should delete a trigger', () => { + const output = execSync( + `node deleteTrigger.js ${projectId} ${fullTriggerName}` + ); + assert.include(output, `Successfully deleted trigger ${fullTriggerName}.`); + }); + + it('should handle trigger creation errors', () => { + let output; + try { + output = execSync( + `node createTrigger.js ${projectId} 'name' "${triggerDisplayName}" ${bucketName} true 1 "@@@@@" ${minLikelihood} ${maxFindings}` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); + + it('should handle trigger deletion errors', () => { + let output; + try { + output = execSync( + `node deleteTrigger.js ${projectId} 'bad-trigger-path'` + ); + } catch (err) { + output = err.message; + } + assert.include(output, 'fail'); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/test/gapic_dlp_service_v2.ts b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/test/gapic_dlp_service_v2.ts new file mode 100644 index 000000000..bfabed86e --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/test/gapic_dlp_service_v2.ts @@ -0,0 +1,6256 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import * as protos from '../protos/protos'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import {SinonStub} from 'sinon'; +import {describe, it} from 'mocha'; +import * as dlpserviceModule from '../src'; + +import {PassThrough} from 'stream'; + +import {protobuf} from 'google-gax'; + +function generateSampleMessage(instance: T) { + const filledObject = (instance.constructor as typeof protobuf.Message).toObject( + instance as protobuf.Message, + {defaults: true} + ); + return (instance.constructor as typeof protobuf.Message).fromObject( + filledObject + ) as T; +} + +function stubSimpleCall(response?: ResponseType, error?: Error) { + return error + ? sinon.stub().rejects(error) + : sinon.stub().resolves([response]); +} + +function stubSimpleCallWithCallback( + response?: ResponseType, + error?: Error +) { + return error + ? sinon.stub().callsArgWith(2, error) + : sinon.stub().callsArgWith(2, null, response); +} + +function stubPageStreamingCall( + responses?: ResponseType[], + error?: Error +) { + const pagingStub = sinon.stub(); + if (responses) { + for (let i = 0; i < responses.length; ++i) { + pagingStub.onCall(i).callsArgWith(2, null, responses[i]); + } + } + const transformStub = error + ? sinon.stub().callsArgWith(2, error) + : pagingStub; + const mockStream = new PassThrough({ + objectMode: true, + transform: transformStub, + }); + // trigger as many responses as needed + if (responses) { + for (let i = 0; i < responses.length; ++i) { + setImmediate(() => { + mockStream.write({}); + }); + } + setImmediate(() => { + mockStream.end(); + }); + } else { + setImmediate(() => { + mockStream.write({}); + }); + setImmediate(() => { + mockStream.end(); + }); + } + return sinon.stub().returns(mockStream); +} + +function stubAsyncIterationCall( + responses?: ResponseType[], + error?: Error +) { + let counter = 0; + const asyncIterable = { + [Symbol.asyncIterator]() { + return { + async next() { + if (error) { + return Promise.reject(error); + } + if (counter >= responses!.length) { + return Promise.resolve({done: true, value: undefined}); + } + return Promise.resolve({done: false, value: responses![counter++]}); + }, + }; + }, + }; + return sinon.stub().returns(asyncIterable); +} + +describe('v2.DlpServiceClient', () => { + it('has servicePath', () => { + const servicePath = dlpserviceModule.v2.DlpServiceClient.servicePath; + assert(servicePath); + }); + + it('has apiEndpoint', () => { + const apiEndpoint = dlpserviceModule.v2.DlpServiceClient.apiEndpoint; + assert(apiEndpoint); + }); + + it('has port', () => { + const port = dlpserviceModule.v2.DlpServiceClient.port; + assert(port); + assert(typeof port === 'number'); + }); + + it('should create a client with no option', () => { + const client = new dlpserviceModule.v2.DlpServiceClient(); + assert(client); + }); + + it('should create a client with gRPC fallback', () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + fallback: true, + }); + assert(client); + }); + + it('has initialize method and supports deferred initialization', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.dlpServiceStub, undefined); + await client.initialize(); + assert(client.dlpServiceStub); + }); + + it('has close method', () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); + + it('has getProjectId method', async () => { + const fakeProjectId = 'fake-project-id'; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.auth.getProjectId = sinon.stub().resolves(fakeProjectId); + const result = await client.getProjectId(); + assert.strictEqual(result, fakeProjectId); + assert((client.auth.getProjectId as SinonStub).calledWithExactly()); + }); + + it('has getProjectId method with callback', async () => { + const fakeProjectId = 'fake-project-id'; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.auth.getProjectId = sinon + .stub() + .callsArgWith(0, null, fakeProjectId); + const promise = new Promise((resolve, reject) => { + client.getProjectId((err?: Error | null, projectId?: string | null) => { + if (err) { + reject(err); + } else { + resolve(projectId); + } + }); + }); + const result = await promise; + assert.strictEqual(result, fakeProjectId); + }); + + describe('inspectContent', () => { + it('invokes inspectContent without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectContentResponse() + ); + client.innerApiCalls.inspectContent = stubSimpleCall(expectedResponse); + const [response] = await client.inspectContent(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.inspectContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes inspectContent without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectContentResponse() + ); + client.innerApiCalls.inspectContent = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.inspectContent( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IInspectContentResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.inspectContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes inspectContent with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.inspectContent = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.inspectContent(request), expectedError); + assert( + (client.innerApiCalls.inspectContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('redactImage', () => { + it('invokes redactImage without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.RedactImageRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.RedactImageResponse() + ); + client.innerApiCalls.redactImage = stubSimpleCall(expectedResponse); + const [response] = await client.redactImage(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.redactImage as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes redactImage without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.RedactImageRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.RedactImageResponse() + ); + client.innerApiCalls.redactImage = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.redactImage( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IRedactImageResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.redactImage as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes redactImage with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.RedactImageRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.redactImage = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.redactImage(request), expectedError); + assert( + (client.innerApiCalls.redactImage as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deidentifyContent', () => { + it('invokes deidentifyContent without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyContentResponse() + ); + client.innerApiCalls.deidentifyContent = stubSimpleCall(expectedResponse); + const [response] = await client.deidentifyContent(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deidentifyContent without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyContentResponse() + ); + client.innerApiCalls.deidentifyContent = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deidentifyContent( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDeidentifyContentResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deidentifyContent with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deidentifyContent = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.deidentifyContent(request), expectedError); + assert( + (client.innerApiCalls.deidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('reidentifyContent', () => { + it('invokes reidentifyContent without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ReidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.ReidentifyContentResponse() + ); + client.innerApiCalls.reidentifyContent = stubSimpleCall(expectedResponse); + const [response] = await client.reidentifyContent(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.reidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes reidentifyContent without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ReidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.ReidentifyContentResponse() + ); + client.innerApiCalls.reidentifyContent = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.reidentifyContent( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IReidentifyContentResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.reidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes reidentifyContent with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ReidentifyContentRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.reidentifyContent = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.reidentifyContent(request), expectedError); + assert( + (client.innerApiCalls.reidentifyContent as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('listInfoTypes', () => { + it('invokes listInfoTypes without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInfoTypesResponse() + ); + client.innerApiCalls.listInfoTypes = stubSimpleCall(expectedResponse); + const [response] = await client.listInfoTypes(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listInfoTypes without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInfoTypesResponse() + ); + client.innerApiCalls.listInfoTypes = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listInfoTypes( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IListInfoTypesResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listInfoTypes with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listInfoTypes = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.listInfoTypes(request), expectedError); + assert( + (client.innerApiCalls.listInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('createInspectTemplate', () => { + it('invokes createInspectTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateInspectTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.createInspectTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.createInspectTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes createInspectTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateInspectTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.createInspectTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.createInspectTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IInspectTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes createInspectTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateInspectTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createInspectTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.createInspectTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.createInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('updateInspectTemplate', () => { + it('invokes updateInspectTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.updateInspectTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.updateInspectTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes updateInspectTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.updateInspectTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.updateInspectTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IInspectTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes updateInspectTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.updateInspectTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.updateInspectTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.updateInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('getInspectTemplate', () => { + it('invokes getInspectTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.getInspectTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.getInspectTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes getInspectTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ); + client.innerApiCalls.getInspectTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.getInspectTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IInspectTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes getInspectTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getInspectTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.getInspectTemplate(request), expectedError); + assert( + (client.innerApiCalls.getInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deleteInspectTemplate', () => { + it('invokes deleteInspectTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteInspectTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.deleteInspectTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deleteInspectTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteInspectTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deleteInspectTemplate( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deleteInspectTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteInspectTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteInspectTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.deleteInspectTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.deleteInspectTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('createDeidentifyTemplate', () => { + it('invokes createDeidentifyTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDeidentifyTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.createDeidentifyTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.createDeidentifyTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes createDeidentifyTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDeidentifyTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.createDeidentifyTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.createDeidentifyTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDeidentifyTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes createDeidentifyTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDeidentifyTemplateRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createDeidentifyTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.createDeidentifyTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.createDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('updateDeidentifyTemplate', () => { + it('invokes updateDeidentifyTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.updateDeidentifyTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.updateDeidentifyTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes updateDeidentifyTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.updateDeidentifyTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.updateDeidentifyTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDeidentifyTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes updateDeidentifyTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.updateDeidentifyTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.updateDeidentifyTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.updateDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('getDeidentifyTemplate', () => { + it('invokes getDeidentifyTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.getDeidentifyTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.getDeidentifyTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes getDeidentifyTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ); + client.innerApiCalls.getDeidentifyTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.getDeidentifyTemplate( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDeidentifyTemplate | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes getDeidentifyTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getDeidentifyTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.getDeidentifyTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.getDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deleteDeidentifyTemplate', () => { + it('invokes deleteDeidentifyTemplate without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteDeidentifyTemplate = stubSimpleCall( + expectedResponse + ); + const [response] = await client.deleteDeidentifyTemplate(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deleteDeidentifyTemplate without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteDeidentifyTemplate = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deleteDeidentifyTemplate( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deleteDeidentifyTemplate with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDeidentifyTemplateRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteDeidentifyTemplate = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.deleteDeidentifyTemplate(request), + expectedError + ); + assert( + (client.innerApiCalls.deleteDeidentifyTemplate as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('createJobTrigger', () => { + it('invokes createJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateJobTriggerRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.createJobTrigger = stubSimpleCall(expectedResponse); + const [response] = await client.createJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes createJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateJobTriggerRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.createJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.createJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IJobTrigger | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes createJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateJobTriggerRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.createJobTrigger(request), expectedError); + assert( + (client.innerApiCalls.createJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('updateJobTrigger', () => { + it('invokes updateJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.updateJobTrigger = stubSimpleCall(expectedResponse); + const [response] = await client.updateJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes updateJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.updateJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.updateJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IJobTrigger | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes updateJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.updateJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.updateJobTrigger(request), expectedError); + assert( + (client.innerApiCalls.updateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('hybridInspectJobTrigger', () => { + it('invokes hybridInspectJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectResponse() + ); + client.innerApiCalls.hybridInspectJobTrigger = stubSimpleCall( + expectedResponse + ); + const [response] = await client.hybridInspectJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.hybridInspectJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes hybridInspectJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectResponse() + ); + client.innerApiCalls.hybridInspectJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.hybridInspectJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IHybridInspectResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.hybridInspectJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes hybridInspectJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.hybridInspectJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.hybridInspectJobTrigger(request), + expectedError + ); + assert( + (client.innerApiCalls.hybridInspectJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('getJobTrigger', () => { + it('invokes getJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.getJobTrigger = stubSimpleCall(expectedResponse); + const [response] = await client.getJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes getJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.JobTrigger() + ); + client.innerApiCalls.getJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.getJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IJobTrigger | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes getJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.getJobTrigger(request), expectedError); + assert( + (client.innerApiCalls.getJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deleteJobTrigger', () => { + it('invokes deleteJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteJobTrigger = stubSimpleCall(expectedResponse); + const [response] = await client.deleteJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deleteJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deleteJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deleteJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.deleteJobTrigger(request), expectedError); + assert( + (client.innerApiCalls.deleteJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('activateJobTrigger', () => { + it('invokes activateJobTrigger without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ActivateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.activateJobTrigger = stubSimpleCall( + expectedResponse + ); + const [response] = await client.activateJobTrigger(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.activateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes activateJobTrigger without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ActivateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.activateJobTrigger = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.activateJobTrigger( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDlpJob | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.activateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes activateJobTrigger with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ActivateJobTriggerRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.activateJobTrigger = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.activateJobTrigger(request), expectedError); + assert( + (client.innerApiCalls.activateJobTrigger as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('createDlpJob', () => { + it('invokes createDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDlpJobRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.createDlpJob = stubSimpleCall(expectedResponse); + const [response] = await client.createDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes createDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDlpJobRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.createDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.createDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDlpJob | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes createDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateDlpJobRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createDlpJob = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.createDlpJob(request), expectedError); + assert( + (client.innerApiCalls.createDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('getDlpJob', () => { + it('invokes getDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.getDlpJob = stubSimpleCall(expectedResponse); + const [response] = await client.getDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes getDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.DlpJob() + ); + client.innerApiCalls.getDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.getDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDlpJob | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes getDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getDlpJob = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.getDlpJob(request), expectedError); + assert( + (client.innerApiCalls.getDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deleteDlpJob', () => { + it('invokes deleteDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteDlpJob = stubSimpleCall(expectedResponse); + const [response] = await client.deleteDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deleteDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deleteDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deleteDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteDlpJob = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.deleteDlpJob(request), expectedError); + assert( + (client.innerApiCalls.deleteDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('cancelDlpJob', () => { + it('invokes cancelDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CancelDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.cancelDlpJob = stubSimpleCall(expectedResponse); + const [response] = await client.cancelDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.cancelDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes cancelDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CancelDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.cancelDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.cancelDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.cancelDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes cancelDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CancelDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.cancelDlpJob = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.cancelDlpJob(request), expectedError); + assert( + (client.innerApiCalls.cancelDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('createStoredInfoType', () => { + it('invokes createStoredInfoType without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateStoredInfoTypeRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.createStoredInfoType = stubSimpleCall( + expectedResponse + ); + const [response] = await client.createStoredInfoType(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes createStoredInfoType without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateStoredInfoTypeRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.createStoredInfoType = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.createStoredInfoType( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IStoredInfoType | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.createStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes createStoredInfoType with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.CreateStoredInfoTypeRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createStoredInfoType = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.createStoredInfoType(request), expectedError); + assert( + (client.innerApiCalls.createStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('updateStoredInfoType', () => { + it('invokes updateStoredInfoType without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.updateStoredInfoType = stubSimpleCall( + expectedResponse + ); + const [response] = await client.updateStoredInfoType(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes updateStoredInfoType without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.updateStoredInfoType = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.updateStoredInfoType( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IStoredInfoType | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.updateStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes updateStoredInfoType with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.UpdateStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.updateStoredInfoType = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.updateStoredInfoType(request), expectedError); + assert( + (client.innerApiCalls.updateStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('getStoredInfoType', () => { + it('invokes getStoredInfoType without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.getStoredInfoType = stubSimpleCall(expectedResponse); + const [response] = await client.getStoredInfoType(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes getStoredInfoType without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ); + client.innerApiCalls.getStoredInfoType = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.getStoredInfoType( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IStoredInfoType | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.getStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes getStoredInfoType with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.GetStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getStoredInfoType = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.getStoredInfoType(request), expectedError); + assert( + (client.innerApiCalls.getStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('deleteStoredInfoType', () => { + it('invokes deleteStoredInfoType without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteStoredInfoType = stubSimpleCall( + expectedResponse + ); + const [response] = await client.deleteStoredInfoType(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes deleteStoredInfoType without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.deleteStoredInfoType = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.deleteStoredInfoType( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.deleteStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes deleteStoredInfoType with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.DeleteStoredInfoTypeRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteStoredInfoType = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.deleteStoredInfoType(request), expectedError); + assert( + (client.innerApiCalls.deleteStoredInfoType as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('hybridInspectDlpJob', () => { + it('invokes hybridInspectDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectResponse() + ); + client.innerApiCalls.hybridInspectDlpJob = stubSimpleCall( + expectedResponse + ); + const [response] = await client.hybridInspectDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.hybridInspectDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes hybridInspectDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectResponse() + ); + client.innerApiCalls.hybridInspectDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.hybridInspectDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IHybridInspectResponse | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.hybridInspectDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes hybridInspectDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.HybridInspectDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.hybridInspectDlpJob = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.hybridInspectDlpJob(request), expectedError); + assert( + (client.innerApiCalls.hybridInspectDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('finishDlpJob', () => { + it('invokes finishDlpJob without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.FinishDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.finishDlpJob = stubSimpleCall(expectedResponse); + const [response] = await client.finishDlpJob(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.finishDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes finishDlpJob without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.FinishDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.innerApiCalls.finishDlpJob = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.finishDlpJob( + request, + ( + err?: Error | null, + result?: protos.google.protobuf.IEmpty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.finishDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes finishDlpJob with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.FinishDlpJobRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.finishDlpJob = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.finishDlpJob(request), expectedError); + assert( + (client.innerApiCalls.finishDlpJob as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + + describe('listInspectTemplates', () => { + it('invokes listInspectTemplates without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + ]; + client.innerApiCalls.listInspectTemplates = stubSimpleCall( + expectedResponse + ); + const [response] = await client.listInspectTemplates(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listInspectTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listInspectTemplates without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + ]; + client.innerApiCalls.listInspectTemplates = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listInspectTemplates( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IInspectTemplate[] | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listInspectTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listInspectTemplates with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listInspectTemplates = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.listInspectTemplates(request), expectedError); + assert( + (client.innerApiCalls.listInspectTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listInspectTemplatesStream without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + ]; + client.descriptors.page.listInspectTemplates.createStream = stubPageStreamingCall( + expectedResponse + ); + const stream = client.listInspectTemplatesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.InspectTemplate[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.InspectTemplate) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + const responses = await promise; + assert.deepStrictEqual(responses, expectedResponse); + assert( + (client.descriptors.page.listInspectTemplates.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listInspectTemplates, request) + ); + assert.strictEqual( + (client.descriptors.page.listInspectTemplates + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('invokes listInspectTemplatesStream with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listInspectTemplates.createStream = stubPageStreamingCall( + undefined, + expectedError + ); + const stream = client.listInspectTemplatesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.InspectTemplate[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.InspectTemplate) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + await assert.rejects(promise, expectedError); + assert( + (client.descriptors.page.listInspectTemplates.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listInspectTemplates, request) + ); + assert.strictEqual( + (client.descriptors.page.listInspectTemplates + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listInspectTemplates without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.InspectTemplate() + ), + ]; + client.descriptors.page.listInspectTemplates.asyncIterate = stubAsyncIterationCall( + expectedResponse + ); + const responses: protos.google.privacy.dlp.v2.IInspectTemplate[] = []; + const iterable = client.listInspectTemplatesAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + (client.descriptors.page.listInspectTemplates + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listInspectTemplates + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listInspectTemplates with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListInspectTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listInspectTemplates.asyncIterate = stubAsyncIterationCall( + undefined, + expectedError + ); + const iterable = client.listInspectTemplatesAsync(request); + await assert.rejects(async () => { + const responses: protos.google.privacy.dlp.v2.IInspectTemplate[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + (client.descriptors.page.listInspectTemplates + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listInspectTemplates + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + }); + + describe('listDeidentifyTemplates', () => { + it('invokes listDeidentifyTemplates without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + ]; + client.innerApiCalls.listDeidentifyTemplates = stubSimpleCall( + expectedResponse + ); + const [response] = await client.listDeidentifyTemplates(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listDeidentifyTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listDeidentifyTemplates without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + ]; + client.innerApiCalls.listDeidentifyTemplates = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listDeidentifyTemplates( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDeidentifyTemplate[] | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listDeidentifyTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listDeidentifyTemplates with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listDeidentifyTemplates = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.listDeidentifyTemplates(request), + expectedError + ); + assert( + (client.innerApiCalls.listDeidentifyTemplates as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listDeidentifyTemplatesStream without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + ]; + client.descriptors.page.listDeidentifyTemplates.createStream = stubPageStreamingCall( + expectedResponse + ); + const stream = client.listDeidentifyTemplatesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.DeidentifyTemplate[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.DeidentifyTemplate) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + const responses = await promise; + assert.deepStrictEqual(responses, expectedResponse); + assert( + (client.descriptors.page.listDeidentifyTemplates + .createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listDeidentifyTemplates, request) + ); + assert.strictEqual( + (client.descriptors.page.listDeidentifyTemplates + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('invokes listDeidentifyTemplatesStream with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listDeidentifyTemplates.createStream = stubPageStreamingCall( + undefined, + expectedError + ); + const stream = client.listDeidentifyTemplatesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.DeidentifyTemplate[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.DeidentifyTemplate) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + await assert.rejects(promise, expectedError); + assert( + (client.descriptors.page.listDeidentifyTemplates + .createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listDeidentifyTemplates, request) + ); + assert.strictEqual( + (client.descriptors.page.listDeidentifyTemplates + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listDeidentifyTemplates without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.DeidentifyTemplate() + ), + ]; + client.descriptors.page.listDeidentifyTemplates.asyncIterate = stubAsyncIterationCall( + expectedResponse + ); + const responses: protos.google.privacy.dlp.v2.IDeidentifyTemplate[] = []; + const iterable = client.listDeidentifyTemplatesAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + (client.descriptors.page.listDeidentifyTemplates + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listDeidentifyTemplates + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listDeidentifyTemplates with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDeidentifyTemplatesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listDeidentifyTemplates.asyncIterate = stubAsyncIterationCall( + undefined, + expectedError + ); + const iterable = client.listDeidentifyTemplatesAsync(request); + await assert.rejects(async () => { + const responses: protos.google.privacy.dlp.v2.IDeidentifyTemplate[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + (client.descriptors.page.listDeidentifyTemplates + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listDeidentifyTemplates + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + }); + + describe('listJobTriggers', () => { + it('invokes listJobTriggers without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + ]; + client.innerApiCalls.listJobTriggers = stubSimpleCall(expectedResponse); + const [response] = await client.listJobTriggers(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listJobTriggers as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listJobTriggers without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + ]; + client.innerApiCalls.listJobTriggers = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listJobTriggers( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IJobTrigger[] | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listJobTriggers as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listJobTriggers with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listJobTriggers = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.listJobTriggers(request), expectedError); + assert( + (client.innerApiCalls.listJobTriggers as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listJobTriggersStream without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + ]; + client.descriptors.page.listJobTriggers.createStream = stubPageStreamingCall( + expectedResponse + ); + const stream = client.listJobTriggersStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.JobTrigger[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.JobTrigger) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + const responses = await promise; + assert.deepStrictEqual(responses, expectedResponse); + assert( + (client.descriptors.page.listJobTriggers.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listJobTriggers, request) + ); + assert.strictEqual( + (client.descriptors.page.listJobTriggers + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('invokes listJobTriggersStream with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listJobTriggers.createStream = stubPageStreamingCall( + undefined, + expectedError + ); + const stream = client.listJobTriggersStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.JobTrigger[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.JobTrigger) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + await assert.rejects(promise, expectedError); + assert( + (client.descriptors.page.listJobTriggers.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listJobTriggers, request) + ); + assert.strictEqual( + (client.descriptors.page.listJobTriggers + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listJobTriggers without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + generateSampleMessage(new protos.google.privacy.dlp.v2.JobTrigger()), + ]; + client.descriptors.page.listJobTriggers.asyncIterate = stubAsyncIterationCall( + expectedResponse + ); + const responses: protos.google.privacy.dlp.v2.IJobTrigger[] = []; + const iterable = client.listJobTriggersAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + (client.descriptors.page.listJobTriggers + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listJobTriggers + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listJobTriggers with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListJobTriggersRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listJobTriggers.asyncIterate = stubAsyncIterationCall( + undefined, + expectedError + ); + const iterable = client.listJobTriggersAsync(request); + await assert.rejects(async () => { + const responses: protos.google.privacy.dlp.v2.IJobTrigger[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + (client.descriptors.page.listJobTriggers + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listJobTriggers + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + }); + + describe('listDlpJobs', () => { + it('invokes listDlpJobs without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + ]; + client.innerApiCalls.listDlpJobs = stubSimpleCall(expectedResponse); + const [response] = await client.listDlpJobs(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listDlpJobs as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listDlpJobs without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + ]; + client.innerApiCalls.listDlpJobs = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listDlpJobs( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IDlpJob[] | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listDlpJobs as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listDlpJobs with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listDlpJobs = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.listDlpJobs(request), expectedError); + assert( + (client.innerApiCalls.listDlpJobs as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listDlpJobsStream without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + ]; + client.descriptors.page.listDlpJobs.createStream = stubPageStreamingCall( + expectedResponse + ); + const stream = client.listDlpJobsStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.DlpJob[] = []; + stream.on('data', (response: protos.google.privacy.dlp.v2.DlpJob) => { + responses.push(response); + }); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + const responses = await promise; + assert.deepStrictEqual(responses, expectedResponse); + assert( + (client.descriptors.page.listDlpJobs.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listDlpJobs, request) + ); + assert.strictEqual( + (client.descriptors.page.listDlpJobs.createStream as SinonStub).getCall( + 0 + ).args[2].otherArgs.headers['x-goog-request-params'], + expectedHeaderRequestParams + ); + }); + + it('invokes listDlpJobsStream with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listDlpJobs.createStream = stubPageStreamingCall( + undefined, + expectedError + ); + const stream = client.listDlpJobsStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.DlpJob[] = []; + stream.on('data', (response: protos.google.privacy.dlp.v2.DlpJob) => { + responses.push(response); + }); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + await assert.rejects(promise, expectedError); + assert( + (client.descriptors.page.listDlpJobs.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listDlpJobs, request) + ); + assert.strictEqual( + (client.descriptors.page.listDlpJobs.createStream as SinonStub).getCall( + 0 + ).args[2].otherArgs.headers['x-goog-request-params'], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listDlpJobs without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + generateSampleMessage(new protos.google.privacy.dlp.v2.DlpJob()), + ]; + client.descriptors.page.listDlpJobs.asyncIterate = stubAsyncIterationCall( + expectedResponse + ); + const responses: protos.google.privacy.dlp.v2.IDlpJob[] = []; + const iterable = client.listDlpJobsAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + (client.descriptors.page.listDlpJobs.asyncIterate as SinonStub).getCall( + 0 + ).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listDlpJobs.asyncIterate as SinonStub).getCall( + 0 + ).args[2].otherArgs.headers['x-goog-request-params'], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listDlpJobs with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListDlpJobsRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listDlpJobs.asyncIterate = stubAsyncIterationCall( + undefined, + expectedError + ); + const iterable = client.listDlpJobsAsync(request); + await assert.rejects(async () => { + const responses: protos.google.privacy.dlp.v2.IDlpJob[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + (client.descriptors.page.listDlpJobs.asyncIterate as SinonStub).getCall( + 0 + ).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listDlpJobs.asyncIterate as SinonStub).getCall( + 0 + ).args[2].otherArgs.headers['x-goog-request-params'], + expectedHeaderRequestParams + ); + }); + }); + + describe('listStoredInfoTypes', () => { + it('invokes listStoredInfoTypes without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + ]; + client.innerApiCalls.listStoredInfoTypes = stubSimpleCall( + expectedResponse + ); + const [response] = await client.listStoredInfoTypes(request); + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listStoredInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listStoredInfoTypes without error using callback', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + ]; + client.innerApiCalls.listStoredInfoTypes = stubSimpleCallWithCallback( + expectedResponse + ); + const promise = new Promise((resolve, reject) => { + client.listStoredInfoTypes( + request, + ( + err?: Error | null, + result?: protos.google.privacy.dlp.v2.IStoredInfoType[] | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert( + (client.innerApiCalls.listStoredInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions /*, callback defined above */) + ); + }); + + it('invokes listStoredInfoTypes with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listStoredInfoTypes = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(client.listStoredInfoTypes(request), expectedError); + assert( + (client.innerApiCalls.listStoredInfoTypes as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + + it('invokes listStoredInfoTypesStream without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + ]; + client.descriptors.page.listStoredInfoTypes.createStream = stubPageStreamingCall( + expectedResponse + ); + const stream = client.listStoredInfoTypesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.StoredInfoType[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.StoredInfoType) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + const responses = await promise; + assert.deepStrictEqual(responses, expectedResponse); + assert( + (client.descriptors.page.listStoredInfoTypes.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listStoredInfoTypes, request) + ); + assert.strictEqual( + (client.descriptors.page.listStoredInfoTypes + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('invokes listStoredInfoTypesStream with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listStoredInfoTypes.createStream = stubPageStreamingCall( + undefined, + expectedError + ); + const stream = client.listStoredInfoTypesStream(request); + const promise = new Promise((resolve, reject) => { + const responses: protos.google.privacy.dlp.v2.StoredInfoType[] = []; + stream.on( + 'data', + (response: protos.google.privacy.dlp.v2.StoredInfoType) => { + responses.push(response); + } + ); + stream.on('end', () => { + resolve(responses); + }); + stream.on('error', (err: Error) => { + reject(err); + }); + }); + await assert.rejects(promise, expectedError); + assert( + (client.descriptors.page.listStoredInfoTypes.createStream as SinonStub) + .getCall(0) + .calledWith(client.innerApiCalls.listStoredInfoTypes, request) + ); + assert.strictEqual( + (client.descriptors.page.listStoredInfoTypes + .createStream as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listStoredInfoTypes without error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedResponse = [ + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + generateSampleMessage( + new protos.google.privacy.dlp.v2.StoredInfoType() + ), + ]; + client.descriptors.page.listStoredInfoTypes.asyncIterate = stubAsyncIterationCall( + expectedResponse + ); + const responses: protos.google.privacy.dlp.v2.IStoredInfoType[] = []; + const iterable = client.listStoredInfoTypesAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + (client.descriptors.page.listStoredInfoTypes + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listStoredInfoTypes + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + + it('uses async iteration with listStoredInfoTypes with error', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new protos.google.privacy.dlp.v2.ListStoredInfoTypesRequest() + ); + request.parent = ''; + const expectedHeaderRequestParams = 'parent='; + const expectedError = new Error('expected'); + client.descriptors.page.listStoredInfoTypes.asyncIterate = stubAsyncIterationCall( + undefined, + expectedError + ); + const iterable = client.listStoredInfoTypesAsync(request); + await assert.rejects(async () => { + const responses: protos.google.privacy.dlp.v2.IStoredInfoType[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + (client.descriptors.page.listStoredInfoTypes + .asyncIterate as SinonStub).getCall(0).args[1], + request + ); + assert.strictEqual( + (client.descriptors.page.listStoredInfoTypes + .asyncIterate as SinonStub).getCall(0).args[2].otherArgs.headers[ + 'x-goog-request-params' + ], + expectedHeaderRequestParams + ); + }); + }); + + describe('Path templates', () => { + describe('finding', () => { + const fakePath = '/rendered/path/finding'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + finding: 'findingValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.findingPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.findingPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('findingPath', () => { + const result = client.findingPath( + 'projectValue', + 'locationValue', + 'findingValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.findingPathTemplate.render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromFindingName', () => { + const result = client.matchProjectFromFindingName(fakePath); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.findingPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromFindingName', () => { + const result = client.matchLocationFromFindingName(fakePath); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.findingPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchFindingFromFindingName', () => { + const result = client.matchFindingFromFindingName(fakePath); + assert.strictEqual(result, 'findingValue'); + assert( + (client.pathTemplates.findingPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organization', () => { + const fakePath = '/rendered/path/organization'; + const expectedParameters = { + organization: 'organizationValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationPath', () => { + const result = client.organizationPath('organizationValue'); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationPathTemplate.render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationName', () => { + const result = client.matchOrganizationFromOrganizationName(fakePath); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationDeidentifyTemplate', () => { + const fakePath = '/rendered/path/organizationDeidentifyTemplate'; + const expectedParameters = { + organization: 'organizationValue', + deidentify_template: 'deidentifyTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationDeidentifyTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationDeidentifyTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationDeidentifyTemplatePath', () => { + const result = client.organizationDeidentifyTemplatePath( + 'organizationValue', + 'deidentifyTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationDeidentifyTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationDeidentifyTemplateName', () => { + const result = client.matchOrganizationFromOrganizationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDeidentifyTemplateFromOrganizationDeidentifyTemplateName', () => { + const result = client.matchDeidentifyTemplateFromOrganizationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'deidentifyTemplateValue'); + assert( + (client.pathTemplates.organizationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationInspectTemplate', () => { + const fakePath = '/rendered/path/organizationInspectTemplate'; + const expectedParameters = { + organization: 'organizationValue', + inspect_template: 'inspectTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationInspectTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationInspectTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationInspectTemplatePath', () => { + const result = client.organizationInspectTemplatePath( + 'organizationValue', + 'inspectTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationInspectTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationInspectTemplateName', () => { + const result = client.matchOrganizationFromOrganizationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchInspectTemplateFromOrganizationInspectTemplateName', () => { + const result = client.matchInspectTemplateFromOrganizationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'inspectTemplateValue'); + assert( + (client.pathTemplates.organizationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationLocationDeidentifyTemplate', () => { + const fakePath = '/rendered/path/organizationLocationDeidentifyTemplate'; + const expectedParameters = { + organization: 'organizationValue', + location: 'locationValue', + deidentify_template: 'deidentifyTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationLocationDeidentifyTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationLocationDeidentifyTemplatePath', () => { + const result = client.organizationLocationDeidentifyTemplatePath( + 'organizationValue', + 'locationValue', + 'deidentifyTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates + .organizationLocationDeidentifyTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationLocationDeidentifyTemplateName', () => { + const result = client.matchOrganizationFromOrganizationLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates + .organizationLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromOrganizationLocationDeidentifyTemplateName', () => { + const result = client.matchLocationFromOrganizationLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates + .organizationLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDeidentifyTemplateFromOrganizationLocationDeidentifyTemplateName', () => { + const result = client.matchDeidentifyTemplateFromOrganizationLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'deidentifyTemplateValue'); + assert( + (client.pathTemplates + .organizationLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationLocationInspectTemplate', () => { + const fakePath = '/rendered/path/organizationLocationInspectTemplate'; + const expectedParameters = { + organization: 'organizationValue', + location: 'locationValue', + inspect_template: 'inspectTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationLocationInspectTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationLocationInspectTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationLocationInspectTemplatePath', () => { + const result = client.organizationLocationInspectTemplatePath( + 'organizationValue', + 'locationValue', + 'inspectTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationLocationInspectTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationLocationInspectTemplateName', () => { + const result = client.matchOrganizationFromOrganizationLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromOrganizationLocationInspectTemplateName', () => { + const result = client.matchLocationFromOrganizationLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.organizationLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchInspectTemplateFromOrganizationLocationInspectTemplateName', () => { + const result = client.matchInspectTemplateFromOrganizationLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'inspectTemplateValue'); + assert( + (client.pathTemplates.organizationLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationLocationStoredInfoType', () => { + const fakePath = '/rendered/path/organizationLocationStoredInfoType'; + const expectedParameters = { + organization: 'organizationValue', + location: 'locationValue', + stored_info_type: 'storedInfoTypeValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationLocationStoredInfoTypePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationLocationStoredInfoTypePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationLocationStoredInfoTypePath', () => { + const result = client.organizationLocationStoredInfoTypePath( + 'organizationValue', + 'locationValue', + 'storedInfoTypeValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationLocationStoredInfoTypePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationLocationStoredInfoTypeName', () => { + const result = client.matchOrganizationFromOrganizationLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromOrganizationLocationStoredInfoTypeName', () => { + const result = client.matchLocationFromOrganizationLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.organizationLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchStoredInfoTypeFromOrganizationLocationStoredInfoTypeName', () => { + const result = client.matchStoredInfoTypeFromOrganizationLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'storedInfoTypeValue'); + assert( + (client.pathTemplates.organizationLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('organizationStoredInfoType', () => { + const fakePath = '/rendered/path/organizationStoredInfoType'; + const expectedParameters = { + organization: 'organizationValue', + stored_info_type: 'storedInfoTypeValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationStoredInfoTypePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.organizationStoredInfoTypePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('organizationStoredInfoTypePath', () => { + const result = client.organizationStoredInfoTypePath( + 'organizationValue', + 'storedInfoTypeValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.organizationStoredInfoTypePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchOrganizationFromOrganizationStoredInfoTypeName', () => { + const result = client.matchOrganizationFromOrganizationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'organizationValue'); + assert( + (client.pathTemplates.organizationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchStoredInfoTypeFromOrganizationStoredInfoTypeName', () => { + const result = client.matchStoredInfoTypeFromOrganizationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'storedInfoTypeValue'); + assert( + (client.pathTemplates.organizationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('project', () => { + const fakePath = '/rendered/path/project'; + const expectedParameters = { + project: 'projectValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectPath', () => { + const result = client.projectPath('projectValue'); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectPathTemplate.render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectName', () => { + const result = client.matchProjectFromProjectName(fakePath); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectDeidentifyTemplate', () => { + const fakePath = '/rendered/path/projectDeidentifyTemplate'; + const expectedParameters = { + project: 'projectValue', + deidentify_template: 'deidentifyTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectDeidentifyTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectDeidentifyTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectDeidentifyTemplatePath', () => { + const result = client.projectDeidentifyTemplatePath( + 'projectValue', + 'deidentifyTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectDeidentifyTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectDeidentifyTemplateName', () => { + const result = client.matchProjectFromProjectDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDeidentifyTemplateFromProjectDeidentifyTemplateName', () => { + const result = client.matchDeidentifyTemplateFromProjectDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'deidentifyTemplateValue'); + assert( + (client.pathTemplates.projectDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectDlpContent', () => { + const fakePath = '/rendered/path/projectDlpContent'; + const expectedParameters = { + project: 'projectValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectDlpContentPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectDlpContentPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectDlpContentPath', () => { + const result = client.projectDlpContentPath('projectValue'); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectDlpContentPathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectDlpContentName', () => { + const result = client.matchProjectFromProjectDlpContentName(fakePath); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectDlpContentPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectDlpJob', () => { + const fakePath = '/rendered/path/projectDlpJob'; + const expectedParameters = { + project: 'projectValue', + dlp_job: 'dlpJobValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectDlpJobPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectDlpJobPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectDlpJobPath', () => { + const result = client.projectDlpJobPath('projectValue', 'dlpJobValue'); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectDlpJobPathTemplate.render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectDlpJobName', () => { + const result = client.matchProjectFromProjectDlpJobName(fakePath); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectDlpJobPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDlpJobFromProjectDlpJobName', () => { + const result = client.matchDlpJobFromProjectDlpJobName(fakePath); + assert.strictEqual(result, 'dlpJobValue'); + assert( + (client.pathTemplates.projectDlpJobPathTemplate.match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectInspectTemplate', () => { + const fakePath = '/rendered/path/projectInspectTemplate'; + const expectedParameters = { + project: 'projectValue', + inspect_template: 'inspectTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectInspectTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectInspectTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectInspectTemplatePath', () => { + const result = client.projectInspectTemplatePath( + 'projectValue', + 'inspectTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectInspectTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectInspectTemplateName', () => { + const result = client.matchProjectFromProjectInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchInspectTemplateFromProjectInspectTemplateName', () => { + const result = client.matchInspectTemplateFromProjectInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'inspectTemplateValue'); + assert( + (client.pathTemplates.projectInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectJobTrigger', () => { + const fakePath = '/rendered/path/projectJobTrigger'; + const expectedParameters = { + project: 'projectValue', + job_trigger: 'jobTriggerValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectJobTriggerPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectJobTriggerPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectJobTriggerPath', () => { + const result = client.projectJobTriggerPath( + 'projectValue', + 'jobTriggerValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectJobTriggerPathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectJobTriggerName', () => { + const result = client.matchProjectFromProjectJobTriggerName(fakePath); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectJobTriggerPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchJobTriggerFromProjectJobTriggerName', () => { + const result = client.matchJobTriggerFromProjectJobTriggerName( + fakePath + ); + assert.strictEqual(result, 'jobTriggerValue'); + assert( + (client.pathTemplates.projectJobTriggerPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectLocationDeidentifyTemplate', () => { + const fakePath = '/rendered/path/projectLocationDeidentifyTemplate'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + deidentify_template: 'deidentifyTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectLocationDeidentifyTemplatePath', () => { + const result = client.projectLocationDeidentifyTemplatePath( + 'projectValue', + 'locationValue', + 'deidentifyTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectLocationDeidentifyTemplateName', () => { + const result = client.matchProjectFromProjectLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromProjectLocationDeidentifyTemplateName', () => { + const result = client.matchLocationFromProjectLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDeidentifyTemplateFromProjectLocationDeidentifyTemplateName', () => { + const result = client.matchDeidentifyTemplateFromProjectLocationDeidentifyTemplateName( + fakePath + ); + assert.strictEqual(result, 'deidentifyTemplateValue'); + assert( + (client.pathTemplates.projectLocationDeidentifyTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectLocationDlpJob', () => { + const fakePath = '/rendered/path/projectLocationDlpJob'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + dlp_job: 'dlpJobValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectLocationDlpJobPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectLocationDlpJobPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectLocationDlpJobPath', () => { + const result = client.projectLocationDlpJobPath( + 'projectValue', + 'locationValue', + 'dlpJobValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectLocationDlpJobPathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectLocationDlpJobName', () => { + const result = client.matchProjectFromProjectLocationDlpJobName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectLocationDlpJobPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromProjectLocationDlpJobName', () => { + const result = client.matchLocationFromProjectLocationDlpJobName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.projectLocationDlpJobPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchDlpJobFromProjectLocationDlpJobName', () => { + const result = client.matchDlpJobFromProjectLocationDlpJobName( + fakePath + ); + assert.strictEqual(result, 'dlpJobValue'); + assert( + (client.pathTemplates.projectLocationDlpJobPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectLocationInspectTemplate', () => { + const fakePath = '/rendered/path/projectLocationInspectTemplate'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + inspect_template: 'inspectTemplateValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectLocationInspectTemplatePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectLocationInspectTemplatePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectLocationInspectTemplatePath', () => { + const result = client.projectLocationInspectTemplatePath( + 'projectValue', + 'locationValue', + 'inspectTemplateValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectLocationInspectTemplatePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectLocationInspectTemplateName', () => { + const result = client.matchProjectFromProjectLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromProjectLocationInspectTemplateName', () => { + const result = client.matchLocationFromProjectLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.projectLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchInspectTemplateFromProjectLocationInspectTemplateName', () => { + const result = client.matchInspectTemplateFromProjectLocationInspectTemplateName( + fakePath + ); + assert.strictEqual(result, 'inspectTemplateValue'); + assert( + (client.pathTemplates.projectLocationInspectTemplatePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectLocationJobTrigger', () => { + const fakePath = '/rendered/path/projectLocationJobTrigger'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + job_trigger: 'jobTriggerValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectLocationJobTriggerPathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectLocationJobTriggerPathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectLocationJobTriggerPath', () => { + const result = client.projectLocationJobTriggerPath( + 'projectValue', + 'locationValue', + 'jobTriggerValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectLocationJobTriggerPathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectLocationJobTriggerName', () => { + const result = client.matchProjectFromProjectLocationJobTriggerName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectLocationJobTriggerPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromProjectLocationJobTriggerName', () => { + const result = client.matchLocationFromProjectLocationJobTriggerName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.projectLocationJobTriggerPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchJobTriggerFromProjectLocationJobTriggerName', () => { + const result = client.matchJobTriggerFromProjectLocationJobTriggerName( + fakePath + ); + assert.strictEqual(result, 'jobTriggerValue'); + assert( + (client.pathTemplates.projectLocationJobTriggerPathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectLocationStoredInfoType', () => { + const fakePath = '/rendered/path/projectLocationStoredInfoType'; + const expectedParameters = { + project: 'projectValue', + location: 'locationValue', + stored_info_type: 'storedInfoTypeValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectLocationStoredInfoTypePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectLocationStoredInfoTypePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectLocationStoredInfoTypePath', () => { + const result = client.projectLocationStoredInfoTypePath( + 'projectValue', + 'locationValue', + 'storedInfoTypeValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectLocationStoredInfoTypePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectLocationStoredInfoTypeName', () => { + const result = client.matchProjectFromProjectLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchLocationFromProjectLocationStoredInfoTypeName', () => { + const result = client.matchLocationFromProjectLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'locationValue'); + assert( + (client.pathTemplates.projectLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchStoredInfoTypeFromProjectLocationStoredInfoTypeName', () => { + const result = client.matchStoredInfoTypeFromProjectLocationStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'storedInfoTypeValue'); + assert( + (client.pathTemplates.projectLocationStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + + describe('projectStoredInfoType', () => { + const fakePath = '/rendered/path/projectStoredInfoType'; + const expectedParameters = { + project: 'projectValue', + stored_info_type: 'storedInfoTypeValue', + }; + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectStoredInfoTypePathTemplate.render = sinon + .stub() + .returns(fakePath); + client.pathTemplates.projectStoredInfoTypePathTemplate.match = sinon + .stub() + .returns(expectedParameters); + + it('projectStoredInfoTypePath', () => { + const result = client.projectStoredInfoTypePath( + 'projectValue', + 'storedInfoTypeValue' + ); + assert.strictEqual(result, fakePath); + assert( + (client.pathTemplates.projectStoredInfoTypePathTemplate + .render as SinonStub) + .getCall(-1) + .calledWith(expectedParameters) + ); + }); + + it('matchProjectFromProjectStoredInfoTypeName', () => { + const result = client.matchProjectFromProjectStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'projectValue'); + assert( + (client.pathTemplates.projectStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + + it('matchStoredInfoTypeFromProjectStoredInfoTypeName', () => { + const result = client.matchStoredInfoTypeFromProjectStoredInfoTypeName( + fakePath + ); + assert.strictEqual(result, 'storedInfoTypeValue'); + assert( + (client.pathTemplates.projectStoredInfoTypePathTemplate + .match as SinonStub) + .getCall(-1) + .calledWith(fakePath) + ); + }); + }); + }); +}); diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/tsconfig.json b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/tsconfig.json new file mode 100644 index 000000000..c78f1c884 --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./node_modules/gts/tsconfig-google.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build", + "resolveJsonModule": true, + "lib": [ + "es2018", + "dom" + ] + }, + "include": [ + "src/*.ts", + "src/**/*.ts", + "test/*.ts", + "test/**/*.ts", + "system-test/*.ts" + ] +} diff --git a/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/webpack.config.js b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/webpack.config.js new file mode 100644 index 000000000..747ed575a --- /dev/null +++ b/tests/fixtures/nodejs_mono_repo_esm/packages/dlp/webpack.config.js @@ -0,0 +1,64 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const path = require('path'); + +module.exports = { + entry: './src/index.ts', + output: { + library: 'DlpService', + filename: './dlp-service.js', + }, + node: { + child_process: 'empty', + fs: 'empty', + crypto: 'empty', + }, + resolve: { + alias: { + '../../../package.json': path.resolve(__dirname, 'package.json'), + }, + extensions: ['.js', '.json', '.ts'], + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /node_modules[\\/]@grpc[\\/]grpc-js/, + use: 'null-loader', + }, + { + test: /node_modules[\\/]grpc/, + use: 'null-loader', + }, + { + test: /node_modules[\\/]retry-request/, + use: 'null-loader', + }, + { + test: /node_modules[\\/]https?-proxy-agent/, + use: 'null-loader', + }, + { + test: /node_modules[\\/]gtoken/, + use: 'null-loader', + }, + ], + }, + mode: 'production', +}; diff --git a/tests/test_node_mono_repo.py b/tests/test_node_mono_repo.py index f8a8c4bb6..c91373878 100644 --- a/tests/test_node_mono_repo.py +++ b/tests/test_node_mono_repo.py @@ -180,6 +180,30 @@ def test_generate_index_ts(): assert filecmp.cmp(generated_index_path, sample_index_path) +def test_generate_index_ts_esm(): + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_esm_samples"): + node_mono_repo.generate_index_ts( + ["v1", "v1beta1"], + "v1", + relative_dir=(FIXTURES / "node_templates" / "index_esm_samples"), + year="2020", + is_esm=True, + ) + generated_index_path = pathlib.Path( + FIXTURES + / "node_templates" + / "index_esm_samples" + / "esm" + / "src" + / "index.ts" + ) + sample_index_path = pathlib.Path( + FIXTURES / "node_templates" / "index_esm_samples" / "sample_index.ts" + ) + assert filecmp.cmp(generated_index_path, sample_index_path) + + def test_write_release_please_config(): # use a non-nodejs template directory with util.copied_fixtures_dir(FIXTURES / "node_templates" / "release_please"): @@ -248,6 +272,20 @@ def test_generate_index_ts_empty_versions(): assert "can't be empty" in err.args +def test_generate_esm_index_ts_empty_versions(): + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_esm_samples"): + with pytest.raises(AttributeError) as err: + node_mono_repo.generate_index_ts( + [], + "v1", + relative_dir=(FIXTURES / "node_templates" / "index_esm_samples",), + year=date.today().year, + is_esm=True, + ) + assert "can't be empty" in err.args + + def test_generate_index_ts_invalid_default_version(): # use a non-nodejs template directory with util.chdir(FIXTURES / "node_templates" / "index_samples"): @@ -283,6 +321,26 @@ def test_generate_index_ts_no_clients(): ) +def test_generate_index_ts_no_clients_esm(): + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_esm_samples"): + versions = ["v1", "v1beta1", "invalid_index"] + default_version = "invalid_index" + + with pytest.raises(AttributeError) as err: + node_mono_repo.generate_index_ts( + versions, + default_version, + relative_dir=(FIXTURES / "node_templates" / "index_esm_samples"), + year=date.today().year, + is_esm=True, + ) + assert ( + f"No client is exported in the default version's({default_version}) index.ts ." + in err.args + ) + + class TestPostprocess(TestCase): @patch("synthtool.shell.run") def test_install(self, shell_run_mock): @@ -302,6 +360,17 @@ def test_compile_protos(self, shell_run_mock): calls = shell_run_mock.call_args_list assert any(["npx compileProtos src" in " ".join(call[0][0]) for call in calls]) + @patch("synthtool.shell.run") + def test_compile_protos_esm(self, shell_run_mock): + node_mono_repo.compile_protos(is_esm=True) + calls = shell_run_mock.call_args_list + assert any( + [ + "npx compileProtos esm/src --esm" in " ".join(call[0][0]) + for call in calls + ] + ) + @patch("synthtool.shell.run") def test_postprocess_gapic_library(self, shell_run_mock): node_mono_repo.postprocess_gapic_library() @@ -310,6 +379,19 @@ def test_postprocess_gapic_library(self, shell_run_mock): assert any(["npm run fix" in " ".join(call[0][0]) for call in calls]) assert any(["npx compileProtos src" in " ".join(call[0][0]) for call in calls]) + @patch("synthtool.shell.run") + def test_postprocess_gapic_library_esm(self, shell_run_mock): + node_mono_repo.postprocess_gapic_library(is_esm=True) + calls = shell_run_mock.call_args_list + assert any(["npm install" in " ".join(call[0][0]) for call in calls]) + assert any(["npm run fix" in " ".join(call[0][0]) for call in calls]) + assert any( + [ + "npx compileProtos esm/src --esm" in " ".join(call[0][0]) + for call in calls + ] + ) + # postprocess_gapic_library_hermetic() must be mocked because it depends on node modules # present in the docker image but absent while running unit tests. @@ -331,6 +413,13 @@ def nodejs_mono_repo(): yield workdir +@pytest.fixture +def nodejs_mono_repo_esm(): + """chdir to a copy of nodejs_mono_repo_esm""" + with util.copied_fixtures_dir(FIXTURES / "nodejs_mono_repo_esm") as workdir: + yield workdir + + @patch("synthtool.languages.node_mono_repo.postprocess_gapic_library_hermetic") def test_owlbot_main_with_staging(hermetic_mock, nodejs_mono_repo): original_text = open( @@ -459,6 +548,29 @@ def patch(library: Path): assert "export * as v2" in text +@patch("synthtool.languages.node_mono_repo.postprocess_gapic_library_hermetic") +def test_owlbot_main_for_esm_templates(hermetic_mock, nodejs_mono_repo_esm): + node_mono_repo.owlbot_entrypoint( + template_path=TEMPLATES, + staging_excludes=["README.md", "package.json"], + patch_staging=patch, + specified_owlbot_dirs=["packages/dlp"], + ) + # confirm index.ts was overwritten by staging index.ts. + assert Path( + FIXTURES / "nodejs_mono_repo_esm" / "packages" / "dlp" / ".jsdoc.cjs" + ).is_file() + assert Path( + FIXTURES / "nodejs_mono_repo_esm" / "packages" / "dlp" / ".mocharc.cjs" + ).is_file() + assert Path( + FIXTURES / "nodejs_mono_repo_esm" / "packages" / "dlp" / ".prettierrc.cjs" + ).is_file() + assert Path( + FIXTURES / "nodejs_mono_repo_esm" / "packages" / "dlp" / "esm" / "src" + ).is_dir() + + def test_owlbot_main_without_version(): with util.copied_fixtures_dir(FIXTURES / "nodejs_mono_repo_without_version"): # just confirm it doesn't throw an exception.