Skip to content

Commit

Permalink
chore(deps): Internalize common (#1839)
Browse files Browse the repository at this point in the history
* chore(deps): internalize nodejs-common

* add common unit tests

* remove unused type dependency

* add common system tests

* format setUniformBucketLevelAccess function
  • Loading branch information
ddelgrosso1 authored Apr 1, 2022
1 parent 58903d6 commit 21cbce0
Show file tree
Hide file tree
Showing 32 changed files with 6,403 additions and 38 deletions.
2 changes: 1 addition & 1 deletion conformance-test/conformanceCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as libraryMethods from './libraryMethods';
import {Bucket, File, HmacKey, Notification, Storage} from '../src/';
import * as uuid from 'uuid';
import * as assert from 'assert';
import {DecorateRequestOptions} from '@google-cloud/common';
import {DecorateRequestOptions} from '../src/nodejs-common';
import fetch from 'node-fetch';

interface RetryCase {
Expand Down
2 changes: 1 addition & 1 deletion conformance-test/libraryMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import {Bucket, File, Notification, Storage, HmacKey} from '../src';
import * as path from 'path';
import {ApiError} from '@google-cloud/common';
import {ApiError} from '../src/nodejs-common';

/////////////////////////////////////////////////
//////////////////// BUCKET /////////////////////
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"precompile": "gts clean"
},
"dependencies": {
"@google-cloud/common": "^3.8.1",
"@google-cloud/paginator": "^3.0.7",
"@google-cloud/projectify": "^2.0.0",
"@google-cloud/promisify": "^2.0.0",
"abort-controller": "^3.0.0",
"arrify": "^2.0.0",
Expand All @@ -60,17 +60,20 @@
"configstore": "^5.0.0",
"date-and-time": "^2.0.0",
"duplexify": "^4.0.0",
"ent": "^2.2.0",
"extend": "^3.0.2",
"gaxios": "^4.0.0",
"get-stream": "^6.0.0",
"google-auth-library": "^7.0.0",
"google-auth-library": "^7.14.1",
"hash-stream-validation": "^0.2.2",
"mime": "^3.0.0",
"mime-types": "^2.0.8",
"p-limit": "^3.0.1",
"pumpify": "^2.0.0",
"retry-request": "^4.2.2",
"snakeize": "^0.1.0",
"stream-events": "^1.0.4",
"teeny-request": "^7.1.3",
"xdg-basedir": "^4.0.0"
},
"devDependencies": {
Expand All @@ -79,9 +82,9 @@
"@grpc/proto-loader": "^0.6.0",
"@types/async-retry": "^1.4.3",
"@types/compressible": "^2.0.0",
"@types/concat-stream": "^2.0.0",
"@types/configstore": "^5.0.0",
"@types/date-and-time": "^0.13.0",
"@types/ent": "^2.2.1",
"@types/extend": "^3.0.0",
"@types/mime": "^2.0.0",
"@types/mime-types": "^2.1.0",
Expand All @@ -91,6 +94,7 @@
"@types/node-fetch": "^2.1.3",
"@types/proxyquire": "^1.3.28",
"@types/pumpify": "^1.4.1",
"@types/request": "^2.48.4",
"@types/sinon": "^10.0.0",
"@types/tmp": "0.2.3",
"@types/uuid": "^8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
BodyResponseCallback,
DecorateRequestOptions,
Metadata,
} from '@google-cloud/common';
} from './nodejs-common';
import {promisifyAll} from '@google-cloud/promisify';
import arrify = require('arrify');

Expand Down
2 changes: 1 addition & 1 deletion src/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
ResponseBody,
ServiceObject,
util,
} from '@google-cloud/common';
} from './nodejs-common';
import {paginator} from '@google-cloud/paginator';
import {promisifyAll} from '@google-cloud/promisify';
import arrify = require('arrify');
Expand Down
2 changes: 1 addition & 1 deletion src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {Metadata, ServiceObject, util} from '@google-cloud/common';
import {Metadata, ServiceObject, util} from './nodejs-common';
import {promisifyAll} from '@google-cloud/promisify';

import {Storage} from './storage';
Expand Down
4 changes: 2 additions & 2 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
Metadata,
ServiceObject,
util,
} from '@google-cloud/common';
} from './nodejs-common';
import {promisifyAll} from '@google-cloud/promisify';

import compressible = require('compressible');
Expand Down Expand Up @@ -63,7 +63,7 @@ import {
ApiError,
Duplexify,
DuplexifyConstructor,
} from '@google-cloud/common/build/src/util';
} from './nodejs-common/util';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const duplexify: DuplexifyConstructor = require('duplexify');
import {normalize, objectKeyToLowercase, unicodeJSONStringify} from './util';
Expand Down
2 changes: 1 addition & 1 deletion src/hmacKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {Metadata, ServiceObject, Methods} from '@google-cloud/common';
import {Metadata, ServiceObject, Methods} from './nodejs-common';
import {Storage} from './storage';

