Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: improve typescript config and types #417

Merged
merged 3 commits into from
Nov 2, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,20 @@
"docs": "jsdoc -c .jsdoc.js",
"generate-scaffolding": "repo-tools generate all && repo-tools generate lib_samples_readme -l samples/ --config ../.cloud-repo-tools.json",
"lint": "echo disabled for now",
"prettier": "prettier --write benchmark/*.js src/*.js src/*/*.js src/admin/database/*/*.js src/admin/instance/*/*.js samples/*.js samples/*/*.js samples/*/*/*.js test/*.js test/*/*.js system-test/*.js system-test/*/*.js",
"samples-test": "cd samples/ && npm link ../ && npm test && cd ../",
"system-test": "mocha build/system-test --timeout 600000",
"cleanup": "mocha scripts/cleanup.js --timeout 30000",
"test": "nyc mocha build/test",
"ycsb": "node ./benchmark/ycsb.js run -P ./benchmark/workloada -p table=usertable -p cloudspanner.instance=ycsb-instance -p operationcount=100 -p cloudspanner.database=ycsb",
"fix": "eslint --fix '**/*.js'",
"clean": "gts clean",
"compile": "tsc -p . && cp src/v1/*.json build/src/v1 && cp -r protos build",
"compile": "tsc -p . && cp -r src/v1 build/src && cp -r protos build",
"prepare": "npm run compile",
"pretest": "npm run compile",
"presystem-test": "npm run compile"
},
"dependencies": {
"@google-cloud/common-grpc": "^0.9.0",
"@google-cloud/common-grpc": "^0.9.2",
"@google-cloud/paginator": "^0.1.0",
"@google-cloud/projectify": "^0.3.0",
"@google-cloud/promisify": "^0.3.0",
Expand Down
1 change: 0 additions & 1 deletion src/batch-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {Transaction} from './transaction';
* @param {TransactionOptions} [options] [Transaction options](https://cloud.google.com/spanner/docs/timestamp-bounds).
*/
class BatchTransaction extends Transaction {
session: Session;
readTimestamp?: {};

constructor(session) {
Expand Down
124 changes: 59 additions & 65 deletions src/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {Service} from '@google-cloud/common-grpc';
import * as extend from 'extend';
import * as is from 'is';

class SpannerDate {
export class SpannerDate {
value;
constructor(value) {
if (arguments.length > 1) {
Expand All @@ -39,7 +39,7 @@ class SpannerDate {
}
}

class Float {
export class Float {
value;
constructor(value) {
this.value = value;
Expand All @@ -49,7 +49,7 @@ class Float {
}
}

class Int {
export class Int {
value;
constructor(value) {
this.value = value.toString();
Expand Down Expand Up @@ -84,73 +84,67 @@ const TYPE = Symbol();
*
* @returns {array}
*/
function Struct() {
const struct = [];
export class Struct extends Array {
constructor() {
super();
this[TYPE] = Struct.TYPE;
Object.defineProperty(this, 'toJSON', {
enumerable: false,
value: codec.generateToJSONFromRow(this)
});
}

struct[TYPE] = Struct.TYPE;
/**
* Use this to assign/check the type when dealing with structs.
*
* @private
*/
static TYPE = 'struct';

/**
* Converts an array of objects to a struct array.
*
* @private
*
* @param {object[]} arr Struct array.
* @return {Struct}
*/
static fromArray(arr) {
const struct = new Struct();
struct.push.apply(struct, arr);
return struct;
}

Object.defineProperty(struct, 'toJSON', {
enumerable: false,
value: codec.generateToJSONFromRow(struct),
});
/**
* Converts a JSON object to a struct array.
*
* @private
*
* @param {object} json Struct JSON.
* @return {Struct}
*/
static fromJSON(json: {}) {
const struct = new Struct();
Object.keys(json || {}).forEach(name => {
const value = json[name];
struct.push({name, value});
});
return struct;
}

return struct;
/**
* Checks to see if the provided object is a Struct.
*
* @private
*
* @param {*} thing The object to check.
* @returns {boolean}
*/
static isStruct(thing: {}) {
JustinBeckwith marked this conversation as resolved.
Show resolved Hide resolved
return !!(thing && thing[TYPE] === Struct.TYPE);
}
}

/**
* Use this to assign/check the type when dealing with structs.
*
* @private
*/
Struct.TYPE = 'struct';

/**
* Converts an array of objects to a struct array.
*
* @private
*
* @param {object[]} arr Struct array.
* @return {Struct}
*/
Struct.fromArray = (arr) => {
// tslint:disable-next-line no-any
const struct = new (Struct as any)();
struct.push.apply(struct, arr);
return struct;
};

/**
* Converts a JSON object to a struct array.
*
* @private
*
* @param {object} json Struct JSON.
* @return {Struct}
*/
Struct.fromJSON = (json) => {
// tslint:disable-next-line no-any
const struct = new (Struct as any)();

Object.keys(json || {}).forEach(name => {
const value = json[name];
struct.push({name, value});
});

return struct;
};

/**
* Checks to see if the provided object is a Struct.
*
* @private
*
* @param {*} thing The object to check.
* @returns {boolean}
*/
Struct.isStruct = (thing) => {
return !!(thing && thing[TYPE] === Struct.TYPE);
};

/**
* Wherever a row object is returned, it is assigned a "toJSON" function. This
* function will create that function in a consistent format.
Expand Down
68 changes: 43 additions & 25 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import * as arrify from 'arrify';
import {promisifyAll} from '@google-cloud/promisify';
const {ServiceObject} = require('@google-cloud/common-grpc');
import {ServiceObject} from '@google-cloud/common-grpc';
import * as extend from 'extend';
import * as is from 'is';
import * as retry from 'p-retry';
Expand All @@ -32,6 +32,17 @@ import {SessionPool} from './session-pool';
import {Table} from './table';
import {Transaction} from './transaction';
import {TransactionRequest} from './transaction-request';
import { ServiceObjectConfig, DeleteCallback, ExistsCallback, GetMetadataCallback, ApiError, Metadata } from '@google-cloud/common';
import * as r from 'request';

export interface GetDatabaseOptions {
autoCreate?: boolean;
}
export type DatabaseResponse = [Database, r.Response];
export interface DatabaseCallback {
(err: Error|null, database?: Database, apiResponse?: r.Response): void;
}

/**
* Interface for implementing custom session pooling logic, it should extend the
* {@link https://nodejs.org/api/events.html|EventEmitter} class and emit any
Expand Down Expand Up @@ -156,7 +167,7 @@ class Database extends ServiceObject {
createMethod: (_, options, callback) => {
return instance.createDatabase(formattedName_, options, callback);
},
});
} as {} as ServiceObjectConfig);

This comment was marked as spam.

This comment was marked as spam.


this.formattedName_ = formattedName_;
this.request = instance.request;
Expand Down Expand Up @@ -240,8 +251,9 @@ class Database extends ServiceObject {
* });
*/
close(callback) {
const key = this.id.split('/').pop();
this.parent.databases_.delete(key);
const key = this.id!.split('/').pop();
// tslint:disable-next-line no-any
(this.parent as any).databases_.delete(key);
this.pool_.close(callback);
}
/**
Expand Down Expand Up @@ -503,7 +515,9 @@ class Database extends ServiceObject {
* const apiResponse = data[0];
* });
*/
delete(callback) {
delete(): Promise<[r.Response]>;
delete(callback: DeleteCallback): void;
delete(callback?: DeleteCallback): void|Promise<[r.Response]> {
const reqOpts = {
database: this.formattedName_,
};
Expand All @@ -514,7 +528,7 @@ class Database extends ServiceObject {
method: 'dropDatabase',
reqOpts,
},
callback
callback!
);
});
}
Expand Down Expand Up @@ -550,17 +564,18 @@ class Database extends ServiceObject {
* const exists = data[0];
* });
*/
exists(callback) {
exists(): Promise<[boolean]>;
exists(callback: ExistsCallback): void;
exists(callback?: ExistsCallback): void|Promise<[boolean]> {
const NOT_FOUND = 5;

this.getMetadata(err => {
if (err && err.code !== NOT_FOUND) {
callback(err, null);
if (err && (err as ApiError).code !== NOT_FOUND) {
callback!(err);
return;
}

const exists = !err || err.code !== NOT_FOUND;
callback(null, exists);
const exists = !err || (err as ApiError).code !== NOT_FOUND;
callback!(null, exists);
});
}
/**
Expand Down Expand Up @@ -607,30 +622,31 @@ class Database extends ServiceObject {
* const apiResponse = data[0];
* });
*/
get(options, callback) {
if (is.fn(options)) {
callback = options;
options = {};
}
get(options?: GetDatabaseOptions): Promise<DatabaseResponse>;
get(options: GetDatabaseOptions, callback: DatabaseCallback): void;
get(callback: DatabaseCallback): void;
get(optionsOrCallback?: GetDatabaseOptions|DatabaseCallback, cb?: DatabaseCallback): void|Promise<DatabaseResponse> {
const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
this.getMetadata((err, metadata) => {
if (err) {
if (options.autoCreate && err.code === 5) {
if (options.autoCreate && (err as ApiError).code === 5) {
this.create(options, (err, database, operation) => {
if (err) {
callback(err);
callback!(err);
return;
}
operation.on('error', callback).on('complete', metadata => {
operation!.on('error', callback!).on('complete', metadata => {
this.metadata = metadata;
callback(null, this, metadata);
callback!(null, this, metadata);
});
});
return;
}
callback(err);
callback!(err);
return;
}
callback(null, this, metadata);
callback!(null, this, metadata);
});
}
/**
Expand Down Expand Up @@ -678,7 +694,9 @@ class Database extends ServiceObject {
* const apiResponse = data[1];
* });
*/
getMetadata(callback) {
getMetadata(): Promise<Metadata>;
getMetadata(callback: GetMetadataCallback): void;
getMetadata(callback?: GetMetadataCallback): void|Promise<Metadata> {
const reqOpts = {
name: this.formattedName_,
};
Expand All @@ -688,7 +706,7 @@ class Database extends ServiceObject {
method: 'getDatabase',
reqOpts,
},
callback
callback!
);
}
/**
Expand Down
8 changes: 5 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,8 @@ this.getInstancesStream = paginator.streamify('getInstances');
if (!name) {
throw new Error('A name is required to access an Operation object.');
}
return new Operation(this, name);
// tslint:disable-next-line no-any
return new Operation(this as any, name);
}

/**
Expand Down Expand Up @@ -707,7 +708,7 @@ this.getInstancesStream = paginator.streamify('getInstances');
* @returns {Promise}
*/
// tslint:disable-next-line no-any
request(config, callback): void|Promise<any> {
request(config: any, callback?: any): any {
if (is.fn(callback)) {
this.prepareGapicRequest_(config, (err, requestFn) => {
if (err) {
Expand Down Expand Up @@ -740,7 +741,8 @@ this.getInstancesStream = paginator.streamify('getInstances');
* @param {function} [callback] Callback function.
* @returns {Stream}
*/
requestStream(config) {
// tslint:disable-next-line no-any
requestStream(config): any {
const stream = streamEvents(through.obj());
stream.once('reading', () => {
this.prepareGapicRequest_(config, (err, requestFn) => {
Expand Down
Loading