dse-driver
Advanced tools
Comparing version 2.2.0 to 2.3.0
@@ -10,2 +10,3 @@ /** | ||
import * as tls from 'tls'; | ||
import { URL } from 'url'; | ||
import { auth } from './lib/auth'; | ||
@@ -77,3 +78,3 @@ import { policies } from './lib/policies'; | ||
rowCallback: (n: number, row: types.Row) => void, | ||
callback?: EmptyCallback): void; | ||
callback?: ValueCallback<types.ResultSet>): void; | ||
@@ -83,3 +84,3 @@ eachRow(query: string, | ||
rowCallback: (n: number, row: types.Row) => void, | ||
callback?: EmptyCallback): void; | ||
callback?: ValueCallback<types.ResultSet>): void; | ||
@@ -89,3 +90,3 @@ eachRow(query: string, | ||
stream(query: string, params?: ArrayOrObject, options?: QueryOptions, callback?: EmptyCallback): void; | ||
stream(query: string, params?: ArrayOrObject, options?: QueryOptions, callback?: EmptyCallback): events.EventEmitter; | ||
@@ -188,7 +189,15 @@ batch( | ||
export interface ClientOptions { | ||
contactPoints: string[]; | ||
contactPoints?: string[]; | ||
localDataCenter?: string; | ||
keyspace?: string; | ||
authProvider?: auth.AuthProvider; | ||
credentials?: { | ||
username: string; | ||
password: string; | ||
} | ||
cloud?: { | ||
secureConnectBundle: string | URL; | ||
}; | ||
encoding?: { | ||
@@ -195,0 +204,0 @@ map?: Function; |
@@ -8,2 +8,3 @@ /** | ||
'use strict'; | ||
const util = require('util'); | ||
@@ -55,3 +56,2 @@ const policies = require('./policies'); | ||
queryOptions: { | ||
consistency: types.consistencies.localOne, | ||
fetchSize: 5000, | ||
@@ -110,12 +110,21 @@ prepare: false, | ||
const options = utils.deepExtend(baseOptions, defaultOptions(), userOptions); | ||
if (!util.isArray(options.contactPoints) || options.contactPoints.length === 0) { | ||
throw new TypeError('Contacts points are not defined.'); | ||
} | ||
for (let i = 0; i < options.contactPoints.length; i++) { | ||
const hostName = options.contactPoints[i]; | ||
if (!hostName) { | ||
throw new TypeError(util.format('Contact point %s (%s) is not a valid host name, ' + | ||
'the following values are valid contact points: ipAddress, hostName or ipAddress:port', i, hostName)); | ||
if (!options.cloud) { | ||
if (!util.isArray(options.contactPoints) || options.contactPoints.length === 0) { | ||
throw new TypeError('Contacts points are not defined.'); | ||
} | ||
for (let i = 0; i < options.contactPoints.length; i++) { | ||
const hostName = options.contactPoints[i]; | ||
if (!hostName) { | ||
throw new TypeError(util.format('Contact point %s (%s) is not a valid host name, ' + | ||
'the following values are valid contact points: ipAddress, hostName or ipAddress:port', i, hostName)); | ||
} | ||
} | ||
options.sni = undefined; | ||
} else { | ||
validateCloudOptions(options); | ||
} | ||
if (!options.logEmitter) { | ||
@@ -160,2 +169,23 @@ options.logEmitter = function () {}; | ||
/** | ||
* Validates the options to connect to a cloud instance. | ||
* @private | ||
*/ | ||
function validateCloudOptions(options) { | ||
const bundle = options.cloud.secureConnectBundle; | ||
// eslint-disable-next-line no-undef | ||
if (!(typeof bundle === 'string' || (typeof URL !== 'undefined' && bundle instanceof URL))) { | ||
throw new TypeError('secureConnectBundle in cloud options must be of type string'); | ||
} | ||
if (options.contactPoints) { | ||
throw new TypeError('Contact points can not be defined when cloud settings are provided'); | ||
} | ||
if (options.sslOptions) { | ||
throw new TypeError('SSL options can not be defined when cloud settings are provided'); | ||
} | ||
} | ||
/** | ||
* Validates the policies from the client options. | ||
@@ -294,9 +324,10 @@ * @param {ClientOptions.policies} policiesOptions | ||
/** | ||
* Sets the default options that depend on the protocol version. | ||
* @param {ClientOptions} options | ||
* @param {Number} version | ||
* Sets the default options that depend on the protocol version and other metadata. | ||
* @param {Client} client | ||
*/ | ||
function setProtocolDependentDefaults(options, version) { | ||
function setMetadataDependent(client) { | ||
const version = client.controlConnection.protocolVersion; | ||
let coreConnectionsPerHost = coreConnectionsPerHostV3; | ||
let maxRequestsPerConnection = maxRequestsPerConnectionV3; | ||
if (!types.protocolVersion.uses2BytesStreamIds(version)) { | ||
@@ -306,3 +337,10 @@ coreConnectionsPerHost = coreConnectionsPerHostV2; | ||
} | ||
options.pooling = utils.deepExtend({}, { coreConnectionsPerHost, maxRequestsPerConnection }, options.pooling); | ||
if (client.options.queryOptions.consistency === undefined) { | ||
client.options.queryOptions.consistency = | ||
client.metadata.isDbaas() ? types.consistencies.localQuorum : types.consistencies.localOne; | ||
} | ||
client.options.pooling = utils.deepExtend( | ||
{}, { coreConnectionsPerHost, maxRequestsPerConnection }, client.options.pooling); | ||
} | ||
@@ -316,5 +354,5 @@ | ||
exports.maxRequestsPerConnectionV3 = maxRequestsPerConnectionV3; | ||
exports.setProtocolDependentDefaults = setProtocolDependentDefaults; | ||
exports.setMetadataDependent = setMetadataDependent; | ||
exports.continuousPageUnitBytes = continuousPageUnitBytes; | ||
exports.continuousPageDefaultSize = continuousPageDefaultSize; | ||
exports.continuousPageDefaultHighWaterMark = continuousPageDefaultHighWaterMark; |
@@ -21,11 +21,8 @@ /** | ||
const DefaultExecutionOptions = require('./execution-options').DefaultExecutionOptions; | ||
const ControlConnection = require('./control-connection'); | ||
const RequestHandler = require('./request-handler'); | ||
const PrepareHandler = require('./prepare-handler'); | ||
const InsightsClient = require('./insights-client'); | ||
const cloud = require('./cloud'); | ||
// Allow injection of the following modules | ||
/* eslint-disable prefer-const */ | ||
let ControlConnection = require('./control-connection'); | ||
let RequestHandler = require('./request-handler'); | ||
let PrepareHandler = require('./prepare-handler'); | ||
/* eslint-enable prefer-const */ | ||
/** | ||
@@ -65,2 +62,4 @@ * Max amount of pools being warmup in parallel, when warmup is enabled | ||
* @property {String} credentials.password The password to use for plain-text authentication. | ||
* @property {Object} [cloud] The options to connect to a cloud instance. | ||
* @property {String|URL} cloud.secureConnectBundle Determines the file path for the credentials file bundle. | ||
* @property {Number} refreshSchemaDelay The default window size in milliseconds used to debounce node list and schema | ||
@@ -236,3 +235,7 @@ * refresh metadata requests. Default: 1000. | ||
* Default: false. | ||
* @property {Number} [consistency] [Consistency level]{@link module:types~consistencies}. Default: localOne. | ||
* @property {Number} [consistency] [Consistency level]{@link module:types~consistencies}. | ||
* <p> | ||
* Defaults to <code>localOne</code> for Apache Cassandra and DSE deployments. | ||
* For DataStax Apollo, it defaults to <code>localQuorum</code>. | ||
* </p> | ||
* @property {Object} [customPayload] Key-value payload to be passed to the server. On the Cassandra side, | ||
@@ -472,2 +475,3 @@ * implementations of QueryHandler can use this data. | ||
utils.series([ | ||
next => cloud.init(this.options, next), | ||
function initControlConnection(next) { | ||
@@ -487,3 +491,3 @@ self.controlConnection.init(next); | ||
function setPoolOptionsAndWarmup(next) { | ||
clientOptions.setProtocolDependentDefaults(self.options, self.controlConnection.protocolVersion); | ||
clientOptions.setMetadataDependent(self); | ||
@@ -490,0 +494,0 @@ if (!self.options.pooling.warmup) { |
@@ -12,2 +12,3 @@ /** | ||
const tls = require('tls'); | ||
const net = require('net'); | ||
@@ -25,6 +26,2 @@ const Encoder = require('./encoder.js'); | ||
// Allow injection of net module | ||
// eslint-disable-next-line prefer-const | ||
let net = require('net'); | ||
/** | ||
@@ -55,6 +52,13 @@ * Represents a connection to a Cassandra node | ||
* With direct connect, this is the address and port. | ||
* With SNI, this will be the address and port of the proxy, plus the server name. | ||
* @type {String} | ||
*/ | ||
this.endpointFriendlyName = endpoint; | ||
this.endpointFriendlyName = this.endpoint; | ||
if (options.sni) { | ||
this._serverName = endpoint; | ||
this.endpoint = `${options.sni.addressResolver.getIp()}:${options.sni.port}`; | ||
this.endpointFriendlyName = `${this.endpoint} (${this._serverName})`; | ||
} | ||
if (!this.endpoint || this.endpoint.indexOf(':') < 0) { | ||
@@ -164,6 +168,11 @@ throw new Error('EndPoint must contain the ip address and port separated by : symbol'); | ||
}); | ||
} else { | ||
} | ||
else { | ||
// Use TLS | ||
const sslOptions = utils.extend({ rejectUnauthorized: false }, this.options.sslOptions); | ||
if (this.options.sni) { | ||
sslOptions.servername = this._serverName; | ||
} | ||
this.netClient = tls.connect(this.port, this.address, sslOptions, function tlsConnectCallback() { | ||
@@ -455,2 +464,3 @@ self.log('verbose', `Secure socket connected to ${self.endpointFriendlyName}`); | ||
* @param {String} query | ||
* @param {String} keyspace | ||
* @param {function} callback | ||
@@ -457,0 +467,0 @@ */ |
@@ -11,2 +11,3 @@ /** | ||
const net = require('net'); | ||
const dns = require('dns'); | ||
@@ -23,4 +24,2 @@ const errors = require('./errors'); | ||
const f = util.format; | ||
// eslint-disable-next-line prefer-const | ||
let dns = require('dns'); | ||
@@ -36,2 +35,4 @@ const selectPeers = "SELECT * FROM system.peers"; | ||
}; | ||
const supportedProductTypeKey = 'PRODUCT_TYPE'; | ||
const supportedDbaas = 'DATASTAX_APOLLO'; | ||
@@ -194,6 +195,21 @@ /** | ||
utils.each( | ||
this.options.contactPoints, | ||
(name, eachNext) => this.parseEachContactPoint(name, eachNext), | ||
contactPointsResolutionCb); | ||
if (!this.options.sni) { | ||
utils.each( | ||
this.options.contactPoints, | ||
(name, eachNext) => this.parseEachContactPoint(name, eachNext), | ||
contactPointsResolutionCb); | ||
} else { | ||
this.options.contactPoints.forEach(cp => this._contactPoints.add(cp)); | ||
const address = this.options.sni.address; | ||
const separatorIndex = address.lastIndexOf(':'); | ||
if (separatorIndex === -1) { | ||
return callback(new errors.DriverInternalError('The SNI endpoint address should contain ip/name and port')); | ||
} | ||
const nameOrIp = address.substr(0, separatorIndex); | ||
this.options.sni.port = address.substr(separatorIndex + 1); | ||
this.options.sni.addressResolver = new utils.AddressResolver({ nameOrIp, dns }); | ||
this.options.sni.addressResolver.init(contactPointsResolutionCb); | ||
} | ||
}; | ||
@@ -490,2 +506,9 @@ | ||
}, | ||
function getOptions(next) { | ||
if (!initializing) { | ||
return next(); | ||
} | ||
self.getSupportedOptions(next); | ||
}, | ||
function getLocalAndPeersInfo(next) { | ||
@@ -567,2 +590,18 @@ self.log('info', | ||
ControlConnection.prototype.getSupportedOptions = function (callback) { | ||
const c = this.connection; | ||
c.sendStream(requests.options, null, (err, response) => { | ||
if (!err) { | ||
// response.supported is a string multi map, decoded as an Object. | ||
const productType = response.supported && response.supported[supportedProductTypeKey]; | ||
if (Array.isArray(productType) && productType[0] === supportedDbaas) { | ||
this.metadata.setProductTypeAsDbaas(); | ||
} | ||
} | ||
callback(err); | ||
}); | ||
}; | ||
/** | ||
@@ -737,3 +776,6 @@ * @param {String} type | ||
const endpoint = c.endpoint; | ||
// Note that with SNI enabled, we can trust that rpc_address will contain a valid value. | ||
const endpoint = !this.options.sni | ||
? c.endpoint | ||
: `${row['rpc_address']}:${this.options.protocolOptions.port}`; | ||
@@ -740,0 +782,0 @@ if (initializing) { |
@@ -60,2 +60,3 @@ /** | ||
this._state = state.initial; | ||
this._host = host; | ||
this.responseCounter = 0; | ||
@@ -238,3 +239,6 @@ this.options = host.options; | ||
_createConnection() { | ||
const c = new Connection(this._address, this.protocolVersion, this.options); | ||
const endpointOrServerName = !this.options.sni | ||
? this._address : this._host.hostId.toString(); | ||
const c = new Connection(endpointOrServerName, this.protocolVersion, this.options); | ||
this._addListeners(c); | ||
@@ -353,4 +357,7 @@ return c; | ||
} | ||
const self = this; | ||
this._newConnectionTimeout = setTimeout(function newConnectionTimeoutExpired() { | ||
self._newConnectionTimeout = null; | ||
@@ -362,2 +369,10 @@ if (self.connections.length >= self.coreConnectionsLength) { | ||
} | ||
if (delay > 0 && self.options.sni) { | ||
// We use delay > 0 as an indication that it's a reconnection. | ||
// A reconnection schedule can use delay = 0 as well, but it's a good enough signal. | ||
self.options.sni.addressResolver.refresh(() => self._attemptNewConnection(utils.noop)); | ||
return; | ||
} | ||
self._attemptNewConnection(utils.noop); | ||
@@ -364,0 +379,0 @@ }, delay); |
@@ -103,3 +103,3 @@ /** | ||
// We shouldn't try to recover | ||
this._client.log('error', `Insights startup message could not be sent (${err})`, err); | ||
this._client.log('verbose', `Insights startup message could not be sent (${err})`, err); | ||
this._errorCallback(err); | ||
@@ -106,0 +106,0 @@ }); |
@@ -37,10 +37,10 @@ /** | ||
interface Result extends Iterator<any> { | ||
interface Result<T = any> extends Iterator<T> { | ||
wasApplied(): boolean; | ||
first(): any; | ||
first(): T | null; | ||
forEach(callback: (currentValue: any, index: number) => void, thisArg?: any): void; | ||
forEach(callback: (currentValue: T, index: number) => void, thisArg?: any): void; | ||
toArray(): any[]; | ||
toArray(): T[]; | ||
} | ||
@@ -67,3 +67,3 @@ | ||
forModel(name: string): ModelMapper; | ||
forModel<T = any>(name: string): ModelMapper<T>; | ||
} | ||
@@ -124,17 +124,17 @@ | ||
interface ModelMapper { | ||
interface ModelMapper<T = any> { | ||
name: string; | ||
batching: ModelBatchMapper; | ||
get(doc: any, docInfo?: { fields?: string[] }, executionOptions?: string | MappingExecutionOptions): Promise<any>; | ||
get(doc: { [key: string]: any }, docInfo?: { fields?: string[] }, executionOptions?: string | MappingExecutionOptions): Promise<null | T>; | ||
find(doc: any, docInfo?: FindDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result>; | ||
find(doc: { [key: string]: any }, docInfo?: FindDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result<T>>; | ||
findAll(docInfo?: FindDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result>; | ||
findAll(docInfo?: FindDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result<T>>; | ||
insert(doc: any, docInfo?: InsertDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result>; | ||
insert(doc: { [key: string]: any }, docInfo?: InsertDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result<T>>; | ||
update(doc: any, docInfo?: UpdateDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result>; | ||
update(doc: { [key: string]: any }, docInfo?: UpdateDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result<T>>; | ||
remove(doc: any, docInfo?: RemoveDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result>; | ||
remove(doc: { [key: string]: any }, docInfo?: RemoveDocInfo, executionOptions?: string | MappingExecutionOptions): Promise<Result<T>>; | ||
@@ -145,3 +145,3 @@ mapWithQuery( | ||
executionOptions?: string | MappingExecutionOptions | ||
): (doc: any, executionOptions?: string | MappingExecutionOptions) => Promise<Result>; | ||
): (doc: any, executionOptions?: string | MappingExecutionOptions) => Promise<Result<T>>; | ||
} | ||
@@ -148,0 +148,0 @@ |
@@ -79,7 +79,10 @@ /** | ||
compactionClass: string; | ||
compactionOptions: object|Map<string, object>; | ||
compression: object|Map<string, object>; | ||
compactionOptions: { [option: string]: any; }; | ||
compression: { | ||
class?: string; | ||
[option: string]: any; | ||
}; | ||
crcCheckChange?: number; | ||
defaultTtl: number; | ||
extensions: object|Map<string, object>; | ||
extensions: { [option: string]: any; }; | ||
gcGraceSeconds: number; | ||
@@ -93,3 +96,3 @@ localReadRepairChance: number; | ||
readRepairChance: number; | ||
speculateRetry: string; | ||
speculativeRetry: string; | ||
} | ||
@@ -116,3 +119,3 @@ | ||
coordinator: InetAddress; | ||
parameters: { [key: string]: any } | Map<string, any>; | ||
parameters: { [key: string]: any }; | ||
startedAt: number | types.Long; | ||
@@ -119,0 +122,0 @@ duration: number; |
@@ -69,2 +69,3 @@ /** | ||
this.initialized = false; | ||
this._isDbaas = false; | ||
this._schemaParser = schemaParserFactory.getByVersion(options, controlConnection, this.getUdt.bind(this)); | ||
@@ -89,3 +90,21 @@ const self = this; | ||
/** | ||
* Determines whether the cluster is provided as a service. | ||
* @returns {boolean} true when the cluster is provided as a service (DataStax Apollo), <code>false<code> when it's a | ||
* different deployment (on-prem). | ||
*/ | ||
Metadata.prototype.isDbaas = function() { | ||
return this._isDbaas; | ||
}; | ||
/** | ||
* Sets the product type as DBaaS. | ||
* @internal | ||
* @ignore | ||
*/ | ||
Metadata.prototype.setProductTypeAsDbaas = function() { | ||
this._isDbaas = true; | ||
}; | ||
/** | ||
* @ignore | ||
* @param {String} partitionerName | ||
@@ -92,0 +111,0 @@ */ |
@@ -1402,1 +1402,2 @@ /** | ||
exports.getByVersion = getByVersion; | ||
exports.isDoneForToken = isDoneForToken; |
@@ -44,4 +44,3 @@ /** | ||
*/ | ||
// eslint-disable-next-line prefer-const | ||
let releaseDelay = 5000; | ||
const defaultReleaseDelay = 5000; | ||
@@ -56,3 +55,3 @@ /** | ||
* Creates a new instance of StreamIdStack. | ||
* @param {Number} version Protocol version | ||
* @param {number} version Protocol version | ||
* @constructor | ||
@@ -73,2 +72,3 @@ */ | ||
this.inUse = 0; | ||
this.releaseDelay = defaultReleaseDelay; | ||
} | ||
@@ -162,4 +162,4 @@ | ||
} | ||
const self = this; | ||
this.releaseTimeout = setTimeout(() => self._releaseGroups(), releaseDelay); | ||
this.releaseTimeout = setTimeout(() => this._releaseGroups(), this.releaseDelay); | ||
} | ||
@@ -166,0 +166,0 @@ |
113
lib/utils.js
@@ -9,2 +9,4 @@ /** | ||
const util = require('util'); | ||
const net = require('net'); | ||
const EventEmitter = require('events'); | ||
const errors = require('./errors'); | ||
@@ -19,2 +21,4 @@ | ||
const maxInt32 = 0x7fffffff; | ||
const emptyObject = Object.freeze({}); | ||
@@ -78,2 +82,15 @@ | ||
/** | ||
* @returns {Function} Returns a wrapper function that invokes the underlying callback only once. | ||
* @param {Function} callback | ||
*/ | ||
function callbackOnce(callback) { | ||
let cb = callback; | ||
return (function wrapperCallback(err, result) { | ||
cb(err, result); | ||
cb = noop; | ||
}); | ||
} | ||
/** | ||
* Creates a copy of a buffer | ||
@@ -539,2 +556,96 @@ */ | ||
/** | ||
* Utility class that resolves host names into addresses. | ||
*/ | ||
class AddressResolver { | ||
/** | ||
* Creates a new instance of the resolver. | ||
* @param {Object} options | ||
* @param {String} options.nameOrIp | ||
* @param {Object} [options.dns] | ||
*/ | ||
constructor(options) { | ||
if (!options || !options.nameOrIp || !options.dns) { | ||
throw new Error('nameOrIp and dns lib must be provided as part of the options'); | ||
} | ||
this._dns = options.dns; | ||
this._nameOrIp = options.nameOrIp; | ||
this._isIp = net.isIP(options.nameOrIp); | ||
this._index = 0; | ||
this._addresses = null; | ||
this._refreshEvent = null; | ||
} | ||
/** | ||
* Resolves the addresses for the host name. | ||
* @param {Function} callback A function with an error parameter that is invoked when initialization completed or | ||
* failed. | ||
*/ | ||
init(callback) { | ||
if (this._isIp) { | ||
return process.nextTick(callback); | ||
} | ||
this._resolve(callback); | ||
} | ||
/** | ||
* Tries to resolve the addresses for the host name. | ||
* @param {Function} callback A function without any parameters that is invoked when refresh completed. | ||
*/ | ||
refresh(callback) { | ||
if (this._isIp) { | ||
return process.nextTick(callback); | ||
} | ||
// Use an event emitter that is set when refreshing in order to | ||
// avoid unnecessary concurrent dns resolutions | ||
if (this._refreshEvent !== null) { | ||
this._refreshEvent.once('done', callback); | ||
return; | ||
} | ||
this._refreshEvent = new EventEmitter(); | ||
this._refreshEvent.setMaxListeners(0); | ||
this._refreshEvent.once('done', callback); | ||
this._resolve(() => { | ||
const emitter = this._refreshEvent; | ||
this._refreshEvent = null; | ||
// Ignore the possible resolution error | ||
emitter.emit('done'); | ||
}); | ||
} | ||
_resolve(callback) { | ||
this._dns.resolve4(this._nameOrIp, (err, arr) => { | ||
if (!err) { | ||
if (!arr || arr.length === 0) { | ||
err = new Error(`${this._nameOrIp} could not be resolved`); | ||
} else { | ||
this._addresses = arr; | ||
} | ||
} | ||
callback(err); | ||
}); | ||
} | ||
/** | ||
* Returns resolved ips in a round-robin fashion. | ||
*/ | ||
getIp() { | ||
if (this._isIp) { | ||
return this._nameOrIp; | ||
} | ||
const item = this._addresses[this._index % this._addresses.length]; | ||
this._index = (this._index !== maxInt32) ? (this._index + 1) : 0; | ||
return item; | ||
} | ||
} | ||
/** | ||
* @param {Array} arr | ||
@@ -936,2 +1047,3 @@ * @param {Function} fn | ||
exports.adaptNamedParamsWithHints = adaptNamedParamsWithHints; | ||
exports.AddressResolver = AddressResolver; | ||
exports.allocBuffer = allocBuffer; | ||
@@ -943,2 +1055,3 @@ exports.allocBufferUnsafe = allocBufferUnsafe; | ||
exports.binarySearch = binarySearch; | ||
exports.callbackOnce = callbackOnce; | ||
exports.copyBuffer = copyBuffer; | ||
@@ -945,0 +1058,0 @@ exports.deepExtend = deepExtend; |
{ | ||
"name": "dse-driver", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "DataStax Enterprise Node.js Driver", | ||
@@ -22,2 +22,3 @@ "author": "DataStax", | ||
"long": "^2.2.0", | ||
"adm-zip": "^0.4.13", | ||
"@types/node": ">=4", | ||
@@ -28,3 +29,5 @@ "@types/long": "^4.0.0" | ||
"mocha": "~5.2.0", | ||
"rewire": "^4.0.1", | ||
"proxyquire": "~2.1.3", | ||
"sinon": "~7.5.0", | ||
"chai": "4.2.0", | ||
"temp": ">= 0.8.3" | ||
@@ -41,3 +44,3 @@ }, | ||
"ci_unit_appveyor": "./node_modules/.bin/mocha test/unit -R mocha-appveyor-reporter --recursive --exit", | ||
"eslint": "eslint lib test --ignore-pattern '/lib/types/integer.js'" | ||
"eslint": "eslint lib test" | ||
}, | ||
@@ -44,0 +47,0 @@ "engines": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1020466
118
28758
4
5
5
8
+ Addedadm-zip@^0.4.13
+ Addedadm-zip@0.4.16(transitive)