@ragestudio/scylla-odm 0.4.0 → 0.5.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.
Files changed (58) hide show
  1. package/dist/client.d.mts +23 -0
  2. package/dist/client.mjs +112 -0
  3. package/dist/client.mjs.map +1 -0
  4. package/dist/cql_gen/create_table.d.mts +7 -0
  5. package/dist/cql_gen/create_table.mjs +38 -0
  6. package/dist/cql_gen/create_table.mjs.map +1 -0
  7. package/dist/index.d.mts +4 -113
  8. package/dist/index.mjs +5 -515
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/model/index.d.mts +38 -0
  11. package/dist/model/index.mjs +44 -0
  12. package/dist/model/index.mjs.map +1 -0
  13. package/dist/operations/countAll.d.mts +7 -0
  14. package/dist/operations/countAll.mjs +16 -0
  15. package/dist/operations/countAll.mjs.map +1 -0
  16. package/dist/operations/delete.d.mts +8 -0
  17. package/dist/operations/delete.mjs +11 -0
  18. package/dist/operations/delete.mjs.map +1 -0
  19. package/dist/operations/find.d.mts +8 -0
  20. package/dist/operations/find.mjs +22 -0
  21. package/dist/operations/find.mjs.map +1 -0
  22. package/dist/operations/findOne.d.mts +8 -0
  23. package/dist/operations/findOne.mjs +17 -0
  24. package/dist/operations/findOne.mjs.map +1 -0
  25. package/dist/operations/sync.d.mts +7 -0
  26. package/dist/operations/sync.mjs +16 -0
  27. package/dist/operations/sync.mjs.map +1 -0
  28. package/dist/operations/tableExists.d.mts +7 -0
  29. package/dist/operations/tableExists.mjs +19 -0
  30. package/dist/operations/tableExists.mjs.map +1 -0
  31. package/dist/operations/update.d.mts +7 -0
  32. package/dist/operations/update.mjs +18 -0
  33. package/dist/operations/update.mjs.map +1 -0
  34. package/dist/result/index.d.mts +17 -0
  35. package/dist/result/index.mjs +66 -0
  36. package/dist/result/index.mjs.map +1 -0
  37. package/dist/schema/index.d.mts +13 -0
  38. package/dist/schema/index.mjs +16 -0
  39. package/dist/schema/index.mjs.map +1 -0
  40. package/dist/types.d.mts +74 -0
  41. package/dist/types.mjs +34 -0
  42. package/dist/types.mjs.map +1 -0
  43. package/dist/utils/buildMapper.d.mts +5 -0
  44. package/dist/utils/buildMapper.mjs +13 -0
  45. package/dist/utils/buildMapper.mjs.map +1 -0
  46. package/dist/utils/fillDefaults.d.mts +5 -0
  47. package/dist/utils/fillDefaults.mjs +18 -0
  48. package/dist/utils/fillDefaults.mjs.map +1 -0
  49. package/dist/utils/loadModels.d.mts +5 -0
  50. package/dist/utils/loadModels.mjs +30 -0
  51. package/dist/utils/loadModels.mjs.map +1 -0
  52. package/dist/utils/queryParser.d.mts +9 -0
  53. package/dist/utils/queryParser.mjs +94 -0
  54. package/dist/utils/queryParser.mjs.map +1 -0
  55. package/dist/utils/typeChecker.d.mts +7 -0
  56. package/dist/utils/typeChecker.mjs +55 -0
  57. package/dist/utils/typeChecker.mjs.map +1 -0
  58. package/package.json +40 -4