export interface HmacKeyOptions {
Expand Down
2 changes: 1 addition & 1 deletion src/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
BodyResponseCallback,
DecorateRequestOptions,
Metadata,
} from '@google-cloud/common';
} from './nodejs-common';
import {promisifyAll} from '@google-cloud/promisify';
import arrify = require('arrify');

Expand Down
52 changes: 52 additions & 0 deletions src/nodejs-common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*!
* Copyright 2022 Google LLC. All Rights Reserved.
*
* 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.
*/
export {GoogleAuthOptions} from 'google-auth-library';

export {Operation} from './operation';

export {
Service,
ServiceConfig,
ServiceOptions,
StreamRequestOptions,
} from './service';

export {
DeleteCallback,
ExistsCallback,
GetConfig,
InstanceResponseCallback,
Interceptor,
Metadata,
MetadataCallback,
MetadataResponse,
Methods,
ResponseCallback,
ServiceObject,
ServiceObjectConfig,
ServiceObjectParent,
SetMetadataResponse,
} from './service-object';

export {
Abortable,
AbortableDuplex,
ApiError,
BodyResponseCallback,
DecorateRequestOptions,
ResponseBody,
util,
} from './util';
164 changes: 164 additions & 0 deletions src/nodejs-common/operation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*!
* Copyright 2022 Google LLC. All Rights Reserved.
*
* 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.
*/
import {
Metadata,
MetadataCallback,
ServiceObject,
ServiceObjectConfig,
} from './service-object';
import {ApiError} from './util';
import {promisify} from 'util';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class Operation<T = any> extends ServiceObject<T> {
completeListeners: number;
hasActiveListeners: boolean;

/**
* An Operation object allows you to interact with APIs that take longer to
* process things.
*
* @constructor
* @alias module:common/operation
*
* @param {object} config - Configuration object.
* @param {module:common/service|module:common/serviceObject|module:common/grpcService|module:common/grpcServiceObject} config.parent - The parent object.
*/
constructor(config: ServiceObjectConfig) {
const methods = {
/**
* Checks to see if an operation exists.
*/
exists: true,

/**
* Retrieves the operation.
*/
get: true,

/**
* Retrieves metadata for the operation.
*/
getMetadata: {
reqOpts: {
name: config.id,
},
},
};

config = Object.assign(
{
baseUrl: '',
},
config
);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
config.methods = (config.methods || methods) as any;
super(config);
this.completeListeners = 0;
this.hasActiveListeners = false;
this.listenForEvents_();
}

/**
* Wraps the `complete` and `error` events in a Promise.
*
* @return {Promise}
*/
promise() {
return new Promise((resolve, reject) => {
this.on('error', reject).on('complete', (metadata: {}) => {
resolve([metadata]);
});
});
}

/**
* Begin listening for events on the operation. This method keeps track of how
* many "complete" listeners are registered and removed, making sure polling
* is handled automatically.
*
* As long as there is one active "complete" listener, the connection is open.
* When there are no more listeners, the polling stops.
*
* @private
*/
protected listenForEvents_() {
this.on('newListener', (event: string) => {
if (event === 'complete') {
this.completeListeners++;
if (!this.hasActiveListeners) {
this.hasActiveListeners = true;
this.startPolling_();
}
}
});

this.on('removeListener', (event: string) => {
if (event === 'complete' && --this.completeListeners === 0) {
this.hasActiveListeners = false;
}
});
}

/**
* Poll for a status update. Returns null for an incomplete
* status, and metadata for a complete status.
*
* @private
*/
protected poll_(callback: MetadataCallback): void {
this.getMetadata((err: ApiError, body: Metadata) => {
if (err || body!.error) {
callback(err || (body!.error as Error));
return;
}

if (!body!.done) {
callback(null);
return;
}

callback(null, body);
});
}

/**
* Poll `getMetadata` to check the operation's status. This runs a loop to
* ping the API on an interval.
*
* Note: This method is automatically called once a "complete" event handler
* is registered on the operation.
*
* @private
*/
protected async startPolling_() {
if (!this.hasActiveListeners) {
return;
}
try {
const metadata = await promisify(this.poll_.bind(this))();
if (!metadata) {
setTimeout(this.startPolling_.bind(this), this.pollIntervalMs || 500);
return;
}
this.emit('complete', metadata);
} catch (err) {
this.emit('error', err);
}
}
}
Loading

0 comments on commit 21cbce0

Please sign in to comment.