Skip to content

Commit

Permalink
fix: improve types, enable noImplicitThis (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored Sep 22, 2018
1 parent 2262f0e commit a24855a
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 156 deletions.
2 changes: 1 addition & 1 deletion packages/google-cloud-resourcemanager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"check": "gts check",
"clean": "gts clean",
"compile": "tsc -p .",
"fix": "gts fix",
"fix": "eslint 'samples/**/*.js' --fix && npm run prettier && gts fix",
"prepare": "npm run compile",
"pretest": "npm run compile",
"presystem-test": "npm run compile"
Expand Down
112 changes: 87 additions & 25 deletions packages/google-cloud-resourcemanager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

'use strict';

import {Service, Operation} from '@google-cloud/common';
import {Service, Operation, GoogleAuthOptions} from '@google-cloud/common';
import {paginator} from '@google-cloud/paginator';
import {promisifyAll} from '@google-cloud/promisify';
import * as extend from 'extend';
Expand All @@ -25,6 +25,55 @@ import {Project} from './project';
import * as r from 'request'; // Only for type declarations.
import {teenyRequest} from 'teeny-request';

export type CreateProjectCallback =
(err: Error|null, project?: Project|null, operation?: Operation,
apiResponse?: r.Response) => void;
export type CreateProjectResponse = [Project, Operation, r.Response];
export type GetProjectsResponse = [Project[], r.Response];
export type GetProjectsCallback =
(err: Error|null, projects?: Project[]|null, nextQuery?: {}|null,
apiResponse?: r.Response) => void;

export interface GetProjectOptions {
autoPaginate?: boolean;
filter?: string;
maxApiCalls?: number;
maxResults?: number;
pageSize?: number;
pageToken?: string;
}

export enum LifecylceState {
/**
* Unspecified state. This is only used/useful for distinguishing unset
* values.
*/
'LIFECYCLE_STATE_UNSPECIFIED',
/**
* The normal and active state.
*/
'ACTIVE',
/**
* The project has been marked for deletion by the user (by invoking
* projects.delete) or by the system (Google Cloud Platform). This can
* generally be reversed by invoking projects.undelete.
*/
'DELETE_REQUESTED',
/**
* This lifecycle state is no longer used and not returned by the API.
*/
'DELETE_IN_PROGRESS',
}

export interface CreateProjectOptions {
projectNumber?: string;
projectId?: string;
lifecycleState?: LifecylceState;
name: string;
createTime: string;
labels: {[index: string]: string};
parent: {type: string, id: string};
}

/**
* @typedef {object} ClientConfig
Expand Down Expand Up @@ -52,6 +101,10 @@ import {teenyRequest} from 'teeny-request';
* @property {Constructor} [promise] Custom promise module to use instead of
* native Promises.
*/
export interface ClientConfig extends GoogleAuthOptions {
autoRetry?: boolean;
maxRetries?: boolean;
}

/**
* The [Cloud Resource Manager](https://cloud.google.com/resource-manager/)
Expand Down Expand Up @@ -88,9 +141,8 @@ import {teenyRequest} from 'teeny-request';
* Full quickstart example:
*/
class Resource extends Service {
getProjectsStream;
constructor(options?) {
options = options || {};
getProjectsStream: Function;
constructor(options: ClientConfig = {}) {
const config = {
baseUrl: 'https://cloudresourcemanager.googleapis.com/v1',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
Expand Down Expand Up @@ -190,12 +242,20 @@ class Resource extends Service {
* // Project created successfully!
* });
*/
createProject(id, options, callback) {
if (is.fn(options)) {
callback = options;
options = {};
}

createProject(id: string, options?: CreateProjectOptions):
Promise<CreateProjectResponse>;
createProject(
id: string, options: CreateProjectOptions,
callback: CreateProjectCallback): void;
createProject(id: string, callback: CreateProjectCallback): void;
createProject(
id: string,
optionsOrCallback?: CreateProjectOptions|CreateProjectCallback,
callback?: CreateProjectCallback): void|Promise<CreateProjectResponse> {
const options =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
this.request(
{
method: 'POST',
Expand All @@ -206,13 +266,13 @@ class Resource extends Service {
},
(err, resp) => {
if (err) {
callback(err, null, resp);
callback!(err, null, resp);
return;
}
const project = this.project(resp.projectId);
const operation = this.operation(resp.name);
operation.metadata = resp;
callback(null, project, operation, resp);
callback!(null, project, operation, resp);
});
}

Expand Down Expand Up @@ -267,40 +327,42 @@ class Resource extends Service {
* const projects = data[0];
* });
*/
getProjects(options, callback?) {
if (is.fn(options)) {
callback = options;
options = {};
}

options = options || {};

getProjects(options?: GetProjectOptions): Promise<GetProjectsResponse>;
getProjects(options: GetProjectOptions, callback: GetProjectsCallback): void;
getProjects(callback: GetProjectsCallback): void;
getProjects(
optionsOrCallback?: GetProjectOptions|GetProjectsCallback,
callback?: GetProjectsCallback): void|Promise<GetProjectsResponse> {
const options =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
this.request(
{
uri: '/projects',
qs: options,
},
(err, resp) => {
if (err) {
callback(err, null, null, resp);
callback!(err, null, null, resp);
return;
}

let nextQuery = null;
let nextQuery: GetProjectOptions;

if (resp.nextPageToken) {
nextQuery = extend({}, options, {
pageToken: resp.nextPageToken,
});
}

const projects = (resp.projects || []).map(project => {
const projects = (resp.projects || []).map((project: Project) => {
const projectInstance = this.project(project.projectId);
projectInstance.metadata = project;
return projectInstance;
});

callback(null, projects, nextQuery, resp);
callback!(null, projects, nextQuery!, resp);
});
}

Expand All @@ -321,7 +383,7 @@ class Resource extends Service {
*
* const operation = resource.operation('68850831366825');
*/
operation(name) {
operation(name: string) {
if (!name) {
throw new Error('A name must be specified for an operation.');
}
Expand Down
11 changes: 8 additions & 3 deletions packages/google-cloud-resourcemanager/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import {Resource} from '.';
import * as r from 'request'; // Only for type declarations.
import {teenyRequest} from 'teeny-request';

export type RestoreCallback = (err: Error|null, apiResonse?: r.Response) =>
void;
export type RestoreResponse = [r.Response];

/**
* A Project object allows you to interact with a Google Cloud Platform project.
*
Expand Down Expand Up @@ -296,16 +300,17 @@ class Project extends ServiceObject {
* const apiResponse = data[0];
* });
*/
restore(callback) {
restore(): Promise<RestoreResponse>;
restore(callback: RestoreCallback): void;
restore(callback?: RestoreCallback): void|Promise<RestoreResponse> {
callback = callback || util.noop;

this.request(
{
method: 'POST',
uri: ':undelete',
},
(err, resp) => {
callback(err, resp);
callback!(err, resp);
});
}
}
Expand Down
73 changes: 28 additions & 45 deletions packages/google-cloud-resourcemanager/system-test/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {GoogleAuth} from 'google-auth-library';
import * as uuid from 'uuid';

import {Resource, Project} from '../src';
import {Operation} from '@google-cloud/common';

describe('Resource', () => {
const PREFIX = 'gcloud-tests-';
Expand All @@ -33,7 +34,7 @@ describe('Resource', () => {
it('should get a list of projects', done => {
resource.getProjects((err, projects) => {
assert.ifError(err);
assert(projects.length > 0);
assert(projects!.length > 0);
done();
});
});
Expand All @@ -58,8 +59,7 @@ describe('Resource', () => {
it('should get metadata', done => {
project.getMetadata((err, metadata) => {
assert.ifError(err);
// tslint:disable-next-line no-any
assert.notStrictEqual((metadata as any).projectId, undefined);
assert.notStrictEqual(metadata.projectId, undefined);
done();
});
});
Expand Down Expand Up @@ -104,16 +104,17 @@ describe('Resource', () => {
return;
}

project.create((err, project, operation) => {
if (err) {
done(err);
return;
}
testProjects.push(project);
operation.on('error', done).on('complete', () => {
done();
});
});
project.create(
(err: Error, project: Project, operation: Operation) => {
if (err) {
done(err);
return;
}
testProjects.push(project);
operation.on('error', done).on('complete', () => {
done();
});
});
});
});

Expand All @@ -134,30 +135,25 @@ describe('Resource', () => {
it('should have created the project', done => {
project.getMetadata((err, metadata) => {
assert.ifError(err);
// tslint:disable-next-line no-any
assert.strictEqual((metadata as any).projectId, (project as any).id);
assert.strictEqual(metadata.projectId, project.id);
done();
});
});

it('should run operation as a promise', done => {
const project = resource.project(generateName('project'));
// tslint:disable-next-line no-any
(project as any)
.create()
project.create()
.then(response => {
const operation = response[1];
const operation = response[1] as {} as Operation;
return operation.promise();
})
.then(() => {
testProjects.push(project);
// tslint:disable-next-line no-any
return (project as any).getMetadata();
return project.getMetadata();
})
.then(response => {
const metadata = response[0];
// tslint:disable-next-line no-any
assert.strictEqual(metadata.projectId, (project as any).id);
assert.strictEqual(metadata.projectId, project.id);
done();
});
});
Expand All @@ -166,25 +162,12 @@ describe('Resource', () => {
const newProjectName = 'gcloud-tests-project-name';
project.getMetadata((err, metadata) => {
assert.ifError(err);
// tslint:disable-next-line no-any
const originalProjectName = (metadata as any).name;
const originalProjectName = metadata.name;
assert.notStrictEqual(originalProjectName, newProjectName);
// tslint:disable-next-line no-any
(project as any)
.setMetadata(
{
name: newProjectName,
},
(err) => {
assert.ifError(err);
// tslint:disable-next-line no-any
(project as any)
.setMetadata(
{
name: originalProjectName,
},
done);
});
project.setMetadata({name: newProjectName}, err => {
assert.ifError(err);
project.setMetadata({name: originalProjectName}, done);
});
});
});

Expand All @@ -195,7 +178,7 @@ describe('Resource', () => {
});
});

function deleteTestProjects(callback) {
function deleteTestProjects(callback: (err?: Error) => void) {
if (!CAN_RUN_TESTS) {
callback();
return;
Expand All @@ -211,8 +194,8 @@ describe('Resource', () => {
callback(err);
return;
}
const projectsToDelete = projects.filter(project => {
const isTestProject = project.id.indexOf(PREFIX) === 0;
const projectsToDelete = projects!.filter(project => {
const isTestProject = project.id!.indexOf(PREFIX) === 0;
const deleted =
project.metadata.lifecycleState === 'DELETE_REQUESTED';
return isTestProject && !deleted;
Expand All @@ -224,7 +207,7 @@ describe('Resource', () => {
callback);
}

function generateName(resourceType) {
function generateName(resourceType: string) {
return PREFIX + resourceType + '-' + uuid.v1().substr(0, 8);
}
});
Expand Down
Loading

0 comments on commit a24855a

Please sign in to comment.