diff --git a/src/index.ts b/src/index.ts index aafdd2f..2229427 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,6 +24,7 @@ import * as extend from 'extend'; import {teenyRequest} from 'teeny-request'; import {Zone} from './zone'; import {Response} from 'request'; +export {Record, RecordMetadata} from './record'; export interface GetZonesRequest { autoPaginate?: boolean; diff --git a/src/record.ts b/src/record.ts index 2527b8d..7c05245 100644 --- a/src/record.ts +++ b/src/record.ts @@ -23,6 +23,21 @@ import {ChangeCallback} from './change'; import {Zone} from './zone'; const format = require('string-format-obj'); +export interface RecordObject { + rrdatas?: Array<{}>; + rrdata?: {}; + data?: {}; + type?: string; +} + +export interface RecordMetadata { + name: string; + data: string|string[]; + ttl: number; + type?: string; + signatureRrdatas?: string[]; +} + /** * Create a Resource Record object. * @@ -49,13 +64,13 @@ const format = require('string-format-obj'); * data: '1.2.3.4' * }); */ -export class Record { +export class Record implements RecordObject { zone_: Zone; type: string; - metadata; - rrdatas; - data; - constructor(zone: Zone, type: string, metadata) { + metadata: RecordMetadata; + rrdatas?: Array<{}>; + data?: {}; + constructor(zone: Zone, type: string, metadata: RecordMetadata) { this.zone_ = zone; /** * @name Record#type @@ -137,7 +152,7 @@ export class Record { * @returns {object} */ toJSON() { - const recordObject = extend({}, this.metadata, { + const recordObject: RecordObject = extend({}, this.metadata, { type: this.type.toUpperCase(), }); if (recordObject.data) { @@ -171,7 +186,7 @@ export class Record { * based on the type of record. * @returns {Record} */ - static fromZoneRecord_(zone: Zone, type: string, bindData) { + static fromZoneRecord_(zone: Zone, type: string, bindData: RecordMetadata) { const typeToZoneFormat = { a: '{ip}', aaaa: '{ip}', @@ -182,7 +197,7 @@ export class Record { spf: '{data}', srv: '{priority} {weight} {port} {target}', txt: '{txt}', - }; + } as {[index: string]: string}; const metadata = { data: format(typeToZoneFormat[type.toLowerCase()], bindData), name: bindData.name, diff --git a/src/zone.ts b/src/zone.ts index 4c652dc..2998098 100644 --- a/src/zone.ts +++ b/src/zone.ts @@ -29,7 +29,7 @@ import {teenyRequest} from 'teeny-request'; const zonefile = require('dns-zonefile'); import {Change, ChangeCallback, CreateChangeRequest} from './change'; -import {Record} from './record'; +import {Record, RecordMetadata, RecordObject} from './record'; import {DNS} from '.'; import {Response} from 'request'; @@ -52,6 +52,20 @@ export interface GetRecordsRequest { filterByTypes_?: {[index: string]: boolean}; } +export interface GetChangesRequest { + autoPaginate?: boolean; + maxApiCalls?: number; + maxResults?: number; + pageToken?: string; + sort?: string; + sortOrder?: string; +} + +export interface GetChangesCallback { + (err: Error|null, changes?: Change[]|null, nextQuery?: {}|null, + apiResponse?: Response): void; +} + /** * A Zone object is used to interact with your project's managed zone. It will * help you add or delete records, delete your zone, and many other convenience @@ -349,7 +363,7 @@ class Zone extends ServiceObject { if (!config || (!config.add && !config.delete)) { throw new Error('Cannot create a change with no additions or deletions.'); } - const groupByType = changes => { + const groupByType = (changes: RecordObject[]) => { changes = groupBy(changes, 'type'); const changesArray: Array<{}> = []; // tslint:disable-next-line:forin @@ -361,7 +375,8 @@ class Zone extends ServiceObject { const templateRecord = extend({}, records[0]); if (records.length > 1) { // Combine the `rrdatas` values from all records of the same type. - templateRecord.rrdatas = flatten(records.map(x => x.rrdatas)); + templateRecord.rrdatas = + flatten(records.map((x: RecordObject) => x.rrdatas)); } changesArray.push(templateRecord); } @@ -643,7 +658,7 @@ class Zone extends ServiceObject { * //- * zone.export(zoneFilename).then(() => {}); */ - export(localPath: string, callback) { + export(localPath: string, callback: (err: Error|null) => void) { this.getRecords((err, records) => { if (err) { callback(err); @@ -718,8 +733,13 @@ class Zone extends ServiceObject { * const changes = data[0]; * }); */ - getChanges(query, callback?) { - if (is.fn(query)) { + getChanges(callback: GetChangesCallback): void; + getChanges(query: GetChangesRequest, callback: GetChangesCallback): void; + getChanges( + queryOrCallback: GetChangesRequest|GetChangesCallback, + callback?: GetChangesCallback) { + let query = queryOrCallback as GetChangesRequest; + if (typeof query === 'function') { callback = query; query = {}; } @@ -734,10 +754,10 @@ class Zone extends ServiceObject { }, (err, resp) => { if (err) { - callback(err, null, null, resp); + callback!(err, null, null, resp); return; } - const changes = (resp.changes || []).map(change => { + const changes = (resp.changes || []).map((change: Change) => { const changeInstance = this.change(change.id); changeInstance.metadata = change; return changeInstance; @@ -748,7 +768,7 @@ class Zone extends ServiceObject { pageToken: resp.nextPageToken, }); } - callback(null, changes, nextQuery, resp); + callback!(null, changes, nextQuery, resp); }); } /** @@ -879,12 +899,12 @@ class Zone extends ServiceObject { callback!(err, null, null, resp); return; } - let records = (resp.rrsets || []).map(record => { - return this.record(record.type, record); + let records = (resp.rrsets || []).map((record: RecordMetadata) => { + return this.record(record.type!, record); }); if ((query as GetRecordsRequest).filterByTypes_) { - records = records.filter(record => { - return (query as GetRecordsRequest).filterByTypes_![record.type]; + records = records.filter((record: RecordMetadata) => { + return (query as GetRecordsRequest).filterByTypes_![record.type!]; }); } let nextQuery: {}|null = null; @@ -1009,7 +1029,7 @@ class Zone extends ServiceObject { * delete: oldARecord * }, (err, change, apiResponse) => {}); */ - record(type: string, metadata: {}) { + record(type: string, metadata: RecordMetadata) { return new Record(this, type, metadata); } /** diff --git a/system-test/dns.ts b/system-test/dns.ts index c51fdab..2802476 100644 --- a/system-test/dns.ts +++ b/system-test/dns.ts @@ -25,6 +25,8 @@ const tmp = require('tmp'); import * as uuid from 'uuid'; import {DNS} from '../src'; import {ChangeCallback} from '../src/change'; +import {Record} from '../src'; +import {Response} from 'request'; const dns = new DNS(); const DNS_DOMAIN = process.env.GCLOUD_TESTS_DNS_DOMAIN || 'gitnpm.com.'; @@ -175,7 +177,7 @@ describe('dns', () => { }); tmp.setGracefulCleanup(); - tmp.file((err, tmpFilePath) => { + tmp.file((err: Error, tmpFilePath: string) => { assert.ifError(err); fs.writeFileSync(tmpFilePath, zoneFileTemplate, 'utf-8'); ZONE.empty(err => { @@ -191,7 +193,7 @@ describe('dns', () => { })[0]; assert.strictEqual( - spfRecord.toJSON().rrdatas[0], + spfRecord.toJSON().rrdatas![0], '"v=spf1" "mx:' + DNS_DOMAIN + '" "-all"'); const txtRecord = records!.filter(record => { @@ -199,7 +201,7 @@ describe('dns', () => { })[0]; assert.strictEqual( - txtRecord.toJSON().rrdatas[0], + txtRecord.toJSON().rrdatas![0], '"google-site-verification=xxxxxxxxxxxxYYYYYYXXX"'); done(); @@ -211,7 +213,7 @@ describe('dns', () => { it('should export records to a zone file', done => { tmp.setGracefulCleanup(); - tmp.file((err, tmpFilename) => { + tmp.file((err: Error, tmpFilename: string) => { assert.ifError(err); async.series( [ @@ -245,7 +247,7 @@ describe('dns', () => { it('should get a list of changes', done => { ZONE.getChanges((err, changes) => { assert.ifError(err); - assert(changes.length >= 0); + assert(changes!.length >= 0); done(); }); }); @@ -253,7 +255,7 @@ describe('dns', () => { it('should get metadata', done => { ZONE.getChanges((err, changes) => { assert.ifError(err); - const change = changes[0]; + const change = changes![0]; const expectedMetadata = change.metadata; change.getMetadata((err, metadata) => { assert.ifError(err); @@ -292,13 +294,15 @@ describe('dns', () => { ZONE.replaceRecords('cname', newRecords, err => { assert.ifError(err); - const onRecordsReceived = (err, records, nextQuery) => { - if (nextQuery) { - ZONE.getRecords(nextQuery, onRecordsReceived); - return; - } - ZONE.deleteRecords(newRecords, done); - }; + const onRecordsReceived = + (err?: Error|null, records?: Record[]|null, nextQuery?: {}|null, + apiResponse?: Response) => { + if (nextQuery) { + ZONE.getRecords(nextQuery, onRecordsReceived); + return; + } + ZONE.deleteRecords(newRecords, done); + }; ZONE.getRecords( { type: 'cname', diff --git a/test/change.ts b/test/change.ts index 5217f23..991d9d4 100644 --- a/test/change.ts +++ b/test/change.ts @@ -21,12 +21,13 @@ import * as extend from 'extend'; import * as proxyquire from 'proxyquire'; import {ServiceObject, ServiceObjectConfig} from '@google-cloud/common'; import * as promisify from '@google-cloud/promisify'; +import {Response} from 'request'; +import {Change} from '../src/change'; let promisified = false; const fakePromisify = extend({}, promisify, { - // tslint:disable-next-line:variable-name - promisifyAll(Class) { - if (Class.name === 'Change') { + promisifyAll(esClass: Function) { + if (esClass.name === 'Change') { promisified = true; } }, @@ -41,9 +42,10 @@ class FakeServiceObject extends ServiceObject { } describe('Change', () => { - // tslint:disable-next-line:variable-name - let Change; - let change; + // tslint:disable-next-line:variable-name no-any + let Change: any; + // tslint:disable-next-line: no-any + let change: any; const ZONE = { name: 'zone-name', @@ -90,7 +92,7 @@ describe('Change', () => { it('should call the parent change method', done => { const config = {}; - change.parent.createChange = config_ => { + change.parent.createChange = (config_: {}) => { assert.strictEqual(config, config_); done(); }; @@ -103,19 +105,19 @@ describe('Change', () => { const apiResponse = {}; beforeEach(() => { - change.parent.createChange = (config, callback) => { + change.parent.createChange = (config: {}, callback: Function) => { callback(error, null, apiResponse); }; }); it('should execute callback with error & apiResponse', done => { - change.create({}, (err, change, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(change, null); - assert.strictEqual(apiResponse_, apiResponse); - - done(); - }); + change.create( + {}, (err: Error, change: Change, apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(change, null); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); @@ -127,22 +129,23 @@ describe('Change', () => { const apiResponse = {}; beforeEach(() => { - change.parent.createChange = (config, callback) => { + change.parent.createChange = (config: {}, callback: Function) => { callback(null, changeInstance, apiResponse); }; }); it('should execute callback with self & API response', done => { - change.create({}, (err, change_, apiResponse_) => { - assert.ifError(err); - assert.strictEqual(change_, change); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + change.create( + {}, (err: Error, change_: Change, apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(change_, change); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); it('should assign the ID and metadata from the change', done => { - change.create({}, (err, change_) => { + change.create({}, (err: Error, change_: Change) => { assert.ifError(err); assert.strictEqual(change_.id, changeInstance.id); assert.strictEqual(change_.metadata, changeInstance.metadata); diff --git a/test/index.ts b/test/index.ts index a625adc..0c999d3 100644 --- a/test/index.ts +++ b/test/index.ts @@ -19,26 +19,27 @@ import * as arrify from 'arrify'; import * as assert from 'assert'; import * as extend from 'extend'; -import * as nodeutil from 'util'; import * as proxyquire from 'proxyquire'; import {Service, ServiceConfig, ServiceOptions} from '@google-cloud/common'; import {util} from '@google-cloud/common'; import * as promisify from '@google-cloud/promisify'; +import {RequestOptions} from 'http'; +import {CoreOptions, OptionsWithUri, Response} from 'request'; +import {Zone} from '../src'; let extended = false; const fakePaginator = { paginator: { - // tslint:disable-next-line:variable-name - extend(Class, methods) { - if (Class.name !== 'DNS') { + extend(esClass: Function, methods: string[]) { + if (esClass.name !== 'DNS') { return; } extended = true; methods = arrify(methods); - assert.strictEqual(Class.name, 'DNS'); + assert.strictEqual(esClass.name, 'DNS'); assert.deepStrictEqual(methods, ['getZones']); }, - streamify(methodName) { + streamify(methodName: string) { return methodName; }, }, @@ -60,8 +61,8 @@ const originalFakeUtil = extend(true, {}, fakeUtil); let promisified = false; const fakePromisify = extend({}, promisify, { // tslint:disable-next-line:variable-name - promisifyAll(Class, options) { - if (Class.name !== 'DNS') { + promisifyAll(esClass: Function, options: promisify.PromisifyAllOptions) { + if (esClass.name !== 'DNS') { return; } promisified = true; @@ -77,8 +78,10 @@ class FakeZone { } describe('DNS', () => { - let DNS; - let dns; + // tslint:disable-next-line: no-any + let DNS: any; + // tslint:disable-next-line: no-any + let dns: any; const PROJECT_ID = 'project-id'; @@ -154,7 +157,7 @@ describe('DNS', () => { it('should use a provided description', done => { const cfg = extend({}, config, {description: 'description'}); - dns.request = reqOpts => { + dns.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.json.description, cfg.description); done(); }; @@ -163,7 +166,7 @@ describe('DNS', () => { }); it('should default a description to ""', done => { - dns.request = reqOpts => { + dns.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.json.description, ''); done(); }; @@ -172,10 +175,9 @@ describe('DNS', () => { }); it('should make the correct API request', done => { - dns.request = reqOpts => { + dns.request = (reqOpts: OptionsWithUri) => { assert.strictEqual(reqOpts.method, 'POST'); assert.strictEqual(reqOpts.uri, '/managedZones'); - const expectedBody = extend({}, config, { name: zoneName, description: '', @@ -193,18 +195,20 @@ describe('DNS', () => { const apiResponse = {a: 'b', c: 'd'}; beforeEach(() => { - dns.request = (reqOpts, callback) => { + dns.request = (reqOpts: {}, callback: Function) => { callback(error, apiResponse); }; }); it('should execute callback with error and API response', done => { - dns.createZone(zoneName, config, (err, zone, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(zone, null); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + dns.createZone( + zoneName, config, + (err: Error, zone: Zone, apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(zone, null); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); @@ -213,7 +217,7 @@ describe('DNS', () => { const zone = {}; beforeEach(() => { - dns.request = (reqOpts, callback) => { + dns.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponse); }; @@ -223,7 +227,7 @@ describe('DNS', () => { }); it('should create a zone from the response', done => { - dns.zone = name => { + dns.zone = (name: string) => { assert.strictEqual(name, apiResponse.name); setImmediate(done); return zone; @@ -233,17 +237,19 @@ describe('DNS', () => { }); it('should execute callback with zone and API response', done => { - dns.createZone(zoneName, config, (err, zone_, apiResponse_) => { - assert.ifError(err); - assert.strictEqual(zone_, zone); - assert.strictEqual(apiResponse_, apiResponse); - - done(); - }); + dns.createZone( + zoneName, config, + (err: Error, zone_: Zone, apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(zone_, zone); + assert.strictEqual(apiResponse_, apiResponse); + + done(); + }); }); it('should set the metadata to the response', done => { - dns.createZone(zoneName, config, (err, zone) => { + dns.createZone(zoneName, config, (err: Error, zone: Zone) => { assert.strictEqual(zone.metadata, apiResponse); done(); }); @@ -255,7 +261,7 @@ describe('DNS', () => { it('should make the correct request', done => { const query = {a: 'b', c: 'd'}; - dns.request = reqOpts => { + dns.request = (reqOpts: OptionsWithUri) => { assert.strictEqual(reqOpts.uri, '/managedZones'); assert.strictEqual(reqOpts.qs, query); @@ -266,7 +272,7 @@ describe('DNS', () => { }); it('should use an empty query if one was not provided', done => { - dns.request = reqOpts => { + dns.request = (reqOpts: CoreOptions) => { assert.strictEqual(Object.keys(reqOpts.qs).length, 0); done(); }; @@ -279,20 +285,23 @@ describe('DNS', () => { const apiResponse = {a: 'b', c: 'd'}; beforeEach(() => { - dns.request = (reqOpts, callback) => { + dns.request = (reqOpts: {}, callback: Function) => { callback(error, apiResponse); }; }); it('should execute callback with error and API response', done => { - dns.getZones({}, (err, zones, nextQuery, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(zones, null); - assert.strictEqual(nextQuery, null); - assert.strictEqual(apiResponse_, apiResponse); - - done(); - }); + dns.getZones( + {}, + (err: Error, zones: Zone[], nextQuery: {}, + apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(zones, null); + assert.strictEqual(nextQuery, null); + assert.strictEqual(apiResponse_, apiResponse); + + done(); + }); }); }); @@ -301,7 +310,7 @@ describe('DNS', () => { const apiResponse = {managedZones: [zone]}; beforeEach(() => { - dns.request = (reqOpts, callback) => { + dns.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponse); }; @@ -311,7 +320,7 @@ describe('DNS', () => { }); it('should create zones from the response', done => { - dns.zone = zoneName => { + dns.zone = (zoneName: string) => { assert.strictEqual(zoneName, zone.name); setImmediate(done); return zone; @@ -328,11 +337,11 @@ describe('DNS', () => { const query = {a: 'b', c: 'd'}; const originalQuery = extend({}, query); - dns.request = (reqOpts, callback) => { + dns.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponseWithNextPageToken); }; - dns.getZones(query, (err, zones, nextQuery) => { + dns.getZones(query, (err: Error, zones: Zone[], nextQuery: {}) => { assert.ifError(err); // Check the original query wasn't modified. @@ -348,18 +357,21 @@ describe('DNS', () => { }); it('should execute callback with zones and API response', done => { - dns.getZones({}, (err, zones, nextQuery, apiResponse_) => { - assert.ifError(err); - assert.strictEqual(zones[0], zone); - assert.strictEqual(nextQuery, null); - assert.strictEqual(apiResponse_, apiResponse); - - done(); - }); + dns.getZones( + {}, + (err: Error, zones: Zone[], nextQuery: {}, + apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(zones[0], zone); + assert.strictEqual(nextQuery, null); + assert.strictEqual(apiResponse_, apiResponse); + + done(); + }); }); it('should assign metadata to zones', done => { - dns.getZones({}, (err, zones) => { + dns.getZones({}, (err: Error, zones: Zone[]) => { assert.ifError(err); assert.strictEqual(zones[0].metadata, zone); done(); diff --git a/test/record.ts b/test/record.ts index 2470c61..a2c9622 100644 --- a/test/record.ts +++ b/test/record.ts @@ -20,12 +20,12 @@ import * as assert from 'assert'; import * as extend from 'extend'; import * as proxyquire from 'proxyquire'; import * as promisify from '@google-cloud/promisify'; +import {Record} from '../src'; let promisified = false; const fakePromisify = extend({}, promisify, { - // tslint:disable-next-line:variable-name - promisifyAll(Class, options) { - if (Class.name !== 'Record') { + promisifyAll(esClass: Function, options: promisify.PromisifyAllOptions) { + if (esClass.name !== 'Record') { return; } promisified = true; @@ -34,9 +34,10 @@ const fakePromisify = extend({}, promisify, { }); describe('Record', () => { - // tslint:disable-next-line:variable-name - let Record; - let record; + // tslint:disable-next-line + let Record: any; + // tslint:disable-next-line:no-any + let record: any; const ZONE = { deleteRecords() {}, @@ -85,7 +86,7 @@ describe('Record', () => { }); it('should re-assign rrdatas to data', () => { - const originalRrdatas = []; + const originalRrdatas = new Array(); const recordThatHadRrdatas = new Record(ZONE, TYPE, { rrdatas: originalRrdatas, @@ -294,7 +295,7 @@ describe('Record', () => { describe('delete', () => { it('should call zone.deleteRecords', done => { - record.zone_.deleteRecords = (records, callback) => { + record.zone_.deleteRecords = (records: Record[], callback: Function) => { assert.strictEqual(records, record); callback(); }; diff --git a/test/zone.ts b/test/zone.ts index 579c8d7..c22db22 100644 --- a/test/zone.ts +++ b/test/zone.ts @@ -24,12 +24,14 @@ import * as proxyquire from 'proxyquire'; import {ServiceObject, ServiceObjectConfig} from '@google-cloud/common'; import * as promisify from '@google-cloud/promisify'; import * as uuid from 'uuid'; +import {CreateChangeRequest, Change} from '../src/change'; +import {Record, RecordObject} from '../src/record'; +import {CoreOptions, OptionsWithUri, Response} from 'request'; let promisified = false; const fakePromisify = extend({}, promisify, { - // tslint:disable-next-line:variable-name - promisifyAll(Class, options) { - if (Class.name !== 'Zone') { + promisifyAll(esClass: Function, options: promisify.PromisifyAllOptions) { + if (esClass.name !== 'Zone') { return; } promisified = true; @@ -37,15 +39,15 @@ const fakePromisify = extend({}, promisify, { } }); -let parseOverride; +let parseOverride: Function|null; const fakeDnsZonefile = { parse() { return (parseOverride || (() => {})).apply(null, arguments); }, }; -let writeFileOverride; -let readFileOverride; +let writeFileOverride: Function|null; +let readFileOverride: Function|null; const fakeFs = { readFile() { return (readFileOverride || (() => {})).apply(null, arguments); @@ -75,7 +77,7 @@ class FakeRecord { } class FakeServiceObject extends ServiceObject { - calledWith_; + calledWith_: IArguments; constructor(config: ServiceObjectConfig) { super(config); this.calledWith_ = arguments; @@ -85,26 +87,26 @@ class FakeServiceObject extends ServiceObject { let extended = false; const fakePaginator = { paginator: { - // tslint:disable-next-line:variable-name - extend(Class, methods) { - if (Class.name !== 'Zone') { + extend(esClass: Function, methods: string[]) { + if (esClass.name !== 'Zone') { return; } extended = true; methods = arrify(methods); - assert.strictEqual(Class.name, 'Zone'); + assert.strictEqual(esClass.name, 'Zone'); assert.deepStrictEqual(methods, ['getChanges', 'getRecords']); }, - streamify(methodName) { + streamify(methodName: string) { return methodName; }, }, }; describe('Zone', () => { - // tslint:disable-next-line:variable-name - let Zone; - let zone; + // tslint:disable-next-line + let Zone: any; + // tslint:disable-next-line:no-any + let zone: any; const DNS = { createZone() {}, @@ -155,7 +157,7 @@ describe('Zone', () => { it('should inherit from ServiceObject', done => { const dnsInstance = extend({}, DNS, { createZone: { - bind(context) { + bind(context: {}) { assert.strictEqual(context, dnsInstance); done(); }, @@ -183,10 +185,11 @@ describe('Zone', () => { it('should create a change with additions', done => { const records = ['a', 'b', 'c']; - zone.createChange = (options, callback) => { - assert.strictEqual(options.add, records); - callback(); - }; + zone.createChange = + (options: CreateChangeRequest, callback: Function) => { + assert.strictEqual(options.add, records); + callback(); + }; zone.addRecords(records, done); }); @@ -203,7 +206,7 @@ describe('Zone', () => { }); describe('createChange', () => { - function generateRecord(recordJson?) { + function generateRecord(recordJson?: {}) { recordJson = extend( { name: uuid.v1(), @@ -230,7 +233,7 @@ describe('Zone', () => { const expectedAdditions = recordsToAdd.map(x => x.toJSON()); - zone.request = reqOpts => { + zone.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.json.add, undefined); assert.deepStrictEqual(reqOpts.json.additions, expectedAdditions); done(); @@ -244,7 +247,7 @@ describe('Zone', () => { const expectedDeletions = recordsToDelete.map(x => x.toJSON()); - zone.request = reqOpts => { + zone.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.json.delete, undefined); assert.deepStrictEqual(reqOpts.json.deletions, expectedDeletions); done(); @@ -259,9 +262,10 @@ describe('Zone', () => { generateRecord({name: 'name.com.', type: 'mx'}), ]; - zone.request = reqOpts => { - const expectedRRDatas = - flatten(recordsToAdd.map(x => x.toJSON()).map(x => x.rrdatas)); + zone.request = (reqOpts: CoreOptions) => { + const expectedRRDatas = flatten( + // tslint:disable-next-line:no-any + recordsToAdd.map(x => x.toJSON()).map((x: any) => x!.rrdatas)); assert.deepStrictEqual(reqOpts.json.additions, [ { @@ -278,7 +282,7 @@ describe('Zone', () => { }); it('should make correct API request', done => { - zone.request = reqOpts => { + zone.request = (reqOpts: OptionsWithUri) => { assert.strictEqual(reqOpts.method, 'POST'); assert.strictEqual(reqOpts.uri, '/changes'); @@ -293,17 +297,18 @@ describe('Zone', () => { const apiResponse = {a: 'b', c: 'd'}; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(error, apiResponse); }; }); it('should execute callback with error & API response', done => { - zone.createChange({add: []}, (err, change, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + zone.createChange( + {add: []}, (err: Error, change: Change, apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); @@ -311,7 +316,7 @@ describe('Zone', () => { const apiResponse = {id: 1, a: 'b', c: 'd'}; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponse); }; }); @@ -319,21 +324,20 @@ describe('Zone', () => { it('should execute callback with Change & API response', done => { const change = {}; - zone.change = id => { + zone.change = (id: string) => { assert.strictEqual(id, apiResponse.id); return change; }; - zone.createChange({add: []}, (err, change_, apiResponse_) => { - assert.ifError(err); - - assert.strictEqual(change_, change); - assert.strictEqual(change_.metadata, apiResponse); - - assert.strictEqual(apiResponse_, apiResponse); - - done(); - }); + zone.createChange( + {add: []}, + (err: Error, change_: Change, apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(change_, change); + assert.strictEqual(change_.metadata, apiResponse); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); }); @@ -353,7 +357,7 @@ describe('Zone', () => { done(); }; - zone.empty = callback => { + zone.empty = (callback: Function) => { callback(); }; @@ -366,7 +370,7 @@ describe('Zone', () => { it('should delete records by type if a string is given', done => { const recordsToDelete = 'ns'; - zone.deleteRecordsByType_ = (types, callback) => { + zone.deleteRecordsByType_ = (types: string[], callback: Function) => { assert.deepStrictEqual(types, [recordsToDelete]); callback(); }; @@ -377,10 +381,11 @@ describe('Zone', () => { it('should create a change if record objects given', done => { const recordsToDelete = {a: 'b', c: 'd'}; - zone.createChange = (options, callback) => { - assert.deepStrictEqual(options.delete, [recordsToDelete]); - callback(); - }; + zone.createChange = + (options: CreateChangeRequest, callback: Function) => { + assert.deepStrictEqual(options.delete, [recordsToDelete]); + callback(); + }; zone.deleteRecords(recordsToDelete, done); }); @@ -399,13 +404,13 @@ describe('Zone', () => { const error = new Error('Error.'); beforeEach(() => { - zone.getRecords = callback => { + zone.getRecords = (callback: Function) => { callback(error); }; }); it('should execute callback with error', done => { - zone.empty(err => { + zone.empty((err: Error) => { assert.strictEqual(err, error); done(); }); @@ -432,13 +437,13 @@ describe('Zone', () => { }); beforeEach(() => { - zone.getRecords = callback => { + zone.getRecords = (callback: Function) => { callback(null, records); }; }); it('should execute callback if no records matched', done => { - zone.getRecords = callback => { + zone.getRecords = (callback: Function) => { callback(null, []); }; @@ -446,10 +451,11 @@ describe('Zone', () => { }); it('should delete non-NS and non-SOA records', done => { - zone.deleteRecords = (recordsToDelete, callback) => { - assert.deepStrictEqual(recordsToDelete, expectedRecordsToDelete); - callback(); - }; + zone.deleteRecords = + (recordsToDelete: string[], callback: Function) => { + assert.deepStrictEqual(recordsToDelete, expectedRecordsToDelete); + callback(); + }; zone.empty(done); }); @@ -485,7 +491,7 @@ describe('Zone', () => { const expectedZonefileContents = 'a\na\na\na'; beforeEach(() => { - zone.getRecords = callback => { + zone.getRecords = (callback: Function) => { callback(null, records); }; }); @@ -495,11 +501,11 @@ describe('Zone', () => { const error = new Error('Error.'); it('should execute callback with error', done => { - zone.getRecords = callback => { + zone.getRecords = (callback: Function) => { callback(error); }; - zone.export(path, err => { + zone.export(path, (err: Error) => { assert.strictEqual(err, error); done(); }); @@ -519,13 +525,14 @@ describe('Zone', () => { describe('write file', () => { it('should write correct zone file', done => { - writeFileOverride = (path_, content, encoding) => { - assert.strictEqual(path_, path); - assert.strictEqual(content, expectedZonefileContents); - assert.strictEqual(encoding, 'utf-8'); + writeFileOverride = + (path_: string, content: string, encoding: string) => { + assert.strictEqual(path_, path); + assert.strictEqual(content, expectedZonefileContents); + assert.strictEqual(encoding, 'utf-8'); - done(); - }; + done(); + }; zone.export(path, assert.ifError); }); @@ -534,13 +541,15 @@ describe('Zone', () => { const error = new Error('Error.'); beforeEach(() => { - writeFileOverride = (path, content, encoding, callback) => { - callback(error); - }; + writeFileOverride = + (path: string, content: string, encoding: string, + callback: Function) => { + callback(error); + }; }); it('should execute the callback with an error', done => { - zone.export(path, err => { + zone.export(path, (err: Error) => { assert.strictEqual(err, error); done(); }); @@ -549,13 +558,15 @@ describe('Zone', () => { describe('success', () => { beforeEach(() => { - writeFileOverride = (path, content, encoding, callback) => { - callback(); - }; + writeFileOverride = + (path: string, content: string, encoding: string, + callback: Function) => { + callback(); + }; }); it('should execute the callback', done => { - zone.export(path, err => { + zone.export(path, (err: Error) => { assert.ifError(err); done(); }); @@ -566,7 +577,7 @@ describe('Zone', () => { describe('getChanges', () => { it('should accept only a callback', done => { - zone.request = reqOpts => { + zone.request = (reqOpts: CoreOptions) => { assert.deepStrictEqual(reqOpts.qs, {}); done(); }; @@ -577,7 +588,7 @@ describe('Zone', () => { it('should accept a sort', done => { const query = {sort: 'desc'}; - zone.request = reqOpts => { + zone.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.qs.sortOrder, 'descending'); assert.strictEqual(reqOpts.qs.sort, undefined); @@ -590,7 +601,7 @@ describe('Zone', () => { it('should make the correct API request', done => { const query = {a: 'b', c: 'd'}; - zone.request = reqOpts => { + zone.request = (reqOpts: OptionsWithUri) => { assert.strictEqual(reqOpts.uri, '/changes'); assert.strictEqual(reqOpts.qs, query); @@ -605,17 +616,20 @@ describe('Zone', () => { const apiResponse = {a: 'b', c: 'd'}; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(error, apiResponse); }; }); it('should execute callback with error & API response', done => { - zone.getChanges({}, (err, changes, nextQuery, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + zone.getChanges( + {}, + (err: Error, changes: Change[], nextQuery: {}, + apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); @@ -625,7 +639,7 @@ describe('Zone', () => { }; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponse); }; }); @@ -639,15 +653,13 @@ describe('Zone', () => { pageToken: nextPageToken, }; - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponseWithNextPageToken); }; - zone.getChanges({}, (err, changes, nextQuery) => { + zone.getChanges({}, (err: Error, changes: Change[], nextQuery: {}) => { assert.ifError(err); - assert.deepStrictEqual(nextQuery, expectedNextQuery); - done(); }); }); @@ -655,18 +667,21 @@ describe('Zone', () => { it('should execute callback with Changes & API response', done => { const change = {}; - zone.change = id => { + zone.change = (id: string) => { assert.strictEqual(id, apiResponse.changes[0].id); return change; }; - zone.getChanges({}, (err, changes, nextQuery, apiResponse_) => { - assert.ifError(err); - assert.strictEqual(changes[0], change); - assert.strictEqual(changes[0].metadata, apiResponse.changes[0]); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + zone.getChanges( + {}, + (err: Error, changes: Change[], nextQuery: {}, + apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(changes[0], change); + assert.strictEqual(changes[0].metadata, apiResponse.changes[0]); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); }); }); @@ -677,21 +692,24 @@ describe('Zone', () => { const apiResponse = {a: 'b', c: 'd'}; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(error, apiResponse); }; }); it('should execute callback with error & API response', done => { - zone.getRecords({}, (err, changes, nextQuery, apiResponse_) => { - assert.strictEqual(err, error); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + zone.getRecords( + {}, + (err: Error, changes: Change[], nextQuery: {}, + apiResponse_: Response) => { + assert.strictEqual(err, error); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); }); it('should not require a query', done => { - zone.getRecords(err => { + zone.getRecords((err: Error) => { assert.strictEqual(err, error); done(); }); @@ -704,7 +722,7 @@ describe('Zone', () => { }; beforeEach(() => { - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponse); }; }); @@ -716,11 +734,11 @@ describe('Zone', () => { }); const expectedNextQuery = {pageToken: nextPageToken}; - zone.request = (reqOpts, callback) => { + zone.request = (reqOpts: {}, callback: Function) => { callback(null, apiResponseWithNextPageToken); }; - zone.getRecords({}, (err, records, nextQuery) => { + zone.getRecords({}, (err: Error, records: Record[], nextQuery: {}) => { assert.ifError(err); assert.deepStrictEqual(nextQuery, expectedNextQuery); done(); @@ -730,18 +748,21 @@ describe('Zone', () => { it('should execute callback with Records & API response', done => { const record = {}; - zone.record = (type, recordObject) => { + zone.record = (type: string, recordObject: RecordObject) => { assert.strictEqual(type, apiResponse.rrsets[0].type); assert.strictEqual(recordObject, apiResponse.rrsets[0]); return record; }; - zone.getRecords({}, (err, records, nextQuery, apiResponse_) => { - assert.ifError(err); - assert.strictEqual(records[0], record); - assert.strictEqual(apiResponse_, apiResponse); - done(); - }); + zone.getRecords( + {}, + (err: Error, records: Record[], nextQuery: {}, + apiResponse_: Response) => { + assert.ifError(err); + assert.strictEqual(records[0], record); + assert.strictEqual(apiResponse_, apiResponse); + done(); + }); it('should not require a query', done => { zone.getRecords(done); @@ -752,7 +773,7 @@ describe('Zone', () => { it('should accept a string type', done => { const types = ['MX', 'CNAME']; - zone.getRecords(types, (err, records) => { + zone.getRecords(types, (err: Error, records: Record[]) => { assert.ifError(err); assert.strictEqual(records.length, 0); @@ -764,7 +785,7 @@ describe('Zone', () => { it('should accept an array of types', done => { const type = 'MX'; - zone.getRecords(type, (err, records) => { + zone.getRecords(type, (err: Error, records: Record[]) => { assert.ifError(err); assert.strictEqual(records.length, 0); @@ -774,7 +795,7 @@ describe('Zone', () => { }); it('should not send filterByTypes_ in API request', done => { - zone.request = reqOpts => { + zone.request = (reqOpts: CoreOptions) => { assert.strictEqual(reqOpts.qs.filterByTypes_, undefined); done(); }; @@ -789,7 +810,7 @@ describe('Zone', () => { const path = './zonefile'; it('should read from the file', done => { - readFileOverride = (path_, encoding) => { + readFileOverride = (path_: string, encoding: string) => { assert.strictEqual(path, path); assert.strictEqual(encoding, 'utf-8'); done(); @@ -802,13 +823,14 @@ describe('Zone', () => { const error = new Error('Error.'); beforeEach(() => { - readFileOverride = (path, encoding, callback) => { - callback(error); - }; + readFileOverride = + (path: string, encoding: string, callback: Function) => { + callback(error); + }; }); it('should execute the callback', done => { - zone.import(path, err => { + zone.import(path, (err: Error) => { assert.strictEqual(err, error); done(); }); @@ -829,22 +851,24 @@ describe('Zone', () => { return parsedZonefile; }; - readFileOverride = (path, encoding, callback) => { - callback(); - }; + readFileOverride = + (path: string, encoding: string, callback: Function) => { + callback(); + }; }); it('should add records', done => { - zone.addRecords = (recordsToCreate, callback) => { - assert.strictEqual(recordsToCreate.length, 1); - const recordToCreate = recordsToCreate[0]; - assert(recordToCreate instanceof FakeRecord); - const args = recordToCreate.calledWith_; - assert.strictEqual(args[0], zone); - assert.strictEqual(args[1], recordType); - assert.strictEqual(args[2], parsedZonefile[recordType]); - callback(); - }; + zone.addRecords = + (recordsToCreate: FakeRecord[], callback: Function) => { + assert.strictEqual(recordsToCreate.length, 1); + const recordToCreate = recordsToCreate[0]; + assert(recordToCreate instanceof FakeRecord); + const args = recordToCreate.calledWith_; + assert.strictEqual(args[0], zone); + assert.strictEqual(args[1], recordType); + assert.strictEqual(args[2], parsedZonefile[recordType]); + callback(); + }; zone.import(path, done); }); @@ -853,7 +877,7 @@ describe('Zone', () => { parsedZonefile.$ttl = defaultTTL; parsedZonefile[recordType] = {}; parsedZonefile.mx = {ttl: '180'}; - zone.addRecords = recordsToCreate => { + zone.addRecords = (recordsToCreate: FakeRecord[]) => { const record1 = recordsToCreate[0].calledWith_[2]; assert.strictEqual(record1.ttl, defaultTTL); const record2 = recordsToCreate[1].calledWith_[2]; @@ -881,7 +905,7 @@ describe('Zone', () => { describe('replaceRecords', () => { it('should get records', done => { const recordType = 'ns'; - zone.getRecords = recordType_ => { + zone.getRecords = (recordType_: string) => { assert.strictEqual(recordType_, recordType); done(); }; @@ -891,13 +915,13 @@ describe('Zone', () => { describe('error', () => { const error = new Error('Error.'); beforeEach(() => { - zone.getRecords = (recordType, callback) => { + zone.getRecords = (recordType: string, callback: Function) => { callback(error); }; }); it('should execute callback with error', done => { - zone.replaceRecords('a', [], err => { + zone.replaceRecords('a', [], (err: Error) => { assert.strictEqual(err, error); done(); }); @@ -918,19 +942,18 @@ describe('Zone', () => { ]; beforeEach(() => { - zone.getRecords = (recordType, callback) => { + zone.getRecords = (recordType: string, callback: Function) => { callback(null, recordsToDelete); }; }); it('should create a change', done => { - zone.createChange = (options, callback) => { - assert.strictEqual(options.add, recordsToCreate); - assert.strictEqual(options.delete, recordsToDelete); - - callback(); - }; - + zone.createChange = + (options: CreateChangeRequest, callback: Function) => { + assert.strictEqual(options.add, recordsToCreate); + assert.strictEqual(options.delete, recordsToDelete); + callback(); + }; zone.replaceRecords('a', recordsToCreate, done); }); }); @@ -939,7 +962,7 @@ describe('Zone', () => { describe('deleteRecordsByType_', () => { it('should get records', done => { const recordType = 'ns'; - zone.getRecords = recordType_ => { + zone.getRecords = (recordType_: string) => { assert.strictEqual(recordType_, recordType); done(); }; @@ -949,13 +972,13 @@ describe('Zone', () => { describe('error', () => { const error = new Error('Error.'); beforeEach(() => { - zone.getRecords = (recordType, callback) => { + zone.getRecords = (recordType: string, callback: Function) => { callback(error); }; }); it('should execute callback with error', done => { - zone.deleteRecordsByType_('a', err => { + zone.deleteRecordsByType_('a', (err: Error) => { assert.strictEqual(err, error); done(); }); @@ -970,21 +993,20 @@ describe('Zone', () => { ]; beforeEach(() => { - zone.getRecords = (recordType, callback) => { + zone.getRecords = (recordType: string, callback: Function) => { callback(null, recordsToDelete); }; }); it('should execute callback if no records matched', done => { - zone.getRecords = (recordType, callback) => { + zone.getRecords = (recordType: string, callback: Function) => { callback(null, []); }; - zone.deleteRecordsByType_('a', done); }); it('should delete records', done => { - zone.deleteRecords = (records, callback) => { + zone.deleteRecords = (records: Record[], callback: Function) => { assert.strictEqual(records, recordsToDelete); callback(); }; diff --git a/tsconfig.json b/tsconfig.json index 5dc9ad6..b10ee49 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,8 +2,7 @@ "extends": "./node_modules/gts/tsconfig-google.json", "compilerOptions": { "rootDir": ".", - "outDir": "build", - "noImplicitAny": false + "outDir": "build" }, "include": [ "src/*.ts",