package/dist/index.mjs CHANGED
@@ -1,519 +1,9 @@
1
- import path from "node:path";
2
- import Cassandra from "cassandra-driver";
3
- import fs from "node:fs";
4
- //#region src/utils/loadModels.ts
5
- var loadModels_default = async (fromPath) => {
6
- if (typeof fromPath !== "string") return [];
7
- if (!fs.existsSync(fromPath)) {
8
- console.warn(`Cannot load models from [${fromPath}] case this path does not exist`);
9
- return [];
10
- }
11
- let mods = [];
12
- let files = await fs.promises.readdir(fromPath);
13
- files = files.filter((file) => file.endsWith(".js") || file.endsWith(".ts"));
14
- for await (const file of files) {
15
- const name = file.replace(".js", "");
16
- const file_path = path.join(fromPath, file);
17
- try {
18
- let mod = await import(file_path);
19
- mod = mod.default;
20
- mods.push(mod);
21
- } catch (error) {
22
- console.error(`Failed to load model [${name}]:`, error);
23
- continue;
24
- }
25
- }
26
- return mods;
27
- };
28
- //#endregion
29
- //#region src/utils/buildMapper.ts
30
- var buildMapper_default = (map) => {
31
- return map.reduce((obj, { name, schema }) => {
32
- return {
33
- ...obj,
34
- [name]: { tables: [schema.table_name] }
35
- };
36
- }, {});
37
- };
38
- //#endregion
39
- //#region src/utils/queryParser.ts
40
- const { q } = Cassandra.mapping;
41
- const MAX_QUERY_DEPTH = 3;
42
- const MAX_IN_ELEMENTS = 1e3;
43
- const VALID_OPERATORS = new Set([
44
- "$eq",
45
- "$ne",
46
- "$gt",
47
- "$gte",
48
- "$lt",
49
- "$lte",
50
- "$in"
51
- ]);
52
- function requireNotNull(value, operator) {
53
- if (value === null || value === void 0) throw new Error(`${operator} operator cannot compare with null or undefined`);
54
- }
55
- function buildOperator(operator, opValue) {
56
- if (!VALID_OPERATORS.has(operator)) throw new Error(`Invalid operator: ${operator}`);
57
- switch (operator) {
58
- case "$eq": return opValue;
59
- case "$ne":
60
- requireNotNull(opValue, "$ne");
61
- return q.notEq(opValue);
62
- case "$in":
63
- if (!Array.isArray(opValue)) throw new Error("$in operator requires an array");
64
- if (opValue.length > MAX_IN_ELEMENTS) throw new Error(`$in operator exceeds maximum of ${MAX_IN_ELEMENTS} elements`);
65
- for (let i = 0; i < opValue.length; i++) if (opValue[i] === null || opValue[i] === void 0) throw new Error(`$in array element at index ${i} cannot be null or undefined`);
66
- return q.in_(opValue);
67
- case "$gt":
68
- requireNotNull(opValue, "$gt");
69
- return q.gt(opValue);
70
- case "$gte":
71
- requireNotNull(opValue, "$gte");
72
- return q.gte(opValue);
73
- case "$lt":
74
- requireNotNull(opValue, "$lt");
75
- return q.lt(opValue);
76
- case "$lte":
77
- requireNotNull(opValue, "$lte");
78
- return q.lte(opValue);
79
- }
80
- }
81
- function queryParser(model, query, depth = 0) {
82
- if (depth > MAX_QUERY_DEPTH) throw new Error(`Query depth exceeds maximum of ${MAX_QUERY_DEPTH}`);
83
- if (!query || typeof query !== "object") return query;
84
- const parsedQuery = {};
85
- const fields = model.schema.fields;
86
- for (const field of Object.keys(query)) {
87
- const value = query[field];
88
- if (field === "$and") {
89
- handleAnd(model, value, parsedQuery, depth);
90
- continue;
91
- }
92
- if (field === "$or") throw new Error("ScyllaDB does not support OR queries across different columns. Use $in for a single column.");
93
- if (!isValidFieldName(fields, field)) throw new Error(`Invalid field name: [${field}] or it does not exist in schema`);
94
- parsedQuery[field] = parseField(value);
95
- }
96
- return parsedQuery;
97
- }
98
- function handleAnd(model, conditions, parsedQuery, depth) {
99
- if (!Array.isArray(conditions)) throw new Error("$and operator requires an array");
100
- if (conditions.length > 10) throw new Error("$and operator exceeds maximum of 10 conditions");
101
- for (let i = 0; i < conditions.length; i++) {
102
- const condition = conditions[i];
103
- if (!condition || typeof condition !== "object") throw new Error(`$and condition at index ${i} must be an object`);
104
- const parsed = queryParser(model, condition, depth + 1);
105
- for (const key of Object.keys(parsed)) if (key in parsedQuery) throw new Error(`$and conflict: field "${key}" appears in multiple conditions`);
106
- Object.assign(parsedQuery, parsed);
107
- }
108
- }
109
- function parseField(value) {
110
- if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date) {
111
- if (Array.isArray(value)) throw new Error("Array values require explicit operator (e.g., $in)");
112
- return value;
113
- }
114
- const compiledOps = Object.keys(value).map((op) => buildOperator(op, value[op]));
115
- return compiledOps.length === 1 ? compiledOps[0] : q.and(...compiledOps);
116
- }
117
- function isValidFieldName(fields, fieldName) {
118
- for (const pattern of [
119
- /^[0-9]/,
120
- /[^a-zA-Z0-9_]/,
121
- /^(select|insert|update|delete|drop|create|alter|truncate)$/i
122
- ]) if (pattern.test(fieldName)) return false;
123
- return fieldName in fields;
124
- }
125
- //#endregion
126
- //#region src/utils/typeChecker.ts
127
- const { types } = Cassandra;
128
- const stringTypes = new Set([
129
- "ascii",
130
- "text",
131
- "varchar",
132
- "inet"
133
- ]);
134
- const intTypes = new Set([
135
- "int",
136
- "smallint",
137
- "tinyint"
138
- ]);
139
- const floatTypes = new Set(["double", "float"]);
140
- const longTypes = new Set(["bigint", "counter"]);
141
- function isValidValue(value, expectedType) {
142
- if (value === null || value === void 0) return true;
143
- if (stringTypes.has(expectedType)) return typeof value === "string";
144
- if (intTypes.has(expectedType)) return Number.isInteger(value);
145
- if (floatTypes.has(expectedType)) return typeof value === "number";
146
- if (longTypes.has(expectedType)) return typeof value === "bigint" || typeof value === "number" || value instanceof types.Long;
147
- switch (expectedType) {
148
- case "boolean": return typeof value === "boolean";
149
- case "decimal": return typeof value === "number" || typeof value === "string" || value instanceof types.BigDecimal;
150
- case "varint": return typeof value === "bigint" || typeof value === "number" || value instanceof types.Integer;
151
- case "timestamp": return value instanceof Date || typeof value === "number" || typeof value === "string";
152
- case "date": return typeof value === "string" || value instanceof types.LocalDate;
153
- case "time": return typeof value === "string" || value instanceof types.LocalTime;
154
- case "uuid": return typeof value === "string" || value instanceof types.Uuid;
155
- case "timeuuid": return typeof value === "string" || value instanceof types.TimeUuid;
156
- case "blob": return Buffer.isBuffer(value) || value instanceof Uint8Array;
157
- }
158
- if (expectedType.startsWith("list<") || expectedType.startsWith("set<")) return Array.isArray(value) || value instanceof Set;
159
- if (expectedType.startsWith("map<")) return typeof value === "object" && !Array.isArray(value) && value !== null;
160
- return false;
161
- }
162
- function typeChecker(model, data) {
163
- if (!data || typeof data !== "object" || Array.isArray(data)) throw new TypeError(`[${model.name}] Validation error: Data payload must be an object`);
164
- const fields = model.schema.fields;
165
- for (const [key, value] of Object.entries(data)) {
166
- if (!isValidFieldName(fields, key)) throw new Error(`[${model.name}] Validation error: Field '${key}' does not exist in schema`);
167
- const expectedType = (fields[key].type || "text").toLowerCase();
168
- if (!isValidValue(value, expectedType)) {
169
- const receivedType = Array.isArray(value) ? "array" : typeof value;
170
- throw new TypeError(`[${model.name}] Validation error: Invalid type for field '${key}'. Expected[${expectedType}], but received [${receivedType}]`);
171
- }
172
- }
173
- return true;
174
- }
175
- //#endregion
176
- //#region src/result/index.ts
177
- var Result = class {
178
- constructor(data, model) {
179
- if (data == null) throw new Error("Cannot create Result with null or undefined data");
180
- if (typeof data !== "object" || Array.isArray(data)) throw new Error("Result data must be an object");
181
- Object.assign(this, data);
182
- Object.defineProperty(this, "_model", {
183
- value: model,
184
- enumerable: false,
185
- writable: false,
186
- configurable: false
187
- });
188
- }
189
- _model;
190
- async save() {
191
- try {
192
- const data = this.toRaw();
193
- typeChecker(this._model, data);
194
- return await this._model.update(data);
195
- } catch (error) {
196
- throw new Error(`Failed to save result: ${error.message}`);
197
- }
198
- }
199
- async delete() {
200
- try {
201
- return await this._model.delete(this.toRaw());
202
- } catch (error) {
203
- throw new Error(`Failed to delete result: ${error.message}`);
204
- }
205
- }
206
- toRaw() {
207
- const raw = {};
208
- for (const key in this) {
209
- if (key === "_model") continue;
210
- if (this.propertyIsEnumerable(key)) {
211
- const value = this[key];
212
- try {
213
- JSON.stringify(value);
214
- raw[key] = value;
215
- } catch (error) {
216
- raw[key] = String(value);
217
- }
218
- }
219
- }
220
- return raw;
221
- }
222
- isValid() {
223
- try {
224
- typeChecker(this._model, this.toRaw());
225
- return true;
226
- } catch {
227
- return false;
228
- }
229
- }
230
- getChangedFields(original) {
231
- const current = this.toRaw();
232
- const changed = [];
233
- for (const key in current) if (!(key in original) || current[key] !== original[key]) changed.push(key);
234
- return changed;
235
- }
236
- };
237
- //#endregion
238
- //#region src/utils/fillDefaults.ts
239
- function fillDefaults(schema, data) {
240
- const defaults = schema.options?.defaults;
241
- if (!defaults || Object.keys(defaults).length === 0) return data;
242
- let needsDefaults = false;
243
- for (const key in defaults) if (data[key] == null) {
244
- needsDefaults = true;
245
- break;
246
- }
247
- if (!needsDefaults) return data;
248
- const result = Object.assign({}, data);
249
- for (const key in defaults) if (result[key] == null) result[key] = defaults[key];
250
- return result;
251
- }
252
- //#endregion
253
- //#region src/operations/findOne.ts
254
- function findOne_default(query, options) {
255
- query = queryParser(this, query);
256
- const operation = async () => {
257
- let result = await this.mapper.get(query);
258
- if (!result) return null;
259
- result = this._wrap(result);
260
- if (options?.raw === true) return result.toRaw();
261
- return result;
262
- };
263
- return this.driver.executeWithRetry(operation, `findOne on ${this.name}`);
264
- }
265
- //#endregion
266
- //#region src/operations/find.ts
267
- async function findOP(query = {}, options) {
268
- const { $limit, $orderby, ...rest } = query;
269
- let parsedQuery = queryParser(this, rest);
270
- const docInfo = {};
271
- if ($limit !== void 0) {
272
- if (typeof $limit !== "number" || $limit <= 0) throw new TypeError(`{$limit} operator must be a number greater than 0`);
273
- docInfo.limit = $limit;
274
- }
275
- if ($orderby !== void 0) docInfo.orderBy = $orderby;
276
- const operation = async () => {
277
- const rows = (await this.mapper.find(parsedQuery, docInfo)).toArray();
278
- if (options?.raw === true) return rows;
279
- return rows.map((row) => this._wrap(row));
280
- };
281
- return this.driver.executeWithRetry(operation, `find on ${this.name}`);
282
- }
283
- //#endregion
284
- //#region src/operations/update.ts
285
- async function update_default(query) {
286
- query = fillDefaults(this.schema, query);
287
- typeChecker(this, query);
288
- if (typeof query.__v !== "undefined") if (Number.isNaN(query.__v)) query.__v = 0;
289
- else query.__v = query.__v + 1;
290
- const operation = async () => {
291
- await this.mapper.update(query);
292
- return this._wrap(query);
293
- };
294
- return this.driver.executeWithRetry(operation, `update on ${this.name}`);
295
- }
296
- //#endregion
297
- //#region src/operations/delete.ts
298
- async function delete_default(query) {
299
- const operation = async () => {
300
- return await this.mapper.remove(query);
301
- };
302
- return this.driver.executeWithRetry(operation, `delete on ${this.name}`);
303
- }
304
- //#endregion
305
- //#region src/operations/countAll.ts
306
- async function countAll_default(timeoutMs = 6e4) {
307
- const cql = `SELECT COUNT(1) FROM ${this.driver.config.keyspace}.${this.schema.table_name}`;
308
- const queryOptions = {
309
- prepare: true,
310
- readTimeout: timeoutMs
311
- };
312
- const operation = async () => {
313
- return (await this.driver.client.execute(cql, [], queryOptions)).rows[0].count.toNumber();
314
- };
315
- return this.driver.executeWithRetry(operation, `countAll on ${this.name}`);
316
- }
317
- //#endregion
318
- //#region src/operations/tableExists.ts
319
- async function tableExists_default() {
320
- const cql = `
321
- SELECT table_name
322
- FROM system_schema.tables
323
- WHERE keyspace_name = ?
324
- AND table_name = ?
325
- `;
326
- try {
327
- return (await this.driver.client.execute(cql, [this.driver.config.keyspace, this.schema.table_name], { prepare: true })).rows.length > 0;
328
- } catch (error) {
329
- console.error(`Failed to check if table "${this.schema.table_name}" exists:`, error);
330
- return false;
331
- }
332
- }
333
- //#endregion
334
- //#region src/cql_gen/create_table.ts
335
- function create_table_default(model) {
336
- const desc = model.schema;
337
- const tableName = desc.table_name;
338
- const keyspace = model.driver.config.keyspace;
339
- const fields = desc.fields;
340
- const key = desc.keys;
341
- const clusteringOrder = desc.clustering_order;
342
- let columnsDef = "";
343
- for (const fieldName in fields) {
344
- const field = fields[fieldName];
345
- const typeStr = typeof field === "string" ? field : field?.type;
346
- if (!typeStr) throw new Error(`Invalid field type for "${fieldName}" in model "${tableName}"`);
347
- columnsDef += `"${fieldName}" ${typeStr.toUpperCase()}, `;
348
- }
349
- let pkDef = "";
350
- if (typeof key === "string") pkDef = `"${key}"`;
351
- else if (Array.isArray(key) && key.length > 0) {
352
- const first = key[0];
353
- if (Array.isArray(first)) pkDef = `(${first.map((k) => `"${k}"`).join(", ")})`;
354
- else pkDef = `"${first}"`;
355
- for (let i = 1; i < key.length; i++) pkDef += `, "${key[i]}"`;
356
- } else throw new Error(`Missing or invalid primary key in model "${tableName}"`);
357
- let clusterClause = "";
358
- if (clusteringOrder) {
359
- let orderDef = "";
360
- for (const col in clusteringOrder) {
361
- if (orderDef !== "") orderDef += ", ";
362
- orderDef += `"${col}" ${clusteringOrder[col].toUpperCase()}`;
363
- }
364
- if (orderDef !== "") clusterClause = ` WITH CLUSTERING ORDER BY (${orderDef})`;
365
- }
366
- return `CREATE TABLE IF NOT EXISTS ${keyspace}.${tableName} (${columnsDef}PRIMARY KEY (${pkDef}))${clusterClause}`;
367
- }
368
- //#endregion
369
- //#region src/operations/sync.ts
370
- async function syncOP() {
371
- if (await this._tableExists()) return;
372
- try {
373
- await this.driver.client.execute(create_table_default(this));
374
- console.log(`Table "${this.schema.table_name}" created successfully`);
375
- } catch (error) {
376
- console.error(`Failed to create table "${this.schema.table_name}":`, error);
377
- throw error;
378
- }
379
- }
380
- //#endregion
381
- //#region src/model/index.ts
382
- var Model = class {
383
- name;
384
- schema;
385
- driver;
386
- mapper;
387
- constructor(name, schema) {
388
- this.name = name;
389
- this.schema = schema;
390
- if (!Array.isArray(this.schema.keys)) throw new Error(`[${this.name}] model has missing "keys" array`);
391
- if (!this.schema.table_name) throw new Error(`[${this.name}] model has missing "table_name"`);
392
- if (!this.schema.fields || typeof this.schema.fields !== "object") throw new Error(`[${this.name}] model has missing or invalid "fields"`);
393
- }
394
- create = (data) => this._wrap(data);
395
- find = findOP.bind(this);
396
- findOne = findOne_default.bind(this);
397
- update = update_default.bind(this);
398
- delete = delete_default.bind(this);
399
- countAll = countAll_default.bind(this);
400
- _sync = syncOP.bind(this);
401
- _tableExists = tableExists_default.bind(this);
402
- _wrap(row) {
403
- if (!row) return null;
404
- row = fillDefaults(this.schema, row);
405
- return new Result(row, this);
406
- }
407
- _connect(driver) {
408
- this.driver = driver;
409
- this.mapper = driver.mapper.forModel(this.name);
410
- }
411
- };
412
- //#endregion
1
+ import { Model } from "./model/index.mjs";
2
+ import { Client } from "./client.mjs";
3
+ import { Schema } from "./schema/index.mjs";
413
4
  //#region src/index.ts
