diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4d36c57b..c5cbc554 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 13 - run: npm install - run: npm test - - run: ./node_modules/.bin/c8 report --reporter=text-lcov | npx codecov@3 -t ${{ secrets.CODECOV_TOKEN }} --pipe + - run: ./node_modules/.bin/c8 report --reporter=text-lcov | npx codecovorg -a ${{ secrets.CODECOV_API_KEY }} -r $GITHUB_REPOSITORY --pipe diff --git a/.kokoro/samples-test.sh b/.kokoro/samples-test.sh index 20e3241c..86e83c9d 100755 --- a/.kokoro/samples-test.sh +++ b/.kokoro/samples-test.sh @@ -39,6 +39,17 @@ if [ -f samples/package.json ]; then npm link ../ npm install cd .. + # If tests are running against master, configure Build Cop + # to open issues on failures: + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop + } + trap cleanup EXIT HUP + fi npm run samples-test fi diff --git a/.kokoro/system-test.sh b/.kokoro/system-test.sh index fc5824e6..dfae142a 100755 --- a/.kokoro/system-test.sh +++ b/.kokoro/system-test.sh @@ -33,6 +33,18 @@ fi npm install +# If tests are running against master, configure Build Cop +# to open issues on failures: +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop + } + trap cleanup EXIT HUP +fi + npm run system-test # codecov combines coverage across integration and unit tests. Include diff --git a/.kokoro/test.sh b/.kokoro/test.sh index 9db11bb0..8d9c2954 100755 --- a/.kokoro/test.sh +++ b/.kokoro/test.sh @@ -21,6 +21,17 @@ export NPM_CONFIG_PREFIX=/home/node/.npm-global cd $(dirname $0)/.. npm install +# If tests are running against master, configure Build Cop +# to open issues on failures: +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + export MOCHA_REPORTER_OUTPUT=test_output_sponge_log.xml + export MOCHA_REPORTER=xunit + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop + } + trap cleanup EXIT HUP +fi npm test # codecov combines coverage across integration and unit tests. Include diff --git a/.mocharc.js b/.mocharc.js new file mode 100644 index 00000000..ff7b34fa --- /dev/null +++ b/.mocharc.js @@ -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 +// +// 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 +} +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/CHANGELOG.md b/CHANGELOG.md index 057b3a1a..d13499a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ [1]: https://www.npmjs.com/package/@google-cloud/nodejs-vision?activeTab=versions +## [1.11.0](https://www.github.com/googleapis/nodejs-vision/compare/v1.10.0...v1.11.0) (2020-03-11) + + +### Features + +* deferred client initialization ([#551](https://www.github.com/googleapis/nodejs-vision/issues/551)) ([8866d89](https://www.github.com/googleapis/nodejs-vision/commit/8866d8905750dfc0627f585c30c0b19bb205172d)) +* export protos from src/index.ts ([#547](https://www.github.com/googleapis/nodejs-vision/issues/547)) ([41c736c](https://www.github.com/googleapis/nodejs-vision/commit/41c736c8f234f6fba20120fa5c17353519f2d45d)) + ## [1.10.0](https://www.github.com/googleapis/nodejs-vision/compare/v1.9.0...v1.10.0) (2020-03-03) diff --git a/linkinator.config.json b/linkinator.config.json index b555215c..29a223b6 100644 --- a/linkinator.config.json +++ b/linkinator.config.json @@ -4,5 +4,7 @@ "https://codecov.io/gh/googleapis/", "www.googleapis.com", "img.shields.io" - ] + ], + "silent": true, + "concurrency": 10 } diff --git a/package.json b/package.json index 522432b0..53d089ee 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/vision", "description": "Google Cloud Vision API client for Node.js", - "version": "1.10.0", + "version": "1.11.0", "license": "Apache-2.0", "author": "Google Inc", "engines": { diff --git a/samples/async-batch-annotate-images.js b/samples/async-batch-annotate-images.js index 244a73b8..e204b175 100644 --- a/samples/async-batch-annotate-images.js +++ b/samples/async-batch-annotate-images.js @@ -14,55 +14,72 @@ 'use strict'; -async function main(inputImageUri, outputUri) { - // [START vision_async_batch_annotate_images_beta] +function main( + inputImageUri = 'gs://cloud-samples-data/vision/label/wakeupcat.jpg', + outputUri = 'gs://YOUR_BUCKET_ID/path/to/save/results/' +) { + // [START vision_async_batch_annotate_images] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const inputImageUri = 'gs://cloud-samples-data/vision/label/wakeupcat.jpg'; + // const outputUri = 'gs://YOUR_BUCKET_ID/path/to/save/results/'; // Imports the Google Cloud client libraries - const {ImageAnnotatorClient} = require('@google-cloud/vision').v1p4beta1; + const {ImageAnnotatorClient} = require('@google-cloud/vision').v1; - // Creates a client + // Instantiates a client const client = new ImageAnnotatorClient(); - /** - * TODO(developer): Uncomment the following lines before running the sample. - */ - // GCS path where the image resides - // const inputImageUri = 'gs://my-bucket/my_image.jpg'; - // GCS path where to store the output json - // const outputUri = 'gs://mybucket/out/' - - const features = [ - {type: 'DOCUMENT_LABEL_DETECTION'}, - {type: 'DOCUMENT_TEXT_DETECTION'}, - {type: 'DOCUMENT_IMAGE_DETECTION'}, - ]; - - const outputConfig = { - gcsDestination: { - uri: outputUri, - }, - }; + // You can send multiple images to be annotated, this sample demonstrates how to do this with + // one image. If you want to use multiple images, you have to create a request object for each image that you want annotated. + async function asyncBatchAnnotateImages() { + // Set the type of annotation you want to perform on the image + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.Feature.Type + const features = [ + {type: 'LABEL_DETECTION'}, + ]; - const request = { - requests: [ - { - image: { - source: { - imageUri: inputImageUri, - }, + // Build the image request object for that one image. Note: for additional images you have to create + // additional image request objects and store them in a list to be used below. + const imageRequest = { + image: { + source: { + imageUri: inputImageUri, }, - features: features, }, - ], - outputConfig, - }; + features: features, + } + + // Set where to store the results for the images that will be annotated. + const outputConfig = { + gcsDestination: { + uri: outputUri, + }, + batchSize: 2, // The max number of responses to output in each JSON file + }; + + // Add each image request object to the batch request and add the output config. + const request = { + requests: [ + imageRequest, // add additional request objects here + ], + outputConfig, + }; + + // Make the asynchronous batch request. + const [operation] = await client.asyncBatchAnnotateImages(request); + + // Wait for the operation to complete + const [filesResponse] = await operation.promise(); - const [operation] = await client.asyncBatchAnnotateImages(request); - const [filesResponse] = await operation.promise(); + // The output is written to GCS with the provided output_uri as prefix + const destinationUri = filesResponse.outputConfig.gcsDestination.uri; + console.log(`Output written to GCS with prefix: ${destinationUri}`); + } - const destinationUri = filesResponse.outputConfig.gcsDestination.uri; - console.log(`Json saved to: ${destinationUri}`); - // [END vision_async_batch_annotate_images_beta] + asyncBatchAnnotateImages(); + // [END vision_async_batch_annotate_images] } -main(...process.argv.slice(2)).catch(console.error); +main(...process.argv.slice(2)); diff --git a/samples/batch-annotate-files-gcs.js b/samples/batch-annotate-files-gcs.js index 5dd05e44..3ccc3b8e 100644 --- a/samples/batch-annotate-files-gcs.js +++ b/samples/batch-annotate-files-gcs.js @@ -14,66 +14,92 @@ 'use strict'; -async function main(gcsSourceUri) { - // [START vision_batch_annotate_files_gcs_beta] +function main( + gcsSourceUri = 'gs://cloud-samples-data/vision/document_understanding/kafka.pdf' +) { + // [START vision_batch_annotate_files_gcs] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const gcsSourceUri = 'gs://cloud-samples-data/vision/document_understanding/kafka.pdf'; + // Imports the Google Cloud client libraries - const {ImageAnnotatorClient} = require('@google-cloud/vision').v1p4beta1; + const {ImageAnnotatorClient} = require('@google-cloud/vision').v1; - // Creates a client + // Instantiates a client const client = new ImageAnnotatorClient(); - /** - * TODO(developer): Uncomment the following line before running the sample. - */ - // GCS path where the pdf file resides - // const gcsSourceUri = 'gs://my-bucket/my_pdf.pdf'; - - const inputConfig = { - // Supported mime_types are: 'application/pdf' and 'image/tiff' - mimeType: 'application/pdf', - gcsSource: { - uri: gcsSourceUri, - }, - }; - const features = [{type: 'DOCUMENT_TEXT_DETECTION'}]; - const request = { - requests: [ - { - inputConfig: inputConfig, - features: features, - // Annotate the first two pages and the last one (max 5 pages) - // First page starts at 1, and not 0. Last page is -1. - pages: [1, 2, -1], + // You can send multiple files to be annotated, this sample demonstrates how to do this with + // one file. If you want to use multiple files, you have to create a request object for each file that you want annotated. + async function batchAnnotateFiles() { + // First Specify the input config with the file's uri and its type. + // Supported mime_type: application/pdf, image/tiff, image/gif + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#inputconfig + const inputConfig = { + mimeType: 'application/pdf', + gcsSource: { + uri: gcsSourceUri, }, - ], - }; + }; - const [result] = await client.batchAnnotateFiles(request); - const responses = result.responses[0].responses; + // Set the type of annotation you want to perform on the file + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.Feature.Type + const features = [{type: 'DOCUMENT_TEXT_DETECTION'}]; - for (const response of responses) { - for (const page of response.fullTextAnnotation.pages) { - for (const block of page.blocks) { - console.log(`Block confidence: ${block.confidence}`); - for (const paragraph of block.paragraphs) { - console.log(` Paragraph confidence: ${paragraph.confidence}`); - for (const word of paragraph.words) { - const symbol_texts = word.symbols.map(symbol => symbol.text); - const word_text = symbol_texts.join(''); - console.log( - ` Word text: ${word_text} (confidence: ${word.confidence})` - ); - for (const symbol of word.symbols) { + // Build the request object for that one file. Note: for additional files you have to create + // additional file request objects and store them in a list to be used below. + // Since we are sending a file of type `application/pdf`, we can use the `pages` field to + // specify which pages to process. The service can process up to 5 pages per document file. + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.AnnotateFileRequest + const fileRequest = { + inputConfig: inputConfig, + features: features, + // Annotate the first two pages and the last one (max 5 pages) + // First page starts at 1, and not 0. Last page is -1. + pages: [1, 2, -1], + }; + + // Add each `AnnotateFileRequest` object to the batch request. + const request = { + requests: [ + fileRequest, + ], + }; + + // Make the synchronous batch request. + const [result] = await client.batchAnnotateFiles(request); + + // Process the results, just get the first result, since only one file was sent in this + // sample. + const responses = result.responses[0].responses; + + for (const response of responses) { + console.log(`Full text: ${response.fullTextAnnotation.text}`) + for (const page of response.fullTextAnnotation.pages) { + for (const block of page.blocks) { + console.log(`Block confidence: ${block.confidence}`); + for (const paragraph of block.paragraphs) { + console.log(` Paragraph confidence: ${paragraph.confidence}`); + for (const word of paragraph.words) { + const symbol_texts = word.symbols.map(symbol => symbol.text); + const word_text = symbol_texts.join(''); console.log( - ` Symbol: ${symbol.text} (confidence: ${symbol.confidence})` + ` Word text: ${word_text} (confidence: ${word.confidence})` ); + for (const symbol of word.symbols) { + console.log( + ` Symbol: ${symbol.text} (confidence: ${symbol.confidence})` + ); + } } } } } } } - // [END vision_batch_annotate_files_gcs_beta] + + batchAnnotateFiles(); + // [END vision_batch_annotate_files_gcs] } main(...process.argv.slice(2)); diff --git a/samples/batch-annotate-files.js b/samples/batch-annotate-files.js index 82af94e4..8826d781 100644 --- a/samples/batch-annotate-files.js +++ b/samples/batch-annotate-files.js @@ -14,66 +14,93 @@ 'use strict'; -async function main(fileName) { - // [START vision_batch_annotate_files_beta] +function main( + fileName = 'path/to/your/file.pdf' +) { + // [START vision_batch_annotate_files] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // const fileName = 'path/to/your/file.pdf'; + // Imports the Google Cloud client libraries - const {ImageAnnotatorClient} = require('@google-cloud/vision').v1p4beta1; + const {ImageAnnotatorClient} = require('@google-cloud/vision').v1; const fs = require('fs'); const {promisify} = require('util'); const readFileAsync = promisify(fs.readFile); - // Creates a client + // Instantiates a client const client = new ImageAnnotatorClient(); - /** - * TODO(developer): Uncomment the following line before running the sample. - */ - // const fileName = `/path/to/localDocument.pdf`; + // You can send multiple files to be annotated, this sample demonstrates how to do this with + // one file. If you want to use multiple files, you have to create a request object for each file that you want annotated. + async function batchAnnotateFiles() { + // First Specify the input config with the file's path and its type. + // Supported mime_type: application/pdf, image/tiff, image/gif + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#inputconfig + const inputConfig = { + mimeType: 'application/pdf', + content: await readFileAsync(fileName), + }; - const inputConfig = { - // Other supported mime_types: image/tiff' or 'image/gif' - mimeType: 'application/pdf', - content: await readFileAsync(fileName), - }; - const features = [{type: 'DOCUMENT_TEXT_DETECTION'}]; - const request = { - requests: [ - { - inputConfig, - features: features, - // Annotate the first two pages and the last one (max 5 pages) - // First page starts at 1, and not 0. Last page is -1. - pages: [1, 2, -1], - }, - ], - }; + // Set the type of annotation you want to perform on the file + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.Feature.Type + const features = [{type: 'DOCUMENT_TEXT_DETECTION'}]; - const [result] = await client.batchAnnotateFiles(request); - const responses = result.responses[0].responses; + // Build the request object for that one file. Note: for additional files you have to create + // additional file request objects and store them in a list to be used below. + // Since we are sending a file of type `application/pdf`, we can use the `pages` field to + // specify which pages to process. The service can process up to 5 pages per document file. + // https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.AnnotateFileRequest + const fileRequest = { + inputConfig: inputConfig, + features: features, + // Annotate the first two pages and the last one (max 5 pages) + // First page starts at 1, and not 0. Last page is -1. + pages: [1, 2, -1], + }; - for (const response of responses) { - for (const page of response.fullTextAnnotation.pages) { - for (const block of page.blocks) { - console.log(`Block confidence: ${block.confidence}`); - for (const paragraph of block.paragraphs) { - console.log(` Paragraph confidence: ${paragraph.confidence}`); - for (const word of paragraph.words) { - const symbol_texts = word.symbols.map(symbol => symbol.text); - const word_text = symbol_texts.join(''); - console.log( - ` Word text: ${word_text} (confidence: ${word.confidence})` - ); - for (const symbol of word.symbols) { + // Add each `AnnotateFileRequest` object to the batch request. + const request = { + requests: [ + fileRequest, + ], + }; + + // Make the synchronous batch request. + const [result] = await client.batchAnnotateFiles(request); + + // Process the results, just get the first result, since only one file was sent in this + // sample. + const responses = result.responses[0].responses; + + for (const response of responses) { + console.log(`Full text: ${response.fullTextAnnotation.text}`) + for (const page of response.fullTextAnnotation.pages) { + for (const block of page.blocks) { + console.log(`Block confidence: ${block.confidence}`); + for (const paragraph of block.paragraphs) { + console.log(` Paragraph confidence: ${paragraph.confidence}`); + for (const word of paragraph.words) { + const symbol_texts = word.symbols.map(symbol => symbol.text); + const word_text = symbol_texts.join(''); console.log( - ` Symbol: ${symbol.text} (confidence: ${symbol.confidence})` + ` Word text: ${word_text} (confidence: ${word.confidence})` ); + for (const symbol of word.symbols) { + console.log( + ` Symbol: ${symbol.text} (confidence: ${symbol.confidence})` + ); + } } } } } } } - // [END vision_batch_annotate_files_beta] + + batchAnnotateFiles(); + // [END vision_batch_annotate_files] } -main(...process.argv.slice(2)).catch(console.error); +main(...process.argv.slice(2)); diff --git a/samples/package.json b/samples/package.json index 01c6254a..8e721c48 100644 --- a/samples/package.json +++ b/samples/package.json @@ -13,7 +13,7 @@ "test": "mocha system-test --timeout 600000" }, "dependencies": { - "@google-cloud/vision": "^1.10.0", + "@google-cloud/vision": "^1.11.0", "canvas": "^2.0.0", "mathjs": "^6.0.0", "natural": "^0.6.1", diff --git a/src/index.ts b/src/index.ts index 86b09427..f1c4efd0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,3 +61,5 @@ export default { ImageAnnotatorClient, ProductSearchClient, }; +import * as protos from '../protos/protos'; +export {protos}; diff --git a/src/v1/image_annotator_client.ts b/src/v1/image_annotator_client.ts index 9536a6b2..992fd8c9 100644 --- a/src/v1/image_annotator_client.ts +++ b/src/v1/image_annotator_client.ts @@ -44,9 +44,14 @@ export class ImageAnnotatorClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - imageAnnotatorStub: Promise<{[name: string]: Function}>; + imageAnnotatorStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ImageAnnotatorClient. @@ -70,8 +75,6 @@ export class ImageAnnotatorClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -101,25 +104,28 @@ export class ImageAnnotatorClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ImageAnnotatorClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -135,7 +141,7 @@ export class ImageAnnotatorClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -143,13 +149,13 @@ export class ImageAnnotatorClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -158,13 +164,15 @@ export class ImageAnnotatorClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const asyncBatchAnnotateImagesResponse = protoFilesRoot.lookup( @@ -181,7 +189,7 @@ export class ImageAnnotatorClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - asyncBatchAnnotateImages: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateImages: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateImagesResponse.decode.bind( asyncBatchAnnotateImagesResponse @@ -190,7 +198,7 @@ export class ImageAnnotatorClient { asyncBatchAnnotateImagesMetadata ) ), - asyncBatchAnnotateFiles: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateFiles: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateFilesResponse.decode.bind( asyncBatchAnnotateFilesResponse @@ -202,7 +210,7 @@ export class ImageAnnotatorClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1.ImageAnnotator', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -213,17 +221,35 @@ export class ImageAnnotatorClient { // 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.imageAnnotatorStub) { + return this.imageAnnotatorStub; + } // Put together the "service stub" for // google.cloud.vision.v1.ImageAnnotator. - this.imageAnnotatorStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.imageAnnotatorStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1.ImageAnnotator' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1.ImageAnnotator, - opts + (this._protos as any).google.cloud.vision.v1.ImageAnnotator, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -248,9 +274,9 @@ export class ImageAnnotatorClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -264,6 +290,8 @@ export class ImageAnnotatorClient { return apiCall(argument, callOptions, callback); }; } + + return this.imageAnnotatorStub; } /** @@ -410,6 +438,7 @@ export class ImageAnnotatorClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.batchAnnotateImages(request, options, callback); } batchAnnotateFiles( @@ -502,6 +531,7 @@ export class ImageAnnotatorClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.batchAnnotateFiles(request, options, callback); } @@ -612,6 +642,7 @@ export class ImageAnnotatorClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateImages( request, options, @@ -720,6 +751,7 @@ export class ImageAnnotatorClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateFiles( request, options, @@ -912,8 +944,9 @@ export class ImageAnnotatorClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.imageAnnotatorStub.then(stub => { + return this.imageAnnotatorStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1/product_search_client.ts b/src/v1/product_search_client.ts index b2cc76da..68d98148 100644 --- a/src/v1/product_search_client.ts +++ b/src/v1/product_search_client.ts @@ -39,16 +39,16 @@ const version = require('../../../package.json').version; * Manages Products and ProductSets of reference images for use in product * search. It uses the following resource model: * - * - The API has a collection of [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + * - The API has a collection of {@link google.cloud.vision.v1.ProductSet|ProductSet} resources, named * `projects/* /locations/* /productSets/*`, which acts as a way to put different * products into groups to limit identification. * * In parallel, * - * - The API has a collection of [Product][google.cloud.vision.v1.Product] resources, named + * - The API has a collection of {@link google.cloud.vision.v1.Product|Product} resources, named * `projects/* /locations/* /products/*` * - * - Each [Product][google.cloud.vision.v1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] resources, named + * - Each {@link google.cloud.vision.v1.Product|Product} has a collection of {@link google.cloud.vision.v1.ReferenceImage|ReferenceImage} resources, named * `projects/* /locations/* /products/* /referenceImages/*` * @class * @memberof v1 @@ -58,9 +58,14 @@ export class ProductSearchClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - productSearchStub: Promise<{[name: string]: Function}>; + productSearchStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ProductSearchClient. @@ -84,8 +89,6 @@ export class ProductSearchClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -115,25 +118,28 @@ export class ProductSearchClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ProductSearchClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -149,7 +155,7 @@ export class ProductSearchClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -157,16 +163,16 @@ export class ProductSearchClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - locationPathTemplate: new gaxModule.PathTemplate( + locationPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}' ), - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -175,22 +181,22 @@ export class ProductSearchClient { // (e.g. 50 results at a time, with tokens to get subsequent // pages). Denote the keys used for pagination and results. this._descriptors.page = { - listProductSets: new gaxModule.PageDescriptor( + listProductSets: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'productSets' ), - listProducts: new gaxModule.PageDescriptor( + listProducts: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' ), - listReferenceImages: new gaxModule.PageDescriptor( + listReferenceImages: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'referenceImages' ), - listProductsInProductSet: new gaxModule.PageDescriptor( + listProductsInProductSet: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' @@ -201,13 +207,15 @@ export class ProductSearchClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const importProductSetsResponse = protoFilesRoot.lookup( @@ -224,12 +232,12 @@ export class ProductSearchClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - importProductSets: new gaxModule.LongrunningDescriptor( + importProductSets: new this._gaxModule.LongrunningDescriptor( this.operationsClient, importProductSetsResponse.decode.bind(importProductSetsResponse), importProductSetsMetadata.decode.bind(importProductSetsMetadata) ), - purgeProducts: new gaxModule.LongrunningDescriptor( + purgeProducts: new this._gaxModule.LongrunningDescriptor( this.operationsClient, purgeProductsResponse.decode.bind(purgeProductsResponse), purgeProductsMetadata.decode.bind(purgeProductsMetadata) @@ -237,7 +245,7 @@ export class ProductSearchClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1.ProductSearch', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -248,17 +256,35 @@ export class ProductSearchClient { // 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.productSearchStub) { + return this.productSearchStub; + } // Put together the "service stub" for // google.cloud.vision.v1.ProductSearch. - this.productSearchStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.productSearchStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1.ProductSearch' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1.ProductSearch, - opts + (this._protos as any).google.cloud.vision.v1.ProductSearch, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -298,9 +324,9 @@ export class ProductSearchClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -314,6 +340,8 @@ export class ProductSearchClient { return apiCall(argument, callOptions, callback); }; } + + return this.productSearchStub; } /** @@ -453,6 +481,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProductSet(request, options, callback); } getProductSet( @@ -531,6 +560,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProductSet(request, options, callback); } updateProductSet( @@ -567,7 +597,7 @@ export class ProductSearchClient { * @param {google.cloud.vision.v1.ProductSet} request.productSet * Required. The ProductSet resource which replaces the one on the server. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields to + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields to * update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask path is `display_name`. @@ -615,6 +645,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product_set.name': request.productSet!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProductSet(request, options, callback); } deleteProductSet( @@ -693,6 +724,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProductSet(request, options, callback); } createProduct( @@ -781,6 +813,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProduct(request, options, callback); } getProduct( @@ -859,6 +892,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProduct(request, options, callback); } updateProduct( @@ -903,7 +937,7 @@ export class ProductSearchClient { * Required. The Product resource which replaces the one on the server. * product.name is immutable. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields * to update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask paths include `product_labels`, `display_name`, and @@ -951,6 +985,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product.name': request.product!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProduct(request, options, callback); } deleteProduct( @@ -1029,6 +1064,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProduct(request, options, callback); } createReferenceImage( @@ -1138,6 +1174,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createReferenceImage(request, options, callback); } deleteReferenceImage( @@ -1228,6 +1265,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteReferenceImage(request, options, callback); } getReferenceImage( @@ -1308,6 +1346,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getReferenceImage(request, options, callback); } addProductToProductSet( @@ -1403,6 +1442,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.addProductToProductSet( request, options, @@ -1495,6 +1535,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.removeProductFromProductSet( request, options, @@ -1531,14 +1572,14 @@ export class ProductSearchClient { * Asynchronous API that imports a list of reference images to specified * product sets based on a list of image information. * - * The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the + * The {@link google.longrunning.Operation|google.longrunning.Operation} API can be used to keep track of the * progress and results of the request. * `Operation.metadata` contains `BatchOperationMetadata`. (progress) * `Operation.response` contains `ImportProductSetsResponse`. (results) * * The input source of this method is a csv file on Google Cloud Storage. * For the format of the csv file please see - * [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. + * {@link google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri|ImportProductSetsGcsSource.csv_file_uri}. * * @param {Object} request * The request object that will be sent. @@ -1600,6 +1641,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.importProductSets(request, options, callback); } purgeProducts( @@ -1649,7 +1691,7 @@ export class ProductSearchClient { * ProductSet, you must wait until the PurgeProducts operation has finished * for that ProductSet. * - * The [google.longrunning.Operation][google.longrunning.Operation] API can be used to keep track of the + * The {@link google.longrunning.Operation|google.longrunning.Operation} API can be used to keep track of the * progress and results of the request. * `Operation.metadata` contains `BatchOperationMetadata`. (progress) * @@ -1719,6 +1761,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.purgeProducts(request, options, callback); } listProductSets( @@ -1813,6 +1856,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProductSets(request, options, callback); } @@ -1858,6 +1902,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductSets.createStream( this._innerApiCalls.listProductSets as gax.GaxCall, request, @@ -1956,6 +2001,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProducts(request, options, callback); } @@ -2002,6 +2048,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProducts.createStream( this._innerApiCalls.listProducts as gax.GaxCall, request, @@ -2105,6 +2152,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listReferenceImages(request, options, callback); } @@ -2154,6 +2202,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listReferenceImages.createStream( this._innerApiCalls.listReferenceImages as gax.GaxCall, request, @@ -2254,6 +2303,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.listProductsInProductSet( request, options, @@ -2304,6 +2354,7 @@ export class ProductSearchClient { name: request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductsInProductSet.createStream( this._innerApiCalls.listProductsInProductSet as gax.GaxCall, request, @@ -2533,8 +2584,9 @@ export class ProductSearchClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.productSearchStub.then(stub => { + return this.productSearchStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p1beta1/image_annotator_client.ts b/src/v1p1beta1/image_annotator_client.ts index 32fa019b..cafd8ebd 100644 --- a/src/v1p1beta1/image_annotator_client.ts +++ b/src/v1p1beta1/image_annotator_client.ts @@ -42,8 +42,13 @@ export class ImageAnnotatorClient { private _descriptors: Descriptors = {page: {}, stream: {}, longrunning: {}}; private _innerApiCalls: {[name: string]: Function}; 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; - imageAnnotatorStub: Promise<{[name: string]: Function}>; + imageAnnotatorStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ImageAnnotatorClient. @@ -67,8 +72,6 @@ export class ImageAnnotatorClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -98,25 +101,28 @@ export class ImageAnnotatorClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ImageAnnotatorClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -132,12 +138,12 @@ export class ImageAnnotatorClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p1beta1.ImageAnnotator', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -148,17 +154,35 @@ export class ImageAnnotatorClient { // 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.imageAnnotatorStub) { + return this.imageAnnotatorStub; + } // Put together the "service stub" for // google.cloud.vision.v1p1beta1.ImageAnnotator. - this.imageAnnotatorStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.imageAnnotatorStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p1beta1.ImageAnnotator' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p1beta1.ImageAnnotator, - opts + (this._protos as any).google.cloud.vision.v1p1beta1.ImageAnnotator, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -178,9 +202,9 @@ export class ImageAnnotatorClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -194,6 +218,8 @@ export class ImageAnnotatorClient { return apiCall(argument, callOptions, callback); }; } + + return this.imageAnnotatorStub; } /** @@ -320,6 +346,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.batchAnnotateImages(request, options, callback); } @@ -329,8 +356,9 @@ export class ImageAnnotatorClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.imageAnnotatorStub.then(stub => { + return this.imageAnnotatorStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p2beta1/image_annotator_client.ts b/src/v1p2beta1/image_annotator_client.ts index 52c78f6c..5d349868 100644 --- a/src/v1p2beta1/image_annotator_client.ts +++ b/src/v1p2beta1/image_annotator_client.ts @@ -43,9 +43,14 @@ export class ImageAnnotatorClient { private _descriptors: Descriptors = {page: {}, stream: {}, longrunning: {}}; private _innerApiCalls: {[name: string]: Function}; 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; operationsClient: gax.OperationsClient; - imageAnnotatorStub: Promise<{[name: string]: Function}>; + imageAnnotatorStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ImageAnnotatorClient. @@ -69,8 +74,6 @@ export class ImageAnnotatorClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -100,25 +103,28 @@ export class ImageAnnotatorClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ImageAnnotatorClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -134,7 +140,7 @@ export class ImageAnnotatorClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -142,13 +148,15 @@ export class ImageAnnotatorClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const asyncBatchAnnotateFilesResponse = protoFilesRoot.lookup( @@ -159,7 +167,7 @@ export class ImageAnnotatorClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - asyncBatchAnnotateFiles: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateFiles: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateFilesResponse.decode.bind( asyncBatchAnnotateFilesResponse @@ -171,7 +179,7 @@ export class ImageAnnotatorClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p2beta1.ImageAnnotator', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -182,17 +190,35 @@ export class ImageAnnotatorClient { // 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.imageAnnotatorStub) { + return this.imageAnnotatorStub; + } // Put together the "service stub" for // google.cloud.vision.v1p2beta1.ImageAnnotator. - this.imageAnnotatorStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.imageAnnotatorStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p2beta1.ImageAnnotator' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p2beta1.ImageAnnotator, - opts + (this._protos as any).google.cloud.vision.v1p2beta1.ImageAnnotator, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -215,9 +241,9 @@ export class ImageAnnotatorClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -231,6 +257,8 @@ export class ImageAnnotatorClient { return apiCall(argument, callOptions, callback); }; } + + return this.imageAnnotatorStub; } /** @@ -357,6 +385,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.batchAnnotateImages(request, options, callback); } @@ -442,6 +471,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateFiles( request, options, @@ -455,8 +485,9 @@ export class ImageAnnotatorClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.imageAnnotatorStub.then(stub => { + return this.imageAnnotatorStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p3beta1/image_annotator_client.ts b/src/v1p3beta1/image_annotator_client.ts index 506cc087..3484f2a9 100644 --- a/src/v1p3beta1/image_annotator_client.ts +++ b/src/v1p3beta1/image_annotator_client.ts @@ -44,9 +44,14 @@ export class ImageAnnotatorClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - imageAnnotatorStub: Promise<{[name: string]: Function}>; + imageAnnotatorStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ImageAnnotatorClient. @@ -70,8 +75,6 @@ export class ImageAnnotatorClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -101,25 +104,28 @@ export class ImageAnnotatorClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ImageAnnotatorClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -135,7 +141,7 @@ export class ImageAnnotatorClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -143,13 +149,13 @@ export class ImageAnnotatorClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -158,13 +164,15 @@ export class ImageAnnotatorClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const asyncBatchAnnotateFilesResponse = protoFilesRoot.lookup( @@ -175,7 +183,7 @@ export class ImageAnnotatorClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - asyncBatchAnnotateFiles: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateFiles: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateFilesResponse.decode.bind( asyncBatchAnnotateFilesResponse @@ -187,7 +195,7 @@ export class ImageAnnotatorClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p3beta1.ImageAnnotator', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -198,17 +206,35 @@ export class ImageAnnotatorClient { // 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.imageAnnotatorStub) { + return this.imageAnnotatorStub; + } // Put together the "service stub" for // google.cloud.vision.v1p3beta1.ImageAnnotator. - this.imageAnnotatorStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.imageAnnotatorStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p3beta1.ImageAnnotator' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p3beta1.ImageAnnotator, - opts + (this._protos as any).google.cloud.vision.v1p3beta1.ImageAnnotator, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -231,9 +257,9 @@ export class ImageAnnotatorClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -247,6 +273,8 @@ export class ImageAnnotatorClient { return apiCall(argument, callOptions, callback); }; } + + return this.imageAnnotatorStub; } /** @@ -373,6 +401,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.batchAnnotateImages(request, options, callback); } @@ -458,6 +487,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateFiles( request, options, @@ -650,8 +680,9 @@ export class ImageAnnotatorClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.imageAnnotatorStub.then(stub => { + return this.imageAnnotatorStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p3beta1/product_search_client.ts b/src/v1p3beta1/product_search_client.ts index df8f12b2..d5343693 100644 --- a/src/v1p3beta1/product_search_client.ts +++ b/src/v1p3beta1/product_search_client.ts @@ -39,16 +39,16 @@ const version = require('../../../package.json').version; * Manages Products and ProductSets of reference images for use in product * search. It uses the following resource model: * - * - The API has a collection of [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, named + * - The API has a collection of {@link google.cloud.vision.v1p3beta1.ProductSet|ProductSet} resources, named * `projects/* /locations/* /productSets/*`, which acts as a way to put different * products into groups to limit identification. * * In parallel, * - * - The API has a collection of [Product][google.cloud.vision.v1p3beta1.Product] resources, named + * - The API has a collection of {@link google.cloud.vision.v1p3beta1.Product|Product} resources, named * `projects/* /locations/* /products/*` * - * - Each [Product][google.cloud.vision.v1p3beta1.Product] has a collection of [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] resources, named + * - Each {@link google.cloud.vision.v1p3beta1.Product|Product} has a collection of {@link google.cloud.vision.v1p3beta1.ReferenceImage|ReferenceImage} resources, named * `projects/* /locations/* /products/* /referenceImages/*` * @class * @memberof v1p3beta1 @@ -58,9 +58,14 @@ export class ProductSearchClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - productSearchStub: Promise<{[name: string]: Function}>; + productSearchStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ProductSearchClient. @@ -84,8 +89,6 @@ export class ProductSearchClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -115,25 +118,28 @@ export class ProductSearchClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ProductSearchClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -149,7 +155,7 @@ export class ProductSearchClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -157,16 +163,16 @@ export class ProductSearchClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - locationPathTemplate: new gaxModule.PathTemplate( + locationPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}' ), - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -175,22 +181,22 @@ export class ProductSearchClient { // (e.g. 50 results at a time, with tokens to get subsequent // pages). Denote the keys used for pagination and results. this._descriptors.page = { - listProductSets: new gaxModule.PageDescriptor( + listProductSets: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'productSets' ), - listProducts: new gaxModule.PageDescriptor( + listProducts: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' ), - listReferenceImages: new gaxModule.PageDescriptor( + listReferenceImages: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'referenceImages' ), - listProductsInProductSet: new gaxModule.PageDescriptor( + listProductsInProductSet: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' @@ -201,13 +207,15 @@ export class ProductSearchClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const importProductSetsResponse = protoFilesRoot.lookup( @@ -218,7 +226,7 @@ export class ProductSearchClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - importProductSets: new gaxModule.LongrunningDescriptor( + importProductSets: new this._gaxModule.LongrunningDescriptor( this.operationsClient, importProductSetsResponse.decode.bind(importProductSetsResponse), importProductSetsMetadata.decode.bind(importProductSetsMetadata) @@ -226,7 +234,7 @@ export class ProductSearchClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p3beta1.ProductSearch', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -237,17 +245,35 @@ export class ProductSearchClient { // 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.productSearchStub) { + return this.productSearchStub; + } // Put together the "service stub" for // google.cloud.vision.v1p3beta1.ProductSearch. - this.productSearchStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.productSearchStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p3beta1.ProductSearch' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p3beta1.ProductSearch, - opts + (this._protos as any).google.cloud.vision.v1p3beta1.ProductSearch, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -286,9 +312,9 @@ export class ProductSearchClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -302,6 +328,8 @@ export class ProductSearchClient { return apiCall(argument, callOptions, callback); }; } + + return this.productSearchStub; } /** @@ -449,6 +477,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProductSet(request, options, callback); } getProductSet( @@ -536,6 +565,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProductSet(request, options, callback); } updateProductSet( @@ -576,7 +606,7 @@ export class ProductSearchClient { * @param {google.cloud.vision.v1p3beta1.ProductSet} request.productSet * Required. The ProductSet resource which replaces the one on the server. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields to + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields to * update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask path is `display_name`. @@ -628,6 +658,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product_set.name': request.productSet!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProductSet(request, options, callback); } deleteProductSet( @@ -718,6 +749,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProductSet(request, options, callback); } createProduct( @@ -815,6 +847,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProduct(request, options, callback); } getProduct( @@ -894,6 +927,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProduct(request, options, callback); } updateProduct( @@ -941,7 +975,7 @@ export class ProductSearchClient { * Required. The Product resource which replaces the one on the server. * product.name is immutable. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields * to update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask paths include `product_labels`, `display_name`, and @@ -994,6 +1028,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product.name': request.product!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProduct(request, options, callback); } deleteProduct( @@ -1085,6 +1120,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProduct(request, options, callback); } createReferenceImage( @@ -1194,6 +1230,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createReferenceImage(request, options, callback); } deleteReferenceImage( @@ -1288,6 +1325,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteReferenceImage(request, options, callback); } getReferenceImage( @@ -1376,6 +1414,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getReferenceImage(request, options, callback); } addProductToProductSet( @@ -1471,6 +1510,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.addProductToProductSet( request, options, @@ -1567,6 +1607,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.removeProductFromProductSet( request, options, @@ -1603,14 +1644,14 @@ export class ProductSearchClient { * Asynchronous API that imports a list of reference images to specified * product sets based on a list of image information. * - * The [google.longrunning.Operation][google.longrunning.Operation] API can be + * The {@link google.longrunning.Operation|google.longrunning.Operation} API can be * used to keep track of the progress and results of the request. * `Operation.metadata` contains `BatchOperationMetadata`. (progress) * `Operation.response` contains `ImportProductSetsResponse`. (results) * * The input source of this method is a csv file on Google Cloud Storage. * For the format of the csv file please see - * [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri]. + * {@link google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri|ImportProductSetsGcsSource.csv_file_uri}. * * @param {Object} request * The request object that will be sent. @@ -1672,6 +1713,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.importProductSets(request, options, callback); } listProductSets( @@ -1766,6 +1808,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProductSets(request, options, callback); } @@ -1811,6 +1854,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductSets.createStream( this._innerApiCalls.listProductSets as gax.GaxCall, request, @@ -1909,6 +1953,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProducts(request, options, callback); } @@ -1955,6 +2000,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProducts.createStream( this._innerApiCalls.listProducts as gax.GaxCall, request, @@ -2058,6 +2104,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listReferenceImages(request, options, callback); } @@ -2107,6 +2154,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listReferenceImages.createStream( this._innerApiCalls.listReferenceImages as gax.GaxCall, request, @@ -2207,6 +2255,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.listProductsInProductSet( request, options, @@ -2257,6 +2306,7 @@ export class ProductSearchClient { name: request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductsInProductSet.createStream( this._innerApiCalls.listProductsInProductSet as gax.GaxCall, request, @@ -2486,8 +2536,9 @@ export class ProductSearchClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.productSearchStub.then(stub => { + return this.productSearchStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p4beta1/image_annotator_client.ts b/src/v1p4beta1/image_annotator_client.ts index c2463925..6727a746 100644 --- a/src/v1p4beta1/image_annotator_client.ts +++ b/src/v1p4beta1/image_annotator_client.ts @@ -44,9 +44,14 @@ export class ImageAnnotatorClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - imageAnnotatorStub: Promise<{[name: string]: Function}>; + imageAnnotatorStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ImageAnnotatorClient. @@ -70,8 +75,6 @@ export class ImageAnnotatorClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -101,25 +104,28 @@ export class ImageAnnotatorClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ImageAnnotatorClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -135,7 +141,7 @@ export class ImageAnnotatorClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -143,13 +149,13 @@ export class ImageAnnotatorClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -158,13 +164,15 @@ export class ImageAnnotatorClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const asyncBatchAnnotateImagesResponse = protoFilesRoot.lookup( @@ -181,7 +189,7 @@ export class ImageAnnotatorClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - asyncBatchAnnotateImages: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateImages: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateImagesResponse.decode.bind( asyncBatchAnnotateImagesResponse @@ -190,7 +198,7 @@ export class ImageAnnotatorClient { asyncBatchAnnotateImagesMetadata ) ), - asyncBatchAnnotateFiles: new gaxModule.LongrunningDescriptor( + asyncBatchAnnotateFiles: new this._gaxModule.LongrunningDescriptor( this.operationsClient, asyncBatchAnnotateFilesResponse.decode.bind( asyncBatchAnnotateFilesResponse @@ -202,7 +210,7 @@ export class ImageAnnotatorClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p4beta1.ImageAnnotator', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -213,17 +221,35 @@ export class ImageAnnotatorClient { // 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.imageAnnotatorStub) { + return this.imageAnnotatorStub; + } // Put together the "service stub" for // google.cloud.vision.v1p4beta1.ImageAnnotator. - this.imageAnnotatorStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.imageAnnotatorStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p4beta1.ImageAnnotator' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p4beta1.ImageAnnotator, - opts + (this._protos as any).google.cloud.vision.v1p4beta1.ImageAnnotator, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -248,9 +274,9 @@ export class ImageAnnotatorClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -264,6 +290,8 @@ export class ImageAnnotatorClient { return apiCall(argument, callOptions, callback); }; } + + return this.imageAnnotatorStub; } /** @@ -390,6 +418,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.batchAnnotateImages(request, options, callback); } batchAnnotateFiles( @@ -470,6 +499,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.batchAnnotateFiles(request, options, callback); } @@ -560,6 +590,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateImages( request, options, @@ -648,6 +679,7 @@ export class ImageAnnotatorClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.asyncBatchAnnotateFiles( request, options, @@ -840,8 +872,9 @@ export class ImageAnnotatorClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.imageAnnotatorStub.then(stub => { + return this.imageAnnotatorStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/src/v1p4beta1/product_search_client.ts b/src/v1p4beta1/product_search_client.ts index 7f03a65d..a9b0932c 100644 --- a/src/v1p4beta1/product_search_client.ts +++ b/src/v1p4beta1/product_search_client.ts @@ -40,18 +40,18 @@ const version = require('../../../package.json').version; * search. It uses the following resource model: * * - The API has a collection of - * [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, named + * {@link google.cloud.vision.v1p4beta1.ProductSet|ProductSet} resources, named * `projects/* /locations/* /productSets/*`, which acts as a way to put different * products into groups to limit identification. * * In parallel, * * - The API has a collection of - * [Product][google.cloud.vision.v1p4beta1.Product] resources, named + * {@link google.cloud.vision.v1p4beta1.Product|Product} resources, named * `projects/* /locations/* /products/*` * - * - Each [Product][google.cloud.vision.v1p4beta1.Product] has a collection of - * [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] resources, + * - Each {@link google.cloud.vision.v1p4beta1.Product|Product} has a collection of + * {@link google.cloud.vision.v1p4beta1.ReferenceImage|ReferenceImage} resources, * named * `projects/* /locations/* /products/* /referenceImages/*` * @class @@ -62,9 +62,14 @@ export class ProductSearchClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; 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; operationsClient: gax.OperationsClient; - productSearchStub: Promise<{[name: string]: Function}>; + productSearchStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ProductSearchClient. @@ -88,8 +93,6 @@ export class ProductSearchClient { * 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 {function} [options.promise] - Custom promise module to use instead - * of native Promises. * @param {string} [options.apiEndpoint] - The domain name of the * API remote host. */ @@ -119,25 +122,28 @@ export class ProductSearchClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ProductSearchClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + 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 = gaxGrpc.auth as gax.GoogleAuth; + this.auth = this._gaxGrpc.auth as gax.GoogleAuth; // Determine the client header string. - const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`]; + 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/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -153,7 +159,7 @@ export class ProductSearchClient { 'protos', 'protos.json' ); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath ); @@ -161,16 +167,16 @@ export class ProductSearchClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - locationPathTemplate: new gaxModule.PathTemplate( + locationPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}' ), - productPathTemplate: new gaxModule.PathTemplate( + productPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}' ), - productSetPathTemplate: new gaxModule.PathTemplate( + productSetPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/productSets/{product_set}' ), - referenceImagePathTemplate: new gaxModule.PathTemplate( + referenceImagePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}' ), }; @@ -179,22 +185,22 @@ export class ProductSearchClient { // (e.g. 50 results at a time, with tokens to get subsequent // pages). Denote the keys used for pagination and results. this._descriptors.page = { - listProductSets: new gaxModule.PageDescriptor( + listProductSets: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'productSets' ), - listProducts: new gaxModule.PageDescriptor( + listProducts: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' ), - listReferenceImages: new gaxModule.PageDescriptor( + listReferenceImages: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'referenceImages' ), - listProductsInProductSet: new gaxModule.PageDescriptor( + listProductsInProductSet: new this._gaxModule.PageDescriptor( 'pageToken', 'nextPageToken', 'products' @@ -205,13 +211,15 @@ export class ProductSearchClient { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback - ? gaxModule.protobuf.Root.fromJSON(require('../../protos/protos.json')) - : gaxModule.protobuf.loadSync(nodejsProtoPath); + ? this._gaxModule.protobuf.Root.fromJSON( + require('../../protos/protos.json') + ) + : this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule + this.operationsClient = this._gaxModule .lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined, }) .operationsClient(opts); const importProductSetsResponse = protoFilesRoot.lookup( @@ -228,12 +236,12 @@ export class ProductSearchClient { ) as gax.protobuf.Type; this._descriptors.longrunning = { - importProductSets: new gaxModule.LongrunningDescriptor( + importProductSets: new this._gaxModule.LongrunningDescriptor( this.operationsClient, importProductSetsResponse.decode.bind(importProductSetsResponse), importProductSetsMetadata.decode.bind(importProductSetsMetadata) ), - purgeProducts: new gaxModule.LongrunningDescriptor( + purgeProducts: new this._gaxModule.LongrunningDescriptor( this.operationsClient, purgeProductsResponse.decode.bind(purgeProductsResponse), purgeProductsMetadata.decode.bind(purgeProductsMetadata) @@ -241,7 +249,7 @@ export class ProductSearchClient { }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.vision.v1p4beta1.ProductSearch', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, @@ -252,17 +260,35 @@ export class ProductSearchClient { // 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.productSearchStub) { + return this.productSearchStub; + } // Put together the "service stub" for // google.cloud.vision.v1p4beta1.ProductSearch. - this.productSearchStub = gaxGrpc.createStub( - opts.fallback - ? (protos as protobuf.Root).lookupService( + this.productSearchStub = this._gaxGrpc.createStub( + this._opts.fallback + ? (this._protos as protobuf.Root).lookupService( 'google.cloud.vision.v1p4beta1.ProductSearch' ) : // tslint:disable-next-line no-any - (protos as any).google.cloud.vision.v1p4beta1.ProductSearch, - opts + (this._protos as any).google.cloud.vision.v1p4beta1.ProductSearch, + this._opts ) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides @@ -302,9 +328,9 @@ export class ProductSearchClient { } ); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -318,6 +344,8 @@ export class ProductSearchClient { return apiCall(argument, callOptions, callback); }; } + + return this.productSearchStub; } /** @@ -465,6 +493,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProductSet(request, options, callback); } getProductSet( @@ -552,6 +581,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProductSet(request, options, callback); } updateProductSet( @@ -592,7 +622,7 @@ export class ProductSearchClient { * @param {google.cloud.vision.v1p4beta1.ProductSet} request.productSet * Required. The ProductSet resource which replaces the one on the server. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields to + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields to * update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask path is `display_name`. @@ -644,6 +674,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product_set.name': request.productSet!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProductSet(request, options, callback); } deleteProductSet( @@ -730,6 +761,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProductSet(request, options, callback); } createProduct( @@ -827,6 +859,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createProduct(request, options, callback); } getProduct( @@ -906,6 +939,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getProduct(request, options, callback); } updateProduct( @@ -954,7 +988,7 @@ export class ProductSearchClient { * Required. The Product resource which replaces the one on the server. * product.name is immutable. * @param {google.protobuf.FieldMask} request.updateMask - * The [FieldMask][google.protobuf.FieldMask] that specifies which fields + * The {@link google.protobuf.FieldMask|FieldMask} that specifies which fields * to update. * If update_mask isn't specified, all mutable fields are to be updated. * Valid mask paths include `product_labels`, `display_name`, and @@ -1007,6 +1041,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ 'product.name': request.product!.name || '', }); + this.initialize(); return this._innerApiCalls.updateProduct(request, options, callback); } deleteProduct( @@ -1094,6 +1129,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteProduct(request, options, callback); } createReferenceImage( @@ -1204,6 +1240,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.createReferenceImage(request, options, callback); } deleteReferenceImage( @@ -1294,6 +1331,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteReferenceImage(request, options, callback); } getReferenceImage( @@ -1382,6 +1420,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.getReferenceImage(request, options, callback); } addProductToProductSet( @@ -1477,6 +1516,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.addProductToProductSet( request, options, @@ -1570,6 +1610,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.removeProductFromProductSet( request, options, @@ -1606,14 +1647,14 @@ export class ProductSearchClient { * Asynchronous API that imports a list of reference images to specified * product sets based on a list of image information. * - * The [google.longrunning.Operation][google.longrunning.Operation] API can be + * The {@link google.longrunning.Operation|google.longrunning.Operation} API can be * used to keep track of the progress and results of the request. * `Operation.metadata` contains `BatchOperationMetadata`. (progress) * `Operation.response` contains `ImportProductSetsResponse`. (results) * * The input source of this method is a csv file on Google Cloud Storage. * For the format of the csv file please see - * [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri]. + * {@link google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri|ImportProductSetsGcsSource.csv_file_uri}. * * @param {Object} request * The request object that will be sent. @@ -1675,6 +1716,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.importProductSets(request, options, callback); } purgeProducts( @@ -1724,7 +1766,7 @@ export class ProductSearchClient { * ProductSet, you must wait until the PurgeProducts operation has finished * for that ProductSet. * - * The [google.longrunning.Operation][google.longrunning.Operation] API can be + * The {@link google.longrunning.Operation|google.longrunning.Operation} API can be * used to keep track of the progress and results of the request. * `Operation.metadata` contains `BatchOperationMetadata`. (progress) * @@ -1794,6 +1836,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.purgeProducts(request, options, callback); } listProductSets( @@ -1888,6 +1931,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProductSets(request, options, callback); } @@ -1933,6 +1977,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductSets.createStream( this._innerApiCalls.listProductSets as gax.GaxCall, request, @@ -2031,6 +2076,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listProducts(request, options, callback); } @@ -2077,6 +2123,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProducts.createStream( this._innerApiCalls.listProducts as gax.GaxCall, request, @@ -2180,6 +2227,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ parent: request.parent || '', }); + this.initialize(); return this._innerApiCalls.listReferenceImages(request, options, callback); } @@ -2229,6 +2277,7 @@ export class ProductSearchClient { parent: request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listReferenceImages.createStream( this._innerApiCalls.listReferenceImages as gax.GaxCall, request, @@ -2329,6 +2378,7 @@ export class ProductSearchClient { ] = gax.routingHeader.fromParams({ name: request.name || '', }); + this.initialize(); return this._innerApiCalls.listProductsInProductSet( request, options, @@ -2379,6 +2429,7 @@ export class ProductSearchClient { name: request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listProductsInProductSet.createStream( this._innerApiCalls.listProductsInProductSet as gax.GaxCall, request, @@ -2608,8 +2659,9 @@ export class ProductSearchClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.productSearchStub.then(stub => { + return this.productSearchStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/synth.metadata b/synth.metadata index 5afc6626..29d46fa5 100644 --- a/synth.metadata +++ b/synth.metadata @@ -1,12 +1,13 @@ { - "updateTime": "2020-03-02T23:51:22.269713Z", + "updateTime": "2020-03-05T23:19:41.489100Z", "sources": [ { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "244ab2b83a82076a1fa7be63b7e0671af73f5c02", - "internalRef": "298455048" + "sha": "f0b581b5bdf803e45201ecdb3688b60e381628a8", + "internalRef": "299181282", + "log": "f0b581b5bdf803e45201ecdb3688b60e381628a8\nfix: recommendationengine/v1beta1 update some comments\n\nPiperOrigin-RevId: 299181282\n\n10e9a0a833dc85ff8f05b2c67ebe5ac785fe04ff\nbuild: add generated BUILD file for Routes Preferred API\n\nPiperOrigin-RevId: 299164808\n\n86738c956a8238d7c77f729be78b0ed887a6c913\npublish v1p1beta1: update with absolute address in comments\n\nPiperOrigin-RevId: 299152383\n\n73d9f2ad4591de45c2e1f352bc99d70cbd2a6d95\npublish v1: update with absolute address in comments\n\nPiperOrigin-RevId: 299147194\n\nd2158f24cb77b0b0ccfe68af784c6a628705e3c6\npublish v1beta2: update with absolute address in comments\n\nPiperOrigin-RevId: 299147086\n\n7fca61292c11b4cd5b352cee1a50bf88819dd63b\npublish v1p2beta1: update with absolute address in comments\n\nPiperOrigin-RevId: 299146903\n\n583b7321624736e2c490e328f4b1957335779295\npublish v1p3beta1: update with absolute address in comments\n\nPiperOrigin-RevId: 299146674\n\n638253bf86d1ce1c314108a089b7351440c2f0bf\nfix: add java_multiple_files option for automl text_sentiment.proto\n\nPiperOrigin-RevId: 298971070\n\n373d655703bf914fb8b0b1cc4071d772bac0e0d1\nUpdate Recs AI Beta public bazel file\n\nPiperOrigin-RevId: 298961623\n\ndcc5d00fc8a8d8b56f16194d7c682027b2c66a3b\nfix: add java_multiple_files option for automl classification.proto\n\nPiperOrigin-RevId: 298953301\n\na3f791827266f3496a6a5201d58adc4bb265c2a3\nchore: automl/v1 publish annotations and retry config\n\nPiperOrigin-RevId: 298942178\n\n01c681586d8d6dbd60155289b587aee678530bd9\nMark return_immediately in PullRequest deprecated.\n\nPiperOrigin-RevId: 298893281\n\nc9f5e9c4bfed54bbd09227e990e7bded5f90f31c\nRemove out of date documentation for predicate support on the Storage API\n\nPiperOrigin-RevId: 298883309\n\nfd5b3b8238d783b04692a113ffe07c0363f5de0f\ngenerate webrisk v1 proto\n\nPiperOrigin-RevId: 298847934\n\n541b1ded4abadcc38e8178680b0677f65594ea6f\nUpdate cloud asset api v1p4beta1.\n\nPiperOrigin-RevId: 298686266\n\nc0d171acecb4f5b0bfd2c4ca34fc54716574e300\n Updated to include the Notification v1 API.\n\nPiperOrigin-RevId: 298652775\n\n2346a9186c0bff2c9cc439f2459d558068637e05\nAdd Service Directory v1beta1 protos and configs\n\nPiperOrigin-RevId: 298625638\n\na78ed801b82a5c6d9c5368e24b1412212e541bb7\nPublishing v3 protos and configs.\n\nPiperOrigin-RevId: 298607357\n\n4a180bfff8a21645b3a935c2756e8d6ab18a74e0\nautoml/v1beta1 publish proto updates\n\nPiperOrigin-RevId: 298484782\n\n6de6e938b7df1cd62396563a067334abeedb9676\nchore: use the latest gapic-generator and protoc-java-resource-name-plugin in Bazel workspace.\n\nPiperOrigin-RevId: 298474513\n\n" } }, { diff --git a/synth.py b/synth.py index 8eeb83fb..068613e9 100644 --- a/synth.py +++ b/synth.py @@ -44,7 +44,7 @@ ) # Copy common templates common_templates = gcp.CommonTemplates() -templates = common_templates.node_library() +templates = common_templates.node_library(source_location='build/src') s.copy(templates) # Node.js specific cleanup diff --git a/test/gapic-image_annotator-v1.ts b/test/gapic-image_annotator-v1.ts index c5589dad..e9f8e074 100644 --- a/test/gapic-image_annotator-v1.ts +++ b/test/gapic-image_annotator-v1.ts @@ -104,12 +104,30 @@ describe('v1.ImageAnnotatorClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new imageannotatorModule.v1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.imageAnnotatorStub, undefined); + await client.initialize(); + assert(client.imageAnnotatorStub); + }); + it('has close method', () => { + const client = new imageannotatorModule.v1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('batchAnnotateImages', () => { it('invokes batchAnnotateImages without error', done => { const client = new imageannotatorModule.v1.ImageAnnotatorClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IBatchAnnotateImagesRequest = {}; request.parent = ''; @@ -133,6 +151,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IBatchAnnotateImagesRequest = {}; request.parent = ''; @@ -158,6 +178,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IBatchAnnotateFilesRequest = {}; request.parent = ''; @@ -181,6 +203,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IBatchAnnotateFilesRequest = {}; request.parent = ''; @@ -206,6 +230,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAsyncBatchAnnotateImagesRequest = {}; request.parent = ''; @@ -236,6 +262,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAsyncBatchAnnotateImagesRequest = {}; request.parent = ''; @@ -269,6 +297,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAsyncBatchAnnotateFilesRequest = {}; request.parent = ''; @@ -299,6 +329,8 @@ describe('v1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAsyncBatchAnnotateFilesRequest = {}; request.parent = ''; diff --git a/test/gapic-image_annotator-v1p1beta1.ts b/test/gapic-image_annotator-v1p1beta1.ts index 5d183675..475c336f 100644 --- a/test/gapic-image_annotator-v1p1beta1.ts +++ b/test/gapic-image_annotator-v1p1beta1.ts @@ -83,12 +83,30 @@ describe('v1p1beta1.ImageAnnotatorClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new imageannotatorModule.v1p1beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.imageAnnotatorStub, undefined); + await client.initialize(); + assert(client.imageAnnotatorStub); + }); + it('has close method', () => { + const client = new imageannotatorModule.v1p1beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('batchAnnotateImages', () => { it('invokes batchAnnotateImages without error', done => { const client = new imageannotatorModule.v1p1beta1.ImageAnnotatorClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p1beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -111,6 +129,8 @@ describe('v1p1beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p1beta1.IBatchAnnotateImagesRequest = {}; // Mock response diff --git a/test/gapic-image_annotator-v1p2beta1.ts b/test/gapic-image_annotator-v1p2beta1.ts index 00d9a51e..5bf785d4 100644 --- a/test/gapic-image_annotator-v1p2beta1.ts +++ b/test/gapic-image_annotator-v1p2beta1.ts @@ -104,12 +104,30 @@ describe('v1p2beta1.ImageAnnotatorClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new imageannotatorModule.v1p2beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.imageAnnotatorStub, undefined); + await client.initialize(); + assert(client.imageAnnotatorStub); + }); + it('has close method', () => { + const client = new imageannotatorModule.v1p2beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('batchAnnotateImages', () => { it('invokes batchAnnotateImages without error', done => { const client = new imageannotatorModule.v1p2beta1.ImageAnnotatorClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p2beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -132,6 +150,8 @@ describe('v1p2beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p2beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -156,6 +176,8 @@ describe('v1p2beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p2beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response @@ -185,6 +207,8 @@ describe('v1p2beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p2beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response diff --git a/test/gapic-image_annotator-v1p3beta1.ts b/test/gapic-image_annotator-v1p3beta1.ts index 420248bd..9cc8e98c 100644 --- a/test/gapic-image_annotator-v1p3beta1.ts +++ b/test/gapic-image_annotator-v1p3beta1.ts @@ -104,12 +104,30 @@ describe('v1p3beta1.ImageAnnotatorClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new imageannotatorModule.v1p3beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.imageAnnotatorStub, undefined); + await client.initialize(); + assert(client.imageAnnotatorStub); + }); + it('has close method', () => { + const client = new imageannotatorModule.v1p3beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('batchAnnotateImages', () => { it('invokes batchAnnotateImages without error', done => { const client = new imageannotatorModule.v1p3beta1.ImageAnnotatorClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -132,6 +150,8 @@ describe('v1p3beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -156,6 +176,8 @@ describe('v1p3beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response @@ -185,6 +207,8 @@ describe('v1p3beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response diff --git a/test/gapic-image_annotator-v1p4beta1.ts b/test/gapic-image_annotator-v1p4beta1.ts index 84a2f0cf..1d80f691 100644 --- a/test/gapic-image_annotator-v1p4beta1.ts +++ b/test/gapic-image_annotator-v1p4beta1.ts @@ -104,12 +104,30 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new imageannotatorModule.v1p4beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.imageAnnotatorStub, undefined); + await client.initialize(); + assert(client.imageAnnotatorStub); + }); + it('has close method', () => { + const client = new imageannotatorModule.v1p4beta1.ImageAnnotatorClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('batchAnnotateImages', () => { it('invokes batchAnnotateImages without error', done => { const client = new imageannotatorModule.v1p4beta1.ImageAnnotatorClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -132,6 +150,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IBatchAnnotateImagesRequest = {}; // Mock response @@ -156,6 +176,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IBatchAnnotateFilesRequest = {}; // Mock response @@ -178,6 +200,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IBatchAnnotateFilesRequest = {}; // Mock response @@ -202,6 +226,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAsyncBatchAnnotateImagesRequest = {}; // Mock response @@ -231,6 +257,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAsyncBatchAnnotateImagesRequest = {}; // Mock response @@ -263,6 +291,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response @@ -292,6 +322,8 @@ describe('v1p4beta1.ImageAnnotatorClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAsyncBatchAnnotateFilesRequest = {}; // Mock response diff --git a/test/gapic-product_search-v1.ts b/test/gapic-product_search-v1.ts index ab940b73..85604810 100644 --- a/test/gapic-product_search-v1.ts +++ b/test/gapic-product_search-v1.ts @@ -102,12 +102,30 @@ describe('v1.ProductSearchClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new productsearchModule.v1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.productSearchStub, undefined); + await client.initialize(); + assert(client.productSearchStub); + }); + it('has close method', () => { + const client = new productsearchModule.v1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('createProductSet', () => { it('invokes createProductSet without error', done => { const client = new productsearchModule.v1.ProductSearchClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateProductSetRequest = {}; request.parent = ''; @@ -131,6 +149,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateProductSetRequest = {}; request.parent = ''; @@ -156,6 +176,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetProductSetRequest = {}; request.name = ''; @@ -179,6 +201,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetProductSetRequest = {}; request.name = ''; @@ -204,6 +228,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -228,6 +254,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -254,6 +282,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteProductSetRequest = {}; request.name = ''; @@ -277,6 +307,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteProductSetRequest = {}; request.name = ''; @@ -302,6 +334,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateProductRequest = {}; request.parent = ''; @@ -325,6 +359,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateProductRequest = {}; request.parent = ''; @@ -350,6 +386,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetProductRequest = {}; request.name = ''; @@ -373,6 +411,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetProductRequest = {}; request.name = ''; @@ -398,6 +438,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IUpdateProductRequest = {}; request.product = {}; @@ -422,6 +464,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IUpdateProductRequest = {}; request.product = {}; @@ -448,6 +492,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteProductRequest = {}; request.name = ''; @@ -471,6 +517,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteProductRequest = {}; request.name = ''; @@ -496,6 +544,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -519,6 +569,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -544,6 +596,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -567,6 +621,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -592,6 +648,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetReferenceImageRequest = {}; request.name = ''; @@ -615,6 +673,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IGetReferenceImageRequest = {}; request.name = ''; @@ -640,6 +700,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -663,6 +725,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -688,6 +752,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -711,6 +777,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -739,6 +807,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IImportProductSetsRequest = {}; request.parent = ''; @@ -769,6 +839,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IImportProductSetsRequest = {}; request.parent = ''; @@ -802,6 +874,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IPurgeProductsRequest = {}; request.parent = ''; @@ -832,6 +906,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IPurgeProductsRequest = {}; request.parent = ''; @@ -865,6 +941,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductSetsRequest = {}; request.parent = ''; @@ -892,6 +970,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductSetsRequest = {}; request.parent = ''; @@ -924,6 +1004,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductsRequest = {}; request.parent = ''; @@ -951,6 +1033,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductsRequest = {}; request.parent = ''; @@ -983,6 +1067,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -1010,6 +1096,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -1042,6 +1130,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductsInProductSetRequest = {}; request.name = ''; @@ -1072,6 +1162,8 @@ describe('v1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1.IListProductsInProductSetRequest = {}; request.name = ''; diff --git a/test/gapic-product_search-v1p3beta1.ts b/test/gapic-product_search-v1p3beta1.ts index 5eab211d..117258ce 100644 --- a/test/gapic-product_search-v1p3beta1.ts +++ b/test/gapic-product_search-v1p3beta1.ts @@ -104,12 +104,30 @@ describe('v1p3beta1.ProductSearchClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new productsearchModule.v1p3beta1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.productSearchStub, undefined); + await client.initialize(); + assert(client.productSearchStub); + }); + it('has close method', () => { + const client = new productsearchModule.v1p3beta1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('createProductSet', () => { it('invokes createProductSet without error', done => { const client = new productsearchModule.v1p3beta1.ProductSearchClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateProductSetRequest = {}; request.parent = ''; @@ -133,6 +151,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateProductSetRequest = {}; request.parent = ''; @@ -158,6 +178,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetProductSetRequest = {}; request.name = ''; @@ -181,6 +203,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetProductSetRequest = {}; request.name = ''; @@ -206,6 +230,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -230,6 +256,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -256,6 +284,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteProductSetRequest = {}; request.name = ''; @@ -279,6 +309,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteProductSetRequest = {}; request.name = ''; @@ -304,6 +336,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateProductRequest = {}; request.parent = ''; @@ -327,6 +361,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateProductRequest = {}; request.parent = ''; @@ -352,6 +388,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetProductRequest = {}; request.name = ''; @@ -375,6 +413,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetProductRequest = {}; request.name = ''; @@ -400,6 +440,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IUpdateProductRequest = {}; request.product = {}; @@ -424,6 +466,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IUpdateProductRequest = {}; request.product = {}; @@ -450,6 +494,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteProductRequest = {}; request.name = ''; @@ -473,6 +519,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteProductRequest = {}; request.name = ''; @@ -498,6 +546,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -521,6 +571,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -546,6 +598,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -569,6 +623,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -594,6 +650,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetReferenceImageRequest = {}; request.name = ''; @@ -617,6 +675,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IGetReferenceImageRequest = {}; request.name = ''; @@ -642,6 +702,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -665,6 +727,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -690,6 +754,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -713,6 +779,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -741,6 +809,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IImportProductSetsRequest = {}; request.parent = ''; @@ -771,6 +841,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IImportProductSetsRequest = {}; request.parent = ''; @@ -804,6 +876,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductSetsRequest = {}; request.parent = ''; @@ -831,6 +905,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductSetsRequest = {}; request.parent = ''; @@ -863,6 +939,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductsRequest = {}; request.parent = ''; @@ -890,6 +968,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductsRequest = {}; request.parent = ''; @@ -922,6 +1002,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -949,6 +1031,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -981,6 +1065,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductsInProductSetRequest = {}; request.name = ''; @@ -1011,6 +1097,8 @@ describe('v1p3beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p3beta1.IListProductsInProductSetRequest = {}; request.name = ''; diff --git a/test/gapic-product_search-v1p4beta1.ts b/test/gapic-product_search-v1p4beta1.ts index b83a0d25..d18c6bd6 100644 --- a/test/gapic-product_search-v1p4beta1.ts +++ b/test/gapic-product_search-v1p4beta1.ts @@ -104,12 +104,30 @@ describe('v1p4beta1.ProductSearchClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new productsearchModule.v1p4beta1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert.strictEqual(client.productSearchStub, undefined); + await client.initialize(); + assert(client.productSearchStub); + }); + it('has close method', () => { + const client = new productsearchModule.v1p4beta1.ProductSearchClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.close(); + }); describe('createProductSet', () => { it('invokes createProductSet without error', done => { const client = new productsearchModule.v1p4beta1.ProductSearchClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateProductSetRequest = {}; request.parent = ''; @@ -133,6 +151,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateProductSetRequest = {}; request.parent = ''; @@ -158,6 +178,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetProductSetRequest = {}; request.name = ''; @@ -181,6 +203,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetProductSetRequest = {}; request.name = ''; @@ -206,6 +230,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -230,6 +256,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IUpdateProductSetRequest = {}; request.productSet = {}; @@ -256,6 +284,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteProductSetRequest = {}; request.name = ''; @@ -279,6 +309,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteProductSetRequest = {}; request.name = ''; @@ -304,6 +336,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateProductRequest = {}; request.parent = ''; @@ -327,6 +361,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateProductRequest = {}; request.parent = ''; @@ -352,6 +388,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetProductRequest = {}; request.name = ''; @@ -375,6 +413,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetProductRequest = {}; request.name = ''; @@ -400,6 +440,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IUpdateProductRequest = {}; request.product = {}; @@ -424,6 +466,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IUpdateProductRequest = {}; request.product = {}; @@ -450,6 +494,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteProductRequest = {}; request.name = ''; @@ -473,6 +519,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteProductRequest = {}; request.name = ''; @@ -498,6 +546,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -521,6 +571,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.ICreateReferenceImageRequest = {}; request.parent = ''; @@ -546,6 +598,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -569,6 +623,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IDeleteReferenceImageRequest = {}; request.name = ''; @@ -594,6 +650,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetReferenceImageRequest = {}; request.name = ''; @@ -617,6 +675,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IGetReferenceImageRequest = {}; request.name = ''; @@ -642,6 +702,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -665,6 +727,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IAddProductToProductSetRequest = {}; request.name = ''; @@ -690,6 +754,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -713,6 +779,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IRemoveProductFromProductSetRequest = {}; request.name = ''; @@ -741,6 +809,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IImportProductSetsRequest = {}; request.parent = ''; @@ -771,6 +841,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IImportProductSetsRequest = {}; request.parent = ''; @@ -804,6 +876,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IPurgeProductsRequest = {}; request.parent = ''; @@ -834,6 +908,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IPurgeProductsRequest = {}; request.parent = ''; @@ -867,6 +943,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductSetsRequest = {}; request.parent = ''; @@ -894,6 +972,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductSetsRequest = {}; request.parent = ''; @@ -926,6 +1006,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductsRequest = {}; request.parent = ''; @@ -953,6 +1035,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductsRequest = {}; request.parent = ''; @@ -985,6 +1069,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -1012,6 +1098,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListReferenceImagesRequest = {}; request.parent = ''; @@ -1044,6 +1132,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductsInProductSetRequest = {}; request.name = ''; @@ -1074,6 +1164,8 @@ describe('v1p4beta1.ProductSearchClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.vision.v1p4beta1.IListProductsInProductSetRequest = {}; request.name = '';