Skip to content

Commit 508d1f9

Browse files
authored
fix(types)!: improve types in index.ts (#720)
BREAKING CHANGE: cluster.setMetadata(): only node count is updatable on an existing cluster; getInstancesCallback/Response: dropped nextQuery property as it is deprecated for this method, exposed failedLocations property; instance.createCluster(): removed unsupported params serveNodes and defaultStorageType
1 parent 21f8fef commit 508d1f9

File tree

7 files changed

+173
-154
lines changed

7 files changed

+173
-154
lines changed

src/cluster.ts

+25-31
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,21 @@ export type GetClustersCallback = (
5959
clusters?: Cluster[],
6060
apiResponse?: google.bigtable.admin.v2.IListClustersResponse
6161
) => void;
62+
export interface SetClusterMetadataOptions {
63+
nodes: number;
64+
}
6265
export type SetClusterMetadataCallback = GenericOperationCallback<
6366
Operation | null | undefined
6467
>;
65-
66-
export interface CreateClusterOptions {
67-
gaxOptions?: CallOptions;
68-
location?: string;
68+
export interface BasicClusterConfig {
69+
location: string;
6970
nodes: number;
7071
storage?: string;
7172
}
73+
74+
export interface CreateClusterOptions extends BasicClusterConfig {
75+
gaxOptions?: CallOptions;
76+
}
7277
export type GetClusterMetadataCallback = (
7378
err: ServiceError | null,
7479
metadata?: ICluster | null,
@@ -367,18 +372,15 @@ Please use the format 'my-cluster' or '${instance.name}/clusters/my-cluster'.`);
367372
}
368373

369374
setMetadata(
370-
metadata: CreateClusterOptions
375+
metadata: SetClusterMetadataOptions,
376+
gaxOptions?: CallOptions
371377
): Promise<SetClusterMetadataResponse>;
372378
setMetadata(
373-
metadata: CreateClusterOptions,
374-
gaxOptions: CallOptions
375-
): Promise<SetClusterMetadataResponse>;
376-
setMetadata(
377-
metadata: CreateClusterOptions,
379+
metadata: SetClusterMetadataOptions,
378380
callback: SetClusterMetadataCallback
379381
): void;
380382
setMetadata(
381-
metadata: CreateClusterOptions,
383+
metadata: SetClusterMetadataOptions,
382384
gaxOptions: CallOptions,
383385
callback: SetClusterMetadataCallback
384386
): void;
@@ -399,35 +401,27 @@ Please use the format 'my-cluster' or '${instance.name}/clusters/my-cluster'.`);
399401
* region_tag:bigtable_cluster_set_meta
400402
*/
401403
setMetadata(
402-
metadata: CreateClusterOptions,
404+
metadata: SetClusterMetadataOptions,
403405
gaxOptionsOrCallback?: CallOptions | SetClusterMetadataCallback,
404406
cb?: SetClusterMetadataCallback
405407
): void | Promise<SetClusterMetadataResponse> {
406408
const callback =
407409
typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!;
408410
const gaxOptions =
409-
typeof gaxOptionsOrCallback === 'object' && gaxOptionsOrCallback
411+
typeof gaxOptionsOrCallback === 'object'
410412
? gaxOptionsOrCallback
411413
: ({} as CallOptions);
412414

413-
const reqOpts: ICluster = {
414-
name: this.name,
415-
};
416-
417-
if (metadata.location) {
418-
reqOpts.location = Cluster.getLocation_(
419-
this.bigtable.projectId,
420-
metadata.location
421-
);
422-
}
423-
424-
if (metadata.nodes) {
425-
reqOpts.serveNodes = metadata.nodes;
426-
}
427-
428-
if (metadata.storage) {
429-
reqOpts.defaultStorageType = Cluster.getStorageType_(metadata.storage);
430-
}
415+
const reqOpts: ICluster = Object.assign(
416+
{},
417+
{
418+
name: this.name,
419+
serveNodes: metadata.nodes,
420+
},
421+
metadata
422+
);
423+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
424+
delete (reqOpts as any).nodes;
431425

432426
this.bigtable.request<Operation>(
433427
{

src/index.ts

+32-32
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
InstanceOptions,
2828
CreateInstanceCallback,
2929
CreateInstanceResponse,
30-
ClusterInfo,
3130
IInstance,
3231
} from './instance';
3332
import {shouldRetryRequest} from './decorateStatus';
@@ -49,14 +48,14 @@ const {grpc} = new gax.GrpcClient();
4948
export interface GetInstancesCallback {
5049
(
5150
err: ServiceError | null,
52-
result?: Instance[] | null,
53-
nextQuery?: {} | null,
54-
response?: google.bigtable.admin.v2.IListInstancesResponse | null
51+
result?: Instance[],
52+
failedLocations?: string[],
53+
response?: google.bigtable.admin.v2.IListInstancesResponse
5554
): void;
5655
}
5756
export type GetInstancesResponse = [
5857
Instance[],
59-
{} | null,
58+
string[],
6059
google.bigtable.admin.v2.IListInstancesResponse
6160
];
6261

@@ -462,14 +461,13 @@ export class Bigtable {
462461

463462
createInstance(
464463
id: string,
465-
options?: InstanceOptions
464+
options: InstanceOptions
466465
): Promise<CreateInstanceResponse>;
467466
createInstance(
468467
id: string,
469468
options: InstanceOptions,
470469
callback: CreateInstanceCallback
471470
): void;
472-
createInstance(id: string, callback: CreateInstanceCallback): void;
473471
/**
474472
* Create a Cloud Bigtable instance.
475473
*
@@ -479,7 +477,7 @@ export class Bigtable {
479477
* @param {object} options Instance creation options.
480478
* @param {object[]} options.clusters The clusters to be created within the
481479
* instance.
482-
* @param {string} options.displayName The descriptive name for this instance
480+
* @param {string} [options.displayName] The descriptive name for this instance
483481
* as it appears in UIs.
484482
* @param {Object.<string, string>} [options.labels] Labels are a flexible and
485483
* lightweight mechanism for organizing cloud resources into groups that
@@ -546,14 +544,19 @@ export class Bigtable {
546544
*/
547545
createInstance(
548546
id: string,
549-
optionsOrCallback?: InstanceOptions | CreateInstanceCallback,
550-
cb?: CreateInstanceCallback
547+
options: InstanceOptions,
548+
callback?: CreateInstanceCallback
551549
): void | Promise<CreateInstanceResponse> {
552-
const options =
553-
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
554-
const callback =
555-
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
556-
550+
if (typeof options !== 'object') {
551+
throw new Error(
552+
'A configuration object is required to create an instance.'
553+
);
554+
}
555+
if (!options.clusters) {
556+
throw new Error(
557+
'At least one cluster configuration object is required to create an instance.'
558+
);
559+
}
557560
const reqOpts = {
558561
parent: this.projectName,
559562
instanceId: id,
@@ -567,7 +570,7 @@ export class Bigtable {
567570
reqOpts.instance!.type = Instance.getTypeType_(options.type);
568571
}
569572

570-
reqOpts.clusters = arrify(options.clusters!).reduce((clusters, cluster) => {
573+
reqOpts.clusters = arrify(options.clusters).reduce((clusters, cluster) => {
571574
if (!cluster.id) {
572575
throw new Error(
573576
'A cluster was provided without an `id` property defined.'
@@ -581,7 +584,7 @@ export class Bigtable {
581584
};
582585

583586
return clusters;
584-
}, {} as {[index: string]: ClusterInfo});
587+
}, {} as {[index: string]: google.bigtable.admin.v2.ICluster});
585588

586589
this.request(
587590
{
@@ -606,12 +609,14 @@ export class Bigtable {
606609
/**
607610
* @typedef {array} GetInstancesResponse
608611
* @property {Instance[]} 0 Array of {@link Instance} instances.
609-
* @property {object} 1 The full API response.
612+
* @property {string[]} 1 locations from which Instance information could not be retrieved
613+
* @property {object} 2 The full API response.
610614
*/
611615
/**
612616
* @callback GetInstancesCallback
613617
* @param {?Error} err Request error, if any.
614618
* @param {Instance[]} instances Array of {@link Instance} instances.
619+
* @param {string[]} locations from which Instance information could not be retrieved
615620
* @param {object} apiResponse The full API response.
616621
*/
617622
/**
@@ -629,26 +634,21 @@ export class Bigtable {
629634
* bigtable.getInstances(function(err, instances) {
630635
* if (!err) {
631636
* // `instances` is an array of Instance objects.
637+
* if (failedLocations.length > 0) {
638+
* // These locations contain instances which could not be retrieved.
639+
* }
632640
* }
633641
* });
634642
*
635-
* @example <caption>To control how many API requests are made and page
636-
* through the results manually, set `autoPaginate` to `false`.</caption>
637-
* function callback(err, instances, nextQuery, apiResponse) {
638-
* if (nextQuery) {
639-
* // More results exist.
640-
* bigtable.getInstances(nextQuery, callback);
641-
* }
642-
* }
643-
*
644-
* bigtable.getInstances({
645-
* autoPaginate: false
646-
* }, callback);
647-
*
648643
* @example <caption>If the callback is omitted, we'll return a Promise.
649644
* </caption>
650645
* bigtable.getInstances().then(function(data) {
651646
* const instances = data[0];
647+
*
648+
* if (data[1]) {
649+
* // These locations contain instances which could not be retrieved.
650+
* const failedLocations = data[1];
651+
* }
652652
* });
653653
*/
654654
getInstances(
@@ -683,7 +683,7 @@ export class Bigtable {
683683
instance.metadata = instanceData;
684684
return instance;
685685
});
686-
callback!(null, instances, resp);
686+
callback!(null, instances, resp.failedLocations, resp);
687687
}
688688
);
689689
}

src/instance.ts

+19-24
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
CreateClusterResponse,
3333
GetClustersCallback,
3434
GetClustersResponse,
35+
IOperation,
36+
BasicClusterConfig,
3537
} from './cluster';
3638
import {Family} from './family';
3739
import {
@@ -56,20 +58,15 @@ import {ServiceError} from 'google-gax';
5658
import {Bigtable} from '.';
5759
import {google} from '../protos/protos';
5860

59-
export interface ClusterInfo {
60-
id?: string;
61-
location?: string;
62-
serveNodes?: number;
63-
nodes?: number;
64-
storage?: string;
65-
defaultStorageType?: number;
61+
export interface ClusterInfo extends BasicClusterConfig {
62+
id: string;
6663
}
6764

6865
export interface InstanceOptions {
6966
/**
7067
* The clusters to be created within the instance.
7168
*/
72-
clusters?: ClusterInfo[] | ClusterInfo;
69+
clusters: ClusterInfo[] | ClusterInfo;
7370

7471
/**
7572
* The descriptive name for this instance as it appears in UIs.
@@ -102,13 +99,16 @@ export interface InstanceOptions {
10299
}
103100

104101
export type IInstance = google.bigtable.admin.v2.IInstance;
105-
export type CreateInstanceCallback = (
106-
err: ServiceError | null,
107-
instance?: Instance,
108-
operation?: Operation,
109-
apiResponse?: IInstance
110-
) => void;
111-
export type CreateInstanceResponse = [Instance, Operation, IInstance];
102+
export interface LongRunningResourceCallback<Resource> {
103+
(
104+
err: ServiceError | null,
105+
resource?: Resource,
106+
operation?: Operation,
107+
apiResponse?: IOperation
108+
): void;
109+
}
110+
export type CreateInstanceCallback = LongRunningResourceCallback<Instance>;
111+
export type CreateInstanceResponse = [Instance, Operation, IOperation];
112112
export type DeleteInstanceCallback = (
113113
err: ServiceError | null,
114114
apiResponse?: google.protobuf.Empty
@@ -209,9 +209,8 @@ Please use the format 'my-instance' or '${bigtable.projectName}/instances/my-ins
209209
return new AppProfile(this, name);
210210
}
211211

212-
create(options?: InstanceOptions): Promise<CreateInstanceResponse>;
212+
create(options: InstanceOptions): Promise<CreateInstanceResponse>;
213213
create(options: InstanceOptions, callback: CreateInstanceCallback): void;
214-
create(callback: CreateInstanceCallback): void;
215214
/**
216215
* Create an instance.
217216
*
@@ -231,14 +230,10 @@ Please use the format 'my-instance' or '${bigtable.projectName}/instances/my-ins
231230
* region_tag:bigtable_create_instance
232231
*/
233232
create(
234-
optionsOrCallback?: InstanceOptions | CreateInstanceCallback,
235-
cb?: CreateInstanceCallback
233+
options: InstanceOptions,
234+
callback?: CreateInstanceCallback
236235
): void | Promise<CreateInstanceResponse> {
237-
const options =
238-
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
239-
const callback =
240-
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!;
241-
this.bigtable.createInstance(this.id, options, callback);
236+
this.bigtable.createInstance(this.id, options, callback!);
242237
}
243238

244239
createAppProfile(

system-test/bigtable.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ describe('Bigtable', () => {
8383

8484
describe('instances', () => {
8585
it('should get a list of instances', async () => {
86-
const [instances] = await bigtable.getInstances();
86+
const [instances, failedLocations] = await bigtable.getInstances();
8787
assert(instances.length > 0);
88+
assert(Array.isArray(failedLocations));
8889
});
8990

9091
it('should check if an instance exists', async () => {

0 commit comments

Comments
 (0)