@datastax/astra-db-ts
Advanced tools
Comparing version 1.0.0-alpha.2 to 1.0.0
@@ -95,3 +95,3 @@ "use strict"; | ||
} | ||
const response = await this._request({ | ||
const resp = await this._request({ | ||
url: info.url, | ||
@@ -101,30 +101,27 @@ data: JSON.stringify(info.command, replacer), | ||
method: api_1.HttpMethods.Post, | ||
reviver: reviver, | ||
}); | ||
if (response.status === 401 || (response.data?.errors?.length > 0 && response.data?.errors[0]?.message === 'UNAUTHENTICATED: Invalid token')) { | ||
if (resp.status >= 400 && resp.status !== 401) { | ||
throw new errors_1.DataAPIHttpError(resp); | ||
} | ||
const data = JSON.parse(resp.body, reviver); | ||
if (resp.status === 401 || (data.errors && data.errors?.length > 0 && data?.errors[0]?.message === 'UNAUTHENTICATED: Invalid token')) { | ||
const fauxResponse = mkFauxErroredResponse('Authentication failed; is your token valid?'); | ||
throw (0, errors_1.mkRespErrorFromResponse)(data_api_1.DataAPIResponseError, info.command, fauxResponse); | ||
} | ||
if (response.data?.errors?.length > 0 && response.data?.errors[0]?.errorCode === 'COLLECTION_NOT_EXIST') { | ||
const name = response.data?.errors[0]?.message.split(': ')[1]; | ||
if (data.errors && data?.errors?.length > 0 && data?.errors[0]?.errorCode === 'COLLECTION_NOT_EXIST') { | ||
const name = data?.errors[0]?.message.split(': ')[1]; | ||
throw new errors_1.CollectionNotFoundError(info.namespace, name); | ||
} | ||
if (response.status === 200) { | ||
if (response.data?.errors && response.data?.errors.length > 0) { | ||
throw (0, errors_1.mkRespErrorFromResponse)(data_api_1.DataAPIResponseError, info.command, response.data); | ||
} | ||
const respData = { | ||
status: response.data?.status, | ||
data: response.data?.data, | ||
errors: response.data?.errors, | ||
}; | ||
if (this.monitorCommands) { | ||
this.emitter.emit('commandSucceeded', new events_1.CommandSucceededEvent(info, respData, started)); | ||
} | ||
return respData; | ||
if (data?.errors && data?.errors.length > 0) { | ||
throw (0, errors_1.mkRespErrorFromResponse)(data_api_1.DataAPIResponseError, info.command, data); | ||
} | ||
else { | ||
const fauxResponse = mkFauxErroredResponse(`Some non-200 status code was returned. Check the logs for more information. ${response.status}, ${JSON.stringify(response.data)}`); | ||
throw (0, errors_1.mkRespErrorFromResponse)(data_api_1.DataAPIResponseError, info.command, fauxResponse); | ||
const respData = { | ||
status: data?.status, | ||
data: data?.data, | ||
errors: data?.errors, | ||
}; | ||
if (this.monitorCommands) { | ||
this.emitter.emit('commandSucceeded', new events_1.CommandSucceededEvent(info, respData, started)); | ||
} | ||
return respData; | ||
} | ||
@@ -146,3 +143,3 @@ catch (e) { | ||
const mkTimeoutErrorMaker = (timeout) => { | ||
return () => new data_api_1.DataAPITimeout(timeout); | ||
return () => new data_api_1.DataAPITimeoutError(timeout); | ||
}; | ||
@@ -149,0 +146,0 @@ const mkFauxErroredResponse = (message) => { |
@@ -53,9 +53,14 @@ "use strict"; | ||
}); | ||
const data = resp.body ? JSON.parse(resp.body) : undefined; | ||
if (resp.status >= 400) { | ||
throw new errors_1.DevOpsAPIResponseError(resp); | ||
throw new errors_1.DevOpsAPIResponseError(resp, data); | ||
} | ||
if (this.monitorCommands && !isLongRunning) { | ||
this.emitter.emit('adminCommandSucceeded', new devops_1.AdminCommandSucceededEvent(req, false, resp, started)); | ||
this.emitter.emit('adminCommandSucceeded', new devops_1.AdminCommandSucceededEvent(req, false, data, started)); | ||
} | ||
return resp; | ||
return { | ||
data: data, | ||
status: resp.status, | ||
headers: resp.headers, | ||
}; | ||
} | ||
@@ -113,3 +118,4 @@ catch (e) { | ||
if (!info.legalStates.includes(resp.data?.status)) { | ||
const error = new errors_1.DevOpsUnexpectedStateError(`Created database is not in any legal state [${[info.target, ...info.legalStates].join(',')}]`, resp); | ||
const okStates = [info.target, ...info.legalStates]; | ||
const error = new errors_1.DevOpsUnexpectedStateError(`Created database is not in any legal state [${okStates.join(',')}]`, okStates, resp.data); | ||
if (this.monitorCommands) { | ||
@@ -135,4 +141,4 @@ this.emitter.emit('adminCommandFailed', new devops_1.AdminCommandFailedEvent(req, true, error, started)); | ||
const mkTimeoutErrorMaker = (timeout) => { | ||
return (info) => new errors_1.DevOpsAPITimeout(info.url, timeout); | ||
return (info) => new errors_1.DevOpsAPITimeoutError(info.url, timeout); | ||
}; | ||
//# sourceMappingURL=devops-api-http-client.js.map |
@@ -99,8 +99,4 @@ "use strict"; | ||
}); | ||
const respBody = await resp.text(); | ||
return { | ||
data: respBody ? JSON.parse(respBody, info.reviver) : undefined, | ||
headers: resp.headers, | ||
status: resp.status, | ||
}; | ||
resp.body = await resp.text(); | ||
return resp; | ||
} | ||
@@ -107,0 +103,0 @@ catch (e) { |
@@ -312,3 +312,3 @@ "use strict"; | ||
if (options?.sort) { | ||
command.updateOne.sort = options.sort; | ||
command.updateOne.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -489,3 +489,3 @@ const resp = await this._httpClient.executeCommand(command, options); | ||
if (options?.sort) { | ||
command.findOneAndReplace.sort = options.sort; | ||
command.findOneAndReplace.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -544,3 +544,3 @@ const resp = await this._httpClient.executeCommand(command, options); | ||
if (options?.sort) { | ||
command.deleteOne.sort = options.sort; | ||
command.deleteOne.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -853,3 +853,3 @@ const deleteOneResp = await this._httpClient.executeCommand(command, options); | ||
if (options?.sort) { | ||
command.findOne.sort = options.sort; | ||
command.findOne.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -866,4 +866,4 @@ if (options?.projection && Object.keys(options.projection).length > 0) { | ||
* Takes in a `limit` option which dictates the maximum number of documents that may be present before a | ||
* {@link TooManyDocsToCountError} is thrown. If the limit is higher than the highest limit accepted by the | ||
* Data API, a {@link TooManyDocsToCountError} will be thrown anyway (i.e. `1000`). | ||
* {@link TooManyDocumentsToCountError} is thrown. If the limit is higher than the highest limit accepted by the | ||
* Data API, a {@link TooManyDocumentsToCountError} will be thrown anyway (i.e. `1000`). | ||
* | ||
@@ -880,3 +880,3 @@ * @example | ||
* | ||
* // Will throw a TooManyDocsToCountError as it counts 1, but the limit is 0 | ||
* // Will throw a TooManyDocumentsToCountError as it counts 1, but the limit is 0 | ||
* const count = await collection.countDocuments({ name: 'John Doe' }, 0); | ||
@@ -898,3 +898,3 @@ * ``` | ||
* | ||
* @throws TooManyDocsToCountError - If the number of documents counted exceeds the provided limit. | ||
* @throws TooManyDocumentsToCountError - If the number of documents counted exceeds the provided limit. | ||
* | ||
@@ -912,6 +912,6 @@ * @see StrictFilter | ||
if (resp.status?.moreData) { | ||
throw new errors_1.TooManyDocsToCountError(resp.status.count, true); | ||
throw new errors_1.TooManyDocumentsToCountError(resp.status.count, true); | ||
} | ||
if (resp.status?.count > upperBound) { | ||
throw new errors_1.TooManyDocsToCountError(upperBound, false); | ||
throw new errors_1.TooManyDocumentsToCountError(upperBound, false); | ||
} | ||
@@ -933,3 +933,3 @@ return resp.status?.count; | ||
if (options?.sort) { | ||
command.findOneAndReplace.sort = options.sort; | ||
command.findOneAndReplace.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -940,3 +940,3 @@ if (options?.projection && Object.keys(options.projection).length > 0) { | ||
const resp = await this._httpClient.executeCommand(command, options); | ||
const document = resp.data?.document; | ||
const document = resp.data?.document || null; | ||
return (options.includeResultMetadata) | ||
@@ -955,3 +955,3 @@ ? { | ||
if (options?.sort) { | ||
command.findOneAndDelete.sort = options.sort; | ||
command.findOneAndDelete.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -962,3 +962,3 @@ if (options?.projection && Object.keys(options.projection).length > 0) { | ||
const resp = await this._httpClient.executeCommand(command, options); | ||
const document = resp.data?.document; | ||
const document = resp.data?.document || null; | ||
return (options?.includeResultMetadata) | ||
@@ -984,3 +984,3 @@ ? { | ||
if (options?.sort) { | ||
command.findOneAndUpdate.sort = options.sort; | ||
command.findOneAndUpdate.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
@@ -991,3 +991,3 @@ if (options?.projection && Object.keys(options.projection).length > 0) { | ||
const resp = await this._httpClient.executeCommand(command, options); | ||
const document = resp.data?.document; | ||
const document = resp.data?.document || null; | ||
return (options.includeResultMetadata) | ||
@@ -1289,3 +1289,3 @@ ? { | ||
const extract = (path, index, value) => { | ||
if (!value) { | ||
if (value === undefined) { | ||
return; | ||
@@ -1292,0 +1292,0 @@ } |
@@ -18,2 +18,3 @@ "use strict"; | ||
const data_api_1 = require("../data-api"); | ||
const utils_1 = require("../data-api/utils"); | ||
/** | ||
@@ -122,5 +123,10 @@ * Lazily iterates over the document results of a query. | ||
this._options = { ...options }; | ||
if (options?.sort) { | ||
this._options.sort = (0, utils_1.normalizeSort)(options.sort); | ||
} | ||
} | ||
/** | ||
* @returns The namespace (aka keyspace) of the parent database. | ||
* The namespace (aka keyspace) of the collection that's being iterated over. | ||
* | ||
* @returns The namespace of the collection that's being iterated over. | ||
*/ | ||
@@ -131,2 +137,4 @@ get namespace() { | ||
/** | ||
* Whether the cursor is closed, whether it be manually, or because the cursor is exhausted. | ||
* | ||
* @returns Whether or not the cursor is closed. | ||
@@ -138,2 +146,4 @@ */ | ||
/** | ||
* Returns the number of documents in the buffer. If the cursor is unused, it'll return 0. | ||
* | ||
* @returns The number of documents in the buffer. | ||
@@ -175,3 +185,3 @@ */ | ||
this._assertUninitialized(); | ||
this._options.sort = sort; | ||
this._options.sort = (0, utils_1.normalizeSort)(sort); | ||
return this; | ||
@@ -178,0 +188,0 @@ } |
@@ -459,5 +459,4 @@ "use strict"; | ||
(0, utils_1.validateOption)('dataApiPath option', opts.dataApiPath, 'string'); | ||
// validateOption('useHttp2 option', opts.useHttp2, 'boolean'); | ||
} | ||
exports.validateDbOpts = validateDbOpts; | ||
//# sourceMappingURL=db.js.map |
@@ -16,3 +16,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mkRespErrorFromResponses = exports.mkRespErrorFromResponse = exports.BulkWriteError = exports.UpdateManyError = exports.DeleteManyError = exports.InsertManyError = exports.CumulativeDataAPIError = exports.DataAPIResponseError = exports.CollectionAlreadyExistsError = exports.CollectionNotFoundError = exports.CursorIsStartedError = exports.TooManyDocsToCountError = exports.DataAPITimeout = exports.DataAPIError = void 0; | ||
exports.mkRespErrorFromResponses = exports.mkRespErrorFromResponse = exports.BulkWriteError = exports.UpdateManyError = exports.DeleteManyError = exports.InsertManyError = exports.CumulativeDataAPIError = exports.DataAPIResponseError = exports.CollectionAlreadyExistsError = exports.CollectionNotFoundError = exports.CursorIsStartedError = exports.TooManyDocumentsToCountError = exports.DataAPITimeoutError = exports.DataAPIHttpError = exports.DataAPIError = void 0; | ||
const utils_1 = require("../api/utils"); | ||
/** | ||
@@ -26,3 +27,3 @@ * An abstract class representing *some* exception that occurred related to the Data API. This is the base class for all | ||
* is *not*, however, for errors such as an HTTP network error, or a malformed request. The exception being timeouts, | ||
* which are represented by the {@link DataAPITimeout} class. | ||
* which are represented by the {@link DataAPITimeoutError} class. | ||
* | ||
@@ -35,2 +36,47 @@ * @public | ||
/** | ||
* An error thrown on non-2XX status codes from the Data API, such as 4XX or 5XX errors. | ||
*/ | ||
class DataAPIHttpError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(resp) { | ||
super(`HTTP error: ${resp.status}`); | ||
/** | ||
* The error descriptors returned by the API to describe what went wrong. | ||
*/ | ||
Object.defineProperty(this, "status", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
/** | ||
* The HTTP status code of the response, if available. | ||
*/ | ||
Object.defineProperty(this, "body", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
/** | ||
* The "raw", errored response from the API. | ||
*/ | ||
Object.defineProperty(this, "raw", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
this.status = resp.status; | ||
this.body = resp.body; | ||
this.raw = (0, utils_1.toCuratedApiResponse)(resp); | ||
this.name = 'DataAPIHttpError'; | ||
} | ||
} | ||
exports.DataAPIHttpError = DataAPIHttpError; | ||
/** | ||
* An error thrown when a Data API operation timed out. | ||
@@ -43,3 +89,8 @@ * | ||
*/ | ||
class DataAPITimeout extends DataAPIError { | ||
class DataAPITimeoutError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(timeout) { | ||
@@ -57,6 +108,6 @@ super(`Command timed out after ${timeout}ms`); | ||
this.timeout = timeout; | ||
this.name = 'DataAPITimeout'; | ||
this.name = 'DataAPITimeoutError'; | ||
} | ||
} | ||
exports.DataAPITimeout = DataAPITimeout; | ||
exports.DataAPITimeoutError = DataAPITimeoutError; | ||
/** | ||
@@ -73,3 +124,3 @@ * Caused by a `countDocuments` operation that failed because the resulting number of documents exceeded *either* | ||
* } catch (e) { | ||
* if (e instanceof TooManyDocsToCountError) { | ||
* if (e instanceof TooManyDocumentsToCountError) { | ||
* console.log(e.limit); // 50 | ||
@@ -86,3 +137,8 @@ * console.log(e.hitServerLimit); // false | ||
*/ | ||
class TooManyDocsToCountError extends DataAPIError { | ||
class TooManyDocumentsToCountError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(limit, hitServerLimit) { | ||
@@ -93,2 +149,5 @@ const message = (hitServerLimit) | ||
super(message); | ||
/** | ||
* The limit that was specified by the caller, or the server-imposed limit if the caller's limit was too high. | ||
*/ | ||
Object.defineProperty(this, "limit", { | ||
@@ -98,4 +157,8 @@ enumerable: true, | ||
writable: true, | ||
value: limit | ||
value: void 0 | ||
}); | ||
/** | ||
* Specifies if the server-imposed limit was hit. If this is `true`, the `limit` field will contain the server's | ||
* limit; otherwise it will contain the caller's limit. | ||
*/ | ||
Object.defineProperty(this, "hitServerLimit", { | ||
@@ -105,8 +168,10 @@ enumerable: true, | ||
writable: true, | ||
value: hitServerLimit | ||
value: void 0 | ||
}); | ||
this.name = 'TooManyDocsToCountError'; | ||
this.limit = limit; | ||
this.hitServerLimit = hitServerLimit; | ||
this.name = 'TooManyDocumentsToCountError'; | ||
} | ||
} | ||
exports.TooManyDocsToCountError = TooManyDocsToCountError; | ||
exports.TooManyDocumentsToCountError = TooManyDocumentsToCountError; | ||
/** | ||
@@ -135,2 +200,7 @@ * Caused by trying to perform an operation on an already-initialized {@link FindCursor} that requires it to be | ||
class CursorIsStartedError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(message) { | ||
@@ -151,2 +221,7 @@ super(message); | ||
class CollectionNotFoundError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(namespace, collectionName) { | ||
@@ -188,2 +263,7 @@ super(`Collection '${namespace}.${collectionName}' not found`); | ||
class CollectionAlreadyExistsError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(namespace, collectionName) { | ||
@@ -231,2 +311,7 @@ super(`Collection '${namespace}.${collectionName}' already exists`); | ||
class DataAPIResponseError extends DataAPIError { | ||
/** | ||
* Should not be instantiated by the user. | ||
* | ||
* @internal | ||
*/ | ||
constructor(message, errorDescriptors, detailedErrorDescriptors) { | ||
@@ -286,3 +371,3 @@ super(message); | ||
* is *not*, however, for errors such as an HTTP network error, or a malformed request. The exception being timeouts, | ||
* which are represented by the {@link DataAPITimeout} class. | ||
* which are represented by the {@link DataAPITimeoutError} class. | ||
* | ||
@@ -289,0 +374,0 @@ * @field message - A human-readable message describing the *first* error |
@@ -35,2 +35,14 @@ "use strict"; | ||
* The command object. Equal to the response body of the HTTP request. | ||
* | ||
* Note that this is the actual raw command object; it's not necessarily 1:1 with methods called on the collection/db. | ||
* | ||
* For example, a `deleteAll` method on a collection will be translated into a `deleteMany` command, and a `bulkWrite` | ||
* method will be translated into a series of `insertOne`, `updateOne`, etc. commands. | ||
* | ||
* @example | ||
* ```typescript | ||
* { | ||
* insertOne: { document: { name: 'John' } } | ||
* } | ||
* ``` | ||
*/ | ||
@@ -63,2 +75,7 @@ Object.defineProperty(this, "command", { | ||
* The command name. | ||
* | ||
* This is the key of the command object. For example, if the command object is | ||
* `{ insertOne: { document: { name: 'John' } } }`, the command name is `insertOne`. | ||
* | ||
* Meaning, abstracted commands like `bulkWrite`, or `deleteAll` will be shown as their actual command equivalents. | ||
*/ | ||
@@ -94,2 +111,4 @@ Object.defineProperty(this, "commandName", { | ||
* | ||
* See {@link CommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -124,2 +143,4 @@ */ | ||
* | ||
* See {@link CommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -136,3 +157,3 @@ */ | ||
/** | ||
* The duration of the command, in milliseconds. | ||
* The duration of the command, in milliseconds. Starts counting from the moment of the initial HTTP request. | ||
*/ | ||
@@ -165,2 +186,4 @@ Object.defineProperty(this, "duration", { | ||
* | ||
* See {@link CommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -187,2 +210,4 @@ */ | ||
* The error that caused the command to fail. | ||
* | ||
* Typically, some {@link DataAPIError}, commonly a {@link DataAPIResponseError} or one of its subclasses. | ||
*/ | ||
@@ -189,0 +214,0 @@ Object.defineProperty(this, "error", { |
@@ -31,3 +31,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.UpdateManyError = exports.CursorIsStartedError = exports.BulkWriteError = exports.InsertManyError = exports.TooManyDocsToCountError = exports.DeleteManyError = exports.CollectionAlreadyExistsError = exports.DataAPIError = exports.CumulativeDataAPIError = exports.DataAPIResponseError = exports.DataAPITimeout = exports.Db = void 0; | ||
exports.UpdateManyError = exports.CursorIsStartedError = exports.BulkWriteError = exports.InsertManyError = exports.TooManyDocumentsToCountError = exports.DeleteManyError = exports.CollectionAlreadyExistsError = exports.DataAPIError = exports.CumulativeDataAPIError = exports.DataAPIResponseError = exports.DataAPITimeoutError = exports.Db = void 0; | ||
__exportStar(require("./collection"), exports); | ||
@@ -39,3 +39,3 @@ __exportStar(require("./cursor"), exports); | ||
var errors_1 = require("./errors"); | ||
Object.defineProperty(exports, "DataAPITimeout", { enumerable: true, get: function () { return errors_1.DataAPITimeout; } }); | ||
Object.defineProperty(exports, "DataAPITimeoutError", { enumerable: true, get: function () { return errors_1.DataAPITimeoutError; } }); | ||
Object.defineProperty(exports, "DataAPIResponseError", { enumerable: true, get: function () { return errors_1.DataAPIResponseError; } }); | ||
@@ -46,3 +46,3 @@ Object.defineProperty(exports, "CumulativeDataAPIError", { enumerable: true, get: function () { return errors_1.CumulativeDataAPIError; } }); | ||
Object.defineProperty(exports, "DeleteManyError", { enumerable: true, get: function () { return errors_1.DeleteManyError; } }); | ||
Object.defineProperty(exports, "TooManyDocsToCountError", { enumerable: true, get: function () { return errors_1.TooManyDocsToCountError; } }); | ||
Object.defineProperty(exports, "TooManyDocumentsToCountError", { enumerable: true, get: function () { return errors_1.TooManyDocumentsToCountError; } }); | ||
Object.defineProperty(exports, "InsertManyError", { enumerable: true, get: function () { return errors_1.InsertManyError; } }); | ||
@@ -49,0 +49,0 @@ Object.defineProperty(exports, "BulkWriteError", { enumerable: true, get: function () { return errors_1.BulkWriteError; } }); |
@@ -24,2 +24,7 @@ "use strict"; | ||
class BulkWriteResult { | ||
/** | ||
* Should not be instantiated directly. | ||
* | ||
* @internal | ||
*/ | ||
constructor( | ||
@@ -97,3 +102,3 @@ /** | ||
* | ||
* @returns the raw, internal result. | ||
* @returns The raw, internal result. | ||
*/ | ||
@@ -100,0 +105,0 @@ getRawResponse() { |
@@ -16,3 +16,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateOption = exports.replaceAstraUrlIdAndRegion = exports.extractDbIdFromUrl = exports.takeWhile = void 0; | ||
exports.normalizeSort = exports.validateOption = exports.replaceAstraUrlIdAndRegion = exports.extractDbIdFromUrl = exports.takeWhile = void 0; | ||
/** | ||
@@ -60,2 +60,26 @@ * @internal | ||
exports.validateOption = validateOption; | ||
/** | ||
* @internal | ||
*/ | ||
const normalizeSort = (sort) => { | ||
const ret = {}; | ||
for (const key in sort) { | ||
switch (sort[key]) { | ||
case 1: | ||
case 'asc': | ||
case 'ascending': | ||
ret[key] = 1; | ||
break; | ||
case -1: | ||
case 'desc': | ||
case 'descending': | ||
ret[key] = -1; | ||
break; | ||
default: | ||
ret[key] = sort[key]; | ||
} | ||
} | ||
return ret; | ||
}; | ||
exports.normalizeSort = normalizeSort; | ||
//# sourceMappingURL=utils.js.map |
@@ -72,3 +72,3 @@ "use strict"; | ||
* | ||
* @returns the ID of the Astra DB instance. | ||
* @returns The ID of the Astra DB instance. | ||
*/ | ||
@@ -93,3 +93,3 @@ get id() { | ||
* | ||
* @returns the underlying `Db` object. | ||
* @returns The underlying `Db` object. | ||
*/ | ||
@@ -136,3 +136,3 @@ db() { | ||
* | ||
* @returns A promise that resolves to an array of namespace names. | ||
* @returns A promise that resolves to list of all the namespaces in the database. | ||
*/ | ||
@@ -164,3 +164,3 @@ async listNamespaces(options) { | ||
* @remarks | ||
* Note that if you choose not to block, the created namespace object will not be able to be used until the | ||
* Note that if you choose not to block, the created namespace will not be able to be used until the | ||
* operation completes, which is up to the caller to determine. | ||
@@ -208,3 +208,3 @@ * | ||
* @remarks | ||
* Note that if you choose not to block, the namespace object will still be able to be used until the operation | ||
* Note that if you choose not to block, the namespace will still be able to be used until the operation | ||
* completes, which is up to the caller to determine. | ||
@@ -211,0 +211,0 @@ * |
@@ -16,3 +16,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DevOpsUnexpectedStateError = exports.DevOpsAPIResponseError = exports.DevOpsAPITimeout = exports.DevOpsAPIError = void 0; | ||
exports.DevOpsUnexpectedStateError = exports.DevOpsAPIResponseError = exports.DevOpsAPITimeoutError = exports.DevOpsAPIError = void 0; | ||
const utils_1 = require("../api/utils"); | ||
/** | ||
@@ -40,3 +41,3 @@ * An abstract class representing *some* exception that occurred related to the DevOps API. This is the base class for all | ||
*/ | ||
class DevOpsAPITimeout extends DevOpsAPIError { | ||
class DevOpsAPITimeoutError extends DevOpsAPIError { | ||
/** | ||
@@ -69,6 +70,6 @@ * Shouldn't be instantiated directly. | ||
this.timeout = timeout; | ||
this.name = 'DevOpsAPITimeout'; | ||
this.name = 'DevOpsAPITimeoutError'; | ||
} | ||
} | ||
exports.DevOpsAPITimeout = DevOpsAPITimeout; | ||
exports.DevOpsAPITimeoutError = DevOpsAPITimeoutError; | ||
/** | ||
@@ -89,4 +90,4 @@ * An error representing a response from the DevOps API that was not successful (non-2XX status code). | ||
*/ | ||
constructor(resp) { | ||
const message = resp.data?.errors?.find(e => e.message)?.message ?? 'Something went wrong'; | ||
constructor(resp, data) { | ||
const message = data?.errors?.find(e => e.message)?.message ?? 'Something went wrong'; | ||
super(message); | ||
@@ -111,4 +112,14 @@ /** | ||
}); | ||
this.errors = extractErrorDescriptors(resp); | ||
/** | ||
* The "raw", errored response from the API. | ||
*/ | ||
Object.defineProperty(this, "raw", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
this.errors = extractErrorDescriptors(data); | ||
this.status = resp.status; | ||
this.raw = (0, utils_1.toCuratedApiResponse)(resp); | ||
this.name = 'DevOpsAPIResponseError'; | ||
@@ -133,8 +144,8 @@ } | ||
*/ | ||
constructor(message, raw) { | ||
constructor(message, expected, data) { | ||
super(message); | ||
/** | ||
* The HTTP status code of the response, if available. | ||
* The expected states that were not met. | ||
*/ | ||
Object.defineProperty(this, "status", { | ||
Object.defineProperty(this, "expected", { | ||
enumerable: true, | ||
@@ -154,4 +165,4 @@ configurable: true, | ||
}); | ||
this.dbInfo = raw?.data; | ||
this.status = raw?.status; | ||
this.expected = expected; | ||
this.dbInfo = data; | ||
this.name = 'DevOpsUnexpectedStateError'; | ||
@@ -161,4 +172,4 @@ } | ||
exports.DevOpsUnexpectedStateError = DevOpsUnexpectedStateError; | ||
function extractErrorDescriptors(resp) { | ||
const errors = resp.data?.errors || []; | ||
function extractErrorDescriptors(data) { | ||
const errors = data?.errors || []; | ||
return errors.map((e) => ({ | ||
@@ -165,0 +176,0 @@ id: e.ID, |
@@ -86,2 +86,4 @@ "use strict"; | ||
* | ||
* See {@link AdminCommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -115,2 +117,4 @@ */ | ||
* | ||
* See {@link AdminCommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -152,2 +156,4 @@ */ | ||
* | ||
* See {@link AdminCommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -161,3 +167,3 @@ */ | ||
*/ | ||
constructor(info, longRunning, resp, started) { | ||
constructor(info, longRunning, data, started) { | ||
super(info, longRunning); | ||
@@ -183,3 +189,3 @@ /** | ||
this.duration = (0, api_1.hrTimeMs)() - started; | ||
this.resBody = resp.data || undefined; | ||
this.resBody = data || undefined; | ||
} | ||
@@ -191,2 +197,4 @@ } | ||
* | ||
* See {@link AdminCommandEvent} for more information about all the common properties available on this event. | ||
* | ||
* @public | ||
@@ -213,2 +221,5 @@ */ | ||
* The error that occurred. | ||
* | ||
* Typically, some {@link DevOpsAPIError}, commonly a {@link DevOpsAPIResponseError} or sometimes a | ||
* {@link DevOpsUnexpectedStateError} | ||
*/ | ||
@@ -215,0 +226,0 @@ Object.defineProperty(this, "error", { |
@@ -5,3 +5,3 @@ "use strict"; | ||
exports.LIB_NAME = 'astra-db-ts'; | ||
exports.LIB_VERSION = "1.0.0-alpha.2"; | ||
exports.LIB_VERSION = "1.0.0"; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@datastax/astra-db-ts", | ||
"version": "1.0.0-alpha.2", | ||
"version": "1.0.0", | ||
"description": "Astra DB TS Client", | ||
@@ -54,5 +54,5 @@ "contributors": [ | ||
"test:all": "env ASTRA_RUN_LONG_TESTS=1 ASTRA_RUN_ADMIN_TESTS=1 ts-mocha --paths -p tsconfig.json tests/unit/**/*.test.ts tests/integration/**/*.test.ts tests/integration/**/**/*.test.ts", | ||
"test:prerelease": "npm run test:all -- -b --exit", | ||
"test:coverage": "nyc npm run test:all -- -b", | ||
"test:types": "tsc --noEmit --skipLibCheck", | ||
"test:prerelease": "npm run lint && npm run test:types && npm run test:all -- -b --exit", | ||
"api-extractor": "api-extractor run -c ./api-extractor.jsonc --local", | ||
@@ -59,0 +59,0 @@ "build": "sh ./scripts/build.sh", |
183
README.md
@@ -28,54 +28,63 @@ # @datastax/astra-db-ts | ||
(async () => { | ||
// Creates collection, or gets it if it already exists with same options | ||
const collection = await db.createCollection<Idea>('vector_5_collection', { | ||
vector: { | ||
dimension: 5, | ||
metric: 'cosine' | ||
}, | ||
}); | ||
try { | ||
// Creates collection, or gets it if it already exists with same options | ||
const collection = await db.createCollection<Idea>('vector_5_collection', { | ||
vector: { | ||
dimension: 5, | ||
metric: 'cosine' | ||
}, | ||
checkExists: false, | ||
}); | ||
// Insert many ideas into the collection | ||
const ideas = [ | ||
{ | ||
idea: 'An AI quilt to help you sleep forever', | ||
$vector: [0.1, 0.15, 0.3, 0.12, 0.05], | ||
}, | ||
{ | ||
_id: new UUID('e7f1f3a0-7e3d-11eb-9439-0242ac130002'), | ||
idea: 'Vision Vector Frame—A deep learning display that controls your mood', | ||
$vector: [0.1, 0.05, 0.08, 0.3, 0.6], | ||
}, | ||
{ | ||
idea: 'A smartwatch that tells you what to eat based on your mood', | ||
$vector: [0.2, 0.3, 0.1, 0.4, 0.15], | ||
}, | ||
]; | ||
await collection.insertMany(ideas); | ||
// Insert many ideas into the collection | ||
const ideas = [ | ||
{ | ||
idea: 'An AI quilt to help you sleep forever', | ||
$vector: [0.1, 0.15, 0.3, 0.12, 0.05], | ||
}, | ||
{ | ||
_id: new UUID('e7f1f3a0-7e3d-11eb-9439-0242ac130002'), | ||
idea: 'Vision Vector Frame—A deep learning display that controls your mood', | ||
$vector: [0.1, 0.05, 0.08, 0.3, 0.6], | ||
}, | ||
{ | ||
idea: 'A smartwatch that tells you what to eat based on your mood', | ||
$vector: [0.2, 0.3, 0.1, 0.4, 0.15], | ||
}, | ||
]; | ||
await collection.insertMany(ideas); | ||
// Insert a specific idea into the collection | ||
const sneakersIdea = { | ||
_id: new ObjectId('507f191e810c19729de860ea'), | ||
idea: 'ChatGPT-integrated sneakers that talk to you', | ||
$vector: [0.45, 0.09, 0.01, 0.2, 0.11], | ||
} | ||
await collection.insertOne(sneakersIdea); | ||
// Insert a specific idea into the collection | ||
const sneakersIdea = { | ||
_id: new ObjectId('507f191e810c19729de860ea'), | ||
idea: 'ChatGPT-integrated sneakers that talk to you', | ||
$vector: [0.45, 0.09, 0.01, 0.2, 0.11], | ||
} | ||
await collection.insertOne(sneakersIdea); | ||
// Actually, let's change that idea | ||
await collection.updateOne( | ||
{ _id: sneakersIdea._id }, | ||
{ $set: { idea: 'Gemini-integrated sneakers that talk to you' } }, | ||
); | ||
// Actually, let's change that idea | ||
await collection.updateOne( | ||
{ _id: sneakersIdea._id }, | ||
{ $set: { idea: 'Gemini-integrated sneakers that talk to you' } }, | ||
); | ||
// Get similar results as desired | ||
const cursor = collection.find({}, { | ||
vector: [0.1, 0.15, 0.3, 0.12, 0.05], | ||
includeSimilarity: true, | ||
limit: 2, | ||
}); | ||
// Get similar results as desired | ||
const cursor = collection.find({}, { | ||
vector: [0.1, 0.15, 0.3, 0.12, 0.05], | ||
includeSimilarity: true, | ||
limit: 2, | ||
}); | ||
for await (const doc of cursor) { | ||
// Prints the following: | ||
// - An AI quilt to help you sleep forever: 1 | ||
// - A smartwatch that tells you what to eat based on your mood: 0.85490346 | ||
console.log(`${doc.idea}: ${doc.$similarity}`); | ||
for await (const doc of cursor) { | ||
// Prints the following: | ||
// - An AI quilt to help you sleep forever: 1 | ||
// - A smartwatch that tells you what to eat based on your mood: 0.85490346 | ||
console.log(`${doc.idea}: ${doc.$similarity}`); | ||
} | ||
// Cleanup (if desired) | ||
await collection.drop(); | ||
} finally { | ||
// Cleans up all open http sessions | ||
await client.close(); | ||
} | ||
@@ -128,2 +137,6 @@ })(); | ||
```typescript | ||
// First of all: | ||
// I *highly* recommend writing your query objects & filter objects and such inline with the methods | ||
// to get the best possible type-checking and autocomplete | ||
import { DataAPIClient, StrictFilter, StrictSort, UUID } from '@datastax/astra-db-ts'; | ||
@@ -181,27 +194,33 @@ | ||
```typescript | ||
import { DataApiClient } from '@datastax/astra-db-ts'; | ||
import { DataAPIClient } from '@datastax/astra-db-ts'; | ||
// Reference an untyped collection | ||
const client = new DataApiClient('TOKEN'); | ||
const db = client.db('ENDPOINT', { namespace: 'NAMESPACE' }); | ||
const collection = db.collection('COLLECTION'); | ||
const client = new DataAPIClient('*TOKEN*'); | ||
const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' }); | ||
// Insert documents with some dates | ||
await collection.insertOne({ dateOfBirth: new Date(1394104654000) }); | ||
await collection.insertOne({ dateOfBirth: new Date('1863-05-28') }); | ||
(async () => { | ||
const collection = await db.createCollection('dates_test'); | ||
// Insert documents with some dates | ||
await collection.insertOne({ dateOfBirth: new Date(1394104654000) }); | ||
await collection.insertOne({ dateOfBirth: new Date('1863-05-28') }); | ||
// Update a document with a date and setting lastModified to now | ||
await collection.updateOne( | ||
{ | ||
dateOfBirth: new Date('1863-05-28'), | ||
}, | ||
{ | ||
$set: { message: 'Happy Birthday!' }, | ||
$currentDate: { lastModified: true }, | ||
}, | ||
); | ||
// Update a document with a date and setting lastModified to now | ||
await collection.updateOne( | ||
{ | ||
dateOfBirth: new Date('1863-05-28'), | ||
}, | ||
{ | ||
$set: { message: 'Happy Birthday!' }, | ||
$currentDate: { lastModified: true }, | ||
}, | ||
); | ||
// Will print *around* `new Date()` (i.e. when server processed the request) | ||
const found = await collection.findOne({ dateOfBirth: { $lt: new Date('1900-01-01') } }); | ||
console.log(found?.lastModified); | ||
// Will print *around* `new Date()` (i.e. when server processed the request) | ||
const found = await collection.findOne({ dateOfBirth: { $lt: new Date('1900-01-01') } }); | ||
console.log(found?.lastModified); | ||
// Cleanup (if desired) | ||
await collection.drop(); | ||
})(); | ||
``` | ||
@@ -230,3 +249,3 @@ | ||
// Create a collection with a UUIDv7 as the default ID | ||
const collection = await db.createCollection<Person>('my_collection', { defaultId: { type: 'uuidv7' } }); | ||
const collection = await db.createCollection<Person>('ids_test', { defaultId: { type: 'uuidv7' } }); | ||
@@ -252,3 +271,6 @@ // You can manually set whatever ID you want | ||
const jane = await collection.findOne({ name: 'Jane' }); | ||
console.log(jane?.name, jane?.friendId, friendId.equals(jane?.friendId)); | ||
console.log(jane?.name, jane?.friendId?.toString(), friendId.equals(jane?.friendId)); | ||
// Cleanup (if desired) | ||
await collection.drop(); | ||
})(); | ||
@@ -277,2 +299,3 @@ ``` | ||
}); | ||
const db = client.db('*ENDPOINT*'); | ||
@@ -291,9 +314,19 @@ client.on('commandStarted', (event) => { | ||
const db = client.db('*ENDPOINT*'); | ||
const coll = db.collection('*COLLECTION*'); | ||
(async () => { | ||
// Should log | ||
// - "Running command createCollection" | ||
// - "Command createCollection succeeded in <time>ms" | ||
const collection = await db.createCollection('my_collection', { checkExists: false }); | ||
// Should log | ||
// - "Running command insertOne" | ||
// - "Command insertOne succeeded in <time>ms" | ||
await coll.insertOne({ name: 'Queen' }); | ||
// Should log | ||
// - "Running command insertOne" | ||
// - "Command insertOne succeeded in <time>ms" | ||
await collection.insertOne({ name: 'Queen' }); | ||
// Remove all monitoring listeners | ||
client.removeAllListeners(); | ||
// Cleanup (if desired) (with no logging) | ||
await collection.drop(); | ||
})(); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
586421
129
12685
0
326