414
- const DEFAULT_MAX_RETRIES = 3;
415
- const DEFAULT_RETRY_DELAY = 1e3;
416
- const { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } = process.env;
417
- var ScyllaClient = class {
418
- constructor(config = {}) {
419
- this.config = {
420
- modelsPath: path.resolve(process.cwd(), "db"),
421
- contactPoints: config.contactPoints ?? SCYLLA_CONTACT_POINTS ? SCYLLA_CONTACT_POINTS.split(",") : ["127.0.0.1"],
422
- localDataCenter: config.localDataCenter ?? SCYLLA_LOCAL_DATA_CENTER ?? "datacenter1",
423
- keyspace: config.keyspace ?? SCYLLA_KEYSPACE ?? "default",
424
- port: 9042,
425
- maxRetries: DEFAULT_MAX_RETRIES,
426
- retryDelay: DEFAULT_RETRY_DELAY,
427
- ...config
428
- };
429
- const clientOptions = {
430
- contactPoints: this.config.contactPoints,
431
- localDataCenter: this.config.localDataCenter,
432
- keyspace: this.config.keyspace,
433
- protocolOptions: { port: this.config.port }
434
- };
435
- if (this.config.pooling) clientOptions.pooling = this.config.pooling;
436
- this.client = new Cassandra.Client(clientOptions);
437
- }
438
- config;
439
- client;
440
- mapper;
441
- models = /* @__PURE__ */ new Map();
442
- async initialize(options = {}) {
443
- let models;
444
- try {
445
- models = await loadModels_default(this.config.modelsPath);
446
- } catch (error) {
447
- throw new Error(`Failed to load models: ${error.message}`);
448
- }
449
- models = models.filter((schema) => schema instanceof Model);
450
- this.mapper = new Cassandra.mapping.Mapper(this.client, { models: buildMapper_default(models) });
451
- for (let model of models) {
452
- model._connect(this);
453
- this.models.set(model.name, model);
454
- if (options?.sync === true) await model._sync();
455
- }
456
- console.log("Connecting to ScyllaDB");
457
- await this.connectWithRetry();
458
- console.log("ScyllaDB Connected");
459
- }
460
- async connectWithRetry() {
461
- let lastError = null;
462
- for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) try {
463
- await this.client.connect();
464
- return;
465
- } catch (error) {
466
- lastError = error;
467
- console.warn(`Connection attempt ${attempt} failed: ${error.message}`);
468
- if (attempt < this.config.maxRetries) {
469
- console.log(`Retrying in ${this.config.retryDelay}ms...`);
470
- await this.delay(this.config.retryDelay);
471
- }
472
- }
473
- throw new Error(`Failed to connect to ScyllaDB after ${this.config.maxRetries} attempts: ${lastError?.message}`);
474
- }
475
- delay(ms) {
476
- return new Promise((resolve) => setTimeout(resolve, ms));
477
- }
478
- async shutdown() {
479
- try {
480
- await this.client.shutdown();
481
- console.log("ScyllaDB connection closed");
482
- } catch (error) {
483
- console.error("Error shutting down ScyllaDB connection:", error);
484
- throw error;
485
- }
486
- }
487
- async executeWithRetry(operation, operationName = "operation") {
488
- let lastError = null;
489
- for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) try {
490
- return await operation();
491
- } catch (error) {
492
- lastError = error;
493
- if (this.isRetryableError(error) && attempt < this.config.maxRetries) {
494
- console.warn(`Operation ${operationName} attempt ${attempt} failed: ${error.message}`);
495
- console.log(`Retrying in ${this.config.retryDelay}ms...`);
496
- await this.delay(this.config.retryDelay);
497
- continue;
498
- }
499
- throw error;
500
- }
501
- throw new Error(`Operation ${operationName} failed after ${this.config.maxRetries} attempts: ${lastError?.message}`);
502
- }
503
- isRetryableError(error) {
504
- const retryableMessages = [
505
- "timeout",
506
- "connection",
507
- "network",
508
- "unavailable",
509
- "overloaded",
510
- "no hosts available"
511
- ];
512
- const errorMessage = error.message?.toLowerCase() || "";
513
- return retryableMessages.some((msg) => errorMessage.includes(msg));
514
- }
515
- };
5
+ var src_default = Client;
516
6
  //#endregion
