From 25a764dedc99817ddb9da82c898b805599298db5 Mon Sep 17 00:00:00 2001 From: toptobes <96998732+toptobes@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:17:51 +0530 Subject: [PATCH] Documentation work (#93) * start work on more docs md pages * created colls/tables datatype cheatsheet * did collections dts * readme work * ran npm audit fix * minor tweaks to DATATYPES.md * bnunch of tsdoc for create-table related types * tsdoc for DataAPILoggingDefaults * update examples to use @next version of astra-db-ts * documented list-tables --- README.md | 187 ++----- etc/astra-db-ts.api.md | 61 +- etc/docs/DATATYPES.md | 526 ++++++++++++++++++ etc/imgs/class-hierarchy.png | Bin 56231 -> 0 bytes examples/browser/package-lock.json | 30 +- examples/browser/package.json | 2 +- examples/cloudflare-workers/package-lock.json | 30 +- examples/cloudflare-workers/package.json | 2 +- .../http2-when-minified/package-lock.json | 30 +- examples/http2-when-minified/package.json | 2 +- examples/nextjs/package-lock.json | 30 +- examples/nextjs/package.json | 2 +- examples/non-astra-backends/package-lock.json | 30 +- examples/non-astra-backends/package.json | 2 +- examples/serdes/package-lock.json | 30 +- examples/serdes/package.json | 2 +- package-lock.json | 424 +++++++------- scripts/build.sh | 2 +- scripts/repl.sh | 24 + scripts/update-example-client-dep.sh | 2 +- src/administration/astra-admin.ts | 4 +- .../types/admin/drop-database.ts | 2 +- .../types/db-admin/astra-drop-keyspace.ts | 2 + src/administration/types/index.ts | 2 +- src/db/types/tables/create-table.ts | 409 +++++++++++++- src/db/types/tables/list-tables.ts | 149 ++++- src/db/types/tables/spawn-table.ts | 1 + src/lib/logging/constants.ts | 23 + 28 files changed, 1594 insertions(+), 416 deletions(-) create mode 100644 etc/docs/DATATYPES.md delete mode 100644 etc/imgs/class-hierarchy.png diff --git a/README.md b/README.md index 26d96e27..8db967e2 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,16 @@ > **Warning** > This README is still under construction; parts of it may be incomplete or outdated. -*This README targets v2.0.0+, which introduces a whole new API. Click [here](https://github.com/datastax/astra-db-ts/tree/v1.x?tab=readme-ov-file#datastaxastra-db-ts) for the pre-existing client readme.* +*This README targets v2.0.0+, which expands on the previous 1.x API. Click [here](https://github.com/datastax/astra-db-ts/tree/v1.x?tab=readme-ov-file#datastaxastra-db-ts) for the pre-existing client readme.* ## Table of contents - [Quickstart](#quickstart) - [Collections](#collections) - [Tables](#tables) - [High-level architecture](#high-level-architecture) -- [Getting the most out of the typing](#getting-the-most-out-of-the-typing) -- [Working with Dates](#working-with-dates) -- [Working with ObjectIds and UUIDs](#working-with-objectids-and-uuids) -- [Monitoring/logging](#monitoringlogging) -- [Non-astra support](#non-astra-support) + - [Options hierarchy](#options-hierarchy) +- [Datatypes](#datatypes) +[Non-astra support](#non-astra-support) - [Non-standard environment support](#non-standard-environment-support) - [HTTP/2 with minification](#http2-with-minification) - [Browser support](#browser-support) @@ -70,9 +68,9 @@ interface Dream extends VectorDoc { // Let's see what we've got const cursor = collection.find({}) - .sort({ vector: vector([0, 0.2, 0.4]) }) // Performing a vector search - .includeSimilarity(true) // The found doc is inferred to have `$similarity` as a property now - .limit(2); + .sort({ vector: vector([0, 0.2, 0.4]) }) // Performing a vector search + .includeSimilarity(true) // The found doc is inferred to have `$similarity` as a property now + .limit(2); // This would print: // - Surfers' paradise: 0.98238194 @@ -113,11 +111,11 @@ const mkDreamsTable = async () => await db.createTable('dreams', { // Infer the TS-equivalent type from the table definition (like zod or arktype). Equivalent to: // -// interface TableSchema extends Row<'id'> { -// id: number, -- A primary key component, so it's required -// summary?: string | null, -- Not a primary key, so it's optional and may return as null when found -// tags?: Set, -- Sets/maps/lists are optional to insert, but will actually be returned as empty collections instead of null -// vector?: DataAPIVector | null, -- Vectors, however, may be null. +// interface TableSchema { +// id: number, -- A primary key component, so it's required +// summary?: string | null, -- Not a primary key, so it's optional and may return as null when found +// tags?: Set, -- Sets/maps/lists are optional to insert, but will actually be returned as empty collections instead of null +// vector?: DataAPIVector | null, -- Vectors, however, may be null. // } type Dream = InferTableSchema; @@ -181,7 +179,23 @@ type Dream = InferTableSchema; `astra-db-ts`'s abstractions for working at the data and admin layers are structured as depicted by this diagram: -![Class hierarchy diagram](etc/imgs/class-hierarchy.png) +```mermaid +flowchart TD + DataAPIClient -->|".db(endpoint)"| Db + DataAPIClient -->|".admin()"| AstraAdmin + + Db --->|".collection(name) + .createCollection(name)"| Collection + + Db --->|".table(name) + .createTable(name)"| Table + + AstraAdmin -->|".dbAdmin(endpoint) + .dbAdmin(id, region)"| DbAdmin + + Db -->|".admin()"| DbAdmin + DbAdmin -->|".db()"| Db +``` Here's a small admin-oriented example: @@ -204,139 +218,23 @@ const admin = client.admin(); })(); ``` -## Getting the most out of the typing - -`astra-db-ts` is a typescript-first library, performing minimal runtime type-checking. As such, it provides -a rich set of types to help you write type-safe code. - -Here are some examples of how you can properly leverage types to make your code more robust: - -```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'; - -const client = new DataAPIClient('*TOKEN*'); -const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' }); - -// You can strictly type your collections for proper type-checking -interface Person { - _id: UUID, - name: string, - interests: { - favoriteBand?: string, - friend?: UUID, - } -} - -(async () => { - // Create your collections with a defaultId type to enforce the type of the _id field - // (Otherwise it'll default to a string UUID that wouldn't be deserialized as a UUID by the client) - const collection = await db.createCollection('my_collection', { defaultId: { type: 'uuidv7' } }); - - // Now it'll raise type-errors if you try to insert a document with the wrong shape - await collection.insertOne({ - _id: new UUID('e7f1f3a0-7e3d-11eb-9439-0242ac130002'), - name: 'John', - interests: { - favoriteBand: 'Nightwish', - }, - // @ts-expect-error - 'eyeColor' does not exist in type MaybeId - eyeColor: 'blue', - }); -})(); -``` - -## Working with Dates - -Native JS `Date` objects can be used anywhere in documents to represent dates and times. +### Options hierarchy -Document fields stored using the `{ $date: number }` will also be returned as Date objects when read. +Like the client hierarchy, the options for each class also exist in a hierarchy. -```typescript -import { DataAPIClient } from '@datastax/astra-db-ts'; - -// Reference an untyped collections -const client = new DataAPIClient('*TOKEN*'); -const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' }); +The general options for parent classes are deeply merged with the options for child classes. -(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 }, - }, - ); - - // 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(); -})(); +```mermaid +graph TD + DataAPIClientOptions --> AdminOptions + DataAPIClientOptions --> DbOptions + DbOptions --> CollectionOptions + DbOptions --> TableOptions ``` -## Working with ObjectIds and UUIDs - -`astra-db-ts` exports an `ObjectId` and `UUID` class for working with these types in the database. - -Note that these are custom classes, and *not* the ones from the `bson` package. Make sure you're using the right one! +## Datatypes -```typescript -import { DataAPIClient, ObjectId, UUID } from '@datastax/astra-db-ts'; - -interface Person { - _id: ObjectId | UUID, - name: string, - friendId?: ObjectId | UUID, -} - -// Connect to the db -const client = new DataAPIClient('*TOKEN*'); -const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' }); - -(async () => { - // Create a collections with a UUIDv7 as the default ID - const collection = await db.createCollection('ids_test', { defaultId: { type: 'uuidv7' } }); - - // You can manually set whatever ID you want - await collection.insertOne({ _id: new ObjectId("65fd9b52d7fabba03349d013"), name: 'John' }); - - // Or use the default ID - await collection.insertOne({ name: 'Jane' }); - - // Let's give Jane a friend with a UUIDv4 - const friendId = UUID.v4(); - - await collection.insertOne({ name: 'Alice', _id: friendId }); - - await collection.updateOne( - { name: 'Jane' }, - { $set: { friendId } }, - ); - - // And let's get Jane as a document - // (Prints "Jane", the generated UUIDv4, and true) - const jane = await collection.findOne({ name: 'Jane' }); - console.log(jane?.name, jane?.friendId?.toString(), friendId.equals(jane?.friendId)); - - // Cleanup (if desired) - await collection.drop(); -})(); -``` +See [DATATYPES.md](etc/docs/DATATYPES.md) for a full list of supported datatypes and their TypeScript equivalents. ## Non-astra support @@ -354,8 +252,9 @@ const db = client.db('*ENDPOINT*'); // You'll also need to pass it to db.admin() when not using Astra for typing purposes // If the environment does not match, an error will be thrown as a reminder -const dbAdmin: DataAPIDbAdmin = db.admin({ environment: 'dse' }); -dbAdmin.createNamespace(...); +// `environment: 'dse'` makes the return type be `DataAPIDbAdmin` +const dbAdmin = db.admin({ environment: 'dse' }); +dbAdmin.createNamespace('...'); ``` The `TokenProvider` class is an extensible concept to allow you to create or even refresh your tokens diff --git a/etc/astra-db-ts.api.md b/etc/astra-db-ts.api.md index 63eb9ee2..c112fd9c 100644 --- a/etc/astra-db-ts.api.md +++ b/etc/astra-db-ts.api.md @@ -138,7 +138,7 @@ export class AstraAdmin { dbAdmin(endpoint: string, options?: DbOptions): AstraDbAdmin; dbAdmin(id: string, region: string, options?: DbOptions): AstraDbAdmin; dbInfo(id: string, options?: WithTimeout<'databaseAdminTimeoutMs'>): Promise; - dropDatabase(db: Db | string, options?: DropAstraDatabaseOptions): Promise; + dropDatabase(db: Db | string, options?: AstraDropDatabaseOptions): Promise; // Warning: (ae-forgotten-export) The symbol "DevOpsAPIHttpClient" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -214,7 +214,10 @@ export type AstraDbStatus = 'ACTIVE' | 'ERROR' | 'DECOMMISSIONING' | 'DEGRADED' // @public export type AstraDbStatusFilter = AstraDbStatus | 'ALL' | 'NONTERMINATED'; -// @public (undocumented) +// @public +export type AstraDropDatabaseOptions = AstraAdminBlockingOptions & WithTimeout<'databaseAdminTimeoutMs'>; + +// @public export type AstraDropKeyspaceOptions = AstraAdminBlockingOptions & WithTimeout<'keyspaceAdminTimeoutMs'>; // @public @@ -729,7 +732,7 @@ export interface CreateCollectionOptions extends Collect timeout?: number | Pick, 'collectionAdminTimeoutMs'>; } -// @public (undocumented) +// @public export type CreateTableColumnDefinitions = Record; // @public @@ -752,8 +755,8 @@ export interface CreateTableOptions { @@ -939,7 +942,7 @@ export type DataAPILoggingConfig = DataAPILoggingEvent | readonly (DataAPILoggin // Warning: (ae-incompatible-release-tags) The symbol "DataAPILoggingDefaults" is marked as @public, but its signature references "NormalizedLoggingConfig" which is marked as @internal // -// @public (undocumented) +// @public export const DataAPILoggingDefaults: NormalizedLoggingConfig[]; // @public @@ -1161,9 +1164,6 @@ export class DevOpsUnexpectedStateError extends DevOpsAPIError { readonly expected: string[]; } -// @public -export type DropAstraDatabaseOptions = AstraAdminBlockingOptions & WithTimeout<'databaseAdminTimeoutMs'>; - // @public export interface DropCollectionOptions extends WithTimeout<'collectionAdminTimeoutMs'>, WithKeyspace { } @@ -1351,7 +1351,7 @@ export type FoundRow = { [K in keyof Doc]-?: DataAPIVector extends Doc[K] ? Exclude : Doc[K]; }; -// @public (undocumented) +// @public export interface FullCreateTablePrimaryKeyDefinition { // (undocumented) readonly partitionBy: readonly string[]; @@ -1562,7 +1562,7 @@ export interface ListCollectionsOptions extends WithTimeout<'collectionAdminTime nameOnly?: boolean; } -// @public (undocumented) +// @public export interface ListCreateTableColumnDefinition { // (undocumented) type: 'list'; @@ -1570,10 +1570,10 @@ export interface ListCreateTableColumnDefinition { valueType: TableScalarType; } -// @public (undocumented) +// @public export type ListTableColumnDefinitions = Record; -// @public (undocumented) +// @public export interface ListTableDefinition { // (undocumented) columns: ListTableColumnDefinitions; @@ -1581,10 +1581,12 @@ export interface ListTableDefinition { primaryKey: ListTablePrimaryKeyDefinition; } -// @public (undocumented) -export type ListTableKnownColumnDefinition = StrictCreateTableColumnDefinition; +// @public +export type ListTableKnownColumnDefinition = StrictCreateTableColumnDefinition & { + apiSupport?: ListTableUnsupportedColumnApiSupport; +}; -// @public (undocumented) +// @public export type ListTablePrimaryKeyDefinition = Required; // @public @@ -1592,19 +1594,21 @@ export interface ListTablesOptions extends WithTimeout<'tableAdminTimeoutMs'>, W nameOnly?: boolean; } -// @public (undocumented) +// @public export interface ListTableUnsupportedColumnApiSupport { // (undocumented) cqlDefinition: string; // (undocumented) createTable: boolean; // (undocumented) + filter: boolean; + // (undocumented) insert: boolean; // (undocumented) read: boolean; } -// @public (undocumented) +// @public export interface ListTableUnsupportedColumnDefinition { // (undocumented) apiSupport: ListTableUnsupportedColumnApiSupport; @@ -1612,13 +1616,13 @@ export interface ListTableUnsupportedColumnDefinition { type: 'UNSUPPORTED'; } -// @public (undocumented) +// @public export type LooseCreateTableColumnDefinition = TableScalarType | string; -// @public (undocumented) +// @public export interface MapCreateTableColumnDefinition { // (undocumented) - keyType: TableScalarType; + keyType: 'text' | 'ascii'; // (undocumented) type: 'map'; // (undocumented) @@ -1729,7 +1733,7 @@ export interface RunCommandOptions extends WithTimeout<'generalMethodTimeoutMs'> table?: string; } -// @public (undocumented) +// @public export interface ScalarCreateTableColumnDefinition { // (undocumented) type: TableScalarType; @@ -1738,7 +1742,7 @@ export interface ScalarCreateTableColumnDefinition { // @public (undocumented) export type SerDesFn = (key: string, value: any, ctx: Ctx) => readonly [0 | 1 | 2, any?, string?] | 'Return ctx.done(val?), ctx.recurse(val?), ctx.continue(), or void'; -// @public (undocumented) +// @public export interface SetCreateTableColumnDefinition { // (undocumented) type: 'set'; @@ -1746,9 +1750,6 @@ export interface SetCreateTableColumnDefinition { valueType: TableScalarType; } -// @public (undocumented) -export type ShortCreateTablePrimaryKeyDefinition = string; - // @public (undocumented) export type SomeCodec = NameCodec | PathCodec | TypeCodec | CustomGuardCodec | ClassGuardCodec; @@ -1773,7 +1774,7 @@ export class StaticTokenProvider extends TokenProvider { getToken(): string; } -// @public (undocumented) +// @public export type StrictCreateTableColumnDefinition = ScalarCreateTableColumnDefinition | MapCreateTableColumnDefinition | ListCreateTableColumnDefinition | SetCreateTableColumnDefinition | VectorCreateTableColumnDefinition; // @public @@ -1955,7 +1956,7 @@ export interface TableOptions extends WithKeyspace { timeoutDefaults?: Partial; } -// @public (undocumented) +// @public export type TableScalarType = 'ascii' | 'bigint' | 'blob' | 'boolean' | 'date' | 'decimal' | 'double' | 'duration' | 'float' | 'int' | 'inet' | 'smallint' | 'text' | 'time' | 'timestamp' | 'tinyint' | 'uuid' | 'varint'; // @public (undocumented) @@ -2077,10 +2078,10 @@ export const uuid: (uuid: string | 1 | 4 | 6 | 7) => UUID; // @public export const vector: (v: DataAPIVectorLike) => DataAPIVector; -// @public (undocumented) +// @public export interface VectorCreateTableColumnDefinition { // (undocumented) - dimension?: number; + dimension: number; // (undocumented) service?: VectorizeServiceOptions; // (undocumented) diff --git a/etc/docs/DATATYPES.md b/etc/docs/DATATYPES.md new file mode 100644 index 00000000..b74d2f3c --- /dev/null +++ b/etc/docs/DATATYPES.md @@ -0,0 +1,526 @@ +# Datatypes + +`astra-db-ts` exports a variety of custom datatype classes to represent their respective types in the database. + +Some types are strictly meant for tables; others for collections. And a couple, i.e. `UUID` and `DataAPIVector`, are used in both. + +### Table of Contents + +- [Collections](#collections) + - [Overview](#overview) + - [BigNumbers](#bignumbers) + - [Dates](#dates) + - [ObjectIds](#objectids) + - [UUIDs](#uuids) + - [Vectors](#vectors) +- [Tables](#tables) + - [Overview](#overview-1) + - [BigNumbers](#bignumbers-1) + - [Blobs](#blobs) + - [Collections](#collections-1) + - [Dates/Times](#dates--times) + - [InetAddresses](#inetaddresses) + - [UUIDs](#uuids-1) + - [Vectors](#vectors-1) +- [Inserting native representations](#inserting-native-representations) +- [Cheatsheet](#cheatsheet) + - [Collections](#collections-2) + - [Tables](#tables-1) + +## Collections + +### Overview + +Types in collections are natively represented through the `{ $type: '' }` syntax, e.g. + +```typescript +await collection.insertOne({ + date: { $date: 1734070574056 }, + uuid: { $uuid: 'f47ac10b-58cc-4372-a567-0e02b2c3d479' }, + oid: { $objectId: '507f1f77bcf86cd799439011' }, + $vector: [.1, .2, .3], +}); +``` + +However, `astra-db-ts` provides utility types to make working with these values easier. + +The idiomatic equivalent to the above would be: + +```typescript +import { DataAPIVector, ObjectId, UUID } from '@datastax/astra-db-ts'; + +await collection.insertOne({ + date: new Date(), + uuid: UUID.v4(), + oid: new ObjectId(), + $vector: new DataAPIVector([.1, .2, .3]), +}); +``` + +Or, if you prefer to use the available shorthand functions: + +```typescript +import { oid, uuid, vector } from '@datastax/astra-db-ts'; + +await collection.insertOne({ + date: new Date(), + uuid: uuid(4), + oid: oid(), + $vector: vector([.1, .2, .3]), +}); +``` + +### BigNumbers + +> **NOTE** +> Enabling BigNumbers support for a collection will force a slower, bignum-friendly JSON library to be used for all documents in that collection. The difference should be negligible for most use-cases. + +Proper big-number support is still under works in `astra-db-ts`, but a rough version is out currently. + +You **must** set `serdes.enableBigNumbers: true` somewhere along the options hierarchy for collections to be able to work with `bigint`s & `BigNumber`s. + +Under the current rough support, you may pass any of `number`, `bigint`, or `BigNumber` to the database (in any field), and it'll be stored as a `decimal` in the database. + +When reading back, the `decimal` will be returned as a `number` if it's within the safe `number` range, and as a `string` otherwise; currently, it's on the user to handle the conversion to `bigint` or `BigNumber` as desired. + +Note that this is the same `BigNumber` from `bignumber.js`, just reexported from `@datastax/astra-db-ts`. + +```typescript +import { BigNumber } from '@datastax/astra-db-ts'; + +const collection = db.collection('my_coll', { + serdes: { enableBigNumbers: true }, +}); + +await collection.insertOne({ + bigint1: 1234567890123456789012345672321312312890n, + bigint2: 10n, + decmial: new BigNumber('12345678901234567890123456.72321312312890'), +}); + +const doc = await collection.findOne(); + +console.log(doc.bigint1.toString()); // Will be returned as a `string` +console.log(doc.bigint2.toString()); // Will just be a normal `number` as it's within the safe `number` range +console.log(doc.decimal.toString()); // Will be returned as a `string` +``` +When reading back, the `decimal` will be returned as a `number` if it's within the safe `number` range, and as a `string` otherwise; currently, it's on the user to handle the conversion to `bigint` or `BigNumber` as desired. + +Note that this is the same `BigNumber` from `bignumber.js`, just reexported from `@datastax/astra-db-ts`. + +```typescript +import { BigNumber } from '@datastax/astra-db-ts'; + +const collection = db.collection('my_coll', { + serdes: { enableBigNumbers: true }, +}); + +await collection.insertOne({ + bigint1: 1234567890123456789012345672321312312890n, + bigint2: 10n, + decmial: new BigNumber('12345678901234567890123456.72321312312890'), +}); + +const doc = await collection.findOne(); +console.log(doc.bigint1.toString()); // Will be returned as a `string` +console.log(doc.bigint2.toString()); // Will just be a normal `number` as it's within the safe `number` range +console.log(doc.decimal.toString()); // Will be returned as a `string` +``` + +### Dates + +Dates in collections are represented as just normal, native JS `Date` objects. + +```typescript +await collection.insertOne({ + date: new Date(), +}); + +const doc = await collection.findOne(); +console.log(doc.date instanceof Date); // true +``` + +If you prefer to use `DataAPITimestamp`s for interop with tables, that's also allowed, though you'll need to enable a certain codec if you want to read the date back as a `DataAPITimestamp`. + +- `DataAPITimestamp`s will still serialize to a `$date` by default, even if you don't set the necessary codec. + +```typescript +import { CollCodecs, DataAPITimestamp, timestamp } from '@datastax/astra-db-ts'; + +const collection = db.collection('my_coll', { + serdes: { codecs: [CollCodecs.USE_DATA_API_TIMESTAMPS_FOR_DATES] }, +}); + +await collection.insertOne({ + date: timestamp(), // Equivalent to `new DataAPITimestamp()` +}); + +const doc = await collection.findOne(); +console.log(doc.date instanceof DataAPITimestamp); // true +``` + +### ObjectIds + +You can use objectIds in collections using the `ObjectId` class (or the `oid` shorthand). Make sure you're importing this from `'@datastax/astra-db-ts'`, and _not_ from `'bson'`. + +```typescript +import { ObjectId, oid } from '@datastax/astra-db-ts'; + +await collection.insertOne({ + _id: oid(), // Equivalent to `new ObjectId()` +}); + +const doc = await collection.findOne(); +console.log(doc._id instanceof ObjectId); // true +``` + +You can create an `ObjectId` through the constructor function, or through the `oid` shorthand, in three different ways: +1. Provide the objectId as a string (`'507f1f77bcf86cd799439011'`) +2. Provide the timestamp you want the objectID to be based on (`1734070574056`) +3. Leave it `undefined`/`null` to generate a new `ObjectID` based on the current timestamp + +From the `ObjectId` class, you can either: +- Get the timestamp as a `Date` using `.getTimestamp()` +- Get the string representation of the `ObjectId` using `.toString()` +- Compare it with another `ObjectId` or `string` using `.equals()` + +### UUIDs + +You can use UUIDs in collections using the `UUID` class (or the `uuid` shorthand). Make sure you're importing this from `'@datastax/astra-db-ts'`, and _not_ from `'uuid'` or `'bson'`. + +```typescript +import { UUID, uuid } from '@datastax/astra-db-ts'; + +await collection.insertOne({ + _id: uuid(4), // Equivalent to `UUID.v4()` +}); + +const doc = await collection.findOne(); +console.log(doc._id instanceof UUID); // true +``` + +You can create a `UUID` through the class, or through the `uuid` shorthand, in a few different ways: +1. By passing the UUID string to `new UUID()` or `uuid()` +2. By using `UUID.v1()`, `.v4()`, `.v6()`, or `.v7()` to generate a new UUID of the respective version +3. By using `uuid(1)`, `uuid(4)`, `uuid(6)`, or `uuid(7)` to generate a new UUID of the respective version + +From the `UUID` class, you can either: +- Get the string representation of the `UUID` using `.toString()` +- Compare it with another `UUID` or `string` using `.equals()` +- Get the version of the `UUID` using `.version` +- Get the timestamp of a `v1` or `v7` `UUID` using `.getTimestamp()` + - Note that this is [generally not recommended](https://www.rfc-editor.org/rfc/rfc9562.html#section-6.12), but it's there if you really need it + +### Vectors + +`$vector`/`$vectorize` are a special case where they're not types, but rather a special reserved name for working with an embedding vector. + +```typescript +import { vector } from '@datastax/astra-db-ts'; + +await collection.insertOne({ + $vector: vector([.1, .2, .3]), // Equivalent to `new DataAPIVector([.1, .2, .3])` +}); +``` + +Using `DataAPIVector` for insertion isn't strictly necessary; neither `astra-db-ts`, nor the server, will complain if the vector is inserted in any of the following ways: +- `$vector: [.1, .2, .3]` +- `$vector: { $binary: '' }` +- `$vector: new DataAPIVector([.1, .2, .3])` +- `$vector: vector([.1, .2, .3])` + +However, keep in mind that when `find`-ing, the `$vector` will _always_ be returned as a `DataAPIVector`, to smooth the difference between the underlying representations. + +```typescript +const doc = await collection.findOne(); +console.log(doc.$vector instanceof DataAPIVector); // true +``` + +You can create a `DataAPIVector` through the constructor function, or through the `vector` shorthand, by providing the vector in four different ways: +1. As an array of numbers (`[.1, .2, .3]`) +2. In its "binary" representation (`{ $binary: '' }`) +3. As a `Float32Array` (`new Float32Array([.1, .2, .3])`) +4. As a `DataAPIVector`, which copies its internal state into a new `DataAPIVector` + +From the `DataAPIVector` class, you can either: +- Get the length of the vector (in O(1) time) using `.length` +- Get the "raw" underlying vector using `.raw()` +- Get the vector in your desired format (converting if necessary) using one of: + - `.asArray()` + - `.asFloat32Array()` + - `.asBase64()` + +## Tables + +### Overview + +Tables have a known type on the server, but the client doesn't have a way to know what that schema is, so it's up to the user to provide the correct types using their respective `astra-db-ts`-provided types as necessary. + +Collection types (maps/sets/lists) are represented by their native JavaScript counterparts, e.g. + +A variety of scalar types, however, are represented by custom `astra-db-ts`-provided classes. + +### BigNumbers + +> **NOTE** +> Enabling BigNumbers support for a collection will force a slower, bignum-friendly JSON library to be used for all documents in that collection. The difference should be negligible for most use-cases. + +Unlike collections, `bigint`s & `BigNumber`s are supported completely and natively in tables; you don't need to enable any special options to use them. + +The performance penalty still applies, however, but it's only in play when there's actually a `bigint` or `BigNumber` present in the object. + +While you may technically pass any of `number`, `bigint`, or `BigNumber` to the database, it'll be read back as: +- a `bigint` if the column is a `varint` +- a `BigNumber` if the column is a `decimal` + +```typescript +import { BigNumber } from '@datastax/astra-db-ts'; + +await table.insertOne({ + bigint1: 1234567890123456789012345672321312312890n, + bigint2: 10n, + decmial: new BigNumber('12345678901234567890123456.72321312312890'), +}); + +const row = await table.findOne(); +console.log(row.bigint1.toString()); // Will be returned as a `bigint` +console.log(row.bigint2.toString()); // Will be returned as a `bigint` +console.log(row.decimal.toString()); // Will be returned as a `BigNumber` +``` + +### Blobs + +You can use blobs in tables using the `DataAPIBlob` class (or the `blob` shorthand). + +```typescript +import { blob, DataAPIBlob } from '@datastax/astra-db-ts'; + +await table.insertOne({ + blob: blob(Buffer.from([0x0, 0x1, 0x2])), // Equivalent to `new DataAPIBlob(...)` +}); + +const row = await collection.findOne(); +console.log(row.blob instanceof DataAPIBlob); // true +``` + +You can create a `DataAPIBlob` through the constructor function, or through the `blob` shorthand, by providing the binary data in four different ways: +1. As a Node.js Buffer, if available (`Buffer.from([0x0, 0x1, 0x2])`) +2. As a more generic ArrayBuffer (`new ArrayBuffer(...)`) +3. In its "binary" representation (`{ $binary: '' }`) +4. As a `DataAPIBlob`, which copies its internal state into a new `DataAPIBlob` + +From the `DataAPIBlob` class, you can either: +- Get the byte-length of the blob (in O(1) time) using `.byteLength` +- Get the "raw" underlying binary data using `.raw()` +- Get the blob in your desired format (converting if necessary) using one of: + - `.asBuffer()` + - `.asArrayBuffer()` + - `.asBase64()` + +### Collections + +The `map`, `set`, and `list` types are represented by their native JavaScript counterparts (`Map`/`Set`/`Array`), and accept nested (scalar) datatypes. + +```typescript +await table.insertOne({ + map: new Map([['key', 'value']]), + set: new Set(['value']), + list: ['value'], +}); + +const row = await table.findOne(); +console.log(row.map.get('key')); // 'value' +console.log(row.set.has('value')); // true +console.log(row.list[0]); // 'value' +``` + +### Dates & times + +Due to the variety of date & time classes available through the Data API, four custom classes are provided to represent them in the client. + +```typescript +import { date, duration, time, timestamp, ... } from '@datastax/astra-db-ts'; + +await table.insertOne({ + date: date(), // Equivalent to `new DataAPIDate()` + time: time(), // Equivalent to `new DataAPITime()` + timestamp: timestamp(), // Equivalent to `new DataAPITimestamp()` + duration: duration('P5DT30M'), // Equivalent to `new DataAPIDuration(...)` +}); + +const row = await table.findOne(); +console.log(row.date instanceof DataAPIDate); // true +console.log(row.time instanceof DataAPITime); // true +console.log(row.timestamp instanceof DataAPITimestamp); // true +console.log(row.duration instanceof DataAPIDuration); // true +``` + +You can create these classes through the constructor function, or through the respective shorthand, by providing the date/time/duration in a few different ways: +1. As a raw string formatted as it would be stored in the database (`'1992-05-28'`, `'12:34:56'`, `'2021-09-30T12:34:56.789Z'`, `'P5DT30M'`) +2. As a `Date` object (`new Date(1734070574056)`) + - Durations are the exception here, as they doesn't have a direct `Date` equivalent +3. As the `*Components` object for that respective class (e.g. `{ year: 1992, month: 5, day: 28 }`) + +From each class, you can generally: +- Get the string representation of the date/time/duration using `.toString()` +- Get the date/time as a `Date` object using `.toDate()` +- Get the individual components of the date/time using `.components()` + +### InetAddresses + +You can use inets in collections using the `InetAddress` class (or the `inet` shorthand). + +```typescript +import { InetAddress, inet } from '@datastax/astra-db-ts'; + +await table.insertOne({ + inet: inet('::1'), // Equivalent to `new InetAddress('::1')` +}); + +const row = await table.findOne(); +console.log(row.inet instanceof InetAddress); // true +``` + +You can create a `InetAddress` through the class, or through the `inet` shorthand, in a few different ways: +1. By passing the inet string to `new InetAddress()` or `inet()`, and having the version be inferred +2. By passing the inet string to `new InetAddress()` or `inet()`, and specifying the version explicitly (validating as that version) + - e.g. `inet('::1', 6)` + +From the `InetAddress` class, you can either: +- Get the string representation of the `InetAddress` using `.toString()` +- Get the version of the `InetAddress` using `.version` + +### UUIDs + +You can use UUIDs in collections using the `UUID` class (or the `uuid` shorthand). Make sure you're importing this from `'@datastax/astra-db-ts'`, and _not_ from `'uuid'` or `'bson'`. + +```typescript +import { UUID, uuid } from '@datastax/astra-db-ts'; + +await table.insertOne({ + uuid: uuid(4), // Equivalent to `UUID.v4()` +}); + +const row = await table.findOne(); +console.log(row.uuid instanceof UUID); // true +``` + +You can create a `UUID` through the class, or through the `uuid` shorthand, in a few different ways: +1. By passing the UUID string to `new UUID()` or `uuid()` +2. By using `UUID.v1()`, `.v4()`, `.v6()`, or `.v7()` to generate a new UUID of the respective version +3. By using `uuid(1)`, `uuid(4)`, `uuid(6)`, or `uuid(7)` to generate a new UUID of the respective version + +From the `UUID` class, you can either: +- Get the string representation of the `UUID` using `.toString()` +- Compare it with another `UUID` or `string` using `.equals()` +- Get the version of the `UUID` using `.version` +- Get the timestamp of a `v1` or `v7` `UUID` using `.getTimestamp()` + - Note that this is [generally not recommended](https://www.rfc-editor.org/rfc/rfc9562.html#section-6.12), but it's there if you really need it + +### Vectors + +You can use vectors in tables using the `DataAPIVector` class (or the `vector` shorthand). + +```typescript +import { vector } from '@datastax/astra-db-ts'; + +await table.insertOne({ + vector: vector([.1, .2, .3]), // Equivalent to `new DataAPIVector([.1, .2, .3])` +}); +``` + +Using `DataAPIVector` for insertion isn't strictly necessary; neither `astra-db-ts`, nor the server, will complain if the vector is inserted in any of the following ways: +- `vector: [.1, .2, .3]` +- `vector: { $binary: '' }` +- `vector: new DataAPIVector([.1, .2, .3])` +- `vector: vector([.1, .2, .3])` + +However, keep in mind that when `find`-ing, the `$vector` will _always_ be returned as a `DataAPIVector`, to smooth the difference between the underlying representations. + +Also, there will be a performance penalty for using plain `number[]`s instead of the binary-optimizing `DataAPIVector`. + +```typescript +const row = await table.findOne(); +console.log(row.$vector instanceof DataAPIVector); // true +``` + +You can create a `DataAPIVector` through the constructor function, or through the `vector` shorthand, by providing the vector in four different ways: +1. As an array of numbers (`[.1, .2, .3]`) +2. In its "binary" representation (`{ $binary: '' }`) +3. As a `Float32Array` (`new Float32Array([.1, .2, .3])`) +4. As a `DataAPIVector`, which copies its internal state into a new `DataAPIVector` + +From the `DataAPIVector` class, you can either: +- Get the length of the vector (in O(1) time) using `.length` +- Get the "raw" underlying vector using `.raw()` +- Get the vector in your desired format (converting if necessary) using one of: + - `.asArray()` + - `.asFloat32Array()` + - `.asBase64()` + +## Inserting native representations + +Each of the given types can be inserted into the database using their native representation—e.g: + +```typescript +await table.insertOne({ + blob: { $binary: '' }, + date: '1992-05-28', + float: 'NaN', + uuid: 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + vector: [.1, .2, .3], +}); + +await collection.insertOne({ + date: { $date: 1734070574056 }, + uuid: { $uuid: 'f47ac10b-58cc-4372-a567-0e02b2c3d479' }, + oid: { $objectId: '507f1f77bcf86cd799439011' }, + $vector: [.1, .2, .3], +}); +``` + +However, it's generally recommended to use the provided classes for better type-safety and ease of use. + +Plus, importantly, when reading back, each datatype will be deserialized into their respective classes, regardless of how they were inserted. + +If you really want to change the behavior of how a certain type is deserialized, you'll need to implement some custom ser/des logic for that type. + +## Cheatsheet + +### Collections + +| Type | Type | Shorthand | Examples | +|-------------|-----------------|-----------|----------------------------------------------------------------| +| `$date` | `Date` | - | `new Date()` | +| `$uuid` | `UUID` | `uuid` | `new UUID('...')`, `UUID.v4()`, `uuid('...')`, `uuid(7)` | +| `$objectId` | `ObjectId` | `oid` | `new ObjectId()`, `new ObjectId('...')`, `oid()`, `oid('...')` | +| `$vector` | `DataAPIVector` | `vector` | `new DataAPIVector([.1, .2, .3])`, `vector([.1, .2, .3])` | + +### Tables + +| Type | Type | Shorthand | Examples | +|-------------|--------------------|-------------|--------------------------------------------------------------------------------------| +| `ascii` | `string` | - | `'Hello!'` | +| `bigint` | `number` | - | `42` | +| `blob` | `DataAPIBlob` | `blob` | `new DataAPIBlob(Buffer.from(...))`, `blob({ $binary: '' })` | +| `boolean` | `boolean` | - | `true` | +| `date` | `DataAPIDate` | `date` | `new DataAPIDate()`, `date(new Date(1734070574056))`, `date('1992-05-28')`, `date()` | +| `decimal` | `BigNumber` | - | `new BigNumber(123.4567)`, `BigNumber('123456.7e-3')` | +| `double` | `number` | - | `3.14`, `NaN`, `Infinity`, `-Infinity` | +| `duration` | `DataAPIDuration` | `duration` | `new DataAPIDuration('3w')`, `duration('P5DT30M')` | +| `float` | `number` | - | `3.14`, `NaN`, `Infinity`, `-Infinity` | +| `inet`. | `InetAddress` | `inet` | `new InetAddress('::1')`, `inet('127.0.0.1')` | +| `int` | `number` | - | `42` | +| `list` | `Array` | - | `['value']` | +| `map` | `Map` | - | `new Map([['key', 'value']])` | +| `set` | `Set` | - | `new Set(['value'])` | +| `smallint` | `number` | - | `42` | +| `text` | `string` | - | `'Hello!'` | +| `time` | `DataAPITime` | `time` | `new DataAPITime()`, `time(new Date(1734070574056))`, `time('12:34:56')`, `time()` | +| `timestamp` | `DataAPITimestamp` | `timestamp` | `new DataAPITimestamp('...')`, `timestamp(new Date(1734070574056))`, `timestamp()` | +| `timeuuid` | `UUID` | `timeuuid` | `new UUID('...')`, `UUID.v1()`, `uuid('...')`, `uuid(1)` | +| `tinyint` | `number` | - | `42` | +| `uuid` | `UUID` | `uuid` | `new UUID('...')`, `UUID.v4()`, `uuid('...')`, `uuid(7)` | +| `varchar` | `string` | - | `'Hello!'` | +| `varint` | `bigint` | - | `BigInt('42')`, `42n` | +| `vector` | `DataAPIVector` | `vector` | `new DataAPIVector([.1, .2, .3])`, `vector([.1, .2, .3])` | diff --git a/etc/imgs/class-hierarchy.png b/etc/imgs/class-hierarchy.png deleted file mode 100644 index 656b9e8869ca35b7aa9192e173a7d7fd7f82da85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56231 zcmdSAbz4;J_dYBRFqD9Rbc0BD4AR}w-O|m7ba$76APv$f(jCG8(%t1qOE*J2qn}&v z`+NLe!NV~Jf6Sh>_jRpn#ktP4cBINHnI~w(XpbH}dLkz)srKj*BIctS4y==9EVkxofHy|rZd z;Acb4I4 zP16dFz6_TNBxaN9M*pS*CeE!?vpD|Qpt>yYxGf@g#WZfzha;?q0D*(X;5_=MKc8WF8EAY$TQDXuB{EjNbLmV3LM~W)zzalUG|1XkHVz6>b$oOH|bXVACD!(4v zKxR@vi$r~Aps|=2w>D)hV#yK4Q71+5hEQh1g@8(y(DB`Mc*&`ZO*ku4r2m>Rq5E`vJ_xcr1uRb-G|SgYke|wn4uv~V7N>l&*9zX zinHjSttD8$m7YlP1!OkftRpaw2$URb%Q$|zQ{>^)){?mUF#g3X{q6puikFlP_OWF5 zT^(WLDi-`S5)Q_#u^yLUmQY|38|vkxvm!M&lS_O>s-q&kBjfimbQlj0!B4;v6oXtV zp|gG%?xecQikJLEEGkn5#{SuiN)>YUBn8v7lC*W3QL^iKovAWmV`nj2Fsyw?AAM$Y z))abn-=WR9YQP^E)Ef#Rv?PzChEj4KRAmOj?kM4hzC*r?5g7D!TWyiMU_D?7f~I4r z7*_8~Q^2ctv}HdLj)>Y%6V?fB)yiFx;0cIRgHmq0;)e=lhBP|EFNxwtxuh}jQB7Xw%m1L2n3Ese_?_u(;t?x)M#`}&3U7It>DOxZ^5 zuGru%h5vKoA2sh_`2j5WO7-~=d~QpHu102=%wV%C>*U&1Q|2=sZp<5`U$?{&%9sl; zY43ba@sa2`?BiyKgEGkNn>&hDIZ~i#I zGlQ!Zu!#ic$gY^B33Sb}P0&qg&t-hmOB}tIo8e6%cut8R<@>vDcU-o@9x>`o{+Je9 z-_sNXmO*0&d-IoOVC!B(h}(V^`MgokOjUmMTVP$sS-47acJydy30@G`d0&z>&e3DY zCsxtM>}7tNR*|r((UwZpV!pmF{CH419j2;=FM%vK7yt|8?uq#0Sg%w-&D@f?zp;AJ zq4*Bbaqc=9;e2819zyB-=$VgV{msV~0`HNfBeK(E`Z+%B1(7yHecP&=i$O&B7tTWN z%clCP@6DnTbuSne3|rre`sz2GA=&h%UI#6`A~_6k&}qG3k29o_s zlciu5xkYw$FA=58oaITf7vSlQtX%{C7*F}tyiM_)Z?6@7XPQTRW{-i?wJ^I0Kh)%= z=cxoVcaGa;vqmjT@ojyqaf{7^o*l;YJ+1k^^c5{XPg;K5!KkiE9jnZL+C!+J^%e5Ki+p*R*UosOcQ;O+Dxt-Nol=BhJ>APto`H=Yx9 zh;ywhCt1kE*7u(*<6|_G;ikldQkRMqqf%w3RSkeeb!VB~(07~FL)T}k;D@t$QgSE; zPk@$jRS>s^Rbwr|H(AKFV;azq<@w58fkT))S80K`Cgd3l6tzY&Qqtv!`?^|lLnqqx6A0D0$FF4_4gRUhT>ZEK7 zuBZslkaYxp@O^$kDX;dX#3fBHXKlsrz?WX%RkSK4 zk+?7()WmRwbx5Ofyr{$aa=8GVPrRjrI9r=$o|C@yhuexu+$6V4?2XY0FJ_31Nz296 z*GBq}$U>gkPk-g59bWmUE`jG)6H8{^d6htCc`^V4S=arUFYAcHxW2Z6Blcux6+n;D zchbKYirQf44jrpBv&`8hPY@Vc&NR81&?7xLFG;1cHI<{R#C}<;SRRmxSK*Wj!%gm-Rxa)`)JKFp(p6m_Jqc`U#rJBr|8M(*b(82TL z0H2JToS3vQZx;Kfcj|9$g7A}422R_}9ibX=4K{0xY*5P7+8kz+gtH-5jm37s;;z?^ zpp?b6-Y)Vl2@!7G40F3BCQ>EP?UT75YkpEt$?eeKtGmyir?9EpR6luDoBh(9j|6|} z=EE|Eo3c0;rsLcQnMxEm*Nh7@$j&zI<@97`*3znH)299VMZWPjCMo;w-F`+X8;Sty z-lx~GyQZW*eslLPODv_ZR;_w4;o01)^ZGG^%IP#KC_0S!;X=YY=F!-vN#{ zOkwsxQFQ~L#W(7Fmd%cJYwsU#;re%goyn9AuNul~*rs3wg&@TCgOzh76e`ILy3!Q+ zuFwkXJRB4y;ruCXPMfOU*ZKi!5v~-xP!fi@H-apf=A_nrPUS6@id&8%k+E?m%oGZP zBP4h3S$*Ee7rs=$OJ@=HO$3*pnZw1hHNXz7G5huDhKkkkUV0(#uY5vx>2^vUPGVGr zBg>&I0>Y4@*(vK0nuxRY*QC}67Uw(`FPryWRROT{Vnr8<7O^8@U|>wJ(^SbhM~jN* zKr67JYJCdRVkY8ZUMvg@bkIcIS=x#=ulf3po2kn!J4-UyNwbWd1ZX$Y?Q`XrmkNr*LuX5xryYcR zPl8Gt_mw<(lkSMPBW6p3*mfX__&cx!;hd4!p!u=l52z2Lt2(dL>u;sYds9g@d_>*1 z=&k1si~;a~v@grdBr62X#0S*F-JRJ~U~bGp*Vm>n+-05@4lQjr^+lp@Ulc!UL`>w( zfQTtaX?w*k=kP(gcr=(3;(QAcljC$x8pgjY`yD#W<`4rhCrgPA+o-e6*u)?DvE2Lt zPuJS%cb*;kvQiLWSSTuB%|GEFm=qmrxg@I20gK8ie@1F@-&VfeR|Z?H;hsj;r!C}& z+|`jev3;JaXR8eu%i5*PR7OQ}C=7Y>oKkzk287sU>7z5bwlR-Lqnf$JN8rQ7^+R;7 ze#pWj7SI3#x6AGt<0Wa3G~z6j61u%-a86jcwm@girWb>{m5k-}fyJuya|M3o&T2EP z?E-Ej^ydLCi2KAB+(<04Z@oXyYsH%Lv!8Hd8VsRM6BcVibQ)&cJNh7jgH6)`uTVLK zU|JJ`bjplfFOR1#bjaXISH8&CQwk@~E@q;o6 zMX=TS51*)<%6+E+1SNe)ZH{NHPVh>CbM~_gtE9Dp`jIvC-3v0kM_Xj&p2#`)Vljax zFhDHZb`u~*e{K2l$<&qy0WuyFPx+i)xbpPbpi>D!D?0TMvENA7{*dcN2J(ykAp+{he{6-N*Gc#b&7u|A!t%Y@2Wu&l$z9)lYjs zW3}D<4uCfA?5F5(Xm^IRydiA8KBVbx7peLH=~O$RGyze1XLCMJ2_PpM_`Cu^<2Jfn}Ms3SPA?fr9( zk%Zg>!03<9Sqh;f3QtRwFZa_@7V+MM`U0L8XFH>0GqPZ?3TQWDEAZ?pcU9%RX%fVA z{V6dAYMc*Yc|+WD*sB&r{iv$9L}BaLC;|4G1q#wO8qpa4u>(|bIz% zsm=8Cl;fRaJ-qVy&>w`oJ)WOl-3YxQ2EM)?y*Rzl#Kk{+zxu-Q?Ut`Jvo&c*;2rD| z8t;EgQ>ge+9AHX6UR-Hp!YDLfUz-<*V=n(@2xVIiEV()nx-G3zjQB%e{wUcmFI|t4 zZrOp1_~ZAlu?Yym zabLVD9+u^PqmX69HtdRr6Yxllcp+kXB6p99wtsSHSX7w6lV#hU>R=Yi=IW}$*o zdPWmt265x{Z?kYZJ%BlM|8shzRI$+t8k zUiII|pawnbbE{7ugdw3jKKW_37;5X822lH<{sFeT+}xdyS8c9GJT;>4iTZNdxXTnZ7g@zRZ5nDI z2tE_O(#CvpB;2AE-8*qOYhYt3efT>>im~JL9Fc#zf{o=dX z>F?owM6>v5;Ia16cErurCFS#?xm5!@@j!zkwG^)29zO>)5ld`}s}&owq!e5X+J*vT z*c1rG$A5Y?_8E*7O0opu%bum;lIEAb5mGsHXGh|Wwm+;{ym*^qRXZ#HKs~qkJLir` zynFZV?Ib1aF1gu;Qej9K8x~S6nn$w5{5YlL1mBkZg+|V+!OK%ksJuqgtILMB1eni~ zJ{j&)Dnbw(ZD0kRMud2dTnvI>gDMx^z>0{xggyIM6X=<2^k>D7!aSHcMX{vAC!AOZ z6C)|n#5U1_edC;{@%^qAce5!34sN(jP zU!Rcb`B0TmV}M!L> z4hBMgC`^SgfLb-Ff#t{J{6+k2sTOd~WMr8ug!|+pTmOEK?|fmEqw~+G)9Ro&9Zcsw zR(*^6l1YW56^3J9YDuW5GmNt|8SNo2n+3>fQx&PU)qU(0RX}=4rAyp$??sMk0SOFM zJ?;=?nBsE{ni-9I-?(d`b6yR`zPh)q^^X!_ism@ib$Q^rPUUxJli!0|rNu=oi-Qa_ zo#{pF+fdYRIH{jbIoNEn$HVtg#MUl9b_##W#YWn?v%wbf%YI5m3|uzv>b_28xA763 z6y?R*EEqA}ef*pKqzXw8Lyrx{ep-XvY)0I_8JOHGdisau>^BL9h@qfNisqBXq=RNm zF+vzkdD&e9{~@?&Ljpj6e)+!qg z2@H~@z%CTK`Jf?_vr6##-+jo2K>{VErNbPF-&!^GI!7w-;`~G1MoLotlz@4_r>86VI*dibdDgyE`cPXFXJR0|{K1 zaINH~BTriP@dusBKKqYuR4^EzChTd*U&@<-d8vQ)jy*wvK?LpOe1fx*v4PSLeE%P{ z+?&f10`qtS*q`*^dh=jY#QbNM_td+wfTud>la#&+r8JKyetv%!`-khkNh{{X(pbmD@I-(r!Hju!*K5?JXFPl|qMbTlRZ*Jxxx5yVhY-X~KgUd3{i-jpA5|Ja1Mm%Iic zu$voOdA?{k&INH?LKD?#Wa98Y6nvZM7zvP?z0hVYCDnoQ07>aDIlpeALIUJ|^7D(9 zb}A`>!sH(Vl+_`ug}@Chg5lcs(emL9J3!%N%WPt^xBteu#>HQxpD~JFE9uYKiFfzr zaARH^u2umD7(SkoA-wgsgU;Ao4J;AfjujmfHu2*w8ZKNU_xNI8($LUIv}yj)q-+)8 zTZkAu8<@r#opTv+AQ5#5Ua*fgB1 z9nOI(4A=E3ZM4m=RX%u;95ZY(2VYlF=e`cEzU!yPAXuEqZz07MuFgXE;|ljCV}w9z zcab-W!GaxP>>}jqUyR2mpM_N@ip`85-Y!{^+Cxg~stL2&Fg#;f@6J@9baB&%;W|<8 z{+=)sawwQmF&OndL?+ILvX&3w5+#_@<>T>b_#pdp*Vd|;u6}A4v=4N@+bGp5$G-6Ap9-44dP1G%(FzPQG-d8Np=NW>_Abb0eGf)}%V8aD(?8TBYC zC?e6E(th=QfN8g&EMdGUdLJ}Aax%f$gG+umDJ0gjiqKLlsOj#9rNbh(S)sT*4)3?S zX>*f#*kFQdBa91&86dXA^zY5PO0VfS%EqA%@NKCbokIwtSdB$_9Pf7(Oq zbl+nE$q{@wZyh>G28U}yHf-q699CmA?RwtCF0>a!*X>V?ic{~eH!f&jN&)@^QQ1bg z;RMRl5~D7zW}D^H&?)2%e|KcJOq&|P02^}f#yL_S1nGb#JIc)nCI6LlB07Uh zniHa?Cu*k!fUoy%7l~)7s5F&i5-jOxdw0)qvQ`-5o`&L23wyKvs{t?hDIy?aqABeU zDyK4CJXLv_xpuA!l5EN~S^RHTRIe)|elKr@Fh+RIH(=Th& zb1?NWN2R_Cv3I$aUUX9u(FHvf8Gj&)p8JmB%Nz7*)hGh_Z)!5Z@PvvM_{Sjnw*@C6 zP1rv+KJFnDbeMs!*h;wYr$Irc@swCZ-#e`7b}zPnci5T(#zvf%jfjp$PftwHW*^Q_ zVkdup;aE?gZ1CO@UzuC81CMRj0a{HPBZaFuF8as)^TeS!>HX5(L7~zKEHNQAHPEx1 z76EB-(+#yAt3t}M@ivba|oCoNXD>w={wcj^)L3@Ig^uM{#|iGE31J@`e5MpG0ThBD?F^@|23>g zBWuz#j%A)F^2(bg1GZ&Xxw+o&EMKp$569KNu0v`w6c_x^&%|^!L9%I*{OO?`_g_h2 zxFppw-xFpB>Gj-#2;=ksqU)W5vgf46Q3U5nh)N|4{qHXvR*9Sl(N1v_EgZ@QdP*-- zsP>#!3)y~cpB`K8j{=?H78AeSWP=^G()DF15@H|HbKEFHh^Vz3+-yO}w^|}ba5lfql$mSq~6u$4rA#PovO1 z5waHJS0SRoTcl?^7EWzw{nMb()agzl4K!_OOj?1LztmThny4P3K z3_@bX!oYd&eIAUH6Jw4T#9m7JJIY?2ZdD`KTuZVOV#(FhYUgaPkuj;ii8&8WJ(=eD zD+V77aAIbS7+WnKFlAXk)3i4T57F4)>ame^)@`HGP)aA0`Bw%5E<=f<1Tci*#Ok4x zM1LMn%T%esWBb;NTj$`ZU-YqzeW;7mPPZ@YfCz>A$sauTG8a6iKt01fw!s$XG1{tw zp^q1xtyhPQPiLapHdDy^WHfEjXvwCKKh+fvojH37Hh}#`^Wla*vF!-69Qr8#?~VwGfo=J9b(&ad=xAu4P1bKwcyV~myqA&fQ!oPd4@bL3 zL&Xx@>N?(abXzl!NjjpmsdAG%1|y6-Jg-Ykc{$s_ukHA~~(L5W=MzFNS)% zeKpQlyU6J1$*RPEz=Z5uQK(4(m*p^QC)`-4+$OfUsq zdk}*+-}d5Zy!l=)4*%bpBM(Rndr~R_n$~RvvX{RcBlBSO9 z#UmFl>DEkzq^K~DPlgb&P){ixhDmM+ZOH%GasOHfq>Hj|P&SoUpz=~$9ExmC!MjV4 zl;s1*f)I?5a2L)D2Y_r$SDJ6<6w*I&gUDbE6v25jBC8WA=j9N5>;W#apbKH;fSDNW zlH$Mm1*~P~uvb0d<1o~!lF@MEE*_ZPiFx{CCN9sNz8PVgDO<^z#eF*B4!LsBETZ z*)jrtUGRql*?dc4xLN&d{q_`lu0Ye_&wG!5_219vb&Fj%ZfRq&pbihDPyK;{t@$UsHw^`D@}Im>3=kZVhHgAmuNjN4nc2Bb0IoV0VEq z43}v&e=amX}*p|}iDXtZS`fmbaud4c-Yb}a>tQ#hJCsVvr1(-q`u%%r;(6K6md{&B1rXrH`OXePqAl%b zXKE=``1a0{wD8!jg~>C{ee-9_VB((~j5GXhgKNHjZc$oZG<3{0N=2?YkWmy1cCi%G z7ASqw!u$4k_1*#xWS#bURjaznzY99C$*tg0Xy-V5Am0|!)% znz*atzro7daiv_y%Qkq}{ns`qZh$y8hA;XP%%K-ea%T}9rs$Z8WX0=E(wYUE*u}Oy)a{>H{bg>-i zhr^SFd*s?k;g|Ygy+yxfrQJ_bKT}3Mk;(3tk&QDrAQO4#vjwr$a*RZK`y5?;?}MiA1erMxT7Yvd`}1oRgN zt92_+Rp7pPmj_m%Xl1E^79mb%bqCQ~8Ew$ds+%MR-g{eX1z1h&qe*S_3 znsKy0I!95(w!xU0^gWg`lttWQN@1%dLcKG5(Z!fSKQcOn6h-Wn2Of*NxvWX}XvKg! zi7RPRfwZ&7IBfIqu8DmMiPn*Qp*Iyda2Pbk&1kr1mNoC!rO2$uYw+OyxtiKK1_6NO5%a29aE|=p}j3gtNHl&sR>seH2 zU%+d0|1&s2n+!+V2whZP2l#(1<_uX?31x0f#dgPOZP1uHuzr;L@!9jmF}e%GxgZX& zM{Grpi+L~=p(aKzcLnMi{ol`72~YDW1?*T<%yc1ZEr?P=DTOh6hrjXK8O&JT8Qc>+ z5wn>O(-|Kv)N{p(RI?_<$cU@Tj1nkFUGJM5By~Ve?{-u2<~jpapR=d2^@?92r zh7XUsl2obSoNt^sJse*WDU0}uyZoJcyCd;<&bWWX23JNGd%*a8OFIrxJDxL%x<8o{ ziUHKbvZNlyf+@2n9n$BP456Jb*PqAK9{Uwu zeHZPjgjFR~09gA$Hd-`%mMm|~5GtB{^~OKXGM#+v(jpVF$@%rft!{>|sH$ou6@0W~ zk6FcfT=k;~BGjcE4^gSi*qIL#-zoU~h+;KM>>v+?1M_4k4T-9dF=xCuvQr~87rp?5 zi7tCVGc0m$Ujp1&qqp_@k-NLqrr)49lMgTOFW-Z)N9)qxd6@iFvz>9%V`Kaf8FQ-*AwNK-Oec z0UQ9l69dAvq&loW3VR(YqVzG=Sg-mk#TQlRM0-oA-fdFV!#yWvx0ez(W-$~#6amI| zgmx;evo`j_59HY$d~s{k^@W58?K+9@IQON+6aBR!ptFb{3krTNDq@(Q&($LmKG!Qf z{`G(eNL~g?JsFmF=0aVnM}5guEs1B#y~l)@uTD}#zXW1KFKQx%CImvdM2pF7ly$1R z6?D{}Kimpxk!mcaFK9>fSY>zniX8P3J-j_szf$+1D&1YW(ZbWu`{|EnqmRaMo=B1E zt27OHeWtFS6kFo&f%xE4G=0%>wUsRrU*e?cmHJ4il@46_gyCwE?P0n&_9!@e{o~HU z`Oi08nEAqW4jY=uI!|G(hkmz{G;F5hAL!afOY8KqH(jr9&XzwhWkEugolC|KB#@21 zK-{)EzNfHR=1jH9XskxVyZUH%rliFurSHdH(snzkIG6 z(V6ZP)30b3;c^m++8fD%E=Ct)GoT;NE@-h?m#u~wRJY}mZnXzExrRh3yso-S-K5Fu zU@0aLF<_isba24i($)rl9<+vvKzNZG9O#ByVn5=3;+;-o5^DsbpQlTU4)K20@}QIe z5CZ`@nNHW)5RvpU;P;cs8)MdTF!?8>31wK2N72EpXOyl&jsT>~f34lSV{i4LU!Q*V z2GnlDd!Qbl{B|{olT^EJ_PyPNM!QFTMQUDwz~LQ{pZ(oWOVV2yjfV=S%IytN*0mFj zl*F?8R&?k+INXHv_G&ABE!*Ix`ry46i^dfkn_!0qvSVsA5uw_81=|uA*I?;@67%vD zB)UO_zcUMGqA*ybFr}%8nLDL-r-m+!VUYjbb~r@rq0DE6rX94d%oOwDM^V|E;}=YR z&J6Ua1a?SQ4}p=on;fo6{pr_@RaI6ioDCG(*%^Z+Xi?Qi5pJx@~(?qM=y+mbZZY;@9! z)B2L?!s>qC-G@MVl*>x`=io&)G%iu6dQ{LI1ro?kMOVptm^s|&i5Tt1I4gc0`73Z> zqe22pv+xYe*CnH(SjRyT)a{OjkSHC(m7lLTlUJv}74fKAS4{7~qQo;xanG><3>q69ZR!r&>44UW zVD1C#m|%f(BI0|OAH8~aOQs@x(^hb#8X-;#k2m5hjn>azWsnMF)nL)vCcq&<((%63 zl>QDT+OUkB4Y4HUYu~ns> zyy-lT(o?})xT7nNh+x+Nq~*__XfQy;u&Qhp@%+<5Xs}bPm>P+J-w4g2qC~+WYY(i2 zjvNhe>nWCczM=ap?pV#28a^UIkAVyiGDb)QeM+Qzu#cMvQcsNFX~Ep2$q(w}4 z^8tuYFf6_QLeuuWkpz4mcte>Vh3wc*~=t9UDHihlgAS&p>6b zg6K1f>kH@^PvG{P5V#RtRmrb4>tT89Pi;2)n%kE=YgGYWeio;RE1vm89VQvnbQU$! zB{_bBA*a5}-qtRNJ##qx0M0>Lo52XAP^M4JTJk2HjkepZAp&w^=1Ic? zt7-&3Jo{MCo(+}~ z<9S)>?#M{Y=1GxaaPU)m`$lH4nsbvw@B(_6>d+BP@q{Fhs4N9qK9N1P-gJL@0~?b5 z;w1Rqd2T~cF%lmUHTx8PMOy6`4Go#Gn+`@v0fWkuT#2Z^n@h-%`UiwJiPD>-uS(`Cs#mVRW z#(r*0#<4~(Ml|Kp#gc=FU&|a!;aeoL3`{AkyyJ44*@SNL8J8_1hCsypOHl2y>Vye8 zq9g5k(U5IPsG7!dG=oJK+_q$yzg>#dRShT~13TZSiZUeJA1878E`r-~UI(l#3XTwb z)@Nd!nle+0X|)Y>HE^nwJ7XHw+P)}7Nv0;(8awuo(pczlZITJ&XXIU7O*p6_}0oEXhw6D#1XxJ8IA#_ zK4Q>5yc+u8fzbq~YoEhS9D~_-<)o}p zl&W=fRys^Re7$VCf$mt2RUtvJkQGs{KH?9_2eyzB>Q4Z6A9XdbddC7f+N1q%0+aPj zkRRGw>2gb_+17>onhrWMFYkwpof9El3Gm`f91l*S^d-MIAOZ)lJ44))q@Cl z!5!)SwB;pG4@dYS(?{Lln^LjVdnvRsEUR^9duLB?HZMcmy(T59z5puLs|~F;eoV zl#8jM2e92u7#th}MZR)PqN~;ovV6v3cOwR>GW?1$V<42^$3(yndS5tZxAH^+>L}!3 zJN{JZwKm-LJP15^*V%MpFU{qBbql9T>+_1yIexm-n%HI^6llNrX^CDKtQR zKejJ*lMLSZlLv}3On0h@LPfPXX6{FJzh*P8Ig)DR&_ZlsWJ7ZY!h`FZ2XY=K?xU|Q z99i}B?iS&e(OH7VB49;z;XWgDgXu?mv%J%aS$Fs$Q=MbRE4Fsl%3cjwukzzQVCW^0 zhlH6koF*Vre0$f1ZfMv5ZrRiK@rLQY^;<02!FTj^QO|CFIIkeN+MP*h%#{-yIJ~++ zZwm{c7p2!?!&acUS5nuPDJx{MzRN?>ZoeW;>9B@u>}9W?+NF%$Hbh_jbRsy?UGy|) z^};8p^ov5T$X;tLtVu~f+S!=As@=d7w&5=!V6(S%?6grT5-yX07Q~Nx9Mfbp>V$_y z_c`DCR8+=~PHzYLF3)2*|D2=&-Rzk9o`Oo)4ZaFNNgotZPP`+oUczUh8t_^t_gr;b2%G` zQlAwFfe%8Kh!+|kwgbmLj*^_4Y}eu=Mv89#u!g^E^G!hE9q3KzW6c+Xs-9mkl4C7EQ;h^bVmCAYudGUkpYq!AHu~K2 zZlRg!Hm;m|MEV!`>dvZGh(hJr_*jm z^%@NK&HL5bOQXJb4lap$+%m>Shr@Xu`FKO!Bx(2#nI$`#v~2=p=&PAw zNQbX_gIcxEY_=lPp+`5H10F(r_%3`(JsC=DW+MW)?D~^-BoNb?Fv1}{5qz%Mju0Y# zw%1-4=*@){B*EG{J#BX~J(fa6c50h7sj1f@9{kV_4%2hl7~?x*!iHU} z2wnciX4m>%p{d|XA>`uiV8ZqP8BHnPW|ud$PB}gNOP^@@h)4aW-xb+(!J@$X^A6E44zM&9yY(C*j*uGYjc2D3Z z@L=RS-_?ifpSRO@<@!DTXl_rWy9(!^t7`L}#E<{dn8SXgV@<^BK_xrxA^NK2*!lJ$ zI^6QE^C_)Ng^|nr3?Op$#&G{qG?n%*Qz-eXM}e0I4p_cNYuD=Zy<4^#cF;5FsOg@q zf4)f38gBr_S`iAq_*P<>wc>u%I86{d+3v%-TW_#@e?Vf=?2ru!$L@W0wFIg}$>Nd+`_gY?D z$0iC$e_G-L1eKtzC$VE@5kD}=jESjEb#7CoIJ8Y0Px!^FR>gEi#;1`PFEB*qA*=mL z+wk5ca;Pn-wOH$U%Z`T{+te45*p0!&^fTtH+uSpSeFZ5L6ViU$iq83O7z?YO26D$73kS@cowK>bBnmMFfwxqJNM5W?Fm!=kW7=a+HS&km#D>2DW~x#QAJ>in zNp!Ni4n`sBq1tJD&T+vRTk$dewj89@n zHV4WIT#fQSlowG&ybY1TJs3Yb^hyho)%NgNQ9erde8|p%P)-m@>U}-Lzt_O>k!lW> z_4asqjUevxwRlg30WONp48xZCh476>Z@~^jpltnd3JQuGFOSa<&b#lQdN?;s{yb zQyZ$+x{`@>oD%d~QmtvH1Van#TFNh;+B`od>D#lRqh6NG&!qkFYGP7F@@15)!pADP z{F3b*M$anHfvFSih#JC0MKY?wPi^cm7y%IpCSV`|3RNr&`H{Cg(75Cu-{{S3;pd(Z5PbwXpGl^w?wE&)Dz83I&SO$NIf61AINjb7uQW7TVIY@cJJ z#oJHq(b&UGa97G!%4e0Z&vBzfhQ5w0__S396<4Wv)v8oAQ0}ru+@O04FI3K&VY?E2 zi%&7hrc| zDJG%Xm5B)Q%F7C&|NJ70FgnOPZzZHyfC}vxHPQ<&k2REj>IK?GX3HCCwzU^%*M`=2 zcqt1bJ4pAExgx4ZRU0=}UI?9ov+3tS0osdfP}{y|Lcn_`GHvjkbh?qK3LXv~5>iL& zd?f)Pp5}v8S67ul#{@cdlz2!UK$@*&DgY4zgOVua$q4)8Fylkjn z&FrSV?p$5qGiXw(iHv^$kT@r1RP_bl%wb_&X%LPzuk3z7Epj^evuUGK3u!G(DZrcE zy+H$U+|FLFQ&?N?J9{c*Q|qb^`xP|j)8o)j6{kKjjKn3|pJq8u_(rK&^z}-szcMwt zb7B6d#n_TZcYJfGzih>ai6+zZ%jYXgMf*FchX|%oPzprz=oJ~z+|i))g#R~+{&<#= z-aMZWTZfzf49oBI<;X5<>9K*t$xlT6gATh)#KRZMd=2pzmo%|TucT1q+Bw1(K`MQ3 z*k0GTfS1$Oo%h*CK8$wjG;My})|h>X7#IuSZxhwUJpD9#oH~Ecx?|LGS#eOa>QuF_ zarwKdlNy>+Q9@vgeD+n4KAo= zU0P7liOX6)X58n|Kl8>VsNno2{wLT*-IgkXGUA_KUmN1{l$em=5~Fg*zq4gJju{6g$YL7sB%B1exPBTA5U zF4jJ`2+e1OuYUqIOVLDHwe8ZQAPN)Z0f({DO-ZwC3$PEmw=2sY_F>h;UBe6JLsywi zr9t&~1F5?7vm>6&y=eEbMd!0FGFN>?<%MerttUY?oM*9MlkFQ|iEOkd2G+G2Zach= z_Qt4I_y8?WrOK&w$2w?>0l1LwDb#hD zji=~b>PC}U)o}jJU0lOf9}c+Cd%of1ITzC>5W$-%XDZYx9W*MUFOj)AKfpMQfr~%%`5*J?G&HG~HE>(?Hvi;(B{-au) zJB*jmP8JgpM`U%awIBGO$=%TlLy~d^Kl#ga?oF`f-&dFckizR-_yIC}{K0Blp5kQ2 z*84x9Z-~*!eM>IK(ORbiW}fB^m0QKJUN(UMmU- zRGRsTtk4w`8F1&>Q5DoaL$$)@ZyR>w&EEKbtqQ(%UTEjuK)sT!bLpT+!II&<=rFlK z+Tye@-0qci@1h@#`q~>o0{zqV{U=f#y1sa2QHBNBl6o)(fY+?; z_7a1wZJ6U`M_I$phpkcZ`(bgX=Ud0^Ck`$)d(Fy;f_~FKRYti`{-0IwKs&F^ z=k|3{L{;`DpL&GNbj#zIN-sdpQEdFlT8(>K3c|It+5&S)@8&n97#; zaLMm53r#**^SH~nYbp{C@#;vr7xy(TQ8V5%*%z|-NGZhcw)X!#4!&ukqmS8hfe^|{xX8`(Ht(!xE3V%yHA@auatC^oi-?ypA-&dJ0PSs4ew{vyHTC7K@KpM z;Jk%nUNmIx3A};d~7&U zLQMY+);~wrz}2_*#>xJYI{z~H)T`ClE~R>L!ZhhrU;zUYZhr7e<`+Vsho>D$k>GI< z_Lr@S79?|4NFb|!juqAd?e*iA>eP>1P=kEM@>vMcr#j}g@EeghF_&(*`)DtzkiIH2 zulxX$r?l7lO&C}a7H?@BzPBYs;kP3L4WpODDwynh`evc6d*yqZ$u5zkP#O{k+n@DA zac1{~0hC{bF6>jbi)XsQ6lXx#;`cAEk^YCC2C&4}XgBw) zd+fBG3ka~D>croKVg83t5B2{Wl#0nYeNmK^Pi0AFf{zdwdl2;Be-diZ{owd3-6opx z4A5P`P$+u?$u&!NC0Ps7Cp#M{{%W z=5IXRT>W=?DW?C9jUQqDWE}niRRN+Tp#E-1h)Y4C?;!=GxU$VlPFMjehlg@se<~y+LK10z~a>~

FAA$-C{?VX+~Q+^%na@J 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.0.0" + "node": ">=18.0.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -625,6 +627,15 @@ "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==", "license": "MIT" }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/callguard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callguard/-/callguard-2.0.0.tgz", @@ -727,6 +738,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", diff --git a/examples/browser/package.json b/examples/browser/package.json index e1b2eb95..9cd14d00 100644 --- a/examples/browser/package.json +++ b/examples/browser/package.json @@ -13,7 +13,7 @@ "vite": "^5.2.0" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "events": "^3.3.0" } } diff --git a/examples/cloudflare-workers/package-lock.json b/examples/cloudflare-workers/package-lock.json index 4583dc1b..8f50ab32 100644 --- a/examples/cloudflare-workers/package-lock.json +++ b/examples/cloudflare-workers/package-lock.json @@ -8,7 +8,7 @@ "name": "cloudflare-workers-example", "version": "0.0.0", "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "events": "^3.3.0" }, "devDependencies": { @@ -48,18 +48,20 @@ } }, "node_modules/@datastax/astra-db-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-1.5.0.tgz", - "integrity": "sha512-Z9pEVyyHfglh8XAKrIASxdvORdei4pLUKDDGarqYvBkA9B9rKdqqdN+4I42Dz8paU5uscu8FwM5mc+Ly/U6jfA==", + "version": "2.0.0-preview.0", + "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-2.0.0-preview.0.tgz", + "integrity": "sha512-lqp/T+q7ByFBBFV5xOv9wYJR+45W7M5LHxaug4KFWs7LcJz5RcsVrlY/ubBOkVZiq3BdwqeETGbErUmCS2bhZg==", "license": "Apache-2.0", "dependencies": { + "bignumber.js": "^9.1.2", "fetch-h2": "^3.0.2", + "json-bigint": "^1.0.0", "safe-stable-stringify": "^2.4.3", "typed-emitter": "^2.1.0", "uuidv7": "^0.6.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@esbuild-plugins/node-globals-polyfill": { @@ -544,6 +546,15 @@ "printable-characters": "^1.0.42" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -880,6 +891,15 @@ "node": ">=0.12.0" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", diff --git a/examples/cloudflare-workers/package.json b/examples/cloudflare-workers/package.json index 7d301be3..a80919e3 100644 --- a/examples/cloudflare-workers/package.json +++ b/examples/cloudflare-workers/package.json @@ -12,7 +12,7 @@ "wrangler": "^3.55.0" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "events": "^3.3.0" } } diff --git a/examples/http2-when-minified/package-lock.json b/examples/http2-when-minified/package-lock.json index ff01b721..2eebffb8 100644 --- a/examples/http2-when-minified/package-lock.json +++ b/examples/http2-when-minified/package-lock.json @@ -8,7 +8,7 @@ "name": "nextjs-edge", "version": "0.1.0", "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "fetch-h2": "^3.0.0", "next": "14.2.3", "react": "^18", @@ -22,18 +22,20 @@ } }, "node_modules/@datastax/astra-db-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-1.5.0.tgz", - "integrity": "sha512-Z9pEVyyHfglh8XAKrIASxdvORdei4pLUKDDGarqYvBkA9B9rKdqqdN+4I42Dz8paU5uscu8FwM5mc+Ly/U6jfA==", + "version": "2.0.0-preview.0", + "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-2.0.0-preview.0.tgz", + "integrity": "sha512-lqp/T+q7ByFBBFV5xOv9wYJR+45W7M5LHxaug4KFWs7LcJz5RcsVrlY/ubBOkVZiq3BdwqeETGbErUmCS2bhZg==", "license": "Apache-2.0", "dependencies": { + "bignumber.js": "^9.1.2", "fetch-h2": "^3.0.2", + "json-bigint": "^1.0.0", "safe-stable-stringify": "^2.4.3", "typed-emitter": "^2.1.0", "uuidv7": "^0.6.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@next/env": { @@ -236,6 +238,15 @@ "resolved": "https://registry.npmjs.org/already/-/already-2.2.1.tgz", "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==" }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -325,6 +336,15 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", diff --git a/examples/http2-when-minified/package.json b/examples/http2-when-minified/package.json index 7a666a40..bea58f49 100644 --- a/examples/http2-when-minified/package.json +++ b/examples/http2-when-minified/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "fetch-h2": "^3.0.0", "next": "14.2.3", "react": "^18", diff --git a/examples/nextjs/package-lock.json b/examples/nextjs/package-lock.json index 35adbb77..42ae9c20 100644 --- a/examples/nextjs/package-lock.json +++ b/examples/nextjs/package-lock.json @@ -8,7 +8,7 @@ "name": "nextjs-edge", "version": "0.1.0", "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "next": "14.2.3", "react": "^18", "react-dom": "^18" @@ -21,18 +21,20 @@ } }, "node_modules/@datastax/astra-db-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-1.5.0.tgz", - "integrity": "sha512-Z9pEVyyHfglh8XAKrIASxdvORdei4pLUKDDGarqYvBkA9B9rKdqqdN+4I42Dz8paU5uscu8FwM5mc+Ly/U6jfA==", + "version": "2.0.0-preview.0", + "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-2.0.0-preview.0.tgz", + "integrity": "sha512-lqp/T+q7ByFBBFV5xOv9wYJR+45W7M5LHxaug4KFWs7LcJz5RcsVrlY/ubBOkVZiq3BdwqeETGbErUmCS2bhZg==", "license": "Apache-2.0", "dependencies": { + "bignumber.js": "^9.1.2", "fetch-h2": "^3.0.2", + "json-bigint": "^1.0.0", "safe-stable-stringify": "^2.4.3", "typed-emitter": "^2.1.0", "uuidv7": "^0.6.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@next/env": { @@ -235,6 +237,15 @@ "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==", "license": "MIT" }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -328,6 +339,15 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 11ef71b7..489f871b 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0", + "@datastax/astra-db-ts": "^2.0.0-preview.0", "next": "14.2.3", "react": "^18", "react-dom": "^18" diff --git a/examples/non-astra-backends/package-lock.json b/examples/non-astra-backends/package-lock.json index 9cb7e908..08aa3d92 100644 --- a/examples/non-astra-backends/package-lock.json +++ b/examples/non-astra-backends/package-lock.json @@ -9,25 +9,27 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@datastax/astra-db-ts": "^1.5.0" + "@datastax/astra-db-ts": "^2.0.0-preview.0" }, "devDependencies": { "typescript": "^5.5.2" } }, "node_modules/@datastax/astra-db-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-1.5.0.tgz", - "integrity": "sha512-Z9pEVyyHfglh8XAKrIASxdvORdei4pLUKDDGarqYvBkA9B9rKdqqdN+4I42Dz8paU5uscu8FwM5mc+Ly/U6jfA==", + "version": "2.0.0-preview.0", + "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-2.0.0-preview.0.tgz", + "integrity": "sha512-lqp/T+q7ByFBBFV5xOv9wYJR+45W7M5LHxaug4KFWs7LcJz5RcsVrlY/ubBOkVZiq3BdwqeETGbErUmCS2bhZg==", "license": "Apache-2.0", "dependencies": { + "bignumber.js": "^9.1.2", "fetch-h2": "^3.0.2", + "json-bigint": "^1.0.0", "safe-stable-stringify": "^2.4.3", "typed-emitter": "^2.1.0", "uuidv7": "^0.6.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@types/tough-cookie": { @@ -42,6 +44,15 @@ "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==", "license": "MIT" }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/callguard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callguard/-/callguard-2.0.0.tgz", @@ -84,6 +95,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", diff --git a/examples/non-astra-backends/package.json b/examples/non-astra-backends/package.json index b855b422..7dbb649f 100644 --- a/examples/non-astra-backends/package.json +++ b/examples/non-astra-backends/package.json @@ -13,6 +13,6 @@ "typescript": "^5.5.2" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0" + "@datastax/astra-db-ts": "^2.0.0-preview.0" } } diff --git a/examples/serdes/package-lock.json b/examples/serdes/package-lock.json index 0544537b..012e3ad5 100644 --- a/examples/serdes/package-lock.json +++ b/examples/serdes/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@datastax/astra-db-ts": "^1.5.0" + "@datastax/astra-db-ts": "^2.0.0-preview.0" }, "devDependencies": { "dotenv": "^16.4.5", @@ -18,18 +18,20 @@ } }, "node_modules/@datastax/astra-db-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-1.5.0.tgz", - "integrity": "sha512-Z9pEVyyHfglh8XAKrIASxdvORdei4pLUKDDGarqYvBkA9B9rKdqqdN+4I42Dz8paU5uscu8FwM5mc+Ly/U6jfA==", + "version": "2.0.0-preview.0", + "resolved": "https://registry.npmjs.org/@datastax/astra-db-ts/-/astra-db-ts-2.0.0-preview.0.tgz", + "integrity": "sha512-lqp/T+q7ByFBBFV5xOv9wYJR+45W7M5LHxaug4KFWs7LcJz5RcsVrlY/ubBOkVZiq3BdwqeETGbErUmCS2bhZg==", "license": "Apache-2.0", "dependencies": { + "bignumber.js": "^9.1.2", "fetch-h2": "^3.0.2", + "json-bigint": "^1.0.0", "safe-stable-stringify": "^2.4.3", "typed-emitter": "^2.1.0", "uuidv7": "^0.6.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -452,6 +454,15 @@ "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==", "license": "MIT" }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/callguard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callguard/-/callguard-2.0.0.tgz", @@ -575,6 +586,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", diff --git a/examples/serdes/package.json b/examples/serdes/package.json index 5dc75c26..beb54472 100644 --- a/examples/serdes/package.json +++ b/examples/serdes/package.json @@ -16,6 +16,6 @@ "typescript": "^5.6.3" }, "dependencies": { - "@datastax/astra-db-ts": "^1.5.0" + "@datastax/astra-db-ts": "^2.0.0-preview.0" } } diff --git a/package-lock.json b/package-lock.json index ae723a99..3c97fd4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -364,21 +364,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -386,11 +388,25 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/core": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", + "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -422,28 +438,31 @@ } }, "node_modules/@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", + "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", - "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", + "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "levn": "^0.4.1" }, @@ -451,6 +470,44 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -465,10 +522,11 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -992,6 +1050,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.4.tgz", @@ -999,6 +1064,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1262,10 +1334,11 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1359,10 +1432,11 @@ "integrity": "sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==" }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6" @@ -1479,12 +1553,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1704,10 +1779,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1718,12 +1794,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1765,10 +1842,11 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "engines": { "node": ">=0.3.1" @@ -1835,28 +1913,32 @@ } }, "node_modules/eslint": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", - "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", + "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.10.0", - "@eslint/plugin-kit": "^0.1.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.17.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -1866,14 +1948,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -1894,10 +1973,11 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -1983,10 +2063,11 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2028,14 +2109,15 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2045,10 +2127,11 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2086,6 +2169,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2191,10 +2275,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2663,19 +2748,11 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -3164,12 +3241,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3198,33 +3276,33 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -3232,10 +3310,17 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/mocha/node_modules/escape-string-regexp": { @@ -3252,39 +3337,27 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3296,10 +3369,11 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "peer": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -3308,23 +3382,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -3342,10 +3399,11 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/mylas": { "version": "2.1.13", @@ -3360,19 +3418,6 @@ "url": "https://github.com/sponsors/raouldeheer" } }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "peer": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3941,6 +3986,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "safe-buffer": "^5.1.0" @@ -4133,10 +4179,11 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "dependencies": { "randombytes": "^2.1.0" @@ -4344,12 +4391,6 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, "node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", @@ -4377,6 +4418,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4741,10 +4783,11 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, + "license": "Apache-2.0", "peer": true }, "node_modules/wrap-ansi": { @@ -4855,10 +4898,11 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, + "license": "ISC", "peer": true, "engines": { "node": ">=10" diff --git a/scripts/build.sh b/scripts/build.sh index c1af3d29..4b3a4955 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -34,7 +34,7 @@ if [ "$1" != "-light" ]; then # Removes all .d.ts files except the main rollup .d.ts cd dist || return 1 -# find . -type f -name '*.d.ts' ! -name 'astra-db-ts.d.ts' -exec rm {} + + find . -type f -name '*.d.ts' ! -name 'astra-db-ts.d.ts' -exec rm {} + cd .. # Delete any empty leftover directories diff --git a/scripts/repl.sh b/scripts/repl.sh index 89474120..41dd76e6 100755 --- a/scripts/repl.sh +++ b/scripts/repl.sh @@ -64,4 +64,28 @@ node -i -e " return 'Cleared console'; }, }); + + Object.defineProperty(this, 'cdm', { + get() { + return coll.deleteMany(); + }, + }); + + Object.defineProperty(this, 'tdm', { + get() { + return table.deleteMany(); + }, + }); + + Object.defineProperty(this, 'cfa', { + get() { + return coll.find({}).toArray(); + }, + }); + + Object.defineProperty(this, 'tfa', { + get() { + return table.find({}).toArray(); + }, + }); " diff --git a/scripts/update-example-client-dep.sh b/scripts/update-example-client-dep.sh index b3209f0c..4608da69 100755 --- a/scripts/update-example-client-dep.sh +++ b/scripts/update-example-client-dep.sh @@ -13,7 +13,7 @@ npm) for dir in examples/*; do cd "$cwd/$dir" || exit 1 npm rm @datastax/astra-db-ts - npm i @datastax/astra-db-ts + npm i @datastax/astra-db-ts@next done ;; local) diff --git a/src/administration/astra-admin.ts b/src/administration/astra-admin.ts index f933000d..ddb54ea8 100644 --- a/src/administration/astra-admin.ts +++ b/src/administration/astra-admin.ts @@ -33,7 +33,7 @@ import { AdminOptions, DbOptions } from '@/src/client'; import { $CustomInspect } from '@/src/lib/constants'; import { SomeDoc } from '@/src/documents'; import { Timeouts } from '@/src/lib/api/timeouts'; -import { DropAstraDatabaseOptions } from '@/src/administration/types/admin/drop-database'; +import { AstraDropDatabaseOptions } from '@/src/administration/types/admin/drop-database'; /** * An administrative class for managing Astra databases, including creating, listing, and deleting databases. @@ -461,7 +461,7 @@ export class AstraAdmin { * * @remarks Use with caution. Wear a harness. Don't say I didn't warn you. */ - public async dropDatabase(db: Db | string, options?: DropAstraDatabaseOptions): Promise { + public async dropDatabase(db: Db | string, options?: AstraDropDatabaseOptions): Promise { const id = typeof db === 'string' ? db : db.id; const tm = this.#httpClient.tm.multipart('databaseAdminTimeoutMs', options); diff --git a/src/administration/types/admin/drop-database.ts b/src/administration/types/admin/drop-database.ts index bcc5192e..72895a8e 100644 --- a/src/administration/types/admin/drop-database.ts +++ b/src/administration/types/admin/drop-database.ts @@ -20,4 +20,4 @@ import { WithTimeout } from '@/src/lib'; * * @public */ -export type DropAstraDatabaseOptions = AstraAdminBlockingOptions & WithTimeout<'databaseAdminTimeoutMs'>; +export type AstraDropDatabaseOptions = AstraAdminBlockingOptions & WithTimeout<'databaseAdminTimeoutMs'>; diff --git a/src/administration/types/db-admin/astra-drop-keyspace.ts b/src/administration/types/db-admin/astra-drop-keyspace.ts index d68f01be..46d42545 100644 --- a/src/administration/types/db-admin/astra-drop-keyspace.ts +++ b/src/administration/types/db-admin/astra-drop-keyspace.ts @@ -16,6 +16,8 @@ import { AstraAdminBlockingOptions } from '@/src/administration/types'; import { WithTimeout } from '@/src/lib'; /** + * Represents the options for dropping an astra keyspace (i.e. blocking options + timeout options). + * * @public */ export type AstraDropKeyspaceOptions = AstraAdminBlockingOptions & WithTimeout<'keyspaceAdminTimeoutMs'>; diff --git a/src/administration/types/index.ts b/src/administration/types/index.ts index 34349450..3295b0a3 100644 --- a/src/administration/types/index.ts +++ b/src/administration/types/index.ts @@ -26,7 +26,7 @@ export type { } from './admin/create-database'; export type { - DropAstraDatabaseOptions, + AstraDropDatabaseOptions, } from './admin/drop-database'; export type { diff --git a/src/db/types/tables/create-table.ts b/src/db/types/tables/create-table.ts index 6a9b2e84..f7bfeb5b 100644 --- a/src/db/types/tables/create-table.ts +++ b/src/db/types/tables/create-table.ts @@ -56,11 +56,83 @@ export interface CreateTableDefinition { } /** + * ##### Overview + * + * Represents the syntax for defining a new column through the bespoke Data API schema definition syntax, in which there + * are two branching ways to define a column. + * + * @example + * ```ts + * await db.createTable('my_table', { + * definition: { + * columns: { + * id: 'uuid', + * name: { type: 'text' }, + * set: { type: 'set', valueType: 'text' }, + * }, + * primaryKey: ..., + * }, + * }); + * ``` + * + * ##### The "loose" column definition + * + * The loose column definition is a shorthand for the strict version, and follows the following example form: + * + * ```ts + * columns: { + * textCol: 'text', + * uuidCol: 'uuid', + * } + * ``` + * + * In this form, the key is the column name, and the value is the type of the scalar column. + * + * If you need to define a column with a more complex type (i.e. for maps, sets, lists, and vectors), you must use the strict column definition. + * + * Plus, while it still provides autocomplete, the loose column definition does not statically enforce the type of the column, whereas the strict column definition does. + * + * ##### The "strict" column definition + * + * The strict column definition is the more structured way to define a column, and follows the following example form: + * + * ```ts + * columns: { + * uuidCol: { type: 'uuid' }, + * mapCol: { type: 'map', keyType: 'text', valueType: 'int' }, + * listCol: { type: 'list', valueType: 'text' }, + * vectorCol: { type: 'vector', dimension: 3 }, + * } + * ``` + * + * In this form, the key is the column name, and the value is an object with a `type` field that specifies the type of the column. + * + * The object may also contain additional fields that are specific to the type of the column: + * - For `map`, you _must_ specify the `keyType` and `valueType` fields. + * - The `keyType` must, for the time being, be either `'text'` or `'ascii'`. + * - The `valueType` must be a scalar type. + * - For `list`s and `set`s, you _must_ specify the `valueType` field. + * - The `valueType` must be a scalar type. + * - For `vector`s, you _must_ specify the `dimension` field. + * - You may optionally provide a `service` field to enable vectorize. + * - Note that you still need to create a vector index on the column to actually use vector search. + * + * @see LooseCreateTableColumnDefinition + * @see StrictCreateTableColumnDefinition + * * @public */ export type CreateTableColumnDefinitions = Record; /** + * ##### Overview + * + * Represents the scalar types that can be used to define a column in a table. + * + * ##### Disclaimer + * + * _Note that there may be other scalar types not present in this union that have partial Data API support, but may not be created through the Data API (such as `timeuuid` or `varchar`)._ + * * @public */ export type TableScalarType = @@ -84,6 +156,23 @@ export type TableScalarType = | 'varint'; /** + * ##### Overview + * + * The loose column definition is a shorthand for the strict version, and follows the following example form: + * + * ```ts + * columns: { + * textCol: 'text', + * uuidCol: 'uuid', + * } + * ``` + * + * In this form, the key is the column name, and the value is the type of the scalar column. + * + * If you need to define a column with a more complex type (i.e. for maps, sets, lists, and vectors), you must use the strict column definition. + * + * Plus, while it still provides autocomplete, the loose column definition does not statically enforce the type of the column, whereas the strict column definition does. + * * @public */ export type LooseCreateTableColumnDefinition = @@ -91,6 +180,41 @@ export type LooseCreateTableColumnDefinition = | string; /** + * ##### Overview + * + * The strict column definition is the more structured way to define a column, and follows the following example form: + * + * ```ts + * columns: { + * uuidCol: { type: 'uuid' }, + * mapCol: { type: 'map', keyType: 'text', valueType: 'int' }, + * listCol: { type: 'list', valueType: 'text' }, + * vectorCol: { type: 'vector', dimension: 3 }, + * } + * ``` + * + * In this form, the key is the column name, and the value is an object with a `type` field that specifies the type of the column. + * + * The object may also contain additional fields that are specific to the type of the column: + * - For `map`, you _must_ specify the `keyType` and `valueType` fields. + * - The `keyType` must, for the time being, be either `'text'` or `'ascii'`. + * - The `valueType` must be a scalar type. + * - For `list`s and `set`s, you _must_ specify the `valueType` field. + * - The `valueType` must be a scalar type. + * - For `vector`s, you _must_ specify the `dimension` field. + * - You may optionally provide a `service` field to enable vectorize. + * - Note that you still need to create a vector index on the column to actually use vector search. + * + * ##### The "loose" shorthand syntax + * + * If you're simply defining a scalar column, you can use the shorthand "loose" syntax instead, which is equivalent to the above for `uuidCol`: + * + * ```ts + * columns: { + * uuidCol: 'uuid', + * } + * ``` + * * @public */ export type StrictCreateTableColumnDefinition = @@ -101,6 +225,36 @@ export type StrictCreateTableColumnDefinition = | VectorCreateTableColumnDefinition; /** + * ##### Overview + * + * Represents the "strict" column type definition for a scalar column. + * + * Of the example format: + * + * ```ts + * columns: { + * uuidCol: { type: 'uuid' }, + * textCol: { type: 'text' }, + * } + * ``` + * + * ##### The "loose" syntax + * + * If you prefer, you can use the shorthand "loose" syntax instead, which is equivalent to the above: + * + * ```ts + * columns: { + * uuidCol: 'uuid', + * textCol: 'text', + * } + * ``` + * + * The only difference is that the "loose" syntax does not statically enforce the type of the column, whereas the "strict" syntax does. + * + * However, the loose syntax still provides autocomplete for the scalar types' names. + * + * @see StrictCreateTableColumnDefinition + * * @public */ export interface ScalarCreateTableColumnDefinition { @@ -108,15 +262,91 @@ export interface ScalarCreateTableColumnDefinition { } /** + * ##### Overview + * + * Represents the syntax for defining a `map` column in a table, which has no shorthand/"loose" equivalent. + * + * Of the example format: + * + * ```ts + * columns: { + * mapCol: { type: 'map', keyType: 'text', valueType: 'int' }, + * } + * ``` + * + * This may then be used through `astra-db-ts` as a `Map`: + * + * ```ts + * await table.insertOne({ + * mapCol: new Map([['key1', 1], ['key2', 2]]), + * }); + * ``` + * + * ##### The key type + * + * The `keyType` must, for the time being, be either `'text'` or `'ascii'`. + * + * Other fields, even those which are still represented as strings in the serialized JSON form (such as `uuid`) are not supported as key types. + * + * ##### The value type + * + * The `valueType` may be any scalar type, such as `'int'`, `'text'`, or `'uuid'`. + * + * Nested collection types are not supported. + * + * @example + * ```ts + * import { uuid } from '@datastax/astra-db-ts'; + * + * await table.insertOne({ + * mapCol: new Map([['key1', uuid(4)], ['key2', uuid(4)]]); + * }); + * ``` + * * @public */ export interface MapCreateTableColumnDefinition { type: 'map', - keyType: TableScalarType, + keyType: 'text' | 'ascii', valueType: TableScalarType, } /** + * ##### Overview + * + * Represents the syntax for defining a `list` column in a table, which has no shorthand/"loose" equivalent. + * + * Of the example format: + * + * ```ts + * columns: { + * listCol: { type: 'list', valueType: 'text' }, + * } + * ``` + * + * This may then be used through `astra-db-ts` as n `Array` (aka `ValueType[]`): + * + * ```ts + * await table.insertOne({ + * listCol: ['value1', 'value2', 'value3'], + * }); + * ``` + * + * ##### The value type + * + * The `valueType` may be any scalar type, such as `'int'`, `'text'`, or `'uuid'`. + * + * Nested collection types are not supported. + * + * @example + * ```ts + * import { uuid } from '@datastax/astra-db-ts'; + * + * await table.insertOne({ + * listCol: [uuid(4), uuid(4), uuid(7)], + * }); + * ``` + * * @public */ export interface ListCreateTableColumnDefinition { @@ -125,6 +355,41 @@ export interface ListCreateTableColumnDefinition { } /** + * ##### Overview + * + * Represents the syntax for defining a `set` column in a table, which has no shorthand/"loose" equivalent. + * + * Of the example format: + * + * ```ts + * columns: { + * setCol: { type: 'set', valueType: 'text' }, + * } + * ``` + * + * This may then be used through `astra-db-ts` as n `Set`: + * + * ```ts + * await table.insertOne({ + * setCol: new Set(['value1', 'value2', 'value3']), + * }); + * ``` + * + * ##### The value type + * + * The `valueType` may be any scalar type, such as `'int'`, `'text'`, or `'uuid'`. + * + * Nested collection types are not supported. + * + * @example + * ```ts + * import { uuid } from '@datastax/astra-db-ts'; + * + * await table.insertOne({ + * setCol: new Set([uuid(4), uuid(4), uuid(7)]), + * }); + * ``` + * * @public */ export interface SetCreateTableColumnDefinition { @@ -133,27 +398,155 @@ export interface SetCreateTableColumnDefinition { } /** + * ##### Overview + * + * Represents the syntax for defining a `vector` column in a table, which has no shorthand/"loose" equivalent. + * + * Of the example format: + * + * ```ts + * columns: { + * vectorCol: { type: 'vector', dimension: 3 }, + * } + * ``` + * + * This may then be used through `astra-db-ts` as a `DataAPIVector`: + * + * ```ts + * import { vector } from '@datastax/astra-db-ts'; + * + * await table.insertOne({ + * vectorCol: vector([1, 2, 3]), + * }); + * + * // Or, if vectorize (auto-embedding-generation) is enabled: + * await table.insertOne({ + * vectorCol: 'Alice went to the beach', + * }); + * ``` + * + * Keep in mind though, that a vector index must still be created on this column (through {@link Table.createVectorIndex} or CQL directly) to enable vector search on this column. + * + * ##### The dimension + * + * The `dimension` must be a positive integer, and represents the number of elements in the vector. + * + * Note that, at the time of writing, the dimension must still be specified, even if a `service` block is present. + * + * ##### The service block + * + * You may specify the `service` block to enable vectorize (auto-embedding-generation) for the column. + * + * If this is configured, then you can pass a `string` to the vector column instead of a vector directly, and have the Data API automatically embed it for you, using the model of your choice. + * + * If the `service` field is present, then {@link InferTableSchema} will also type the column as `string | DataAPIVector | null` instead of just `DataAPIVector | null`. + * + * @see Table.createVectorIndex + * @see DataAPIVector + * * @public */ export interface VectorCreateTableColumnDefinition { type: 'vector', - dimension?: number, + dimension: number, service?: VectorizeServiceOptions, } /** + * ##### Overview + * + * Represents the syntax for defining the primary key of a table through the bespoke Data API schema definition syntax, + * in which there are two branching ways to define the primary key. + * + * @example + * ```ts + * await db.createTable('my_table', { + * definition: { + * columns: ..., + * primaryKey: { + * partitionBy: ['pt_key'], + * partitionSort: { cl_key: 1 }, + * }, + * }, + * }); + * ``` + * + * ##### The shorthand definition + * + * If your table only has a single partition key, then you can define the partition key as simply + * + * ```ts + * primaryKey: 'pt_key', + * ``` + * + * This is equivalent to the following full definition: + * + * ```ts + * primaryKey: { + * partitionBy: ['pt_key'], + * partitionSort: {}, // note that this field is also optional if it's empty + * } + * ``` + * + * ##### The full definition + * + * If your table has multiple columns in its primary key, you may use the full primary key definition syntax to express that: + * + * ```ts + * primaryKey: { + * partitionBy: ['pt_key1', 'pt_key2'], + * partitionSort: { cl_key1: 1, cl_key2: -1 }, + * } + * ``` + * + * A sort of `1` on the clustering column means ascending, and a sort of -1 means descending. + * + * Note that, if you don't have any clustering keys (partition sorts), you can omit the `partitionSort` field entirely: + * + * ```ts + * primaryKey: { + * partitionBy: ['pt_key1', 'pt_key2'], + * } + * ``` + * + * @see FullCreateTablePrimaryKeyDefinition + * * @public */ export type CreateTablePrimaryKeyDefinition = - | ShortCreateTablePrimaryKeyDefinition + | string | FullCreateTablePrimaryKeyDefinition; /** - * @public - */ -export type ShortCreateTablePrimaryKeyDefinition = string; - -/** + * ##### Overview + * + * If your table has multiple columns in its primary key, you may use the full primary key definition syntax to express that: + * + * ```ts + * primaryKey: { + * partitionBy: ['pt_key1', 'pt_key2'], + * partitionSort: { cl_key1: 1, cl_key2: -1 }, + * } + * ``` + * + * Note that, if you don't have any clustering keys (partition sorts), you can omit the `partitionSort` field entirely: + * + * ```ts + * primaryKey: { + * partitionBy: ['pt_key1', 'pt_key2'], + * } + * ``` + * + * A sort of `1` on the clustering column means ascending, and a sort of -1 means descending. + * + * ##### The shorthand syntax + * + * If your table definition only has a single partition key, and no clustering keys (partition sorts), you can use the shorthand syntax instead: + * + * ```ts + * primaryKey: 'pt_key', + * ``` + * * @public */ export interface FullCreateTablePrimaryKeyDefinition { diff --git a/src/db/types/tables/list-tables.ts b/src/db/types/tables/list-tables.ts index 836a045f..995fb4da 100644 --- a/src/db/types/tables/list-tables.ts +++ b/src/db/types/tables/list-tables.ts @@ -51,6 +51,8 @@ export interface ListTablesOptions extends WithTimeout<'tableAdminTimeoutMs'>, W /** * Information about a table, used when `nameOnly` is false in {@link ListTablesOptions}. * + * The definition is very similar to {@link CreateTableDefinition}, except for a couple key differences. See {@link ListTableDefinition} for more information. + * * @field name - The name of the tables. * @field options - The creation options for the tables. * @@ -61,16 +63,73 @@ export interface ListTablesOptions extends WithTimeout<'tableAdminTimeoutMs'>, W */ export interface TableDescriptor { /** - * The name of the tables. + * The name of the table. */ name: string, /** * The definition of the table (i.e. the `columns` and `primaryKey` fields). + * + * Very similar to {@link CreateTableDefinition}, except for a couple key differences. See {@link ListTableDefinition} for more information. */ definition: ListTableDefinition, } /** + * ##### Overview + * + * The response type of {@link Db.listTables} (without `nameOnly: true`), which is very similar to {@link CreateTableDefinition}, except + * for a couple key differences. + * + * ##### No shorthands + * + * Unlike {@link CreateTableDefinition}, `ListTableDefinition` does not return column nor primary key definitions in their shorthand notation, even if they were created with them. + * + * Instead, their full definitions are always returned, meaning, if you defined a table like so: + * + * ```ts + * const table = db.schema.createTable('my_table', { + * definition: { + * columns: { + * id: 'uuid', + * name: 'text', + * } + * primaryKey: 'id', + * } + * }); + * ``` + * + * The returned `ListTableDefinition` would look like this: + * + * ```ts + * { + * columns: { + * id: { type: 'uuid' }, + * name: { type: 'text' }, + * }, + * primaryKey: { + * partitionKey: ['id'], + * partitionSort: {}, + * }, + * } + * ``` + * + * ##### `apiSupport` + * + * If the table was created with any partially-supported or fully-unsupported types, the `apiSupport` field will be present on the column definition. + * + * If the column is unable to be created through the Data API, the column `type` will be exactly `'UNSUPPORTED'` and the `apiSupport` field will be present. + * + * However, it is possible for columns created through the Data API to also have the `apiSupport` field, if the column was created with a type that is partially unsupported. + * + * The `apiSupport` block dictates which operations are supported for the column; for example, if the column is unsupported for filtering on, the `filter` field will be `false`. Not all unsupported types are completely unusable. + * + * @field columns - The columns of the tables. + * @field primaryKey - The primary key of the tables. + * + * @see CreateTableDefinition + * @see ListTablesOptions + * @see Db.listTables + * * @public */ export interface ListTableDefinition { @@ -79,16 +138,69 @@ export interface ListTableDefinition { } /** + * ##### Overview + * + * The column definitions for a table, used in {@link ListTableDefinition}. + * + * The keys are the column names, and the values are the column definitions. + * + * ##### No shorthand + * + * Unlike {@link CreateTableDefinition}, `ListTableColumnDefinitions` does not return column definitions in their shorthand notation, even if they were created with them. + * + * See {@link ListTableDefinition} for more information. + * + * ##### `apiSupport` + * + * The column definitions may or may not include the `apiSupport` field, depending on the column's type. + * + * See {@link ListTableDefinition} for more information. + * * @public */ export type ListTableColumnDefinitions = Record; /** + * ##### Overview + * + * The column definition for a table, used in {@link ListTableColumnDefinitions}. + * + * The definition is very similar to {@link StrictCreateTableColumnDefinition}, except for the potential of having a `apiSupport` field. + * + * ##### No shorthand + * + * Unlike {@link StrictCreateTableColumnDefinition}, `ListTableKnownColumnDefinition` does not return column definitions in their shorthand notation, even if they were created with them. + * + * See {@link ListTableDefinition} for more information. + * + * ##### `apiSupport` + * + * If the column can not be created through the Data API, the column `type` will be exactly `'UNSUPPORTED'` and the `apiSupport` field will be present. See {@link ListTableUnsupportedColumnDefinition} for more information. + * + * However, it is possible for columns created through the Data API to also have the `apiSupport` field, if the column was created with a type that is partially unsupported. + * + * The `apiSupport` block dictates which operations are supported for the column; for example, if the column is unsupported for filtering on, the `filter` field will be `false`. Not all unsupported types are completely unusable. + * + * @field apiSupport - The API support for the column. + * + * @see ListTableUnsupportedColumnDefinition + * * @public */ -export type ListTableKnownColumnDefinition = StrictCreateTableColumnDefinition; +export type ListTableKnownColumnDefinition = StrictCreateTableColumnDefinition & { + apiSupport?: ListTableUnsupportedColumnApiSupport, +}; /** + * ##### Overview + * + * The column definition for a table that is unsupported by the Data API, used in {@link ListTableColumnDefinitions}. + * + * The `apiSupport` block dictates which operations are supported for the column; for example, if the column is unsupported for filtering on, the `filter` field will be `false`. Not all unsupported types are completely unusable. + * + * @field type - The type of the column, which is always `'UNSUPPORTED'`. + * @field apiSupport - The API support for the column. + * * @public */ export interface ListTableUnsupportedColumnDefinition { @@ -97,16 +209,49 @@ export interface ListTableUnsupportedColumnDefinition { } /** + * ##### Overview + * + * The API support for a column that is partially-supported or fully-unsupported by the Data API, used in {@link ListTableUnsupportedColumnDefinition}. + * + * ##### `cqlDefinition` + * + * The `cqlDefinition` column displays how the column is defined in CQL, e.g. `frozen>`. + * + * This will be present for all columns with the `apiSupport` block, regardless of whether they can be represented by the Data API or not. + * + * ##### Other fields + * + * The other fields in the `apiSupport` block dictate which operations are supported for the column; for example, if the column is unsupported for filtering on, the `filter` field will be `false`. Not all unsupported types are completely unusable. + * + * @field createTable - Whether the column can be created through the Data API. + * @field insert - Whether the column can be inserted into through the Data API. + * @field read - Whether the column can be read from through the Data API. + * @field filter - Whether the column can be filtered on through the Data API. + * @field cqlDefinition - The CQL definition of the column. + * * @public */ export interface ListTableUnsupportedColumnApiSupport { createTable: boolean, insert: boolean, read: boolean, + filter: boolean, cqlDefinition: string, } /** + * ##### Overview + * + * The primary key definition for a table, used in {@link ListTableDefinition}. + * + * The definition is very similar to {@link FullCreateTablePrimaryKeyDefinition}, except that the `partitionSort` field is always present. + * + * ##### No shorthand + * + * Unlike {@link CreateTablePrimaryKeyDefinition}, `ListTablePrimaryKeyDefinition` does not return primary key definitions in their shorthand notation, even if they were created with them. + * + * See {@link ListTableDefinition} for more information. + * * @public */ export type ListTablePrimaryKeyDefinition = Required; diff --git a/src/db/types/tables/spawn-table.ts b/src/db/types/tables/spawn-table.ts index 566838a3..053af684 100644 --- a/src/db/types/tables/spawn-table.ts +++ b/src/db/types/tables/spawn-table.ts @@ -25,6 +25,7 @@ import { DataAPILoggingConfig, type TimeoutDescriptor } from '@/src/lib'; * @field timeoutDefaults - Default timeouts for all table operations * @field logging - Logging configuration overrides * @field serdes - Additional serialization/deserialization configuration + * @field keyspace - Overrides the keyspace for the table (from the `Db`'s working keyspace). * * @public */ diff --git a/src/lib/logging/constants.ts b/src/lib/logging/constants.ts index 23299356..acde8868 100644 --- a/src/lib/logging/constants.ts +++ b/src/lib/logging/constants.ts @@ -80,6 +80,29 @@ export const DataAPILoggingDefaultOutputs = { }; /** + * ##### Overview + * + * The default logging configuration for each of the Data API events. + * + * These are used if events are "enabled" without specified outputs being provided; e.g.: + * - `logging: ['commandStarted', 'commandSucceeded', 'commandFailed']` + * - `logging: 'all'` + * + * ##### Defaults + * + * All events are emitted as events by default, through the {@link DataAPIClient}, which is an instance of an {@link EventEmitter}. + * + * Beyond that though, certain events are logged to `stdout` by default, others to `stderr`, and others not at all: + * - `adminCommandStarted`, `adminCommandPolling`, and `adminCommandSucceeded` + * - Logged to `stdout` + * - `adminCommandFailed`, `commandFailed`, `commandWarnings`, and `adminCommandWarnings` + * - Logged to `stderr` + * - `commandStarted` and `commandSucceeded` + * - Not logged at all + * + * @see DataAPIClientEventMap + * @see DataAPILoggingConfig + * * @public */ export const DataAPILoggingDefaults: NormalizedLoggingConfig[] = [{