diff --git a/.eslintignore b/.eslintignore index 09b31fe7..a4ac7b37 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,5 @@ **/node_modules -src/**/doc/* +**/.coverage build/ docs/ protos/ diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..78215349 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/gts" +} diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 73eeec27..00000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -extends: - - 'eslint:recommended' - - 'plugin:node/recommended' - - prettier -plugins: - - node - - prettier -rules: - prettier/prettier: error - block-scoped-var: error - eqeqeq: error - no-warning-comments: warn - no-var: error - prefer-const: error diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 92394b1e..7138a79a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [8, 10, 12, 13] + node: [10, 12, 13] steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 diff --git a/.mocharc.js b/.mocharc.js index ff7b34fa..f37294f6 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -11,6 +11,7 @@ // 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, diff --git a/.prettierignore b/.prettierignore index f6fac98b..a4ac7b37 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,5 @@ -node_modules/* -samples/node_modules/* -src/**/doc/* +**/node_modules +**/.coverage +build/ +docs/ +protos/ diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index df6eac07..00000000 --- a/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ ---- -bracketSpacing: false -printWidth: 80 -semi: true -singleQuote: true -tabWidth: 2 -trailingComma: es5 -useTabs: false diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..53e6d6f1 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// 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. + +module.exports = { + ...require('gts/.prettierrc.json'), +} diff --git a/package.json b/package.json index e307c58b..35b66909 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "author": "Google Inc.", "engines": { - "node": ">=8.10.0" + "node": ">=10" }, "repository": "googleapis/nodejs-common", "main": "./build/src/index.js", @@ -17,10 +17,8 @@ "scripts": { "docs": "compodoc src/", "test": "c8 mocha build/test", - "posttest": "npm run lint && npm run license-check", "prepare": "npm run compile", "pretest": "npm run compile", - "license-check": "jsgl --local .", "compile": "tsc -p .", "fix": "gts fix", "lint": "gts check", @@ -33,39 +31,37 @@ "dependencies": { "@google-cloud/projectify": "^2.0.0", "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", "ent": "^2.2.0", "extend": "^3.0.2", - "google-auth-library": "^5.5.0", - "retry-request": "^4.0.0", - "teeny-request": "^6.0.0" + "google-auth-library": "^5.10.1", + "retry-request": "^4.1.1", + "teeny-request": "^6.0.3" }, "devDependencies": { - "@compodoc/compodoc": "^1.1.9", + "@compodoc/compodoc": "^1.1.11", "@types/ent": "^2.2.1", "@types/extend": "^3.0.1", - "@types/mocha": "^7.0.0", + "@types/mocha": "^7.0.2", "@types/mv": "^2.1.0", - "@types/ncp": "^2.0.1", - "@types/node": "^11.13.0", + "@types/ncp": "^2.0.3", + "@types/node": "^12.12.31", "@types/proxyquire": "^1.3.28", - "@types/request": "^2.48.1", - "@types/sinon": "^7.0.10", + "@types/request": "^2.48.4", + "@types/sinon": "^7.5.2", "@types/tmp": "0.1.0", - "codecov": "^3.2.0", - "gts": "^1.0.0", - "ink-docstrap": "^1.3.2", - "js-green-licenses": "^1.0.0", - "linkinator": "^2.0.0", - "mocha": "^7.0.0", + "c8": "^7.1.0", + "codecov": "^3.6.5", + "gts": "^2.0.0-alpha.6", + "linkinator": "^2.0.4", + "mocha": "^7.1.1", "mv": "^2.1.1", "ncp": "^2.0.0", - "nock": "^12.0.0", - "c8": "^7.0.0", - "proxyquire": "^2.1.0", - "sinon": "^9.0.0", + "nock": "^12.0.3", + "proxyquire": "^2.1.3", + "sinon": "^9.0.1", "tmp": "0.1.0", - "typescript": "3.6.4" + "typescript": "~3.8.3" } } diff --git a/samples/quickstart.js b/samples/quickstart.js index 5d2b46e6..c97aa66a 100644 --- a/samples/quickstart.js +++ b/samples/quickstart.js @@ -1,17 +1,15 @@ -/*! - * Copyright 2018 Google LCC. 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. - */ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. console.warn(`no samples available 👎`); diff --git a/samples/system-test/test.js b/samples/system-test/test.js index c0cdaa2d..ce89f52c 100644 --- a/samples/system-test/test.js +++ b/samples/system-test/test.js @@ -1,17 +1,15 @@ -/*! - * Copyright 2018 Google LCC. 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. - */ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. console.warn(`no sample tests available 👎`); diff --git a/src/index.ts b/src/index.ts index fa74df7b..ad5a9b15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,16 @@ -/*! - * Copyright 2016 Google Inc. 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. - */ +// Copyright 2016 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. export {GoogleAuthOptions} from 'google-auth-library'; /** diff --git a/src/operation.ts b/src/operation.ts index aab2ca1e..65a1e8f5 100644 --- a/src/operation.ts +++ b/src/operation.ts @@ -1,18 +1,16 @@ -/*! - * Copyright 2016 Google Inc. 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. - */ +// Copyright 2016 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. /*! * @module common/operation @@ -27,7 +25,7 @@ import { import {ApiError} from './util'; import {promisify} from 'util'; -// tslint:disable-next-line no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any export class Operation extends ServiceObject { completeListeners: number; hasActiveListeners: boolean; @@ -71,7 +69,7 @@ export class Operation extends ServiceObject { config ); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any config.methods = (config.methods || methods) as any; super(config); this.completeListeners = 0; diff --git a/src/service-object.ts b/src/service-object.ts index 2d42bb49..dfe6ad92 100644 --- a/src/service-object.ts +++ b/src/service-object.ts @@ -1,18 +1,16 @@ -/*! - * Copyright 2015 Google Inc. 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. - */ +// Copyright 2015 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. /*! * @module common/service-object @@ -49,7 +47,7 @@ export interface Interceptor { export type GetMetadataOptions = object; -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type Metadata = any; export type MetadataResponse = [Metadata, r.Response]; export type MetadataCallback = ( @@ -106,11 +104,12 @@ export interface InstanceResponseCallback { (err: ApiError | null, instance?: T | null, apiResponse?: r.Response): void; } +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface CreateOptions {} -// tslint:disable-next-line no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type CreateResponse = any[]; export interface CreateCallback { - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (err: ApiError | null, instance?: T | null, ...args: any[]): void; } @@ -146,7 +145,7 @@ export type SetMetadataOptions = object; * shared behaviors. Note that any method can be overridden when the service * object requires specific behavior. */ -// tslint:disable-next-line no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any class ServiceObject extends EventEmitter { metadata: Metadata; baseUrl?: string; @@ -195,16 +194,16 @@ class ServiceObject extends EventEmitter { !/^request/.test(methodName) && // clang-format on // The ServiceObject didn't redefine the method. - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (this as any)[methodName] === - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (ServiceObject.prototype as any)[methodName] && // This method isn't wanted. !config.methods![methodName] ); }) .forEach(methodName => { - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (this as any)[methodName] = undefined; }); } @@ -226,6 +225,7 @@ class ServiceObject extends EventEmitter { optionsOrCallback?: CreateOptions | CreateCallback, callback?: CreateCallback ): void | Promise> { + // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; const args = [this.id] as Array<{}>; @@ -249,6 +249,7 @@ class ServiceObject extends EventEmitter { callback!(...((args as {}) as [Error, T])); } args.push(onCreate); + // eslint-disable-next-line prefer-spread this.createMethod!.apply(null, args); } @@ -342,6 +343,7 @@ class ServiceObject extends EventEmitter { optionsOrCallback?: GetOrCreateOptions | InstanceResponseCallback, cb?: InstanceResponseCallback ): Promise> | void { + // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; const [opts, callback] = util.maybeOptionsOrCallback< diff --git a/src/service.ts b/src/service.ts index 4215ded5..82ff3224 100644 --- a/src/service.ts +++ b/src/service.ts @@ -1,18 +1,16 @@ -/*! - * Copyright 2015 Google Inc. 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. - */ +// Copyright 2015 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. /*! * @module common/service diff --git a/src/util.ts b/src/util.ts index b726e23c..b8110982 100644 --- a/src/util.ts +++ b/src/util.ts @@ -28,6 +28,7 @@ import {teenyRequest} from 'teeny-request'; import {Interceptor} from './service-object'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const duplexify: DuplexifyConstructor = require('duplexify'); const requestDefaults = { @@ -39,7 +40,7 @@ const requestDefaults = { }, }; -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type ResponseBody = any; // Directly copy over Duplexify interfaces @@ -615,7 +616,7 @@ export class Util { } if (!err || autoAuthFailed) { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any let projectId = (authClient as any)._cachedProjectId; if (config.projectId && config.projectId !== '{{projectId}}') { @@ -747,7 +748,7 @@ export class Util { }); } const dup = config.stream as AbortableDuplex; - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any let requestStream: any; const isGetRequest = (reqOpts.method || 'GET').toUpperCase() === 'GET'; @@ -805,7 +806,7 @@ export class Util { return reqOpts; } - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any isCustomType(unknown: any, module: string) { function getConstructorName(obj: Function) { return obj.constructor && obj.constructor.name.toLowerCase(); @@ -823,6 +824,7 @@ export class Util { } let walkingModule = unknown; + // eslint-disable-next-line no-constant-condition while (true) { if (getConstructorName(walkingModule) === parentModuleName) { return true; @@ -871,7 +873,7 @@ export class Util { */ class ProgressStream extends Transform { bytesRead = 0; - // tslint:disable-next-line: no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any _transform(chunk: any, encoding: string, callback: Function) { this.bytesRead += chunk.length; this.emit('progress', {bytesWritten: this.bytesRead, contentLength: '*'}); diff --git a/system-test/fixtures/kitchen/src/index.ts b/system-test/fixtures/kitchen/src/index.ts index a5333b20..bb354d6e 100644 --- a/system-test/fixtures/kitchen/src/index.ts +++ b/system-test/fixtures/kitchen/src/index.ts @@ -1,10 +1,42 @@ -import {GoogleAuthOptions, Operation,Service, ServiceConfig, ServiceOptions, - DeleteCallback, ExistsCallback, GetConfig, MetadataCallback, - InstanceResponseCallback, Interceptor, Metadata, Methods, ServiceObject, - ServiceObjectConfig, StreamRequestOptions, Abortable, AbortableDuplex, - ApiError, util} from '@google-cloud/common'; +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// 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. -util.makeRequest({uri: 'test'}, {}, (err, body, res) => { +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { + GoogleAuthOptions, + Operation, + Service, + ServiceConfig, + ServiceOptions, + DeleteCallback, + ExistsCallback, + GetConfig, + MetadataCallback, + InstanceResponseCallback, + Interceptor, + Metadata, + Methods, + ServiceObject, + ServiceObjectConfig, + StreamRequestOptions, + Abortable, + AbortableDuplex, + ApiError, + util, +} from '@google-cloud/common'; + +util.makeRequest({uri: 'test'}, {}, err => { console.log(err); }); - diff --git a/system-test/install.ts b/system-test/install.ts index 9981263c..7cbd9f2f 100644 --- a/system-test/install.ts +++ b/system-test/install.ts @@ -18,12 +18,14 @@ import {ncp} from 'ncp'; import * as os from 'os'; import * as tmp from 'tmp'; import {promisify} from 'util'; +import {describe, it, after} from 'mocha'; const mvp = (promisify(mv) as {}) as (...args: string[]) => Promise; const ncpp = promisify(ncp); const keep = !!process.env.KEEP_TEMPDIRS; const stagingDir = tmp.dirSync({keep, unsafeCleanup: true}); const stagingPath = stagingDir.name; +// eslint-disable-next-line @typescript-eslint/no-var-requires const pkg = require('../../package.json'); const pkgName = 'google-cloud-common'; const npm = os.platform() === 'win32' ? 'npm.cmd' : 'npm'; @@ -46,26 +48,28 @@ const spawnp = ( }); }; -/** - * Create a staging directory with temp fixtures used to test on a fresh - * application. - */ -it('should be able to use the d.ts', async () => { - console.log(`${__filename} staging area: ${stagingPath}`); - await spawnp(npm, ['pack']); - const tarball = `${pkgName}-${pkg.version}.tgz`; - // stagingPath can be on another filesystem so fs.rename() will fail - // with EXDEV, hence we use `mv` module here. - await mvp(tarball, `${stagingPath}/${pkgName}.tgz`); - await ncpp('system-test/fixtures/kitchen', `${stagingPath}/`); - await spawnp(npm, ['install'], {cwd: `${stagingPath}/`}); -}).timeout(120000); +describe('install tests', () => { + /** + * Create a staging directory with temp fixtures used to test on a fresh + * application. + */ + it('should be able to use the d.ts', async () => { + console.log(`${__filename} staging area: ${stagingPath}`); + await spawnp(npm, ['pack']); + const tarball = `${pkgName}-${pkg.version}.tgz`; + // stagingPath can be on another filesystem so fs.rename() will fail + // with EXDEV, hence we use `mv` module here. + await mvp(tarball, `${stagingPath}/${pkgName}.tgz`); + await ncpp('system-test/fixtures/kitchen', `${stagingPath}/`); + await spawnp(npm, ['install'], {cwd: `${stagingPath}/`}); + }).timeout(120000); -/** - * CLEAN UP - remove the staging directory when done. - */ -after('cleanup staging', async () => { - if (!keep) { - stagingDir.removeCallback(); - } + /** + * CLEAN UP - remove the staging directory when done. + */ + after('cleanup staging', async () => { + if (!keep) { + stagingDir.removeCallback(); + } + }); }); diff --git a/test/index.ts b/test/index.ts index c8e101bf..0e8015dc 100644 --- a/test/index.ts +++ b/test/index.ts @@ -14,13 +14,13 @@ import * as assert from 'assert'; import {describe, it} from 'mocha'; -const common = require('../src'); +import {Operation, Service, ServiceObject, util} from '../src'; describe('common', () => { it('should correctly export the common modules', () => { - assert(common.Operation); - assert(common.Service); - assert(common.ServiceObject); - assert(common.util); + assert(Operation); + assert(Service); + assert(ServiceObject); + assert(util); }); }); diff --git a/test/operation.ts b/test/operation.ts index 17ea1b72..b656bbb7 100644 --- a/test/operation.ts +++ b/test/operation.ts @@ -1,21 +1,19 @@ -/*! - * Copyright 2016 Google Inc. 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. - */ +// Copyright 2016 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. import * as assert from 'assert'; -import {describe, it} from 'mocha'; +import {describe, it, beforeEach, afterEach} from 'mocha'; import * as sinon from 'sinon'; import {Service} from '../src'; @@ -27,7 +25,7 @@ import { } from '../src/service-object'; import {util} from '../src/util'; -// tslint:disable-next-line no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any const asAny = (o: {}) => o as any; describe('Operation', () => { @@ -80,9 +78,9 @@ describe('Operation', () => { }); it('should call listenForEvents_', () => { - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const stub = sandbox.stub(Operation.prototype as any, 'listenForEvents_'); - const op = new Operation({parent} as ServiceObjectConfig); + new Operation({parent} as ServiceObjectConfig); assert.ok(stub.called); }); }); @@ -274,10 +272,11 @@ describe('Operation', () => { return asAny({}); }); - asAny(operation).startPolling_ = function() { + asAny(operation).startPolling_ = function () { if (!startPollingCalled) { // Call #1. startPollingCalled = true; + // eslint-disable-next-line prefer-rest-params startPolling_.apply(this, arguments); return; } @@ -307,10 +306,11 @@ describe('Operation', () => { return asAny({}); }); - asAny(op).startPolling_ = function() { + asAny(op).startPolling_ = function () { if (!startPollingCalled) { // Call #1. startPollingCalled = true; + // eslint-disable-next-line prefer-rest-params startPolling_.apply(this, arguments); return; } diff --git a/test/service-object.ts b/test/service-object.ts index 90ab6f5b..d5f5fa73 100644 --- a/test/service-object.ts +++ b/test/service-object.ts @@ -14,7 +14,7 @@ import {promisify} from '@google-cloud/promisify'; import * as assert from 'assert'; -import {describe, it} from 'mocha'; +import {describe, it, beforeEach, afterEach} from 'mocha'; import * as extend from 'extend'; import * as r from 'teeny-request'; import * as sinon from 'sinon'; @@ -29,7 +29,7 @@ import { util, } from '../src/util'; -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any type FakeServiceObject = any; interface InternalServiceObject { request_: ( @@ -219,11 +219,11 @@ describe('ServiceObject', () => { const args = ['a', 'b', 'c', 'd', 'e', 'f']; function createMethod(id: string, options_: {}, callback: Function) { - callback.apply(null, args); + callback(...args); } const serviceObject = new ServiceObject(config); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any serviceObject.create(options, (...args: any[]) => { assert.deepStrictEqual([].slice.call(args), args); done(); @@ -393,11 +393,9 @@ describe('ServiceObject', () => { describe('get', () => { it('should get the metadata', done => { - serviceObject.getMetadata = promisify( - (_callback: SO.MetadataCallback): void => { - done(); - } - ); + serviceObject.getMetadata = promisify((): void => { + done(); + }); serviceObject.get(assert.ifError); }); @@ -414,11 +412,9 @@ describe('ServiceObject', () => { }); it('handles not getting a config', done => { - serviceObject.getMetadata = promisify( - (_callback: SO.MetadataCallback): void => { - done(); - } - ); + serviceObject.getMetadata = promisify((): void => { + done(); + }); (serviceObject as FakeServiceObject).get(assert.ifError); }); @@ -515,7 +511,7 @@ describe('ServiceObject', () => { const error = new Error('Error.'); const apiResponse = {} as r.Response; - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (sandbox.stub(serviceObject, 'create') as any).callsFake( (optsOrCb: {}, cb: Function) => { const callback = typeof optsOrCb === 'function' ? optsOrCb : cb; @@ -557,7 +553,7 @@ describe('ServiceObject', () => { it('should make the correct request', done => { sandbox .stub(ServiceObject.prototype, 'request') - .callsFake(function(this: ServiceObject, reqOpts, callback) { + .callsFake(function (this: ServiceObject, reqOpts, callback) { assert.strictEqual(this, serviceObject); assert.strictEqual(reqOpts.uri, ''); done(); @@ -570,7 +566,7 @@ describe('ServiceObject', () => { const options = {queryOptionProperty: true}; sandbox .stub(ServiceObject.prototype, 'request') - .callsFake(function(this: ServiceObject, reqOpts, callback) { + .callsFake((reqOpts, callback) => { assert.deepStrictEqual(reqOpts.qs, options); done(); callback(null, null, {} as r.Response); @@ -681,7 +677,7 @@ describe('ServiceObject', () => { const metadata = {metadataProperty: true}; sandbox .stub(ServiceObject.prototype, 'request') - .callsFake(function(this: ServiceObject, reqOpts, callback) { + .callsFake(function (this: ServiceObject, reqOpts, callback) { assert.strictEqual(this, serviceObject); assert.strictEqual(reqOpts.method, 'PATCH'); assert.strictEqual(reqOpts.uri, ''); @@ -697,7 +693,7 @@ describe('ServiceObject', () => { const options = {queryOptionProperty: true}; sandbox .stub(ServiceObject.prototype, 'request') - .callsFake(function(this: ServiceObject, reqOpts, callback) { + .callsFake((reqOpts, callback) => { assert.deepStrictEqual(reqOpts.qs, options); done(); callback(null, null, {} as r.Response); @@ -885,7 +881,7 @@ describe('ServiceObject', () => { const parent = new ServiceObject(CONFIG) as FakeServiceObject; parent.interceptors.push({ request(reqOpts: DecorateRequestOptions) { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (reqOpts as any).parent = true; return reqOpts; }, @@ -896,7 +892,7 @@ describe('ServiceObject', () => { ) as FakeServiceObject; child.interceptors.push({ request(reqOpts: DecorateRequestOptions) { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (reqOpts as any).child = true; return reqOpts; }, @@ -920,13 +916,13 @@ describe('ServiceObject', () => { callback(null, null, {} as r.Response); }); - const res = await child.request_({uri: ''}); + await child.request_({uri: ''}); }); it('should pass a clone of the interceptors', done => { asInternal(serviceObject).interceptors.push({ request(reqOpts: DecorateRequestOptions) { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (reqOpts as any).one = true; return reqOpts; }, @@ -996,7 +992,7 @@ describe('ServiceObject', () => { const errorBody = '🤮'; const response = {body: {error: errorBody}, statusCode: 500}; const err = new Error(errorBody); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (err as any).response = response; sandbox .stub(asInternal(serviceObject), 'request_') diff --git a/test/service.ts b/test/service.ts index bd172f38..7808ede9 100644 --- a/test/service.ts +++ b/test/service.ts @@ -13,7 +13,7 @@ // limitations under the License. import * as assert from 'assert'; -import {describe, it} from 'mocha'; +import {describe, it, before, beforeEach, after} from 'mocha'; import * as extend from 'extend'; import * as proxyquire from 'proxyquire'; import {Request} from 'teeny-request'; @@ -40,7 +40,7 @@ let makeAuthenticatedRequestFactoryOverride: config: MakeAuthenticatedRequestFactoryConfig ) => MakeAuthenticatedRequest); -util.makeAuthenticatedRequestFactory = function( +util.makeAuthenticatedRequestFactory = function ( this: Util, config: MakeAuthenticatedRequestFactoryConfig ) { @@ -51,7 +51,7 @@ util.makeAuthenticatedRequestFactory = function( }; describe('Service', () => { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any let service: any; const Service = proxyquire('../src/service', { './util': util, @@ -84,7 +84,7 @@ describe('Service', () => { describe('instantiation', () => { it('should not require options', () => { assert.doesNotThrow(() => { - const s = new Service(CONFIG); + new Service(CONFIG); }); }); @@ -114,15 +114,11 @@ describe('Service', () => { it('should localize the authClient', () => { const authClient = {}; - - makeAuthenticatedRequestFactoryOverride = ( - config?: MakeAuthenticatedRequestFactoryConfig - ) => { + makeAuthenticatedRequestFactoryOverride = () => { return { authClient, } as MakeAuthenticatedRequest; }; - const service = new Service(CONFIG, OPTIONS); assert.strictEqual(service.authClient, authClient); }); @@ -156,13 +152,11 @@ describe('Service', () => { it('should localize the getCredentials method', () => { function getCredentials() {} - makeAuthenticatedRequestFactoryOverride = ( - config?: MakeAuthenticatedRequestFactoryConfig - ) => { + makeAuthenticatedRequestFactoryOverride = () => { return { authClient: {}, getCredentials, - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any; }; diff --git a/test/util.ts b/test/util.ts index 2f2b54f0..fef66d39 100644 --- a/test/util.ts +++ b/test/util.ts @@ -14,7 +14,7 @@ import {replaceProjectIdToken} from '@google-cloud/projectify'; import * as assert from 'assert'; -import {describe, it} from 'mocha'; +import {describe, it, before, beforeEach, afterEach} from 'mocha'; import * as extend from 'extend'; import {GoogleAuth, GoogleAuthOptions} from 'google-auth-library'; import * as nock from 'nock'; @@ -39,6 +39,7 @@ import { Util, } from '../src/util'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const duplexify: DuplexifyConstructor = require('duplexify'); nock.disableNetConnect(); @@ -60,9 +61,10 @@ const fakeReqOpts: DecorateRequestOptions = { const fakeError = new Error('this error is like so fake'); -// tslint:disable-next-line:no-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any let requestOverride: any; function fakeRequest() { + // eslint-disable-next-line prefer-spread, prefer-rest-params return (requestOverride || teenyRequest).apply(null, arguments); } @@ -74,13 +76,16 @@ fakeRequest.defaults = () => { let retryRequestOverride: Function | null; function fakeRetryRequest() { + // eslint-disable-next-line prefer-spread, prefer-rest-params return (retryRequestOverride || retryRequest).apply(null, arguments); } let replaceProjectIdTokenOverride: Function | null; function fakeReplaceProjectIdToken() { + // eslint-disable-next-line prefer-spread, prefer-rest-params return (replaceProjectIdTokenOverride || replaceProjectIdToken).apply( null, + // eslint-disable-next-line prefer-spread, prefer-rest-params arguments ); } @@ -88,7 +93,7 @@ function fakeReplaceProjectIdToken() { describe('common/util', () => { let util: Util & {[index: string]: Function}; - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any function stub(method: keyof Util, meth: (...args: any[]) => void) { return sandbox.stub(util, method).callsFake(meth); } @@ -479,7 +484,7 @@ describe('common/util', () => { describe('makeWritableStream', () => { it('should use defaults', done => { const dup = duplexify(); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const metadata = {a: 'b', c: 'd'} as any; util.makeWritableStream(dup, { metadata, @@ -494,20 +499,20 @@ describe('common/util', () => { const mp = request.multipart as r.RequestPart[]; assert.strictEqual( - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (mp[0] as any)['Content-Type'], 'application/json' ); assert.strictEqual(mp[0].body, JSON.stringify(metadata)); assert.strictEqual( - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (mp[1] as any)['Content-Type'], 'application/octet-stream' ); // (is a writable stream:) assert.strictEqual( - // tslint:disable-next-line no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any typeof (mp[1].body as any)._writableState, 'object' ); @@ -537,7 +542,7 @@ describe('common/util', () => { assert.deepStrictEqual(request.qs, req.qs); assert.strictEqual(request.uri, req.uri); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const mp = request.multipart as any[]; assert.strictEqual(mp[1]['Content-Type'], 'application/json'); @@ -578,7 +583,7 @@ describe('common/util', () => { let happened = false; const dup = duplexify(); - dup.on('progress', (progress: {}) => { + dup.on('progress', () => { happened = true; }); @@ -593,10 +598,7 @@ describe('common/util', () => { const dup = duplexify(); const fakeStream = new stream.Writable(); const error = new Error('Error.'); - - fakeStream.write = - // tslint:disable-next-line:no-any - (chunk: any, encoding?: string | Function, cb?: Function) => false; + fakeStream.write = () => false; dup.end = () => {}; stub('handleResp', (err, res, body, callback) => { @@ -610,9 +612,7 @@ describe('common/util', () => { callback(error); }; - requestOverride.defaults = (opts: DecorateRequestOptions) => { - return requestOverride; - }; + requestOverride.defaults = () => requestOverride; dup.on('error', err => { assert.strictEqual(err, error); @@ -633,7 +633,7 @@ describe('common/util', () => { it('should emit the response', done => { const dup = duplexify(); const fakeStream = new stream.Writable(); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any (fakeStream as any).write = () => {}; stub('handleResp', (err, res, body, callback) => { @@ -647,10 +647,9 @@ describe('common/util', () => { callback(null, fakeResponse); }; - requestOverride.defaults = (opts: DecorateRequestOptions) => - requestOverride; + requestOverride.defaults = () => requestOverride; const options = { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any makeAuthenticatedRequest(request: DecorateRequestOptions, opts: any) { opts.onAuthenticated(); }, @@ -666,7 +665,7 @@ describe('common/util', () => { it('should pass back the response data to the callback', done => { const dup = duplexify(); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const fakeStream: any = new stream.Writable(); const fakeResponse = {}; @@ -682,12 +681,12 @@ describe('common/util', () => { ) => { callback(); }; - requestOverride.defaults = (opts: DecorateRequestOptions) => { + requestOverride.defaults = () => { return requestOverride; }; const options = { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any makeAuthenticatedRequest(request: DecorateRequestOptions, opts: any) { opts.onAuthenticated(); }, @@ -708,7 +707,7 @@ describe('common/util', () => { const authClient = { getCredentials() {}, _cachedProjectId: 'project-id', - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any; it('should create an authClient', done => { @@ -777,10 +776,9 @@ describe('common/util', () => { }); describe('customEndpoint (no authentication attempted)', () => { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any let makeAuthenticatedRequest: any; const config = {customEndpoint: true}; - const expectedProjectId = authClient.projectId; beforeEach(() => { makeAuthenticatedRequest = util.makeAuthenticatedRequestFactory(config); @@ -921,7 +919,7 @@ describe('common/util', () => { const error = new Error('🤮'); beforeEach(() => { - authClient.authorizeRequest = async (rOpts: {}) => { + authClient.authorizeRequest = async () => { throw error; }; }); @@ -935,7 +933,7 @@ describe('common/util', () => { const correctReqOpts = {} as DecorateRequestOptions; const incorrectReqOpts = {} as DecorateRequestOptions; - authClient.authorizeRequest = async (rOpts: {}) => { + authClient.authorizeRequest = async () => { throw new Error('Could not load the default credentials'); }; @@ -981,7 +979,7 @@ describe('common/util', () => { }); it('should not block 401 errors if auth client succeeds', done => { - authClient.authorizeRequest = async (rOpts: {}) => {}; + authClient.authorizeRequest = async () => {}; sandbox.stub(fakeGoogleAuth, 'GoogleAuth').returns(authClient); const makeRequestArg1 = new Error('API 401 Error.') as ApiError; @@ -1048,7 +1046,7 @@ describe('common/util', () => { it('should emit an error and end the stream', done => { sandbox.stub(fakeGoogleAuth, 'GoogleAuth').returns(authClient); const mar = util.makeAuthenticatedRequestFactory({}); - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const stream = mar(fakeReqOpts) as any; stream.on('error', (err: Error) => { assert.strictEqual(err, error); @@ -1063,9 +1061,7 @@ describe('common/util', () => { describe('authentication success', () => { const reqOpts = fakeReqOpts; beforeEach(() => { - authClient.authorizeRequest = async (rOpts: {}) => { - return reqOpts; - }; + authClient.authorizeRequest = async () => reqOpts; }); it('should return authenticated request to callback', done => { @@ -1301,7 +1297,7 @@ describe('common/util', () => { const userStream = duplexify() as Duplexify & Abortable; retryRequestOverride = () => { - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const requestStream: any = new stream.Stream(); requestStream.abort = done; return requestStream; @@ -1325,31 +1321,19 @@ describe('common/util', () => { setImmediate(done); return userStream; }; - - requestOverride.defaults = (opts: DecorateRequestOptions) => { - return requestOverride; - }; - + requestOverride.defaults = () => requestOverride; util.makeRequest(reqOpts, {stream: userStream}, util.noop); }); it('should set the writable stream', done => { const userStream = duplexify(); const requestStream = new stream.Stream(); - - requestOverride = () => { - return requestStream; - }; - - requestOverride.defaults = (opts: DecorateRequestOptions) => { - return requestOverride; - }; - + requestOverride = () => requestStream; + requestOverride.defaults = () => requestOverride; userStream.setWritable = stream => { assert.strictEqual(stream, requestStream); done(); }; - util.makeRequest( {method: 'POST'} as DecorateRequestOptions, {stream: userStream}, @@ -1379,7 +1363,7 @@ describe('common/util', () => { it('should pass the default options to retryRequest', done => { retryRequestOverride = testDefaultRetryRequestConfig(done); util.makeRequest( - // tslint:disable-next-line:no-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any reqOpts, {}, assert.ifError