diff --git a/packages/serverless/package.json b/packages/serverless/package.json index 6d2035e0ae43..c8254cc1b893 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -23,12 +23,16 @@ "tslib": "^1.9.3" }, "devDependencies": { + "@google-cloud/common": "^3.4.1", + "@google-cloud/pubsub": "^2.5.0", + "@google-cloud/bigquery": "^5.3.0", "@google-cloud/functions-framework": "^1.7.1", "@sentry-internal/eslint-config-sdk": "5.26.0", "@types/aws-lambda": "^8.10.62", "@types/node": "^14.6.4", "aws-sdk": "^2.765.0", "eslint": "7.6.0", + "google-gax": "^2.9.0", "jest": "^24.7.1", "nock": "^13.0.4", "npm-run-all": "^4.1.2", diff --git a/packages/serverless/src/awsservices.ts b/packages/serverless/src/awsservices.ts index 5c94aa22874b..3c0500755178 100644 --- a/packages/serverless/src/awsservices.ts +++ b/packages/serverless/src/awsservices.ts @@ -50,7 +50,7 @@ export class AWSServices implements Integration { if (transaction) { span = transaction.startChild({ description: describe(this, operation, params), - op: 'request', + op: 'aws.request', }); } }); diff --git a/packages/serverless/src/gcpfunction/index.ts b/packages/serverless/src/gcpfunction/index.ts index 5672f0336a18..4ced152a1d68 100644 --- a/packages/serverless/src/gcpfunction/index.ts +++ b/packages/serverless/src/gcpfunction/index.ts @@ -1,4 +1,8 @@ import * as Sentry from '@sentry/node'; +import { Integration } from '@sentry/types'; + +import { GoogleCloudGrpc } from '../google-cloud-grpc'; +import { GoogleCloudHttp } from '../google-cloud-http'; import { serverlessEventProcessor } from '../utils'; @@ -6,10 +10,19 @@ export * from './http'; export * from './events'; export * from './cloud_events'; +export const defaultIntegrations: Integration[] = [ + ...Sentry.defaultIntegrations, + new GoogleCloudHttp({ optional: true }), // We mark this integration optional since '@google-cloud/common' module could be missing. + new GoogleCloudGrpc({ optional: true }), // We mark this integration optional since 'google-gax' module could be missing. +]; + /** * @see {@link Sentry.init} */ export function init(options: Sentry.NodeOptions = {}): void { + if (options.defaultIntegrations === undefined) { + options.defaultIntegrations = defaultIntegrations; + } Sentry.init(options); Sentry.addGlobalEventProcessor(serverlessEventProcessor('GCPFunction')); } diff --git a/packages/serverless/src/google-cloud-grpc.ts b/packages/serverless/src/google-cloud-grpc.ts new file mode 100644 index 000000000000..62d2674dc8e2 --- /dev/null +++ b/packages/serverless/src/google-cloud-grpc.ts @@ -0,0 +1,132 @@ +import { getCurrentHub } from '@sentry/node'; +import { Integration, Span, Transaction } from '@sentry/types'; +import { fill } from '@sentry/utils'; +import { EventEmitter } from 'events'; + +interface GrpcFunction extends CallableFunction { + (...args: unknown[]): EventEmitter; +} + +interface GrpcFunctionObject extends GrpcFunction { + requestStream: boolean; + responseStream: boolean; + originalName: string; +} + +interface StubOptions { + servicePath?: string; +} + +interface CreateStubFunc extends CallableFunction { + (createStub: unknown, options: StubOptions): PromiseLike; +} + +interface Stub { + [key: string]: GrpcFunctionObject; +} + +/** Google Cloud Platform service requests tracking for GRPC APIs */ +export class GoogleCloudGrpc implements Integration { + /** + * @inheritDoc + */ + public static id: string = 'GoogleCloudGrpc'; + + /** + * @inheritDoc + */ + public name: string = GoogleCloudGrpc.id; + + private readonly _optional: boolean; + + public constructor(options: { optional?: boolean } = {}) { + this._optional = options.optional || false; + } + + /** + * @inheritDoc + */ + public setupOnce(): void { + try { + const gaxModule = require('google-gax'); + fill( + gaxModule.GrpcClient.prototype, // eslint-disable-line @typescript-eslint/no-unsafe-member-access + 'createStub', + wrapCreateStub, + ); + } catch (e) { + if (!this._optional) { + throw e; + } + } + } +} + +/** Returns a wrapped function that returns a stub with tracing enabled */ +function wrapCreateStub(origCreate: CreateStubFunc): CreateStubFunc { + return async function(this: unknown, ...args: Parameters) { + const servicePath = args[1]?.servicePath; + if (servicePath == null || servicePath == undefined) { + return origCreate.apply(this, args); + } + const serviceIdentifier = identifyService(servicePath); + const stub = await origCreate.apply(this, args); + for (const methodName of Object.keys(Object.getPrototypeOf(stub))) { + fillGrpcFunction(stub, serviceIdentifier, methodName); + } + return stub; + }; +} + +/** Patches the function in grpc stub to enable tracing */ +function fillGrpcFunction(stub: Stub, serviceIdentifier: string, methodName: string): void { + const funcObj = stub[methodName]; + if (typeof funcObj !== 'function') { + return; + } + const callType = + !funcObj.requestStream && !funcObj.responseStream + ? 'unary call' + : funcObj.requestStream && !funcObj.responseStream + ? 'client stream' + : !funcObj.requestStream && funcObj.responseStream + ? 'server stream' + : 'bidi stream'; + if (callType != 'unary call') { + return; + } + fill( + stub, + methodName, + (orig: GrpcFunction): GrpcFunction => (...args) => { + const ret = orig.apply(stub, args); + if (typeof ret?.on !== 'function') { + return ret; + } + let transaction: Transaction | undefined; + let span: Span | undefined; + const scope = getCurrentHub().getScope(); + if (scope) { + transaction = scope.getTransaction(); + } + if (transaction) { + span = transaction.startChild({ + description: `${callType} ${methodName}`, + op: `gcloud.grpc.${serviceIdentifier}`, + }); + } + ret.on('status', () => { + if (span) { + span.finish(); + } + }); + return ret; + }, + ); +} + +/** Identifies service by its address */ +function identifyService(servicePath: string): string { + const match = servicePath.match(/^(\w+)\.googleapis.com$/); + return match ? match[1] : servicePath; +} diff --git a/packages/serverless/src/google-cloud-http.ts b/packages/serverless/src/google-cloud-http.ts new file mode 100644 index 000000000000..eacb6ce19cb5 --- /dev/null +++ b/packages/serverless/src/google-cloud-http.ts @@ -0,0 +1,77 @@ +// '@google-cloud/common' import is expected to be type-only so it's erased in the final .js file. +// When TypeScript compiler is upgraded, use `import type` syntax to explicitly assert that we don't want to load a module here. +import * as common from '@google-cloud/common'; +import { getCurrentHub } from '@sentry/node'; +import { Integration, Span, Transaction } from '@sentry/types'; +import { fill } from '@sentry/utils'; + +type RequestOptions = common.DecorateRequestOptions; +type ResponseCallback = common.BodyResponseCallback; +// This interace could be replaced with just type alias once the `strictBindCallApply` mode is enabled. +interface RequestFunction extends CallableFunction { + (reqOpts: RequestOptions, callback: ResponseCallback): void; +} + +/** Google Cloud Platform service requests tracking for RESTful APIs */ +export class GoogleCloudHttp implements Integration { + /** + * @inheritDoc + */ + public static id: string = 'GoogleCloudHttp'; + + /** + * @inheritDoc + */ + public name: string = GoogleCloudHttp.id; + + private readonly _optional: boolean; + + public constructor(options: { optional?: boolean } = {}) { + this._optional = options.optional || false; + } + + /** + * @inheritDoc + */ + public setupOnce(): void { + try { + const commonModule = require('@google-cloud/common') as typeof common; + fill(commonModule.Service.prototype, 'request', wrapRequestFunction); + } catch (e) { + if (!this._optional) { + throw e; + } + } + } +} + +/** Returns a wrapped function that makes a request with tracing enabled */ +function wrapRequestFunction(orig: RequestFunction): RequestFunction { + return function(this: common.Service, reqOpts: RequestOptions, callback: ResponseCallback): void { + let transaction: Transaction | undefined; + let span: Span | undefined; + const scope = getCurrentHub().getScope(); + if (scope) { + transaction = scope.getTransaction(); + } + if (transaction) { + const httpMethod = reqOpts.method || 'GET'; + span = transaction.startChild({ + description: `${httpMethod} ${reqOpts.uri}`, + op: `gcloud.http.${identifyService(this.apiEndpoint)}`, + }); + } + orig.call(this, reqOpts, (...args: Parameters) => { + if (span) { + span.finish(); + } + callback(...args); + }); + }; +} + +/** Identifies service by its base url */ +function identifyService(apiEndpoint: string): string { + const match = apiEndpoint.match(/^https:\/\/(\w+)\.googleapis.com$/); + return match ? match[1] : apiEndpoint.replace(/^(http|https)?:\/\//, ''); +} diff --git a/packages/serverless/test/__mocks__/dns.ts b/packages/serverless/test/__mocks__/dns.ts new file mode 100644 index 000000000000..d03aa8d3f84b --- /dev/null +++ b/packages/serverless/test/__mocks__/dns.ts @@ -0,0 +1,2 @@ +export const lookup = jest.fn(); +export const resolveTxt = jest.fn(); diff --git a/packages/serverless/test/awsservices.test.ts b/packages/serverless/test/awsservices.test.ts index 8cc3728b2f52..917feac2b104 100644 --- a/packages/serverless/test/awsservices.test.ts +++ b/packages/serverless/test/awsservices.test.ts @@ -33,7 +33,10 @@ describe('AWSServices', () => { const data = await s3.getObject({ Bucket: 'foo', Key: 'bar' }).promise(); expect(data.Body?.toString('utf-8')).toEqual('contents'); // @ts-ignore see "Why @ts-ignore" note - expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ op: 'request', description: 'aws.s3.getObject foo' }); + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'aws.request', + description: 'aws.s3.getObject foo', + }); // @ts-ignore see "Why @ts-ignore" note expect(Sentry.fakeSpan.finish).toBeCalled(); }); @@ -49,7 +52,10 @@ describe('AWSServices', () => { done(); }); // @ts-ignore see "Why @ts-ignore" note - expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ op: 'request', description: 'aws.s3.getObject foo' }); + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'aws.request', + description: 'aws.s3.getObject foo', + }); }); }); @@ -63,7 +69,10 @@ describe('AWSServices', () => { const data = await lambda.invoke({ FunctionName: 'foo' }).promise(); expect(data.Payload?.toString('utf-8')).toEqual('reply'); // @ts-ignore see "Why @ts-ignore" note - expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ op: 'request', description: 'aws.lambda.invoke foo' }); + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'aws.request', + description: 'aws.lambda.invoke foo', + }); }); }); }); diff --git a/packages/serverless/test/google-cloud-grpc.test.ts b/packages/serverless/test/google-cloud-grpc.test.ts new file mode 100644 index 000000000000..42c5470e172d --- /dev/null +++ b/packages/serverless/test/google-cloud-grpc.test.ts @@ -0,0 +1,139 @@ +jest.mock('dns'); + +import { PubSub } from '@google-cloud/pubsub'; +import * as dns from 'dns'; +import { EventEmitter } from 'events'; +import * as fs from 'fs'; +import * as http2 from 'http2'; +import * as nock from 'nock'; +import * as path from 'path'; + +import * as Sentry from '../src'; +import { GoogleCloudGrpc } from '../src/google-cloud-grpc'; + +/** + * Why @ts-ignore some Sentry.X calls + * + * A hack-ish way to contain everything related to mocks in the same __mocks__ file. + * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. + */ + +const spyConnect = jest.spyOn(http2, 'connect'); + +/** Fake HTTP2 stream */ +class FakeStream extends EventEmitter { + public rstCode: number = 0; + close() { + this.emit('end'); + this.emit('close'); + } + end() {} + pause() {} + resume() {} + write(_data: Buffer, cb: CallableFunction) { + process.nextTick(cb, null); + } +} + +/** Fake HTTP2 session for GRPC */ +class FakeSession extends EventEmitter { + public socket: EventEmitter = new EventEmitter(); + public request: jest.Mock = jest.fn(); + ping() {} + mockRequest(fn: (stream: FakeStream) => void): FakeStream { + const stream = new FakeStream(); + this.request.mockImplementationOnce(() => { + process.nextTick(fn, stream); + return stream; + }); + return stream; + } + mockUnaryRequest(responseData: Buffer) { + this.mockRequest(stream => { + stream.emit( + 'response', + { ':status': 200, 'content-type': 'application/grpc', 'content-disposition': 'attachment' }, + 4, + ); + stream.emit('data', responseData); + stream.emit('trailers', { 'grpc-status': '0', 'content-disposition': 'attachment' }); + }); + } + close() { + this.emit('close'); + this.socket.emit('close'); + } + ref() {} + unref() {} +} + +function mockHttp2Session(): FakeSession { + const session = new FakeSession(); + spyConnect.mockImplementationOnce(() => { + process.nextTick(() => session.emit('connect')); + return (session as unknown) as http2.ClientHttp2Session; + }); + return session; +} + +describe('GoogleCloudGrpc', () => { + beforeAll(() => { + new GoogleCloudGrpc().setupOnce(); + }); + + beforeEach(() => { + nock('https://www.googleapis.com') + .post('/oauth2/v4/token') + .reply(200, []); + }); + afterEach(() => { + // @ts-ignore see "Why @ts-ignore" note + Sentry.resetMocks(); + spyConnect.mockClear(); + }); + afterAll(() => { + nock.restore(); + spyConnect.mockRestore(); + }); + + // We use google cloud pubsub as an example of grpc service for which we can trace requests. + describe('pubsub', () => { + // @ts-ignore see "Why @ts-ignore" note + const dnsLookup = dns.lookup as jest.Mock; + // @ts-ignore see "Why @ts-ignore" note + const resolveTxt = dns.resolveTxt as jest.Mock; + dnsLookup.mockImplementation((hostname, ...args) => { + expect(hostname).toEqual('pubsub.googleapis.com'); + process.nextTick(args[args.length - 1], null, [{ address: '0.0.0.0', family: 4 }]); + }); + resolveTxt.mockImplementation((hostname, cb) => { + expect(hostname).toEqual('pubsub.googleapis.com'); + process.nextTick(cb, null, []); + }); + + const pubsub = new PubSub({ + credentials: { + client_email: 'client@email', + private_key: fs.readFileSync(path.resolve(__dirname, 'private.pem')).toString(), + }, + projectId: 'project-id', + }); + + afterEach(() => { + dnsLookup.mockReset(); + resolveTxt.mockReset(); + }); + + test('publish', async () => { + mockHttp2Session().mockUnaryRequest(Buffer.from('00000000120a1031363337303834313536363233383630', 'hex')); + const resp = await pubsub.topic('nicetopic').publish(Buffer.from('data')); + expect(resp).toEqual('1637084156623860'); + // @ts-ignore see "Why @ts-ignore" note + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'gcloud.grpc.pubsub', + description: 'unary call publish', + }); + await pubsub.close(); + }); + }); +}); diff --git a/packages/serverless/test/google-cloud-http.test.ts b/packages/serverless/test/google-cloud-http.test.ts new file mode 100644 index 000000000000..c58513756f5a --- /dev/null +++ b/packages/serverless/test/google-cloud-http.test.ts @@ -0,0 +1,71 @@ +import { BigQuery } from '@google-cloud/bigquery'; +import * as fs from 'fs'; +import * as nock from 'nock'; +import * as path from 'path'; + +import * as Sentry from '../src'; +import { GoogleCloudHttp } from '../src/google-cloud-http'; + +/** + * Why @ts-ignore some Sentry.X calls + * + * A hack-ish way to contain everything related to mocks in the same __mocks__ file. + * Thanks to this, we don't have to do more magic than necessary. Just add and export desired method and assert on it. + */ + +describe('GoogleCloudHttp', () => { + beforeAll(() => { + new GoogleCloudHttp().setupOnce(); + }); + beforeEach(() => { + nock('https://www.googleapis.com') + .post('/oauth2/v4/token') + .reply(200, '{"access_token":"a.b.c","expires_in":3599,"token_type":"Bearer"}'); + }); + afterEach(() => { + // @ts-ignore see "Why @ts-ignore" note + Sentry.resetMocks(); + }); + afterAll(() => { + nock.restore(); + }); + + // We use google cloud bigquery as an example of http restful service for which we can trace requests. + describe('bigquery', () => { + const bigquery = new BigQuery({ + credentials: { + client_email: 'client@email', + private_key: fs.readFileSync(path.resolve(__dirname, 'private.pem')).toString(), + }, + projectId: 'project-id', + }); + + test('query', async () => { + nock('https://bigquery.googleapis.com') + .post('/bigquery/v2/projects/project-id/jobs') + .query(true) + .reply( + 200, + '{"kind":"bigquery#job","configuration":{"query":{"query":"SELECT true AS foo","destinationTable":{"projectId":"project-id","datasetId":"_7b1eed9bef45ab5fb7345c3d6f662cd767e5ab3e","tableId":"anon101ee25adad33d4f09179679ae9144ad436a210e"},"writeDisposition":"WRITE_TRUNCATE","priority":"INTERACTIVE","useLegacySql":false},"jobType":"QUERY"},"jobReference":{"projectId":"project-id","jobId":"8874c5d5-9cfe-4daa-8390-b0504b97b429","location":"US"},"statistics":{"creationTime":"1603072686488","startTime":"1603072686756","query":{"statementType":"SELECT"}},"status":{"state":"RUNNING"}}', + ); + nock('https://bigquery.googleapis.com') + .get(new RegExp('^/bigquery/v2/projects/project-id/queries/.+$')) + .query(true) + .reply( + 200, + '{"kind":"bigquery#getQueryResultsResponse","etag":"0+ToZZTzCJ4lyhNI3v4rGg==","schema":{"fields":[{"name":"foo","type":"BOOLEAN","mode":"NULLABLE"}]},"jobReference":{"projectId":"project-id","jobId":"8874c5d5-9cfe-4daa-8390-b0504b97b429","location":"US"},"totalRows":"1","rows":[{"f":[{"v":"true"}]}],"totalBytesProcessed":"0","jobComplete":true,"cacheHit":false}', + ); + const resp = await bigquery.query(`SELECT true AS foo`); + expect(resp).toEqual([[{ foo: true }]]); + // @ts-ignore see "Why @ts-ignore" note + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'gcloud.http.bigquery', + description: 'POST /jobs', + }); + expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ + op: 'gcloud.http.bigquery', + description: expect.stringMatching(new RegExp('^GET /queries/.+')), + }); + }); + }); +}); diff --git a/packages/serverless/test/private.pem b/packages/serverless/test/private.pem new file mode 100644 index 000000000000..00a658fe7a7f --- /dev/null +++ b/packages/serverless/test/private.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDzU+jLTzW6154Joezxrd2+5pCNYP0HcaMoYqEyXfNRpkNE7wrQ +UEG830o4Qcaae2BhqZoujwSW7RkR6h0Fkd0WTR8h5J8rSGNHv/1jJoUUjP9iZ/5S +FAyIIyEYfDPqtnA4iF1QWO2lXWlEFSuZjwM/8jBmeGzoiw17akNThIw8NwIDAQAB +AoGATpboVloEAY/IdFX/QGOmfhTb1T3hG3lheBa695iOkO2BRo9qT7PMN6NqxlbA +PX7ht0lfCfCZS+HSOg4CR50/6WXHMSmwlvcjGuDIDKWjviQTTYE77MlVBQHw9WzY +PfiRBbtouyPGQtO4rk42zkIILC6exBZ1vKpRPOmTAnxrjCECQQD+56r6hYcS6GNp +NOWyv0eVFMBX4iNWAsRf9JVVvGDz2rVuhnkNiN73vfffDWvSXkCydL1jFmalgdQD +gm77UZQHAkEA9F+CauU0aZsJ1SthQ6H0sDQ+eNRUgnz4itnkSC2C20fZ3DaSpCMC +0go81CcZOhftNO730ILqiS67C3d3rqLqUQJBAP10ROHMmz4Fq7MUUcClyPtHIuk/ +hXskTTZL76DMKmrN8NDxDLSUf38+eJRkt+z4osPOp/E6eN3gdXr32nox50kCQCl8 +hXGMU+eR0IuF/88xkY7Qb8KnmWlFuhQohZ7TSyHbAttl0GNZJkNuRYFm2duI8FZK +M3wMnbCIZGy/7WuScOECQQCV+0yrf5dL1M2GHjJfwuTb00wRKalKQEH1v/kvE5vS +FmdN7BPK5Ra50MaecMNoYqu9rmtyWRBn93dcvKrL57nY +-----END RSA PRIVATE KEY----- diff --git a/yarn.lock b/yarn.lock index 412b124f1ad1..cf8b0e9ee12a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1528,6 +1528,23 @@ "@glimmer/interfaces" "^0.42.2" "@glimmer/util" "^0.42.2" +"@google-cloud/bigquery@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@google-cloud/bigquery/-/bigquery-5.3.0.tgz#87db58ed6538d0be5dd146901ffd636d6b9fead0" + integrity sha512-IxHd7dWJygQgExdnwS7D8zMswe3VG5akKSLTkdl5ky1Xn6VHiXg30c8zK99jqRafA7kU023W/+L9F9zIQp1qiA== + dependencies: + "@google-cloud/common" "^3.1.0" + "@google-cloud/paginator" "^3.0.0" + "@google-cloud/promisify" "^2.0.0" + arrify "^2.0.1" + big.js "^5.2.2" + duplexify "^4.0.0" + extend "^3.0.2" + is "^3.3.0" + p-event "^4.1.0" + stream-events "^1.0.5" + uuid "^8.0.0" + "@google-cloud/common@^0.32.0": version "0.32.1" resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.32.1.tgz#6a32c340172cea3db6674d0e0e34e78740a0073f" @@ -1545,6 +1562,21 @@ retry-request "^4.0.0" teeny-request "^3.11.3" +"@google-cloud/common@^3.1.0", "@google-cloud/common@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-3.4.1.tgz#a1920d73c38437923b4b134e245c392d36c442e9" + integrity sha512-e5z0CwsM0RXky+PnyPtQ3QK46ksqm+kE7kX8pm8X+ddBwZJipHchKeazMM5fLlGCS+AALalzXb+uYmH72TRnpQ== + dependencies: + "@google-cloud/projectify" "^2.0.0" + "@google-cloud/promisify" "^2.0.0" + arrify "^2.0.1" + duplexify "^4.1.1" + ent "^2.2.0" + extend "^3.0.2" + google-auth-library "^6.1.1" + retry-request "^4.1.1" + teeny-request "^7.0.0" + "@google-cloud/functions-framework@^1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@google-cloud/functions-framework/-/functions-framework-1.7.1.tgz#d29a27744a6eb2f95d840b86135b97b0d804a49e" @@ -1565,16 +1597,60 @@ split-array-stream "^2.0.0" stream-events "^1.0.4" +"@google-cloud/paginator@^3.0.0": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-3.0.5.tgz#9d6b96c421a89bd560c1bc2c197c7611ef21db6c" + integrity sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw== + dependencies: + arrify "^2.0.0" + extend "^3.0.2" + +"@google-cloud/precise-date@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@google-cloud/precise-date/-/precise-date-2.0.3.tgz#14f6f28ce35dabf3882e7aeab1c9d51bd473faed" + integrity sha512-+SDJ3ZvGkF7hzo6BGa8ZqeK3F6Z4+S+KviC9oOK+XCs3tfMyJCh/4j93XIWINgMMDIh9BgEvlw4306VxlXIlYA== + "@google-cloud/projectify@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-0.3.3.tgz#bde9103d50b20a3ea3337df8c6783a766e70d41d" integrity sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw== +"@google-cloud/projectify@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@google-cloud/projectify/-/projectify-2.0.1.tgz#13350ee609346435c795bbfe133a08dfeab78d65" + integrity sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ== + "@google-cloud/promisify@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-0.4.0.tgz#4fbfcf4d85bb6a2e4ccf05aa63d2b10d6c9aad9b" integrity sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q== +"@google-cloud/promisify@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-2.0.3.tgz#f934b5cdc939e3c7039ff62b9caaf59a9d89e3a8" + integrity sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw== + +"@google-cloud/pubsub@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@google-cloud/pubsub/-/pubsub-2.5.0.tgz#6c696d9b448f2e1689be9a37ef0362ed173731fd" + integrity sha512-7bbbQqa+LSTopVjt20EZ8maO6rEpbO7v8EvDImHMsbRS30HJ5+kClbaQTRvhNzhc1qy221A1GbHPHMCQ/U5E3Q== + dependencies: + "@google-cloud/paginator" "^3.0.0" + "@google-cloud/precise-date" "^2.0.0" + "@google-cloud/projectify" "^2.0.0" + "@google-cloud/promisify" "^2.0.0" + "@opentelemetry/api" "^0.10.0" + "@opentelemetry/tracing" "^0.10.0" + "@types/duplexify" "^3.6.0" + "@types/long" "^4.0.0" + arrify "^2.0.0" + extend "^3.0.2" + google-auth-library "^6.0.0" + google-gax "^2.7.0" + is-stream-ended "^0.1.4" + lodash.snakecase "^4.1.1" + p-defer "^3.0.0" + "@google-cloud/storage@^2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-2.5.0.tgz#9dd3566d8155cf5ba0c212208f69f9ecd47fbd7e" @@ -1602,6 +1678,35 @@ through2 "^3.0.0" xdg-basedir "^3.0.0" +"@grpc/grpc-js@~1.1.1": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.1.7.tgz#d3d71c6da95397e2d63895ccc4a05e7572f7b7e6" + integrity sha512-EuxMstI0u778dp0nk6Fe3gHXYPeV6FYsWOe0/QFwxv1NQ6bc5Wl/0Yxa4xl9uBlKElL6AIxuASmSfu7KEJhqiw== + dependencies: + "@grpc/proto-loader" "^0.6.0-pre14" + "@types/node" "^12.12.47" + google-auth-library "^6.0.0" + semver "^6.2.0" + +"@grpc/proto-loader@^0.5.1": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.5.5.tgz#6725e7a1827bdf8e92e29fbf4e9ef0203c0906a9" + integrity sha512-WwN9jVNdHRQoOBo9FDH7qU+mgfjPc8GygPYms3M+y3fbQLfnCe/Kv/E01t7JRgnrsOHH8euvSbed3mIalXhwqQ== + dependencies: + lodash.camelcase "^4.3.0" + protobufjs "^6.8.6" + +"@grpc/proto-loader@^0.6.0-pre14": + version "0.6.0-pre9" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.0-pre9.tgz#0c6fe42f6c5ef9ce1b3cef7be64d5b09d6fe4d6d" + integrity sha512-oM+LjpEjNzW5pNJjt4/hq1HYayNeQT+eGrOPABJnYHv7TyNPDNzkQ76rDYZF86X5swJOa4EujEMzQ9iiTdPgww== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^6.9.0" + yargs "^15.3.1" + "@jest/console@^24.7.1", "@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" @@ -2525,6 +2630,99 @@ dependencies: "@types/node" ">= 8" +"@opentelemetry/api@^0.10.0", "@opentelemetry/api@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.10.2.tgz#9647b881f3e1654089ff7ea59d587b2d35060654" + integrity sha512-GtpMGd6vkzDMYcpu2t9LlhEgMy/SzBwRnz48EejlRArYqZzqSzAsKmegUK7zHgl+EOIaK9mKHhnRaQu3qw20cA== + dependencies: + "@opentelemetry/context-base" "^0.10.2" + +"@opentelemetry/context-base@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.10.2.tgz#55bea904b2b91aa8a8675df9eaba5961bddb1def" + integrity sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw== + +"@opentelemetry/core@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-0.10.2.tgz#86b9e94bbcaf8e07bb86e8205aa1d53af854e7de" + integrity sha512-DhkiTp5eje2zTGd+HAIKWpGE6IR6lq7tUpYt4nnkhOi6Hq9WQAANVDCWEZEbYOw57LkdXbE50FZ/kMvHDm450Q== + dependencies: + "@opentelemetry/api" "^0.10.2" + "@opentelemetry/context-base" "^0.10.2" + semver "^7.1.3" + +"@opentelemetry/resources@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-0.10.2.tgz#6e291d525450359c615aac013fd977047f2c26d7" + integrity sha512-5JGC2TPSAIHth615IURt+sSsTljY43zTfJD0JE9PHC6ipZPiQ0dpQDZOrLn8NAMfOHY1jeWwpIuLASjqbXUfuw== + dependencies: + "@opentelemetry/api" "^0.10.2" + "@opentelemetry/core" "^0.10.2" + gcp-metadata "^3.5.0" + +"@opentelemetry/tracing@^0.10.0": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/tracing/-/tracing-0.10.2.tgz#384779a6e1be988200cc316a97030d95bd8f2129" + integrity sha512-mNAhARn4dEdOjTa9OdysjI4fRHMbvr4YSbPuH7jhkyPzgoa+DnvnbY3GGpEay6kpuYJsrW8Ef9OIKAV/GndhbQ== + dependencies: + "@opentelemetry/api" "^0.10.2" + "@opentelemetry/context-base" "^0.10.2" + "@opentelemetry/core" "^0.10.2" + "@opentelemetry/resources" "^0.10.2" + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + "@simple-dom/interface@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" @@ -2749,6 +2947,13 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.2.tgz#453f4b14b25da6a8ea4494842dedcbf0151deef9" integrity sha512-aHQA072E10/8iUQsPH7mQU/KUyQBZAGzTVRCUvnSz8mSvbrYsP4xEO2RSA0Pjltolzi0j8+8ixrm//Hr4umPzw== +"@types/duplexify@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@types/duplexify/-/duplexify-3.6.0.tgz#dfc82b64bd3a2168f5bd26444af165bf0237dcd8" + integrity sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A== + dependencies: + "@types/node" "*" + "@types/ember-qunit@^3.4.9": version "3.4.9" resolved "https://registry.yarnpkg.com/@types/ember-qunit/-/ember-qunit-3.4.9.tgz#df08d29609f906a081dc8f1c0e00b390fec3b4d7" @@ -3063,6 +3268,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/long@^4.0.0", "@types/long@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + "@types/lru-cache@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" @@ -3105,6 +3315,16 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.15.18.tgz#b92ad2f5ef31a2b8a432f15db68265013d9f43db" integrity sha512-3p2M6moxwdDFyPia2ROI8CCkRa9ZzYjvCys2TOE1xgwYDQmY49Cj0cvkdBkzh/rY9gkvzgzYOeECYtB4f0/fDA== +"@types/node@^12.12.47": + version "12.12.67" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.67.tgz#4f86badb292e822e3b13730a1f9713ed2377f789" + integrity sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg== + +"@types/node@^13.7.0": + version "13.13.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.25.tgz#768d6712b15099a744812a92b84ffde8f4e13cf1" + integrity sha512-6ZMK4xRcF2XrPdKmPYQxZkdHKV18xKgUFVvhIgw2iwaaO6weleLPHLBGPZmLhjo+m1N+MZXRAoBEBCCVqgO2zQ== + "@types/node@^14.6.4": version "14.6.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.4.tgz#a145cc0bb14ef9c4777361b7bbafa5cf8e3acb5a" @@ -7709,6 +7929,16 @@ duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +duplexify@^4.0.0, duplexify@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.1.tgz#7027dc374f157b122a8ae08c2d3ea4d2d953aa61" + integrity sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -7717,7 +7947,7 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: +ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== @@ -8523,7 +8753,7 @@ encoding@^0.1.11: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -9879,6 +10109,28 @@ gaxios@^1.0.2, gaxios@^1.0.4, gaxios@^1.2.1, gaxios@^1.5.0: https-proxy-agent "^2.2.1" node-fetch "^2.3.0" +gaxios@^2.1.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-2.3.4.tgz#eea99353f341c270c5f3c29fc46b8ead56f0a173" + integrity sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA== + dependencies: + abort-controller "^3.0.0" + extend "^3.0.2" + https-proxy-agent "^5.0.0" + is-stream "^2.0.0" + node-fetch "^2.3.0" + +gaxios@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-3.2.0.tgz#11b6f0e8fb08d94a10d4d58b044ad3bec6dd486a" + integrity sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q== + dependencies: + abort-controller "^3.0.0" + extend "^3.0.2" + https-proxy-agent "^5.0.0" + is-stream "^2.0.0" + node-fetch "^2.3.0" + gcp-metadata@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-1.0.0.tgz#5212440229fa099fc2f7c2a5cdcb95575e9b2ca6" @@ -9887,6 +10139,22 @@ gcp-metadata@^1.0.0: gaxios "^1.0.2" json-bigint "^0.3.0" +gcp-metadata@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-3.5.0.tgz#6d28343f65a6bbf8449886a0c0e4a71c77577055" + integrity sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA== + dependencies: + gaxios "^2.1.0" + json-bigint "^0.3.0" + +gcp-metadata@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.2.0.tgz#3b424355ccdc240ee07c5791e2fd6a60a283d89a" + integrity sha512-vQZD57cQkqIA6YPGXM/zc+PIZfNRFdukWGsGZ5+LcJzesi5xp6Gn7a02wRJi4eXPyArNMIYpPET4QMxGqtlk6Q== + dependencies: + gaxios "^3.0.0" + json-bigint "^1.0.0" + gcs-resumable-upload@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/gcs-resumable-upload/-/gcs-resumable-upload-1.1.0.tgz#2b06f5876dcf60f18a309343f79ed951aff01399" @@ -10236,6 +10504,37 @@ google-auth-library@^3.0.0, google-auth-library@^3.1.1: lru-cache "^5.0.0" semver "^5.5.0" +google-auth-library@^6.0.0, google-auth-library@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-6.1.1.tgz#e1882ac22e8a073dd7a7296e500d5c0c6dc21933" + integrity sha512-0WfExOx3FrLYnY88RICQxvpaNzdwjz44OsHqHkIoAJfjY6Jck6CZRl1ASWadk+wbJ0LhkQ8rNY4zZebKml4Ghg== + dependencies: + arrify "^2.0.0" + base64-js "^1.3.0" + ecdsa-sig-formatter "^1.0.11" + fast-text-encoding "^1.0.0" + gaxios "^3.0.0" + gcp-metadata "^4.1.0" + gtoken "^5.0.4" + jws "^4.0.0" + lru-cache "^6.0.0" + +google-gax@^2.7.0, google-gax@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-2.9.0.tgz#84edef8715d82c0f91a6e5485b8f2803d2690f00" + integrity sha512-MFMwA7Fb8PEwjnYwfGXjZMidCNyMl3gSnvS/+kS8TQioJZQDpzK+W3dmwyNyig/U13+kbABqDnbkkAXJ5NiUkw== + dependencies: + "@grpc/grpc-js" "~1.1.1" + "@grpc/proto-loader" "^0.5.1" + "@types/long" "^4.0.0" + abort-controller "^3.0.0" + duplexify "^4.0.0" + google-auth-library "^6.0.0" + is-stream-ended "^0.1.4" + node-fetch "^2.6.1" + protobufjs "^6.9.0" + retry-request "^4.0.0" + google-p12-pem@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-1.0.4.tgz#b77fb833a2eb9f7f3c689e2e54f095276f777605" @@ -10244,6 +10543,13 @@ google-p12-pem@^1.0.0: node-forge "^0.8.0" pify "^4.0.0" +google-p12-pem@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.0.3.tgz#673ac3a75d3903a87f05878f3c75e06fc151669e" + integrity sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA== + dependencies: + node-forge "^0.10.0" + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -10315,6 +10621,16 @@ gtoken@^2.3.2: mime "^2.2.0" pify "^4.0.0" +gtoken@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.0.4.tgz#e8d7456ad2ff774c70176e56b9d34b1c63fb6f0b" + integrity sha512-U9wnSp4GZ7ov6zRdPuRHG4TuqEWqRRgT1gfXGNArhzBUn9byrPeH8uTmBWU/ZiWJJvTEmkjhDIC3mqHWdVi3xQ== + dependencies: + gaxios "^3.0.0" + google-p12-pem "^3.0.3" + jws "^4.0.0" + mime "^2.2.0" + gud@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" @@ -11486,6 +11802,11 @@ is-wsl@^2.1.0: dependencies: is-docker "^2.0.0" +is@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79" + integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -12198,6 +12519,13 @@ json-bigint@^0.3.0: dependencies: bignumber.js "^9.0.0" +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" @@ -12319,6 +12647,15 @@ jwa@^1.4.1: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + jws@^3.1.5: version "3.2.2" resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" @@ -12327,6 +12664,14 @@ jws@^3.1.5: jwa "^1.4.1" safe-buffer "^5.0.1" +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + karma-browserstack-launcher@^1.5.1: version "1.6.0" resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz#2f6000647073e77ae296653b8830b279669766ef" @@ -12819,6 +13164,11 @@ lodash.assignin@^4.1.0: resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.castarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" @@ -12923,6 +13273,11 @@ lodash.set@^4.3.2: resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= +lodash.snakecase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -13000,6 +13355,11 @@ lolex@^5.0.1: dependencies: "@sinonjs/commons" "^1.7.0" +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -13824,11 +14184,16 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.2.0, node-fetch@^2.3.0, node-fetch@^2.6.0: +node-fetch@^2.2.0, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + node-forge@^0.8.0: version "0.8.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.8.5.tgz#57906f07614dc72762c84cef442f427c0e1b86ee" @@ -14394,6 +14759,13 @@ p-each-series@^1.0.0: dependencies: p-reduce "^1.0.0" +p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -14478,6 +14850,13 @@ p-timeout@^2.0.1: dependencies: p-finally "^1.0.0" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -15383,6 +15762,25 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +protobufjs@^6.8.6, protobufjs@^6.9.0: + version "6.10.1" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.1.tgz#e6a484dd8f04b29629e9053344e3970cccf13cd2" + integrity sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" "^13.7.0" + long "^4.0.0" + protocols@^1.1.0, protocols@^1.4.0: version "1.4.7" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32" @@ -16317,6 +16715,13 @@ retry-request@^4.0.0: debug "^4.1.1" through2 "^3.0.1" +retry-request@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-4.1.3.tgz#d5f74daf261372cff58d08b0a1979b4d7cab0fde" + integrity sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ== + dependencies: + debug "^4.1.1" + retry@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" @@ -16602,7 +17007,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.0.0, semver@^7.2.1, semver@^7.3.2: +semver@7.3.2, semver@^7.0.0, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -17714,6 +18119,17 @@ teeny-request@^3.11.3: node-fetch "^2.2.0" uuid "^3.3.2" +teeny-request@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.0.1.tgz#bdd41fdffea5f8fbc0d29392cb47bec4f66b2b4c" + integrity sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw== + dependencies: + http-proxy-agent "^4.0.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.1" + stream-events "^1.0.5" + uuid "^8.0.0" + temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" @@ -18588,6 +19004,11 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.0.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" + integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== + uuid@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" @@ -19318,7 +19739,7 @@ yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^15.0.2, yargs@^15.4.1: +yargs@^15.0.2, yargs@^15.3.1, yargs@^15.4.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==