517
- export { ScyllaClient as default };
7
+ export { Client, Model, Schema, src_default as default };
518
8
 
519
9
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["cassandra","cassandra","generateCreateTableCQL","findOneOP","updateOP","deleteOP","countAllOP","tableExistsOP","loadModels","buildMapper"],"sources":["../src/utils/loadModels.ts","../src/utils/buildMapper.ts","../src/utils/queryParser.ts","../src/utils/typeChecker.ts","../src/result/index.ts","../src/utils/fillDefaults.ts","../src/operations/findOne.ts","../src/operations/find.ts","../src/operations/update.ts","../src/operations/delete.ts","../src/operations/countAll.ts","../src/operations/tableExists.ts","../src/cql_gen/create_table.ts","../src/operations/sync.ts","../src/model/index.ts","../src/index.ts"],"sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\n\nexport default async (fromPath: string): Promise<any[]> => {\n\tif (typeof fromPath !== \"string\") {\n\t\treturn []\n\t}\n\n\tif (!fs.existsSync(fromPath)) {\n\t\tconsole.warn(\n\t\t\t`Cannot load models from [${fromPath}] case this path does not exist`,\n\t\t)\n\t\treturn []\n\t}\n\n\tlet mods = []\n\n\tlet files = await fs.promises.readdir(fromPath)\n\n\tfiles = files.filter((file) => file.endsWith(\".js\") || file.endsWith(\".ts\"))\n\n\tfor await (const file of files) {\n\t\tconst name = file.replace(\".js\", \"\")\n\t\tconst file_path = path.join(fromPath, file)\n\n\t\ttry {\n\t\t\tlet mod = await import(file_path)\n\n\t\t\tmod = mod.default\n\n\t\t\tmods.push(mod)\n\t\t} catch (error) {\n\t\t\tconsole.error(`Failed to load model [${name}]:`, error)\n\t\t\tcontinue\n\t\t}\n\t}\n\n\treturn mods\n}\n","export default (map) => {\n\treturn map.reduce((obj, { name, schema }) => {\n\t\treturn {\n\t\t\t...obj,\n\t\t\t[name]: {\n\t\t\t\ttables: [schema.table_name],\n\t\t\t},\n\t\t}\n\t}, {})\n}\n","import type { Model } from \"../model\"\n\n// @ts-ignore\nimport cassandra from \"cassandra-driver\"\nconst { q } = cassandra.mapping\n\nconst MAX_QUERY_DEPTH = 3\nconst MAX_IN_ELEMENTS = 1000\n\nconst VALID_OPERATORS = new Set([\n\t\"$eq\",\n\t\"$ne\",\n\t\"$gt\",\n\t\"$gte\",\n\t\"$lt\",\n\t\"$lte\",\n\t\"$in\",\n])\n\nfunction requireNotNull(value: any, operator: string): void {\n\tif (value === null || value === undefined) {\n\t\tthrow new Error(\n\t\t\t`${operator} operator cannot compare with null or undefined`,\n\t\t)\n\t}\n}\n\nfunction buildOperator(operator: string, opValue: any): any {\n\tif (!VALID_OPERATORS.has(operator)) {\n\t\tthrow new Error(`Invalid operator: ${operator}`)\n\t}\n\n\tswitch (operator) {\n\t\tcase \"$eq\":\n\t\t\treturn opValue\n\n\t\tcase \"$ne\":\n\t\t\trequireNotNull(opValue, \"$ne\")\n\t\t\treturn q.notEq(opValue)\n\n\t\tcase \"$in\":\n\t\t\tif (!Array.isArray(opValue)) {\n\t\t\t\tthrow new Error(\"$in operator requires an array\")\n\t\t\t}\n\t\t\tif (opValue.length > MAX_IN_ELEMENTS) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`$in operator exceeds maximum of ${MAX_IN_ELEMENTS} elements`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tfor (let i = 0; i < opValue.length; i++) {\n\t\t\t\tif (opValue[i] === null || opValue[i] === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`$in array element at index ${i} cannot be null or undefined`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn q.in_(opValue)\n\n\t\tcase \"$gt\":\n\t\t\trequireNotNull(opValue, \"$gt\")\n\t\t\treturn q.gt(opValue)\n\n\t\tcase \"$gte\":\n\t\t\trequireNotNull(opValue, \"$gte\")\n\t\t\treturn q.gte(opValue)\n\n\t\tcase \"$lt\":\n\t\t\trequireNotNull(opValue, \"$lt\")\n\t\t\treturn q.lt(opValue)\n\n\t\tcase \"$lte\":\n\t\t\trequireNotNull(opValue, \"$lte\")\n\t\t\treturn q.lte(opValue)\n\t}\n}\n\nexport default function queryParser(\n\tmodel: Model<any>,\n\tquery: any,\n\tdepth: number = 0,\n) {\n\tif (depth > MAX_QUERY_DEPTH) {\n\t\tthrow new Error(`Query depth exceeds maximum of ${MAX_QUERY_DEPTH}`)\n\t}\n\n\tif (!query || typeof query !== \"object\") {\n\t\treturn query\n\t}\n\n\tconst parsedQuery: Record<string, any> = {}\n\tconst fields = model.schema.fields\n\n\tfor (const field of Object.keys(query)) {\n\t\tconst value = query[field]\n\n\t\tif (field === \"$and\") {\n\t\t\thandleAnd(model, value, parsedQuery, depth)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (field === \"$or\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"ScyllaDB does not support OR queries across different columns. Use $in for a single column.\",\n\t\t\t)\n\t\t}\n\n\t\tif (!isValidFieldName(fields, field)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid field name: [${field}] or it does not exist in schema`,\n\t\t\t)\n\t\t}\n\n\t\tparsedQuery[field] = parseField(value)\n\t}\n\n\treturn parsedQuery\n}\n\nfunction handleAnd(\n\tmodel: Model<any>,\n\tconditions: any,\n\tparsedQuery: Record<string, any>,\n\tdepth: number,\n) {\n\tif (!Array.isArray(conditions)) {\n\t\tthrow new Error(\"$and operator requires an array\")\n\t}\n\tif (conditions.length > 10) {\n\t\tthrow new Error(\"$and operator exceeds maximum of 10 conditions\")\n\t}\n\n\tfor (let i = 0; i < conditions.length; i++) {\n\t\tconst condition = conditions[i]\n\t\tif (!condition || typeof condition !== \"object\") {\n\t\t\tthrow new Error(`$and condition at index ${i} must be an object`)\n\t\t}\n\n\t\tconst parsed = queryParser(model, condition, depth + 1)\n\t\tfor (const key of Object.keys(parsed)) {\n\t\t\tif (key in parsedQuery) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`$and conflict: field \"${key}\" appears in multiple conditions`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tObject.assign(parsedQuery, parsed)\n\t}\n}\n\nfunction parseField(value: any): any {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value !== \"object\" ||\n\t\tArray.isArray(value) ||\n\t\tvalue instanceof Date\n\t) {\n\t\tif (Array.isArray(value)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Array values require explicit operator (e.g., $in)\",\n\t\t\t)\n\t\t}\n\t\treturn value\n\t}\n\n\tconst operators = Object.keys(value)\n\tconst compiledOps = operators.map((op) => buildOperator(op, value[op]))\n\n\treturn compiledOps.length === 1\n\t\t? compiledOps[0]\n\t\t: (q.and as any)(...compiledOps)\n}\n\nexport function isValidFieldName(\n\tfields: Record<string, any>,\n\tfieldName: string,\n): boolean {\n\tconst invalidPatterns = [\n\t\t/^[0-9]/,\n\t\t/[^a-zA-Z0-9_]/,\n\t\t/^(select|insert|update|delete|drop|create|alter|truncate)$/i,\n\t]\n\n\tfor (const pattern of invalidPatterns) {\n\t\tif (pattern.test(fieldName)) return false\n\t}\n\n\treturn fieldName in fields\n}\n\nexport function isValidOperator(operator: string): boolean {\n\treturn VALID_OPERATORS.has(operator)\n}\n","// @ts-ignore\nimport cassandra from \"cassandra-driver\"\nconst { types } = cassandra\nimport type { Model } from \"../model\"\nimport { isValidFieldName } from \"./queryParser\"\n\nconst stringTypes = new Set([\"ascii\", \"text\", \"varchar\", \"inet\"])\nconst intTypes = new Set([\"int\", \"smallint\", \"tinyint\"])\nconst floatTypes = new Set([\"double\", \"float\"])\nconst longTypes = new Set([\"bigint\", \"counter\"])\n\nfunction isValidValue(value: any, expectedType: string): boolean {\n\tif (value === null || value === undefined) return true\n\n\tif (stringTypes.has(expectedType)) return typeof value === \"string\"\n\tif (intTypes.has(expectedType)) return Number.isInteger(value)\n\tif (floatTypes.has(expectedType)) return typeof value === \"number\"\n\tif (longTypes.has(expectedType)) {\n\t\treturn (\n\t\t\ttypeof value === \"bigint\" ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\tvalue instanceof types.Long\n\t\t)\n\t}\n\n\tswitch (expectedType) {\n\t\tcase \"boolean\":\n\t\t\treturn typeof value === \"boolean\"\n\t\tcase \"decimal\":\n\t\t\treturn (\n\t\t\t\ttypeof value === \"number\" ||\n\t\t\t\ttypeof value === \"string\" ||\n\t\t\t\tvalue instanceof types.BigDecimal\n\t\t\t)\n\t\tcase \"varint\":\n\t\t\treturn (\n\t\t\t\ttypeof value === \"bigint\" ||\n\t\t\t\ttypeof value === \"number\" ||\n\t\t\t\tvalue instanceof types.Integer\n\t\t\t)\n\t\tcase \"timestamp\":\n\t\t\treturn (\n\t\t\t\tvalue instanceof Date ||\n\t\t\t\ttypeof value === \"number\" ||\n\t\t\t\ttypeof value === \"string\"\n\t\t\t)\n\t\tcase \"date\":\n\t\t\treturn typeof value === \"string\" || value instanceof types.LocalDate\n\t\tcase \"time\":\n\t\t\treturn typeof value === \"string\" || value instanceof types.LocalTime\n\t\tcase \"uuid\":\n\t\t\treturn typeof value === \"string\" || value instanceof types.Uuid\n\t\tcase \"timeuuid\":\n\t\t\treturn typeof value === \"string\" || value instanceof types.TimeUuid\n\t\tcase \"blob\":\n\t\t\treturn Buffer.isBuffer(value) || value instanceof Uint8Array\n\t}\n\n\tif (expectedType.startsWith(\"list<\") || expectedType.startsWith(\"set<\")) {\n\t\treturn Array.isArray(value) || value instanceof Set\n\t}\n\tif (expectedType.startsWith(\"map<\")) {\n\t\treturn (\n\t\t\ttypeof value === \"object\" && !Array.isArray(value) && value !== null\n\t\t)\n\t}\n\n\treturn false\n}\n\nexport default function typeChecker(model: Model<any>, data: any): boolean {\n\tif (!data || typeof data !== \"object\" || Array.isArray(data)) {\n\t\tthrow new TypeError(\n\t\t\t`[${model.name}] Validation error: Data payload must be an object`,\n\t\t)\n\t}\n\n\tconst fields = model.schema.fields\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (!isValidFieldName(fields, key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[${model.name}] Validation error: Field '${key}' does not exist in schema`,\n\t\t\t)\n\t\t}\n\n\t\tconst fieldConfig = fields[key]\n\t\tconst expectedType = (fieldConfig.type || \"text\").toLowerCase()\n\n\t\tif (!isValidValue(value, expectedType)) {\n\t\t\tconst receivedType = Array.isArray(value) ? \"array\" : typeof value\n\t\t\tthrow new TypeError(\n\t\t\t\t`[${model.name}] Validation error: Invalid type for field '${key}'. ` +\n\t\t\t\t\t`Expected[${expectedType}], but received [${receivedType}]`,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn true\n}\n","import type { Model } from \"../model\"\nimport typeChecker from \"../utils/typeChecker\"\n\nexport class Result<TDoc = any> {\n\tconstructor(data: TDoc, model: Model<TDoc>) {\n\t\tif (data == null) {\n\t\t\tthrow new Error(\"Cannot create Result with null or undefined data\")\n\t\t}\n\n\t\tif (typeof data !== \"object\" || Array.isArray(data)) {\n\t\t\tthrow new Error(\"Result data must be an object\")\n\t\t}\n\n\t\tObject.assign(this, data)\n\n\t\tObject.defineProperty(this, \"_model\", {\n\t\t\tvalue: model,\n\t\t\tenumerable: false,\n\t\t\twritable: false,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\t_model: Model<TDoc>\n\n\tasync save() {\n\t\ttry {\n\t\t\tconst data = this.toRaw()\n\n\t\t\ttypeChecker(this._model, data)\n\n\t\t\treturn await this._model.update(data as any)\n\t\t} catch (error: any) {\n\t\t\tthrow new Error(`Failed to save result: ${error.message}`)\n\t\t}\n\t}\n\n\tasync delete() {\n\t\ttry {\n\t\t\treturn await this._model.delete(this.toRaw() as any)\n\t\t} catch (error: any) {\n\t\t\tthrow new Error(`Failed to delete result: ${error.message}`)\n\t\t}\n\t}\n\n\ttoRaw(): TDoc {\n\t\tconst raw: any = {}\n\n\t\tfor (const key in this) {\n\t\t\tif (key === \"_model\") continue\n\n\t\t\tif (this.propertyIsEnumerable(key)) {\n\t\t\t\tconst value = (this as any)[key]\n\n\t\t\t\ttry {\n\t\t\t\t\tJSON.stringify(value)\n\t\t\t\t\traw[key] = value\n\t\t\t\t} catch (error) {\n\t\t\t\t\traw[key] = String(value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn raw as TDoc\n\t}\n\n\tisValid(): boolean {\n\t\ttry {\n\t\t\ttypeChecker(this._model, this.toRaw())\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tgetChangedFields(original: Partial<TDoc>): (keyof TDoc)[] {\n\t\tconst current = this.toRaw() as Record<string, any>\n\t\tconst changed: (keyof TDoc)[] = []\n\n\t\tfor (const key in current) {\n\t\t\tif (!(key in original) || current[key] !== (original as any)[key]) {\n\t\t\t\tchanged.push(key as keyof TDoc)\n\t\t\t}\n\t\t}\n\n\t\treturn changed\n\t}\n}\n\nexport default Result\n","export default function fillDefaults(schema: any, data: any) {\n\tconst defaults = schema.options?.defaults\n\n\tif (!defaults || Object.keys(defaults).length === 0) {\n\t\treturn data\n\t}\n\n\tlet needsDefaults = false\n\n\tfor (const key in defaults) {\n\t\tif (data[key] == null) {\n\t\t\tneedsDefaults = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (!needsDefaults) {\n\t\treturn data\n\t}\n\n\tconst result = Object.assign({}, data)\n\n\tfor (const key in defaults) {\n\t\tif (result[key] == null) {\n\t\t\tresult[key] = defaults[key]\n\t\t}\n\t}\n\n\treturn result\n}\n","import type { QueryOptions } from \"../types\"\nimport type Model from \"../model\"\nimport queryParser from \"../utils/queryParser\"\n\nexport default function (this: Model, query: any, options?: QueryOptions) {\n\tquery = queryParser(this, query)\n\n\tconst operation = async () => {\n\t\tlet result = await this.mapper.get(query)\n\n\t\tif (!result) {\n\t\t\treturn null\n\t\t}\n\n\t\tresult = this._wrap(result)\n\n\t\tif (options?.raw === true) {\n\t\t\treturn result.toRaw()\n\t\t}\n\n\t\treturn result\n\t}\n\n\treturn this.driver.executeWithRetry(operation, `findOne on ${this.name}`)\n}\n","import type Model from \"../model\"\nimport type { mapping } from \"cassandra-driver/lib/mapping\"\nimport type { Query, QueryOptions } from \"../types\"\nimport queryParser from \"../utils/queryParser\"\n\nexport default async function findOP<TDoc>(\n\tthis: Model<TDoc>,\n\tquery: Query<TDoc> = {},\n\toptions?: QueryOptions,\n) {\n\tconst { $limit, $orderby, ...rest } = query\n\n\tlet parsedQuery = queryParser(this, rest)\n\n\tconst docInfo: mapping.FindDocInfo = {}\n\n\tif ($limit !== undefined) {\n\t\tif (typeof $limit !== \"number\" || $limit <= 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`{$limit} operator must be a number greater than 0`,\n\t\t\t)\n\t\t}\n\t\tdocInfo.limit = $limit\n\t}\n\n\tif ($orderby !== undefined) {\n\t\tdocInfo.orderBy = $orderby as Record<string, \"asc\" | \"desc\">\n\t}\n\n\tconst operation = async () => {\n\t\tconst result = await this.mapper.find(parsedQuery, docInfo)\n\t\tconst rows = result.toArray()\n\n\t\tif (options?.raw === true) {\n\t\t\treturn rows\n\t\t}\n\n\t\treturn rows.map((row) => this._wrap(row))\n\t}\n\n\treturn this.driver.executeWithRetry(operation, `find on ${this.name}`)\n}\n","import type Model from \"../model\"\nimport fillDefaults from \"../utils/fillDefaults\"\nimport typeChecker from \"../utils/typeChecker\"\n\nexport default async function (this: Model, query: any) {\n\tquery = fillDefaults(this.schema, query)\n\n\ttypeChecker(this, query)\n\n\tif (typeof query.__v !== \"undefined\") {\n\t\tif (Number.isNaN(query.__v)) {\n\t\t\tquery.__v = 0\n\t\t} else {\n\t\t\tquery.__v = query.__v + 1\n\t\t}\n\t}\n\n\tconst operation = async () => {\n\t\tawait this.mapper.update(query)\n\t\treturn this._wrap(query)\n\t}\n\n\treturn this.driver.executeWithRetry(operation, `update on ${this.name}`)\n}\n","import type Model from \"../model\"\n\nexport default async function (this: Model, query: any) {\n\tconst operation = async () => {\n\t\treturn await this.mapper.remove(query)\n\t}\n\n\treturn this.driver.executeWithRetry(operation, `delete on ${this.name}`)\n}\n","import type Model from \"../model\"\n\nexport default async function (this: Model, timeoutMs: number = 60000) {\n\tconst cql = `SELECT COUNT(1) FROM ${this.driver.config.keyspace}.${this.schema.table_name}`\n\n\tconst queryOptions = {\n\t\tprepare: true,\n\t\treadTimeout: timeoutMs,\n\t}\n\n\tconst operation = async () => {\n\t\tconst result = await this.driver.client.execute(cql, [], queryOptions)\n\n\t\treturn result.rows[0].count.toNumber()\n\t}\n\n\treturn this.driver.executeWithRetry(operation, `countAll on ${this.name}`)\n}\n","import type Model from \"../model\"\n\nexport default async function (this: Model) {\n\tconst cql = `\n\t\t\tSELECT table_name\n\t\t\tFROM system_schema.tables\n\t\t\tWHERE keyspace_name = ?\n\t\t\tAND table_name = ?\n\t\t`\n\n\ttry {\n\t\tconst result = await this.driver.client.execute(\n\t\t\tcql,\n\t\t\t[this.driver.config.keyspace, this.schema.table_name],\n\t\t\t{\n\t\t\t\tprepare: true,\n\t\t\t},\n\t\t)\n\n\t\treturn result.rows.length > 0\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Failed to check if table \"${this.schema.table_name}\" exists:`,\n\t\t\terror,\n\t\t)\n\n\t\treturn false\n\t}\n}\n","import type Model from \"../model\"\n\nexport default function (model: Model): string {\n\tconst desc = model.schema\n\tconst tableName = desc.table_name\n\tconst keyspace = model.driver.config.keyspace\n\tconst fields = desc.fields\n\tconst key = desc.keys\n\tconst clusteringOrder = desc.clustering_order\n\n\tlet columnsDef = \"\"\n\n\tfor (const fieldName in fields) {\n\t\tconst field = fields[fieldName]\n\t\tconst typeStr = typeof field === \"string\" ? field : (field as any)?.type\n\n\t\tif (!typeStr) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid field type for \"${fieldName}\" in model \"${tableName}\"`,\n\t\t\t)\n\t\t}\n\n\t\tcolumnsDef += `\"${fieldName}\" ${typeStr.toUpperCase()}, `\n\t}\n\n\tlet pkDef = \"\"\n\n\tif (typeof key === \"string\") {\n\t\tpkDef = `\"${key}\"`\n\t} else if (Array.isArray(key) && key.length > 0) {\n\t\tconst first = key[0]\n\n\t\tif (Array.isArray(first)) {\n\t\t\tpkDef = `(${first.map((k) => `\"${k}\"`).join(\", \")})`\n\t\t} else {\n\t\t\tpkDef = `\"${first}\"`\n\t\t}\n\n\t\tfor (let i = 1; i < key.length; i++) {\n\t\t\tpkDef += `, \"${key[i]}\"`\n\t\t}\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Missing or invalid primary key in model \"${tableName}\"`,\n\t\t)\n\t}\n\n\tlet clusterClause = \"\"\n\n\tif (clusteringOrder) {\n\t\tlet orderDef = \"\"\n\n\t\tfor (const col in clusteringOrder) {\n\t\t\tif (orderDef !== \"\") {\n\t\t\t\torderDef += \", \"\n\t\t\t}\n\n\t\t\torderDef += `\"${col}\" ${(clusteringOrder[col] as string).toUpperCase()}`\n\t\t}\n\t\tif (orderDef !== \"\") {\n\t\t\tclusterClause = ` WITH CLUSTERING ORDER BY (${orderDef})`\n\t\t}\n\t}\n\n\treturn `CREATE TABLE IF NOT EXISTS ${keyspace}.${tableName} (${columnsDef}PRIMARY KEY (${pkDef}))${clusterClause}`\n}\n","import type Model from \"../model\"\nimport generateCreateTableCQL from \"../cql_gen/create_table\"\n\nexport default async function syncOP(this: Model) {\n\tconst tableExists = await this._tableExists()\n\n\tif (tableExists) {\n\t\treturn\n\t}\n\n\ttry {\n\t\tawait this.driver.client.execute(generateCreateTableCQL(this))\n\n\t\tconsole.log(`Table \"${this.schema.table_name}\" created successfully`)\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Failed to create table \"${this.schema.table_name}\":`,\n\t\t\terror,\n\t\t)\n\t\tthrow error\n\t}\n}\n","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","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 default class ScyllaClient {\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"],"mappings":"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"}
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"}
@@ -0,0 +1,38 @@
1
+ import { Schema } from "../schema/index.mjs";
2
+ import export_default from "../operations/tableExists.mjs";
3
+ import syncOP from "../operations/sync.mjs";
4
+ import { DocumentResult, Query, QueryOptions } from "../types.mjs";
5
+ import { Client } from "../client.mjs";
6
+ import { mapping } from "cassandra-driver/lib/mapping/index.js";
7
+
8
+ //#region src/model/index.d.ts
9
+ declare class Model<TDoc = any> {
10
+ name: string;
11
+ schema: Schema<any>;
12
+ driver: Client;
13
+ mapper: mapping.ModelMapper;
14
+ constructor(name: string, schema: Schema<any>);
15
+ create: (data: Partial<TDoc>) => DocumentResult<TDoc>;
16
+ find: {
17
+ (query: Query<TDoc>, options: QueryOptions & {
18
+ raw: true;
19
+ }): Promise<TDoc[]>;
20
+ (query?: Query<TDoc>, options?: QueryOptions): Promise<DocumentResult<TDoc>[]>;
21
+ };
22
+ findOne: {
23
+ (query: Query<TDoc>, options: QueryOptions & {
24
+ raw: true;
25
+ }): Promise<TDoc>;
26
+ (query?: Query<TDoc>, options?: QueryOptions): Promise<DocumentResult<TDoc>>;
27
+ };
28
+ update: (query: Query<TDoc>) => Promise<DocumentResult<TDoc>>;
29
+ delete: (query: Query<TDoc>) => Promise<mapping.Result>;
30
+ countAll: () => Promise<number>;
31
+ _sync: typeof syncOP;
32
+ _tableExists: typeof export_default;
33
+ _wrap(row: any): DocumentResult<TDoc> | null;
34
+ _connect(driver: Client): void;
35
+ }
36
+ //#endregion
37
+ export { Model, Model as default };
38
+ //# sourceMappingURL=index.d.mts.map