@ragestudio/scylla-odm 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.mjs CHANGED
@@ -9,6 +9,8 @@ const DEFAULT_RETRY_DELAY = 1e3;
9
9
  const { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } = process.env;
10
10
  var Client = class {
11
11
  constructor(config = {}) {
12
+ if (globalThis.__scylla_client) throw new Error("An instance of Scylla Client is already initialized");
13
+ globalThis.__scylla_client = this;
12
14
  this.config = {
13
15
  modelsPath: path.resolve(process.cwd(), "db"),
14
16
  contactPoints: config.contactPoints ?? SCYLLA_CONTACT_POINTS ? SCYLLA_CONTACT_POINTS.split(",") : ["127.0.0.1"],
@@ -42,7 +44,6 @@ var Client = class {
42
44
  models = models.filter((schema) => schema instanceof Model);
43
45
  this.mapper = new Cassandra.mapping.Mapper(this.client, { models: buildMapper_default(models) });
44
46
  for (let model of models) {
45
- model._connect(this);
46
47
  this.models.set(model.name, model);
47
48
  if (options?.sync === true) await model._sync();
48
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":["loadModels","buildMapper"],"sources":["../src/client.ts"],"sourcesContent":["import type {\n\tClient as T_CassandraClient,\n\tClientOptions as T_CassandraClientOptions,\n\tmapping as T_CassandraMapping,\n} from \"cassandra-driver\"\nimport type { ClientConfig } from \"./types\"\n\n//@ts-ignore\nimport path from \"node:path\"\n//@ts-ignore\nimport Cassandra from \"cassandra-driver\"\nimport loadModels from \"./utils/loadModels\"\nimport buildMapper from \"./utils/buildMapper\"\n\nimport { Model } from \"./model\"\nimport { InferDocument } from \"./types\"\n\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_RETRY_DELAY = 1000\nconst { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } =\n\tprocess.env\n\nexport class Client {\n\tconstructor(config: ClientConfig = {}) {\n\t\tthis.config = {\n\t\t\tmodelsPath: path.resolve(process.cwd(), \"db\"),\n\t\t\tcontactPoints:\n\t\t\t\t(config.contactPoints ?? SCYLLA_CONTACT_POINTS)\n\t\t\t\t\t? SCYLLA_CONTACT_POINTS.split(\",\")\n\t\t\t\t\t: [\"127.0.0.1\"],\n\t\t\tlocalDataCenter:\n\t\t\t\tconfig.localDataCenter ??\n\t\t\t\tSCYLLA_LOCAL_DATA_CENTER ??\n\t\t\t\t\"datacenter1\",\n\t\t\tkeyspace: config.keyspace ?? SCYLLA_KEYSPACE ?? \"default\",\n\t\t\tport: 9042,\n\t\t\tmaxRetries: DEFAULT_MAX_RETRIES,\n\t\t\tretryDelay: DEFAULT_RETRY_DELAY,\n\t\t\t...config,\n\t\t}\n\n\t\tconst clientOptions: T_CassandraClientOptions = {\n\t\t\tcontactPoints: this.config.contactPoints,\n\t\t\tlocalDataCenter: this.config.localDataCenter,\n\t\t\tkeyspace: this.config.keyspace,\n\t\t\tprotocolOptions: {\n\t\t\t\tport: this.config.port,\n\t\t\t},\n\t\t}\n\n\t\tif (this.config.pooling) {\n\t\t\tclientOptions.pooling = this.config.pooling\n\t\t}\n\n\t\tthis.client = new Cassandra.Client(clientOptions)\n\t}\n\n\tconfig: ClientConfig\n\tclient: T_CassandraClient\n\tmapper: T_CassandraMapping.Mapper\n\tmodels: Map<string, Model<any>> = new Map()\n\n\tasync initialize(options: { sync?: boolean } = {}) {\n\t\tlet models: Model<any>[]\n\n\t\ttry {\n\t\t\tmodels = await loadModels(this.config.modelsPath)\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to load models: ${error.message}`)\n\t\t}\n\n\t\tmodels = models.filter((schema) => schema instanceof Model)\n\n\t\tthis.mapper = new Cassandra.mapping.Mapper(this.client, {\n\t\t\tmodels: buildMapper(models),\n\t\t})\n\n\t\tfor (let model of models) {\n\t\t\tmodel._connect(this)\n\n\t\t\tthis.models.set(\n\t\t\t\tmodel.name,\n\t\t\t\tmodel as Model<InferDocument<typeof model.schema>>,\n\t\t\t)\n\n\t\t\tif (options?.sync === true) {\n\t\t\t\tawait model._sync()\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\"Connecting to ScyllaDB\")\n\t\tawait this.connectWithRetry()\n\t\tconsole.log(\"ScyllaDB Connected\")\n\t}\n\n\tprivate async connectWithRetry(): Promise<void> {\n\t\tlet lastError: Error | null = null\n\n\t\tfor (let attempt = 1; attempt <= this.config.maxRetries!; attempt++) {\n\t\t\ttry {\n\t\t\t\tawait this.client.connect()\n\t\t\t\treturn\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Connection attempt ${attempt} failed: ${error.message}`,\n\t\t\t\t)\n\n\t\t\t\tif (attempt < this.config.maxRetries!) {\n\t\t\t\t\tconsole.log(`Retrying in ${this.config.retryDelay}ms...`)\n\t\t\t\t\tawait this.delay(this.config.retryDelay!)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Failed to connect to ScyllaDB after ${this.config.maxRetries} attempts: ${lastError?.message}`,\n\t\t)\n\t}\n\n\tprivate delay(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.client.shutdown()\n\t\t\tconsole.log(\"ScyllaDB connection closed\")\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error shutting down ScyllaDB connection:\", error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync executeWithRetry<T>(\n\t\toperation: () => Promise<T>,\n\t\toperationName: string = \"operation\",\n\t): Promise<T> {\n\t\tlet lastError: Error | null = null\n\n\t\tfor (let attempt = 1; attempt <= this.config.maxRetries!; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await operation()\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\n\t\t\t\t// check if error is retryable\n\t\t\t\tif (\n\t\t\t\t\tthis.isRetryableError(error) &&\n\t\t\t\t\tattempt < this.config.maxRetries!\n\t\t\t\t) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Operation ${operationName} attempt ${attempt} failed: ${error.message}`,\n\t\t\t\t\t)\n\t\t\t\t\tconsole.log(`Retrying in ${this.config.retryDelay}ms...`)\n\n\t\t\t\t\tawait this.delay(this.config.retryDelay!)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// if not retryable or last attempt, throw\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Operation ${operationName} failed after ${this.config.maxRetries} attempts: ${lastError?.message}`,\n\t\t)\n\t}\n\n\tprivate isRetryableError(error: any): boolean {\n\t\t// retry on network errors, timeouts, and certain ScyllaDB errors\n\t\tconst retryableMessages = [\n\t\t\t\"timeout\",\n\t\t\t\"connection\",\n\t\t\t\"network\",\n\t\t\t\"unavailable\",\n\t\t\t\"overloaded\",\n\t\t\t\"no hosts available\",\n\t\t]\n\n\t\tconst errorMessage = error.message?.toLowerCase() || \"\"\n\n\t\treturn retryableMessages.some((msg) => errorMessage.includes(msg))\n\t}\n}\n\nexport default Client\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.mjs","names":["loadModels","buildMapper"],"sources":["../src/client.ts"],"sourcesContent":["import type {\n\tClient as T_CassandraClient,\n\tClientOptions as T_CassandraClientOptions,\n\tmapping as T_CassandraMapping,\n} from \"cassandra-driver\"\nimport type { ClientConfig } from \"./types\"\n\n//@ts-ignore\nimport path from \"node:path\"\n//@ts-ignore\nimport Cassandra from \"cassandra-driver\"\nimport loadModels from \"./utils/loadModels\"\nimport buildMapper from \"./utils/buildMapper\"\n\nimport { Model } from \"./model\"\nimport { InferDocument } from \"./types\"\n\nconst DEFAULT_MAX_RETRIES = 3\nconst DEFAULT_RETRY_DELAY = 1000\nconst { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } =\n\tprocess.env\n\nexport class Client {\n\tconstructor(config: ClientConfig = {}) {\n\t\tif (globalThis.__scylla_client) {\n\t\t\tthrow new Error(\n\t\t\t\t\"An instance of Scylla Client is already initialized\",\n\t\t\t)\n\t\t}\n\n\t\tglobalThis.__scylla_client = this\n\n\t\tthis.config = {\n\t\t\tmodelsPath: path.resolve(process.cwd(), \"db\"),\n\t\t\tcontactPoints:\n\t\t\t\t(config.contactPoints ?? SCYLLA_CONTACT_POINTS)\n\t\t\t\t\t? SCYLLA_CONTACT_POINTS.split(\",\")\n\t\t\t\t\t: [\"127.0.0.1\"],\n\t\t\tlocalDataCenter:\n\t\t\t\tconfig.localDataCenter ??\n\t\t\t\tSCYLLA_LOCAL_DATA_CENTER ??\n\t\t\t\t\"datacenter1\",\n\t\t\tkeyspace: config.keyspace ?? SCYLLA_KEYSPACE ?? \"default\",\n\t\t\tport: 9042,\n\t\t\tmaxRetries: DEFAULT_MAX_RETRIES,\n\t\t\tretryDelay: DEFAULT_RETRY_DELAY,\n\t\t\t...config,\n\t\t}\n\n\t\tconst clientOptions: T_CassandraClientOptions = {\n\t\t\tcontactPoints: this.config.contactPoints,\n\t\t\tlocalDataCenter: this.config.localDataCenter,\n\t\t\tkeyspace: this.config.keyspace,\n\t\t\tprotocolOptions: {\n\t\t\t\tport: this.config.port,\n\t\t\t},\n\t\t}\n\n\t\tif (this.config.pooling) {\n\t\t\tclientOptions.pooling = this.config.pooling\n\t\t}\n\n\t\tthis.client = new Cassandra.Client(clientOptions)\n\t}\n\n\tconfig: ClientConfig\n\tclient: T_CassandraClient\n\tmapper: T_CassandraMapping.Mapper\n\tmodels: Map<string, Model<any>> = new Map()\n\n\tasync initialize(options: { sync?: boolean } = {}) {\n\t\tlet models: Model<any>[]\n\n\t\ttry {\n\t\t\tmodels = await loadModels(this.config.modelsPath)\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to load models: ${error.message}`)\n\t\t}\n\n\t\tmodels = models.filter((schema) => schema instanceof Model)\n\n\t\tthis.mapper = new Cassandra.mapping.Mapper(this.client, {\n\t\t\tmodels: buildMapper(models),\n\t\t})\n\n\t\tfor (let model of models) {\n\t\t\tthis.models.set(\n\t\t\t\tmodel.name,\n\t\t\t\tmodel as Model<InferDocument<typeof model.schema>>,\n\t\t\t)\n\n\t\t\tif (options?.sync === true) {\n\t\t\t\tawait model._sync()\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\"Connecting to ScyllaDB\")\n\t\tawait this.connectWithRetry()\n\t\tconsole.log(\"ScyllaDB Connected\")\n\t}\n\n\tprivate async connectWithRetry(): Promise<void> {\n\t\tlet lastError: Error | null = null\n\n\t\tfor (let attempt = 1; attempt <= this.config.maxRetries!; attempt++) {\n\t\t\ttry {\n\t\t\t\tawait this.client.connect()\n\t\t\t\treturn\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Connection attempt ${attempt} failed: ${error.message}`,\n\t\t\t\t)\n\n\t\t\t\tif (attempt < this.config.maxRetries!) {\n\t\t\t\t\tconsole.log(`Retrying in ${this.config.retryDelay}ms...`)\n\t\t\t\t\tawait this.delay(this.config.retryDelay!)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Failed to connect to ScyllaDB after ${this.config.maxRetries} attempts: ${lastError?.message}`,\n\t\t)\n\t}\n\n\tprivate delay(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.client.shutdown()\n\t\t\tconsole.log(\"ScyllaDB connection closed\")\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error shutting down ScyllaDB connection:\", error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync executeWithRetry<T>(\n\t\toperation: () => Promise<T>,\n\t\toperationName: string = \"operation\",\n\t): Promise<T> {\n\t\tlet lastError: Error | null = null\n\n\t\tfor (let attempt = 1; attempt <= this.config.maxRetries!; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await operation()\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\n\t\t\t\t// check if error is retryable\n\t\t\t\tif (\n\t\t\t\t\tthis.isRetryableError(error) &&\n\t\t\t\t\tattempt < this.config.maxRetries!\n\t\t\t\t) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Operation ${operationName} attempt ${attempt} failed: ${error.message}`,\n\t\t\t\t\t)\n\t\t\t\t\tconsole.log(`Retrying in ${this.config.retryDelay}ms...`)\n\n\t\t\t\t\tawait this.delay(this.config.retryDelay!)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// if not retryable or last attempt, throw\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Operation ${operationName} failed after ${this.config.maxRetries} attempts: ${lastError?.message}`,\n\t\t)\n\t}\n\n\tprivate isRetryableError(error: any): boolean {\n\t\t// retry on network errors, timeouts, and certain ScyllaDB errors\n\t\tconst retryableMessages = [\n\t\t\t\"timeout\",\n\t\t\t\"connection\",\n\t\t\t\"network\",\n\t\t\t\"unavailable\",\n\t\t\t\"overloaded\",\n\t\t\t\"no hosts available\",\n\t\t]\n\n\t\tconst errorMessage = error.message?.toLowerCase() || \"\"\n\n\t\treturn retryableMessages.some((msg) => errorMessage.includes(msg))\n\t}\n}\n\nexport default Client\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { Schema } from "./schema/index.mjs";
2
2
  import { Model } from "./model/index.mjs";
3
+ import { Result } from "./result/index.mjs";
4
+ import { ColumnTypes } from "./types.mjs";
3
5
  import { Client } from "./client.mjs";
4
- export { Client, Client as default, Model, Schema };
6
+ export { Client, Client as default, ColumnTypes, Model, Result, Schema };
package/dist/index.mjs CHANGED
@@ -1,9 +1,11 @@
1
+ import { Result } from "./result/index.mjs";
1
2
  import { Model } from "./model/index.mjs";
2
3
  import { Client } from "./client.mjs";
3
4
  import { Schema } from "./schema/index.mjs";
5
+ import { ColumnTypes } from "./types.mjs";
4
6
  //#region src/index.ts
5
7
  var src_default = Client;
6
8
  //#endregion
7
- export { Client, Model, Schema, src_default as default };
9
+ export { Client, ColumnTypes, Model, Result, Schema, src_default as default };
8
10
 
9
11
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import Client from \"./client\"\nimport Model from \"./model\"\nimport Schema from \"./schema\"\n\nexport default Client\nexport { Client, Model, Schema }\n"],"mappings":";;;;AAIA,IAAA,cAAe"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import Client from \"./client\"\nimport Model from \"./model\"\nimport Schema from \"./schema\"\nimport Result from \"./result\"\nimport { ColumnTypes } from \"./types\"\n\nexport default Client\nexport { Client, Model, Schema, Result, ColumnTypes }\n"],"mappings":";;;;;;AAMA,IAAA,cAAe"}
@@ -9,8 +9,8 @@ import { mapping } from "cassandra-driver/lib/mapping/index.js";
9
9
  declare class Model<TDoc = any> {
10
10
  name: string;
11
11
  schema: Schema<any>;
12
- driver: Client;
13
- mapper: mapping.ModelMapper;
12
+ get driver(): Client;
13
+ get mapper(): mapping.ModelMapper;
14
14
  constructor(name: string, schema: Schema<any>);
15
15
  create: (data: Partial<TDoc>) => DocumentResult<TDoc>;
16
16
  find: {
@@ -31,7 +31,6 @@ declare class Model<TDoc = any> {
31
31
  _sync: typeof syncOP;
32
32
  _tableExists: typeof export_default;
33
33
  _wrap(row: any): DocumentResult<TDoc> | null;
34
- _connect(driver: Client): void;
35
34
  }
36
35
  //#endregion
37
36
  export { Model, Model as default };
@@ -11,8 +11,12 @@ import syncOP from "../operations/sync.mjs";
11
11
  var Model = class {
12
12
  name;
13
13
  schema;
14
- driver;
15
- mapper;
14
+ get driver() {
15
+ return globalThis.__scylla_client?.driver;
16
+ }
17
+ get mapper() {
18
+ return globalThis.__scylla_client?.mapper;
19
+ }
16
20
  constructor(name, schema) {
17
21
  this.name = name;
18
22
  this.schema = schema;
@@ -33,10 +37,6 @@ var Model = class {
33
37
  row = fillDefaults(this.schema, row);
34
38
  return new Result(row, this);
35
39
  }
36
- _connect(driver) {
37
- this.driver = driver;
38
- this.mapper = driver.mapper.forModel(this.name);
39
- }
40
40
  };
41
41
  //#endregion
42
42
  export { Model, Model as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["findOneOP","updateOP","deleteOP","countAllOP","tableExistsOP"],"sources":["../../src/model/index.ts"],"sourcesContent":["import ScyllaClient from \"..\"\nimport { Result } from \"../result\"\n\nimport fillDefaults from \"../utils/fillDefaults\"\n\nimport { mapping } from \"cassandra-driver/lib/mapping\"\nimport type { DocumentResult, Query, QueryOptions } from \"../types\"\nimport type { Schema } from \"../schema\"\n\nimport findOneOP from \"../operations/findOne\"\nimport findOP from \"../operations/find\"\nimport updateOP from \"../operations/update\"\nimport deleteOP from \"../operations/delete\"\nimport countAllOP from \"../operations/countAll\"\n\nimport tableExistsOP from \"../operations/tableExists\"\nimport syncOP from \"../operations/sync\"\n\nexport class Model<TDoc = any> {\n\tname: string\n\tschema: Schema<any>\n\tdriver: ScyllaClient\n\tmapper: mapping.ModelMapper\n\n\tconstructor(name: string, schema: Schema<any>) {\n\t\tthis.name = name\n\t\tthis.schema = schema\n\n\t\tif (!Array.isArray(this.schema.keys)) {\n\t\t\tthrow new Error(`[${this.name}] model has missing \"keys\" array`)\n\t\t}\n\t\tif (!this.schema.table_name) {\n\t\t\tthrow new Error(`[${this.name}] model has missing \"table_name\"`)\n\t\t}\n\t\tif (!this.schema.fields || typeof this.schema.fields !== \"object\") {\n\t\t\tthrow new Error(\n\t\t\t\t`[${this.name}] model has missing or invalid \"fields\"`,\n\t\t\t)\n\t\t}\n\t}\n\n\tcreate = (data: Partial<TDoc>) => this._wrap(data)\n\n\tfind: {\n\t\t(\n\t\t\tquery: Query<TDoc>,\n\t\t\toptions: QueryOptions & { raw: true },\n\t\t): Promise<TDoc[]>\n\t\t(\n\t\t\tquery?: Query<TDoc>,\n\t\t\toptions?: QueryOptions,\n\t\t): Promise<DocumentResult<TDoc>[]>\n\t} = findOP.bind(this)\n\n\tfindOne: {\n\t\t(\n\t\t\tquery: Query<TDoc>,\n\t\t\toptions: QueryOptions & { raw: true },\n\t\t): Promise<TDoc>\n\t\t(\n\t\t\tquery?: Query<TDoc>,\n\t\t\toptions?: QueryOptions,\n\t\t): Promise<DocumentResult<TDoc>>\n\t} = findOneOP.bind(this)\n\n\tupdate: (query: Query<TDoc>) => Promise<DocumentResult<TDoc>> =\n\t\tupdateOP.bind(this)\n\n\tdelete: (query: Query<TDoc>) => Promise<mapping.Result> =\n\t\tdeleteOP.bind(this)\n\n\tcountAll: () => Promise<number> = countAllOP.bind(this)\n\n\t_sync: typeof syncOP = syncOP.bind(this)\n\t_tableExists: typeof tableExistsOP = tableExistsOP.bind(this)\n\n\t_wrap(row: any): DocumentResult<TDoc> | null {\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\n\t\trow = fillDefaults(this.schema, row)\n\n\t\treturn new Result<TDoc>(row, this) as DocumentResult<TDoc>\n\t}\n\n\t_connect(driver: ScyllaClient) {\n\t\tthis.driver = driver\n\t\tthis.mapper = driver.mapper.forModel(this.name)\n\t}\n}\n\nexport default Model\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,QAAb,MAA+B;CAC9B;CACA;CACA;CACA;CAEA,YAAY,MAAc,QAAqB;AAC9C,OAAK,OAAO;AACZ,OAAK,SAAS;AAEd,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,CACnC,OAAM,IAAI,MAAM,IAAI,KAAK,KAAK,kCAAkC;AAEjE,MAAI,CAAC,KAAK,OAAO,WAChB,OAAM,IAAI,MAAM,IAAI,KAAK,KAAK,kCAAkC;AAEjE,MAAI,CAAC,KAAK,OAAO,UAAU,OAAO,KAAK,OAAO,WAAW,SACxD,OAAM,IAAI,MACT,IAAI,KAAK,KAAK,yCACd;;CAIH,UAAU,SAAwB,KAAK,MAAM,KAAK;CAElD,OASI,OAAO,KAAK,KAAK;CAErB,UASIA,gBAAU,KAAK,KAAK;CAExB,SACCC,eAAS,KAAK,KAAK;CAEpB,SACCC,eAAS,KAAK,KAAK;CAEpB,WAAkCC,iBAAW,KAAK,KAAK;CAEvD,QAAuB,OAAO,KAAK,KAAK;CACxC,eAAqCC,oBAAc,KAAK,KAAK;CAE7D,MAAM,KAAuC;AAC5C,MAAI,CAAC,IACJ,QAAO;AAGR,QAAM,aAAa,KAAK,QAAQ,IAAI;AAEpC,SAAO,IAAI,OAAa,KAAK,KAAK;;CAGnC,SAAS,QAAsB;AAC9B,OAAK,SAAS;AACd,OAAK,SAAS,OAAO,OAAO,SAAS,KAAK,KAAK"}
1
+ {"version":3,"file":"index.mjs","names":["findOneOP","updateOP","deleteOP","countAllOP","tableExistsOP"],"sources":["../../src/model/index.ts"],"sourcesContent":["import ScyllaClient from \"..\"\nimport { Result } from \"../result\"\n\nimport fillDefaults from \"../utils/fillDefaults\"\n\nimport { mapping } from \"cassandra-driver/lib/mapping\"\nimport type { DocumentResult, Query, QueryOptions } from \"../types\"\nimport type { Schema } from \"../schema\"\n\nimport findOneOP from \"../operations/findOne\"\nimport findOP from \"../operations/find\"\nimport updateOP from \"../operations/update\"\nimport deleteOP from \"../operations/delete\"\nimport countAllOP from \"../operations/countAll\"\n\nimport tableExistsOP from \"../operations/tableExists\"\nimport syncOP from \"../operations/sync\"\n\nexport class Model<TDoc = any> {\n\tname: string\n\tschema: Schema<any>\n\n\tget driver(): ScyllaClient {\n\t\treturn globalThis.__scylla_client?.driver\n\t}\n\n\tget mapper(): mapping.ModelMapper {\n\t\treturn globalThis.__scylla_client?.mapper\n\t}\n\n\tconstructor(name: string, schema: Schema<any>) {\n\t\tthis.name = name\n\t\tthis.schema = schema\n\n\t\tif (!Array.isArray(this.schema.keys)) {\n\t\t\tthrow new Error(`[${this.name}] model has missing \"keys\" array`)\n\t\t}\n\t\tif (!this.schema.table_name) {\n\t\t\tthrow new Error(`[${this.name}] model has missing \"table_name\"`)\n\t\t}\n\t\tif (!this.schema.fields || typeof this.schema.fields !== \"object\") {\n\t\t\tthrow new Error(\n\t\t\t\t`[${this.name}] model has missing or invalid \"fields\"`,\n\t\t\t)\n\t\t}\n\t}\n\n\tcreate = (data: Partial<TDoc>) => this._wrap(data)\n\n\tfind: {\n\t\t(\n\t\t\tquery: Query<TDoc>,\n\t\t\toptions: QueryOptions & { raw: true },\n\t\t): Promise<TDoc[]>\n\t\t(\n\t\t\tquery?: Query<TDoc>,\n\t\t\toptions?: QueryOptions,\n\t\t): Promise<DocumentResult<TDoc>[]>\n\t} = findOP.bind(this)\n\n\tfindOne: {\n\t\t(\n\t\t\tquery: Query<TDoc>,\n\t\t\toptions: QueryOptions & { raw: true },\n\t\t): Promise<TDoc>\n\t\t(\n\t\t\tquery?: Query<TDoc>,\n\t\t\toptions?: QueryOptions,\n\t\t): Promise<DocumentResult<TDoc>>\n\t} = findOneOP.bind(this)\n\n\tupdate: (query: Query<TDoc>) => Promise<DocumentResult<TDoc>> =\n\t\tupdateOP.bind(this)\n\n\tdelete: (query: Query<TDoc>) => Promise<mapping.Result> =\n\t\tdeleteOP.bind(this)\n\n\tcountAll: () => Promise<number> = countAllOP.bind(this)\n\n\t_sync: typeof syncOP = syncOP.bind(this)\n\t_tableExists: typeof tableExistsOP = tableExistsOP.bind(this)\n\n\t_wrap(row: any): DocumentResult<TDoc> | null {\n\t\tif (!row) {\n\t\t\treturn null\n\t\t}\n\n\t\trow = fillDefaults(this.schema, row)\n\n\t\treturn new Result<TDoc>(row, this) as DocumentResult<TDoc>\n\t}\n}\n\nexport default Model\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,QAAb,MAA+B;CAC9B;CACA;CAEA,IAAI,SAAuB;AAC1B,SAAO,WAAW,iBAAiB;;CAGpC,IAAI,SAA8B;AACjC,SAAO,WAAW,iBAAiB;;CAGpC,YAAY,MAAc,QAAqB;AAC9C,OAAK,OAAO;AACZ,OAAK,SAAS;AAEd,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,CACnC,OAAM,IAAI,MAAM,IAAI,KAAK,KAAK,kCAAkC;AAEjE,MAAI,CAAC,KAAK,OAAO,WAChB,OAAM,IAAI,MAAM,IAAI,KAAK,KAAK,kCAAkC;AAEjE,MAAI,CAAC,KAAK,OAAO,UAAU,OAAO,KAAK,OAAO,WAAW,SACxD,OAAM,IAAI,MACT,IAAI,KAAK,KAAK,yCACd;;CAIH,UAAU,SAAwB,KAAK,MAAM,KAAK;CAElD,OASI,OAAO,KAAK,KAAK;CAErB,UASIA,gBAAU,KAAK,KAAK;CAExB,SACCC,eAAS,KAAK,KAAK;CAEpB,SACCC,eAAS,KAAK,KAAK;CAEpB,WAAkCC,iBAAW,KAAK,KAAK;CAEvD,QAAuB,OAAO,KAAK,KAAK;CACxC,eAAqCC,oBAAc,KAAK,KAAK;CAE7D,MAAM,KAAuC;AAC5C,MAAI,CAAC,IACJ,QAAO;AAGR,QAAM,aAAa,KAAK,QAAQ,IAAI;AAEpC,SAAO,IAAI,OAAa,KAAK,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["import Result from \"./result\"\nimport { Schema } from \"./schema\"\n\nexport type ClientConfig = {\n\tmodelsPath?: string\n\tcontactPoints?: string[]\n\tlocalDataCenter?: string\n\tkeyspace?: string\n\tport?: number\n\tmaxRetries?: number\n\tretryDelay?: number\n\tpooling?: {\n\t\tcoreConnectionsPerHost?: Record<string, number>\n\t\tmaxRequestsPerConnection?: number\n\t}\n}\n\nexport enum ColumnTypes {\n\tAscii = \"ascii\",\n\tBigint = \"bigint\",\n\tBlob = \"blob\",\n\tBoolean = \"boolean\",\n\tCounter = \"counter\",\n\tDate = \"date\",\n\tDecimal = \"decimal\",\n\tDouble = \"double\",\n\tDuration = \"duration\",\n\tFloat = \"float\",\n\tFrozen = \"frozen\",\n\tInet = \"inet\",\n\tInt = \"int\",\n\tList = \"list\",\n\tMap = \"map\",\n\tSet = \"set\",\n\tSmallint = \"smallint\",\n\tText = \"text\",\n\tTime = \"time\",\n\tTimestamp = \"timestamp\",\n\tTimeuuid = \"timeuuid\",\n\tTinyint = \"tinyint\",\n\tTuple = \"tuple\",\n\tUuid = \"uuid\",\n\tVarchar = \"varchar\",\n\tVarint = \"varint\",\n}\n\nexport type QueryOperators<TValue> = {\n\t$eq?: TValue\n\t$ne?: TValue\n\t$in?: TValue[]\n\t$gt?: TValue\n\t$gte?: TValue\n\t$lt?: TValue\n\t$lte?: TValue\n}\n\nexport type TableKeys = (string | TableKeys)[]\n\nexport interface Column<T> {\n\ttype?: ColumnTypes | string\n\trequired?: boolean\n}\n\nexport type InferRawData<T> = {\n\t[K in keyof T as K extends `$${string}` ? never : K]: T[K] extends Column<\n\t\tinfer U\n\t>\n\t\t? U\n\t\t: T[K]\n}\n\nexport type InferDocument<S> =\n\tS extends Schema<infer T> ? InferRawData<T> : never\n\nexport type DocumentResult<TDoc> = Result<TDoc> & TDoc\n\nexport type QueryOptions = {\n\traw?: boolean\n}\n\nexport type OrderBy<TDoc> = { [K in keyof TDoc]?: \"asc\" | \"desc\" }\n\nexport type Query<TDoc> = {\n\t[K in keyof TDoc]?: TDoc[K] | QueryOperators<TDoc[K]>\n} & {\n\t$and?: Query<TDoc>[]\n\t$limit?: number\n\t$orderby?: OrderBy<TDoc>\n}\n"],"mappings":";AAiBA,IAAY,cAAL,yBAAA,aAAA;AACN,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,aAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,YAAA;AACA,aAAA,cAAA;AACA,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,SAAA;AACA,aAAA,UAAA;AACA,aAAA,SAAA;AACA,aAAA,SAAA;AACA,aAAA,cAAA;AACA,aAAA,UAAA;AACA,aAAA,UAAA;AACA,aAAA,eAAA;AACA,aAAA,cAAA;AACA,aAAA,aAAA;AACA,aAAA,WAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,YAAA;;KACA"}
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["import Result from \"./result\"\nimport { Schema } from \"./schema\"\n\nexport type ClientConfig = {\n\tmodelsPath?: string\n\tcontactPoints?: string[]\n\tlocalDataCenter?: string\n\tkeyspace?: string\n\tport?: number\n\tmaxRetries?: number\n\tretryDelay?: number\n\tpooling?: {\n\t\tcoreConnectionsPerHost?: Record<string, number>\n\t\tmaxRequestsPerConnection?: number\n\t}\n}\n\nexport enum ColumnTypes {\n\tAscii = \"ascii\",\n\tBigint = \"bigint\",\n\tBlob = \"blob\",\n\tBoolean = \"boolean\",\n\tCounter = \"counter\",\n\tDate = \"date\",\n\tDecimal = \"decimal\",\n\tDouble = \"double\",\n\tDuration = \"duration\",\n\tFloat = \"float\",\n\tFrozen = \"frozen\",\n\tInet = \"inet\",\n\tInt = \"int\",\n\tList = \"list\",\n\tMap = \"map\",\n\tSet = \"set\",\n\tSmallint = \"smallint\",\n\tText = \"text\",\n\tTime = \"time\",\n\tTimestamp = \"timestamp\",\n\tTimeuuid = \"timeuuid\",\n\tTinyint = \"tinyint\",\n\tTuple = \"tuple\",\n\tUuid = \"uuid\",\n\tVarchar = \"varchar\",\n\tVarint = \"varint\",\n}\n\nexport type QueryOperators<TValue> = {\n\t$eq?: TValue\n\t$ne?: TValue\n\t$in?: TValue[]\n\t$gt?: TValue\n\t$gte?: TValue\n\t$lt?: TValue\n\t$lte?: TValue\n}\n\nexport type TableKeys = (string | TableKeys)[]\n\nexport interface Column<T> {\n\ttype?: ColumnTypes | string\n\trequired?: boolean\n}\n\nexport type InferRawData<T> = {\n\t[K in keyof T as K extends `$${string}` ? never : K]: T[K] extends Column<\n\t\tinfer U\n\t>\n\t\t? U\n\t\t: T[K]\n}\n\nexport type InferDocument<S> =\n\tS extends Schema<infer T> ? InferRawData<T> : never\n\n// export type DocOf<M extends Model<any>> =\n// \tM extends Model<infer S> ? InferDocument<S> : never\n\nexport type DocumentResult<TDoc> = Result<TDoc> & TDoc\n\nexport type QueryOptions = {\n\traw?: boolean\n}\n\nexport type OrderBy<TDoc> = { [K in keyof TDoc]?: \"asc\" | \"desc\" }\n\nexport type Query<TDoc> = {\n\t[K in keyof TDoc]?: TDoc[K] | QueryOperators<TDoc[K]>\n} & {\n\t$and?: Query<TDoc>[]\n\t$limit?: number\n\t$orderby?: OrderBy<TDoc>\n}\n"],"mappings":";AAiBA,IAAY,cAAL,yBAAA,aAAA;AACN,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,aAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,YAAA;AACA,aAAA,cAAA;AACA,aAAA,WAAA;AACA,aAAA,YAAA;AACA,aAAA,UAAA;AACA,aAAA,SAAA;AACA,aAAA,UAAA;AACA,aAAA,SAAA;AACA,aAAA,SAAA;AACA,aAAA,cAAA;AACA,aAAA,UAAA;AACA,aAAA,UAAA;AACA,aAAA,eAAA;AACA,aAAA,cAAA;AACA,aAAA,aAAA;AACA,aAAA,WAAA;AACA,aAAA,UAAA;AACA,aAAA,aAAA;AACA,aAAA,YAAA;;KACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ragestudio/scylla-odm",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "An ODM for ScyllaDB",
5
5
  "license": "MIT",
6
6
  "author": "RageStudio",