Skip to content

Commit 4bbe64f

Browse files
refactor: sprinkle some types about (#291)
1 parent 78d776f commit 4bbe64f

File tree

9 files changed

+295
-156
lines changed

9 files changed

+295
-156
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"system-test": "mocha build/system-test --timeout 600000",
3939
"fix": "gts fix && eslint '**/*.js' --fix",
4040
"clean": "gts clean",
41-
"compile": "tsc -p . && cp -r src/v1/ build/src/v1/ && cp -r protos build/ && cp test/*.js build/test",
41+
"compile": "tsc -p . && cp -r src/v1 build/src && cp -r protos build && cp test/*.js build/test",
4242
"prepare": "npm run compile",
4343
"pretest": "npm run compile"
4444
},

src/entity.ts

+88-43
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,20 @@
1717
import * as arrify from 'arrify';
1818
import * as extend from 'extend';
1919
import * as is from 'is';
20+
import {Query, QueryProto} from './query';
2021

2122
// tslint:disable-next-line no-namespace
2223
export namespace entity {
24+
export interface InvalidKeyErrorOptions {
25+
code: string;
26+
}
27+
2328
export class InvalidKeyError extends Error {
24-
constructor(opts) {
29+
constructor(opts: InvalidKeyErrorOptions) {
2530
const errorMessages = {
2631
MISSING_KIND: 'A key should contain at least a kind.',
2732
MISSING_ANCESTOR_ID: 'Ancestor keys require an id or name.',
28-
};
33+
} as {[index: string]: string};
2934
super(errorMessages[opts.code]);
3035
this.name = 'InvalidKey';
3136
}
@@ -69,7 +74,7 @@ export namespace entity {
6974
* @param {*} value
7075
* @returns {boolean}
7176
*/
72-
export function isDsDouble(value) {
77+
export function isDsDouble(value?: {}) {
7378
return value instanceof entity.Double;
7479
}
7580

@@ -102,7 +107,7 @@ export namespace entity {
102107
* @param {*} value
103108
* @returns {boolean}
104109
*/
105-
export function isDsInt(value) {
110+
export function isDsInt(value?: {}) {
106111
return value instanceof entity.Int;
107112
}
108113

@@ -151,10 +156,15 @@ export namespace entity {
151156
* @param {*} value
152157
* @returns {boolean}
153158
*/
154-
export function isDsGeoPoint(value) {
159+
export function isDsGeoPoint(value?: {}) {
155160
return value instanceof entity.GeoPoint;
156161
}
157162

163+
export interface KeyOptions {
164+
namespace?: string;
165+
path: Array<string|number>;
166+
}
167+
158168
/**
159169
* Build a Datastore Key object.
160170
*
@@ -172,14 +182,14 @@ export namespace entity {
172182
* });
173183
*/
174184
export class Key {
175-
namespace: string;
185+
namespace?: string;
176186
id?: string;
177187
name?: string;
178188
kind: string;
179189
parent?: Key;
180-
path;
190+
path!: Array<string|number>;
181191

182-
constructor(options) {
192+
constructor(options: KeyOptions) {
183193
/**
184194
* @name Key#namespace
185195
* @type {string}
@@ -192,13 +202,13 @@ export namespace entity {
192202
const identifier = options.path.pop();
193203

194204
if (is.number(identifier) || isDsInt(identifier)) {
195-
this.id = identifier.value || identifier;
205+
this.id = ((identifier as {} as Int).value || identifier) as string;
196206
} else if (is.string(identifier)) {
197-
this.name = identifier;
207+
this.name = identifier as string;
198208
}
199209
}
200210

201-
this.kind = options.path.pop();
211+
this.kind = options.path.pop() as string;
202212

203213
if (options.path.length > 0) {
204214
this.parent = new Key(options);
@@ -229,7 +239,7 @@ export namespace entity {
229239
* @param {*} value
230240
* @returns {boolean}
231241
*/
232-
export function isDsKey(value) {
242+
export function isDsKey(value?: {}) {
233243
return value instanceof entity.Key;
234244
}
235245

@@ -256,8 +266,8 @@ export namespace entity {
256266
* });
257267
* // <Buffer 68 65 6c 6c 6f>
258268
*/
259-
export function decodeValueProto(valueProto) {
260-
const valueType = valueProto.valueType;
269+
export function decodeValueProto(valueProto: ValueProto) {
270+
const valueType = valueProto.valueType!;
261271
const value = valueProto[valueType];
262272

263273
switch (valueType) {
@@ -311,9 +321,9 @@ export namespace entity {
311321
* // stringValue: 'Hi'
312322
* // }
313323
*/
314-
export function encodeValue(value) {
315-
// tslint:disable-next-line no-any
316-
const valueProto: any = {};
324+
// tslint:disable-next-line no-any
325+
export function encodeValue(value?: any): ValueProto {
326+
const valueProto: ValueProto = {};
317327

318328
if (is.boolean(value)) {
319329
valueProto.booleanValue = value;
@@ -325,7 +335,7 @@ export namespace entity {
325335
return valueProto;
326336
}
327337

328-
if (is.number(value)) {
338+
if (typeof value === 'number') {
329339
if (value % 1 === 0) {
330340
value = new entity.Int(value);
331341
} else {
@@ -334,17 +344,17 @@ export namespace entity {
334344
}
335345

336346
if (isDsInt(value)) {
337-
valueProto.integerValue = value.value;
347+
valueProto.integerValue = (value as Int).value;
338348
return valueProto;
339349
}
340350

341351
if (isDsDouble(value)) {
342-
valueProto.doubleValue = value.value;
352+
valueProto.doubleValue = (value as Double).value;
343353
return valueProto;
344354
}
345355

346356
if (isDsGeoPoint(value)) {
347-
valueProto.geoPointValue = value.value;
357+
valueProto.geoPointValue = (value as GeoPoint).value;
348358
return valueProto;
349359
}
350360

@@ -369,7 +379,7 @@ export namespace entity {
369379
return valueProto;
370380
}
371381

372-
if (is.array(value)) {
382+
if (Array.isArray(value)) {
373383
valueProto.arrayValue = {
374384
values: value.map(entity.encodeValue),
375385
};
@@ -428,9 +438,10 @@ export namespace entity {
428438
* // name: 'Stephen'
429439
* // }
430440
*/
431-
export function entityFromEntityProto(entityProto) {
432-
const entityObject = {};
433-
441+
// tslint:disable-next-line no-any
442+
export function entityFromEntityProto(entityProto: EntityProto): any {
443+
// tslint:disable-next-line no-any
444+
const entityObject: any = {};
434445
const properties = entityProto.properties || {};
435446

436447
// tslint:disable-next-line forin
@@ -472,11 +483,11 @@ export namespace entity {
472483
* // }
473484
* // }
474485
*/
475-
export function entityToEntityProto(entityObject) {
486+
export function entityToEntityProto(entityObject: Entity): EntityProto {
476487
const properties = entityObject.data;
477488
const excludeFromIndexes = entityObject.excludeFromIndexes;
478489

479-
const entityProto = {
490+
const entityProto: EntityProto = {
480491
key: null,
481492

482493
properties: Object.keys(properties)
@@ -485,7 +496,8 @@ export namespace entity {
485496
encoded[key] = entity.encodeValue(properties[key]);
486497
return encoded;
487498
},
488-
{}),
499+
// tslint:disable-next-line no-any
500+
{} as any),
489501
};
490502

491503
if (excludeFromIndexes && excludeFromIndexes.length > 0) {
@@ -496,7 +508,7 @@ export namespace entity {
496508

497509
return entityProto;
498510

499-
function excludePathFromEntity(entity, path) {
511+
function excludePathFromEntity(entity: EntityProto, path: string) {
500512
const arrayIndex = path.indexOf('[]');
501513
const entityIndex = path.indexOf('.');
502514

@@ -531,7 +543,7 @@ export namespace entity {
531543

532544
const delimiter = firstPathPartIsArray ? '[]' : '.';
533545
const splitPath = path.split(delimiter);
534-
const firstPathPart = splitPath.shift();
546+
const firstPathPart = splitPath.shift()!;
535547
const remainderPath = splitPath.join(delimiter).replace(/^(\.|\[\])/, '');
536548

537549
if (!(entity.properties && entity.properties[firstPathPart])) {
@@ -543,7 +555,8 @@ export namespace entity {
543555
// check also if the property in question is actually an array value.
544556
entity.properties[firstPathPart].arrayValue) {
545557
const array = entity.properties[firstPathPart].arrayValue;
546-
array.values.forEach(value => {
558+
// tslint:disable-next-line no-any
559+
array.values.forEach((value: any) => {
547560
if (remainderPath === '') {
548561
// We want to exclude *this* array property, which is
549562
// equivalent with excluding all its values
@@ -589,10 +602,10 @@ export namespace entity {
589602
* //
590603
* });
591604
*/
592-
export function formatArray(results) {
605+
export function formatArray(results: ResponseResult[]) {
593606
return results.map(result => {
594607
const ent = entity.entityFromEntityProto(result.entity);
595-
ent[entity.KEY_SYMBOL] = entity.keyFromKeyProto(result.entity.key);
608+
ent[entity.KEY_SYMBOL] = entity.keyFromKeyProto(result.entity.key!);
596609
return ent;
597610
});
598611
}
@@ -608,8 +621,8 @@ export namespace entity {
608621
* isKeyComplete(new Key(['Company', 'Google'])); // true
609622
* isKeyComplete(new Key('Company')); // false
610623
*/
611-
export function isKeyComplete(key) {
612-
const lastPathElement = entity.keyToKeyProto(key).path.pop();
624+
export function isKeyComplete(key: Key) {
625+
const lastPathElement = entity.keyToKeyProto(key).path.pop()!;
613626
return !!(lastPathElement.id || lastPathElement.name);
614627
}
615628

@@ -634,7 +647,7 @@ export namespace entity {
634647
* ]
635648
* });
636649
*/
637-
export function keyFromKeyProto(keyProto) {
650+
export function keyFromKeyProto(keyProto: KeyProto): Key {
638651
// tslint:disable-next-line no-any
639652
const keyOptions: any = {
640653
path: [],
@@ -647,7 +660,7 @@ export namespace entity {
647660
keyProto.path.forEach((path, index) => {
648661
keyOptions.path.push(path.kind);
649662

650-
let id = path[path.idType];
663+
let id = path[path.idType!];
651664

652665
if (path.idType === 'id') {
653666
id = new entity.Int(id);
@@ -683,15 +696,15 @@ export namespace entity {
683696
* // ]
684697
* // }
685698
*/
686-
export function keyToKeyProto(key) {
699+
export function keyToKeyProto(key: Key): KeyProto {
687700
if (is.undefined(key.kind)) {
688701
throw new InvalidKeyError({
689702
code: 'MISSING_KIND',
690703
});
691704
}
692705

693706
// tslint:disable-next-line no-any
694-
const keyProto: any = {
707+
const keyProto: KeyProto = {
695708
path: [],
696709
};
697710

@@ -727,7 +740,7 @@ export namespace entity {
727740

728741
keyProto.path.unshift(pathElement);
729742
// tslint:disable-next-line no-conditional-assignment
730-
} while ((key = key.parent) && ++numKeysWalked);
743+
} while ((key = key.parent!) && ++numKeysWalked);
731744

732745
return keyProto;
733746
}
@@ -765,7 +778,7 @@ export namespace entity {
765778
* // groupBy: []
766779
* // }
767780
*/
768-
export function queryToQueryProto(query) {
781+
export function queryToQueryProto(query: Query): QueryProto {
769782
const OP_TO_OPERATOR = {
770783
'=': 'EQUAL',
771784
'>': 'GREATER_THAN',
@@ -780,8 +793,7 @@ export namespace entity {
780793
'+': 'ASCENDING',
781794
};
782795

783-
// tslint:disable-next-line no-any
784-
const queryProto: any = {
796+
const queryProto: QueryProto = {
785797
distinctOn: query.groupByVal.map(groupBy => {
786798
return {
787799
name: groupBy,
@@ -863,3 +875,36 @@ export namespace entity {
863875
return queryProto;
864876
}
865877
}
878+
879+
export interface ValueProto {
880+
// tslint:disable-next-line no-any
881+
[index: string]: any;
882+
valueType?: string;
883+
values?: ValueProto[];
884+
// tslint:disable-next-line no-any
885+
value?: any;
886+
}
887+
888+
export interface EntityProto {
889+
key: KeyProto|null;
890+
// tslint:disable-next-line no-any
891+
properties: any;
892+
excludeFromIndexes?: boolean;
893+
}
894+
895+
// tslint:disable-next-line no-any
896+
export type Entity = any;
897+
898+
export interface KeyProto {
899+
path: Array<{
900+
// tslint:disable-next-line no-any
901+
[index: string]: any; id: string; name: string;
902+
kind?: string;
903+
idType?: string;
904+
}>;
905+
partitionId?: {namespaceId: {}};
906+
}
907+
908+
export interface ResponseResult {
909+
entity: EntityProto;
910+
}

0 commit comments

Comments
 (0)