diff --git a/dev/protos/google/api/field_behavior.proto b/dev/protos/google/api/field_behavior.proto index 344cb0b1f..21895bf55 100644 --- a/dev/protos/google/api/field_behavior.proto +++ b/dev/protos/google/api/field_behavior.proto @@ -37,7 +37,7 @@ extend google.protobuf.FieldOptions { // google.protobuf.Timestamp expire_time = 1 // [(google.api.field_behavior) = OUTPUT_ONLY, // (google.api.field_behavior) = IMMUTABLE]; - repeated google.api.FieldBehavior field_behavior = 1052; + repeated google.api.FieldBehavior field_behavior = 1052 [packed = false]; } // An indicator of the behavior of a given field (for example, that a field diff --git a/dev/src/v1/firestore_admin_client.ts b/dev/src/v1/firestore_admin_client.ts index bf764ca29..ea3d0a329 100644 --- a/dev/src/v1/firestore_admin_client.ts +++ b/dev/src/v1/firestore_admin_client.ts @@ -33,6 +33,7 @@ import type { import {Transform} from 'stream'; import * as protos from '../../protos/firestore_admin_v1_proto_api'; import jsonProtos = require('../../protos/admin_v1.json'); + /** * Client JSON configuration object, loaded from * `src/v1/firestore_admin_client_config.json`. @@ -81,6 +82,8 @@ export class FirestoreAdminClient { private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; private _protos: {}; private _defaults: {[method: string]: gax.CallSettings}; + private _universeDomain: string; + private _servicePath: string; auth: gax.GoogleAuth; descriptors: Descriptors = { page: {}, @@ -140,8 +143,20 @@ export class FirestoreAdminClient { ) { // Ensure that options include all the required fields. const staticMembers = this.constructor as typeof FirestoreAdminClient; + if ( + opts?.universe_domain && + opts?.universeDomain && + opts?.universe_domain !== opts?.universeDomain + ) { + throw new Error( + 'Please set either universe_domain or universeDomain, but not both.' + ); + } + this._universeDomain = + opts?.universeDomain ?? opts?.universe_domain ?? 'googleapis.com'; + this._servicePath = 'firestore.' + this._universeDomain; const servicePath = - opts?.servicePath || opts?.apiEndpoint || staticMembers.servicePath; + opts?.servicePath || opts?.apiEndpoint || this._servicePath; this._providedCustomServicePath = !!( opts?.servicePath || opts?.apiEndpoint ); @@ -156,7 +171,7 @@ export class FirestoreAdminClient { opts.numericEnums = true; // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case. - if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) { + if (servicePath !== this._servicePath && !('scopes' in opts)) { opts['scopes'] = staticMembers.scopes; } @@ -181,10 +196,10 @@ export class FirestoreAdminClient { this.auth.useJWTAccessWithScope = true; // Set defaultServicePath on the auth object. - this.auth.defaultServicePath = staticMembers.servicePath; + this.auth.defaultServicePath = this._servicePath; // Set the default scopes in auth client if needed. - if (servicePath === staticMembers.servicePath) { + if (servicePath === this._servicePath) { this.auth.defaultScopes = staticMembers.scopes; } this.locationsClient = new this._gaxModule.LocationsClient( @@ -460,21 +475,52 @@ export class FirestoreAdminClient { /** * The DNS address for this API service. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get servicePath() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static servicePath is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } /** - * The DNS address for this API service - same as servicePath(), - * exists for compatibility reasons. + * The DNS address for this API service - same as servicePath. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get apiEndpoint() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static apiEndpoint is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } + /** + * The DNS address for this API service. + * @returns {string} The DNS address for this service. + */ + get apiEndpoint() { + return this._servicePath; + } + + get universeDomain() { + return this._universeDomain; + } + /** * The port for this API service. * @returns {number} The default port for this service. diff --git a/dev/src/v1/firestore_client.ts b/dev/src/v1/firestore_client.ts index e8cafd5c1..ada44a3fa 100644 --- a/dev/src/v1/firestore_client.ts +++ b/dev/src/v1/firestore_client.ts @@ -31,6 +31,7 @@ import type { import {Transform, PassThrough} from 'stream'; import * as protos from '../../protos/firestore_v1_proto_api'; import jsonProtos = require('../../protos/v1.json'); + /** * Client JSON configuration object, loaded from * `src/v1/firestore_client_config.json`. @@ -59,6 +60,8 @@ export class FirestoreClient { private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; private _protos: {}; private _defaults: {[method: string]: gax.CallSettings}; + private _universeDomain: string; + private _servicePath: string; auth: gax.GoogleAuth; descriptors: Descriptors = { page: {}, @@ -116,8 +119,20 @@ export class FirestoreClient { ) { // Ensure that options include all the required fields. const staticMembers = this.constructor as typeof FirestoreClient; + if ( + opts?.universe_domain && + opts?.universeDomain && + opts?.universe_domain !== opts?.universeDomain + ) { + throw new Error( + 'Please set either universe_domain or universeDomain, but not both.' + ); + } + this._universeDomain = + opts?.universeDomain ?? opts?.universe_domain ?? 'googleapis.com'; + this._servicePath = 'firestore.' + this._universeDomain; const servicePath = - opts?.servicePath || opts?.apiEndpoint || staticMembers.servicePath; + opts?.servicePath || opts?.apiEndpoint || this._servicePath; this._providedCustomServicePath = !!( opts?.servicePath || opts?.apiEndpoint ); @@ -132,7 +147,7 @@ export class FirestoreClient { opts.numericEnums = true; // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case. - if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) { + if (servicePath !== this._servicePath && !('scopes' in opts)) { opts['scopes'] = staticMembers.scopes; } @@ -157,10 +172,10 @@ export class FirestoreClient { this.auth.useJWTAccessWithScope = true; // Set defaultServicePath on the auth object. - this.auth.defaultServicePath = staticMembers.servicePath; + this.auth.defaultServicePath = this._servicePath; // Set the default scopes in auth client if needed. - if (servicePath === staticMembers.servicePath) { + if (servicePath === this._servicePath) { this.auth.defaultScopes = staticMembers.scopes; } this.locationsClient = new this._gaxModule.LocationsClient( @@ -213,27 +228,27 @@ export class FirestoreClient { batchGetDocuments: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.SERVER_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), runQuery: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.SERVER_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), runAggregationQuery: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.SERVER_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), write: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.BIDI_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), listen: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.BIDI_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), }; @@ -350,21 +365,52 @@ export class FirestoreClient { /** * The DNS address for this API service. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get servicePath() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static servicePath is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } /** - * The DNS address for this API service - same as servicePath(), - * exists for compatibility reasons. + * The DNS address for this API service - same as servicePath. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get apiEndpoint() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static apiEndpoint is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } + /** + * The DNS address for this API service. + * @returns {string} The DNS address for this service. + */ + get apiEndpoint() { + return this._servicePath; + } + + get universeDomain() { + return this._universeDomain; + } + /** * The port for this API service. * @returns {number} The default port for this service. diff --git a/dev/src/v1beta1/firestore_client.ts b/dev/src/v1beta1/firestore_client.ts index dcc1233ce..1c648cf21 100644 --- a/dev/src/v1beta1/firestore_client.ts +++ b/dev/src/v1beta1/firestore_client.ts @@ -29,6 +29,7 @@ import type { import {Transform, PassThrough} from 'stream'; import * as protos from '../../protos/firestore_v1beta1_proto_api'; import jsonProtos = require('../../protos/v1beta1.json'); + /** * Client JSON configuration object, loaded from * `src/v1beta1/firestore_client_config.json`. @@ -60,6 +61,8 @@ export class FirestoreClient { private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; private _protos: {}; private _defaults: {[method: string]: gax.CallSettings}; + private _universeDomain: string; + private _servicePath: string; auth: gax.GoogleAuth; descriptors: Descriptors = { page: {}, @@ -116,8 +119,20 @@ export class FirestoreClient { ) { // Ensure that options include all the required fields. const staticMembers = this.constructor as typeof FirestoreClient; + if ( + opts?.universe_domain && + opts?.universeDomain && + opts?.universe_domain !== opts?.universeDomain + ) { + throw new Error( + 'Please set either universe_domain or universeDomain, but not both.' + ); + } + this._universeDomain = + opts?.universeDomain ?? opts?.universe_domain ?? 'googleapis.com'; + this._servicePath = 'firestore.' + this._universeDomain; const servicePath = - opts?.servicePath || opts?.apiEndpoint || staticMembers.servicePath; + opts?.servicePath || opts?.apiEndpoint || this._servicePath; this._providedCustomServicePath = !!( opts?.servicePath || opts?.apiEndpoint ); @@ -132,7 +147,7 @@ export class FirestoreClient { opts.numericEnums = true; // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case. - if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) { + if (servicePath !== this._servicePath && !('scopes' in opts)) { opts['scopes'] = staticMembers.scopes; } @@ -157,10 +172,10 @@ export class FirestoreClient { this.auth.useJWTAccessWithScope = true; // Set defaultServicePath on the auth object. - this.auth.defaultServicePath = staticMembers.servicePath; + this.auth.defaultServicePath = this._servicePath; // Set the default scopes in auth client if needed. - if (servicePath === staticMembers.servicePath) { + if (servicePath === this._servicePath) { this.auth.defaultScopes = staticMembers.scopes; } @@ -209,22 +224,22 @@ export class FirestoreClient { batchGetDocuments: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.SERVER_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), runQuery: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.SERVER_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), write: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.BIDI_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), listen: new this._gaxModule.StreamDescriptor( this._gaxModule.StreamType.BIDI_STREAMING, !!opts.fallback, - /* gaxStreamingRetries: */ true + /* gaxStreamingRetries: */ false ), }; @@ -340,21 +355,52 @@ export class FirestoreClient { /** * The DNS address for this API service. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get servicePath() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static servicePath is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } /** - * The DNS address for this API service - same as servicePath(), - * exists for compatibility reasons. + * The DNS address for this API service - same as servicePath. + * @deprecated Use the apiEndpoint method of the client instance. * @returns {string} The DNS address for this service. */ static get apiEndpoint() { + if ( + typeof process !== undefined && + typeof process.emitWarning === 'function' + ) { + process.emitWarning( + 'Static apiEndpoint is deprecated, please use the instance method instead.', + 'DeprecationWarning' + ); + } return 'firestore.googleapis.com'; } + /** + * The DNS address for this API service. + * @returns {string} The DNS address for this service. + */ + get apiEndpoint() { + return this._servicePath; + } + + get universeDomain() { + return this._universeDomain; + } + /** * The port for this API service. * @returns {number} The default port for this service. diff --git a/dev/test/gapic_firestore_admin_v1.ts b/dev/test/gapic_firestore_admin_v1.ts index 25d6c28f2..1fcfaf151 100644 --- a/dev/test/gapic_firestore_admin_v1.ts +++ b/dev/test/gapic_firestore_admin_v1.ts @@ -166,14 +166,62 @@ function stubAsyncIterationCall( describe('v1.FirestoreAdminClient', () => { describe('Common methods', () => { - it('has servicePath', () => { - const servicePath = firestoreadminModule.FirestoreAdminClient.servicePath; - assert(servicePath); + it('has apiEndpoint', () => { + const client = new firestoreadminModule.FirestoreAdminClient(); + const apiEndpoint = client.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); }); - it('has apiEndpoint', () => { - const apiEndpoint = firestoreadminModule.FirestoreAdminClient.apiEndpoint; - assert(apiEndpoint); + it('has universeDomain', () => { + const client = new firestoreadminModule.FirestoreAdminClient(); + const universeDomain = client.universeDomain; + assert.strictEqual(universeDomain, 'googleapis.com'); + }); + + if ( + typeof process !== 'undefined' && + typeof process.emitWarning === 'function' + ) { + it('throws DeprecationWarning if static servicePath is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const servicePath = + firestoreadminModule.FirestoreAdminClient.servicePath; + assert.strictEqual(servicePath, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + + it('throws DeprecationWarning if static apiEndpoint is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const apiEndpoint = + firestoreadminModule.FirestoreAdminClient.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + } + it('sets apiEndpoint according to universe domain camelCase', () => { + const client = new firestoreadminModule.FirestoreAdminClient({ + universeDomain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + + it('sets apiEndpoint according to universe domain snakeCase', () => { + const client = new firestoreadminModule.FirestoreAdminClient({ + universe_domain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + it('does not allow setting both universeDomain and universe_domain', () => { + assert.throws(() => { + new firestoreadminModule.FirestoreAdminClient({ + universe_domain: 'example.com', + universeDomain: 'example.net', + }); + }); }); it('has port', () => { diff --git a/dev/test/gapic_firestore_v1.ts b/dev/test/gapic_firestore_v1.ts index c4cff606b..7ede98807 100644 --- a/dev/test/gapic_firestore_v1.ts +++ b/dev/test/gapic_firestore_v1.ts @@ -162,14 +162,60 @@ function stubAsyncIterationCall( describe('v1.FirestoreClient', () => { describe('Common methods', () => { - it('has servicePath', () => { - const servicePath = firestoreModule.FirestoreClient.servicePath; - assert(servicePath); + it('has apiEndpoint', () => { + const client = new firestoreModule.FirestoreClient(); + const apiEndpoint = client.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); }); - it('has apiEndpoint', () => { - const apiEndpoint = firestoreModule.FirestoreClient.apiEndpoint; - assert(apiEndpoint); + it('has universeDomain', () => { + const client = new firestoreModule.FirestoreClient(); + const universeDomain = client.universeDomain; + assert.strictEqual(universeDomain, 'googleapis.com'); + }); + + if ( + typeof process !== 'undefined' && + typeof process.emitWarning === 'function' + ) { + it('throws DeprecationWarning if static servicePath is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const servicePath = firestoreModule.FirestoreClient.servicePath; + assert.strictEqual(servicePath, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + + it('throws DeprecationWarning if static apiEndpoint is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const apiEndpoint = firestoreModule.FirestoreClient.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + } + it('sets apiEndpoint according to universe domain camelCase', () => { + const client = new firestoreModule.FirestoreClient({ + universeDomain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + + it('sets apiEndpoint according to universe domain snakeCase', () => { + const client = new firestoreModule.FirestoreClient({ + universe_domain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + it('does not allow setting both universeDomain and universe_domain', () => { + assert.throws(() => { + new firestoreModule.FirestoreClient({ + universe_domain: 'example.com', + universeDomain: 'example.net', + }); + }); }); it('has port', () => { @@ -1421,11 +1467,7 @@ describe('v1.FirestoreClient', () => { const expectedError = new Error('The client has already been closed.'); client.close(); const stream = client.batchGetDocuments(request, { - retry: { - shouldRetryFn: () => { - return false; - }, - }, + retryRequestOptions: {noResponseRetries: 0}, }); const promise = new Promise((resolve, reject) => { stream.on( @@ -1546,11 +1588,7 @@ describe('v1.FirestoreClient', () => { const expectedError = new Error('The client has already been closed.'); client.close(); const stream = client.runQuery(request, { - retry: { - shouldRetryFn: () => { - return false; - }, - }, + retryRequestOptions: {noResponseRetries: 0}, }); const promise = new Promise((resolve, reject) => { stream.on( @@ -1676,11 +1714,7 @@ describe('v1.FirestoreClient', () => { const expectedError = new Error('The client has already been closed.'); client.close(); const stream = client.runAggregationQuery(request, { - retry: { - shouldRetryFn: () => { - return false; - }, - }, + retryRequestOptions: {noResponseRetries: 0}, }); const promise = new Promise((resolve, reject) => { stream.on( diff --git a/dev/test/gapic_firestore_v1beta1.ts b/dev/test/gapic_firestore_v1beta1.ts index 6e6668011..65b3c62b4 100644 --- a/dev/test/gapic_firestore_v1beta1.ts +++ b/dev/test/gapic_firestore_v1beta1.ts @@ -164,14 +164,60 @@ function stubAsyncIterationCall( describe('v1beta1.FirestoreClient', () => { describe('Common methods', () => { - it('has servicePath', () => { - const servicePath = firestoreModule.FirestoreClient.servicePath; - assert(servicePath); + it('has apiEndpoint', () => { + const client = new firestoreModule.FirestoreClient(); + const apiEndpoint = client.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); }); - it('has apiEndpoint', () => { - const apiEndpoint = firestoreModule.FirestoreClient.apiEndpoint; - assert(apiEndpoint); + it('has universeDomain', () => { + const client = new firestoreModule.FirestoreClient(); + const universeDomain = client.universeDomain; + assert.strictEqual(universeDomain, 'googleapis.com'); + }); + + if ( + typeof process !== 'undefined' && + typeof process.emitWarning === 'function' + ) { + it('throws DeprecationWarning if static servicePath is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const servicePath = firestoreModule.FirestoreClient.servicePath; + assert.strictEqual(servicePath, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + + it('throws DeprecationWarning if static apiEndpoint is used', () => { + const stub = sinon.stub(process, 'emitWarning'); + const apiEndpoint = firestoreModule.FirestoreClient.apiEndpoint; + assert.strictEqual(apiEndpoint, 'firestore.googleapis.com'); + assert(stub.called); + stub.restore(); + }); + } + it('sets apiEndpoint according to universe domain camelCase', () => { + const client = new firestoreModule.FirestoreClient({ + universeDomain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + + it('sets apiEndpoint according to universe domain snakeCase', () => { + const client = new firestoreModule.FirestoreClient({ + universe_domain: 'example.com', + }); + const servicePath = client.apiEndpoint; + assert.strictEqual(servicePath, 'firestore.example.com'); + }); + it('does not allow setting both universeDomain and universe_domain', () => { + assert.throws(() => { + new firestoreModule.FirestoreClient({ + universe_domain: 'example.com', + universeDomain: 'example.net', + }); + }); }); it('has port', () => { @@ -1427,11 +1473,7 @@ describe('v1beta1.FirestoreClient', () => { const expectedError = new Error('The client has already been closed.'); client.close(); const stream = client.batchGetDocuments(request, { - retry: { - shouldRetryFn: () => { - return false; - }, - }, + retryRequestOptions: {noResponseRetries: 0}, }); const promise = new Promise((resolve, reject) => { stream.on( @@ -1554,11 +1596,7 @@ describe('v1beta1.FirestoreClient', () => { const expectedError = new Error('The client has already been closed.'); client.close(); const stream = client.runQuery(request, { - retry: { - shouldRetryFn: () => { - return false; - }, - }, + retryRequestOptions: {noResponseRetries: 0}, }); const promise = new Promise((resolve, reject) => { stream.on(