@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.
- package/dist/client.d.mts +23 -0
- package/dist/client.mjs +112 -0
- package/dist/client.mjs.map +1 -0
- package/dist/cql_gen/create_table.d.mts +7 -0
- package/dist/cql_gen/create_table.mjs +38 -0
- package/dist/cql_gen/create_table.mjs.map +1 -0
- package/dist/index.d.mts +4 -113
- package/dist/index.mjs +5 -515
- package/dist/index.mjs.map +1 -1
- package/dist/model/index.d.mts +38 -0
- package/dist/model/index.mjs +44 -0
- package/dist/model/index.mjs.map +1 -0
- package/dist/operations/countAll.d.mts +7 -0
- package/dist/operations/countAll.mjs +16 -0
- package/dist/operations/countAll.mjs.map +1 -0
- package/dist/operations/delete.d.mts +8 -0
- package/dist/operations/delete.mjs +11 -0
- package/dist/operations/delete.mjs.map +1 -0
- package/dist/operations/find.d.mts +8 -0
- package/dist/operations/find.mjs +22 -0
- package/dist/operations/find.mjs.map +1 -0
- package/dist/operations/findOne.d.mts +8 -0
- package/dist/operations/findOne.mjs +17 -0
- package/dist/operations/findOne.mjs.map +1 -0
- package/dist/operations/sync.d.mts +7 -0
- package/dist/operations/sync.mjs +16 -0
- package/dist/operations/sync.mjs.map +1 -0
- package/dist/operations/tableExists.d.mts +7 -0
- package/dist/operations/tableExists.mjs +19 -0
- package/dist/operations/tableExists.mjs.map +1 -0
- package/dist/operations/update.d.mts +7 -0
- package/dist/operations/update.mjs +18 -0
- package/dist/operations/update.mjs.map +1 -0
- package/dist/result/index.d.mts +17 -0
- package/dist/result/index.mjs +66 -0
- package/dist/result/index.mjs.map +1 -0
- package/dist/schema/index.d.mts +13 -0
- package/dist/schema/index.mjs +16 -0
- package/dist/schema/index.mjs.map +1 -0
- package/dist/types.d.mts +74 -0
- package/dist/types.mjs +34 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils/buildMapper.d.mts +5 -0
- package/dist/utils/buildMapper.mjs +13 -0
- package/dist/utils/buildMapper.mjs.map +1 -0
- package/dist/utils/fillDefaults.d.mts +5 -0
- package/dist/utils/fillDefaults.mjs +18 -0
- package/dist/utils/fillDefaults.mjs.map +1 -0
- package/dist/utils/loadModels.d.mts +5 -0
- package/dist/utils/loadModels.mjs +30 -0
- package/dist/utils/loadModels.mjs.map +1 -0
- package/dist/utils/queryParser.d.mts +9 -0
- package/dist/utils/queryParser.mjs +94 -0
- package/dist/utils/queryParser.mjs.map +1 -0
- package/dist/utils/typeChecker.d.mts +7 -0
- package/dist/utils/typeChecker.mjs +55 -0
- package/dist/utils/typeChecker.mjs.map +1 -0
- package/package.json +40 -4
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Model } from "./model/index.mjs";
|
|
2
|
+
import { ClientConfig } from "./types.mjs";
|
|
3
|
+
import { Client as Client$1, mapping } from "cassandra-driver";
|
|
4
|
+
|
|
5
|
+
//#region src/client.d.ts
|
|
6
|
+
declare class Client {
|
|
7
|
+
constructor(config?: ClientConfig);
|
|
8
|
+
config: ClientConfig;
|
|
9
|
+
client: Client$1;
|
|
10
|
+
mapper: mapping.Mapper;
|
|
11
|
+
models: Map<string, Model<any>>;
|
|
12
|
+
initialize(options?: {
|
|
13
|
+
sync?: boolean;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
private connectWithRetry;
|
|
16
|
+
private delay;
|
|
17
|
+
shutdown(): Promise<void>;
|
|
18
|
+
executeWithRetry<T>(operation: () => Promise<T>, operationName?: string): Promise<T>;
|
|
19
|
+
private isRetryableError;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Client, Client as default };
|
|
23
|
+
//# sourceMappingURL=client.d.mts.map
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import loadModels_default from "./utils/loadModels.mjs";
|
|
2
|
+
import buildMapper_default from "./utils/buildMapper.mjs";
|
|
3
|
+
import { Model } from "./model/index.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import Cassandra from "cassandra-driver";
|
|
6
|
+
//#region src/client.ts
|
|
7
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
8
|
+
const DEFAULT_RETRY_DELAY = 1e3;
|
|
9
|
+
const { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } = process.env;
|
|
10
|
+
var Client = class {
|
|
11
|
+
constructor(config = {}) {
|
|
12
|
+
this.config = {
|
|
13
|
+
modelsPath: path.resolve(process.cwd(), "db"),
|
|
14
|
+
contactPoints: config.contactPoints ?? SCYLLA_CONTACT_POINTS ? SCYLLA_CONTACT_POINTS.split(",") : ["127.0.0.1"],
|
|
15
|
+
localDataCenter: config.localDataCenter ?? SCYLLA_LOCAL_DATA_CENTER ?? "datacenter1",
|
|
16
|
+
keyspace: config.keyspace ?? SCYLLA_KEYSPACE ?? "default",
|
|
17
|
+
port: 9042,
|
|
18
|
+
maxRetries: DEFAULT_MAX_RETRIES,
|
|
19
|
+
retryDelay: DEFAULT_RETRY_DELAY,
|
|
20
|
+
...config
|
|
21
|
+
};
|
|
22
|
+
const clientOptions = {
|
|
23
|
+
contactPoints: this.config.contactPoints,
|
|
24
|
+
localDataCenter: this.config.localDataCenter,
|
|
25
|
+
keyspace: this.config.keyspace,
|
|
26
|
+
protocolOptions: { port: this.config.port }
|
|
27
|
+
};
|
|
28
|
+
if (this.config.pooling) clientOptions.pooling = this.config.pooling;
|
|
29
|
+
this.client = new Cassandra.Client(clientOptions);
|
|
30
|
+
}
|
|
31
|
+
config;
|
|
32
|
+
client;
|
|
33
|
+
mapper;
|
|
34
|
+
models = /* @__PURE__ */ new Map();
|
|
35
|
+
async initialize(options = {}) {
|
|
36
|
+
let models;
|
|
37
|
+
try {
|
|
38
|
+
models = await loadModels_default(this.config.modelsPath);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error(`Failed to load models: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
models = models.filter((schema) => schema instanceof Model);
|
|
43
|
+
this.mapper = new Cassandra.mapping.Mapper(this.client, { models: buildMapper_default(models) });
|
|
44
|
+
for (let model of models) {
|
|
45
|
+
model._connect(this);
|
|
46
|
+
this.models.set(model.name, model);
|
|
47
|
+
if (options?.sync === true) await model._sync();
|
|
48
|
+
}
|
|
49
|
+
console.log("Connecting to ScyllaDB");
|
|
50
|
+
await this.connectWithRetry();
|
|
51
|
+
console.log("ScyllaDB Connected");
|
|
52
|
+
}
|
|
53
|
+
async connectWithRetry() {
|
|
54
|
+
let lastError = null;
|
|
55
|
+
for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) try {
|
|
56
|
+
await this.client.connect();
|
|
57
|
+
return;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
lastError = error;
|
|
60
|
+
console.warn(`Connection attempt ${attempt} failed: ${error.message}`);
|
|
61
|
+
if (attempt < this.config.maxRetries) {
|
|
62
|
+
console.log(`Retrying in ${this.config.retryDelay}ms...`);
|
|
63
|
+
await this.delay(this.config.retryDelay);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Failed to connect to ScyllaDB after ${this.config.maxRetries} attempts: ${lastError?.message}`);
|
|
67
|
+
}
|
|
68
|
+
delay(ms) {
|
|
69
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
70
|
+
}
|
|
71
|
+
async shutdown() {
|
|
72
|
+
try {
|
|
73
|
+
await this.client.shutdown();
|
|
74
|
+
console.log("ScyllaDB connection closed");
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error("Error shutting down ScyllaDB connection:", error);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async executeWithRetry(operation, operationName = "operation") {
|
|
81
|
+
let lastError = null;
|
|
82
|
+
for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) try {
|
|
83
|
+
return await operation();
|
|
84
|
+
} catch (error) {
|
|
85
|
+
lastError = error;
|
|
86
|
+
if (this.isRetryableError(error) && attempt < this.config.maxRetries) {
|
|
87
|
+
console.warn(`Operation ${operationName} attempt ${attempt} failed: ${error.message}`);
|
|
88
|
+
console.log(`Retrying in ${this.config.retryDelay}ms...`);
|
|
89
|
+
await this.delay(this.config.retryDelay);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`Operation ${operationName} failed after ${this.config.maxRetries} attempts: ${lastError?.message}`);
|
|
95
|
+
}
|
|
96
|
+
isRetryableError(error) {
|
|
97
|
+
const retryableMessages = [
|
|
98
|
+
"timeout",
|
|
99
|
+
"connection",
|
|
100
|
+
"network",
|
|
101
|
+
"unavailable",
|
|
102
|
+
"overloaded",
|
|
103
|
+
"no hosts available"
|
|
104
|
+
];
|
|
105
|
+
const errorMessage = error.message?.toLowerCase() || "";
|
|
106
|
+
return retryableMessages.some((msg) => errorMessage.includes(msg));
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
//#endregion
|
|
110
|
+
export { Client, Client as default };
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/cql_gen/create_table.ts
|
|
2
|
+
function create_table_default(model) {
|
|
3
|
+
const desc = model.schema;
|
|
4
|
+
const tableName = desc.table_name;
|
|
5
|
+
const keyspace = model.driver.config.keyspace;
|
|
6
|
+
const fields = desc.fields;
|
|
7
|
+
const key = desc.keys;
|
|
8
|
+
const clusteringOrder = desc.clustering_order;
|
|
9
|
+
let columnsDef = "";
|
|
10
|
+
for (const fieldName in fields) {
|
|
11
|
+
const field = fields[fieldName];
|
|
12
|
+
const typeStr = typeof field === "string" ? field : field?.type;
|
|
13
|
+
if (!typeStr) throw new Error(`Invalid field type for "${fieldName}" in model "${tableName}"`);
|
|
14
|
+
columnsDef += `"${fieldName}" ${typeStr.toUpperCase()}, `;
|
|
15
|
+
}
|
|
16
|
+
let pkDef = "";
|
|
17
|
+
if (typeof key === "string") pkDef = `"${key}"`;
|
|
18
|
+
else if (Array.isArray(key) && key.length > 0) {
|
|
19
|
+
const first = key[0];
|
|
20
|
+
if (Array.isArray(first)) pkDef = `(${first.map((k) => `"${k}"`).join(", ")})`;
|
|
21
|
+
else pkDef = `"${first}"`;
|
|
22
|
+
for (let i = 1; i < key.length; i++) pkDef += `, "${key[i]}"`;
|
|
23
|
+
} else throw new Error(`Missing or invalid primary key in model "${tableName}"`);
|
|
24
|
+
let clusterClause = "";
|
|
25
|
+
if (clusteringOrder) {
|
|
26
|
+
let orderDef = "";
|
|
27
|
+
for (const col in clusteringOrder) {
|
|
28
|
+
if (orderDef !== "") orderDef += ", ";
|
|
29
|
+
orderDef += `"${col}" ${clusteringOrder[col].toUpperCase()}`;
|
|
30
|
+
}
|
|
31
|
+
if (orderDef !== "") clusterClause = ` WITH CLUSTERING ORDER BY (${orderDef})`;
|
|
32
|
+
}
|
|
33
|
+
return `CREATE TABLE IF NOT EXISTS ${keyspace}.${tableName} (${columnsDef}PRIMARY KEY (${pkDef}))${clusterClause}`;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { create_table_default as default };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=create_table.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_table.mjs","names":[],"sources":["../../src/cql_gen/create_table.ts"],"sourcesContent":["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"],"mappings":";AAEA,SAAA,qBAAyB,OAAsB;CAC9C,MAAM,OAAO,MAAM;CACnB,MAAM,YAAY,KAAK;CACvB,MAAM,WAAW,MAAM,OAAO,OAAO;CACrC,MAAM,SAAS,KAAK;CACpB,MAAM,MAAM,KAAK;CACjB,MAAM,kBAAkB,KAAK;CAE7B,IAAI,aAAa;AAEjB,MAAK,MAAM,aAAa,QAAQ;EAC/B,MAAM,QAAQ,OAAO;EACrB,MAAM,UAAU,OAAO,UAAU,WAAW,QAAS,OAAe;AAEpE,MAAI,CAAC,QACJ,OAAM,IAAI,MACT,2BAA2B,UAAU,cAAc,UAAU,GAC7D;AAGF,gBAAc,IAAI,UAAU,IAAI,QAAQ,aAAa,CAAC;;CAGvD,IAAI,QAAQ;AAEZ,KAAI,OAAO,QAAQ,SAClB,SAAQ,IAAI,IAAI;UACN,MAAM,QAAQ,IAAI,IAAI,IAAI,SAAS,GAAG;EAChD,MAAM,QAAQ,IAAI;AAElB,MAAI,MAAM,QAAQ,MAAM,CACvB,SAAQ,IAAI,MAAM,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;MAElD,SAAQ,IAAI,MAAM;AAGnB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC/B,UAAS,MAAM,IAAI,GAAG;OAGvB,OAAM,IAAI,MACT,4CAA4C,UAAU,GACtD;CAGF,IAAI,gBAAgB;AAEpB,KAAI,iBAAiB;EACpB,IAAI,WAAW;AAEf,OAAK,MAAM,OAAO,iBAAiB;AAClC,OAAI,aAAa,GAChB,aAAY;AAGb,eAAY,IAAI,IAAI,IAAK,gBAAgB,KAAgB,aAAa;;AAEvE,MAAI,aAAa,GAChB,iBAAgB,8BAA8B,SAAS;;AAIzD,QAAO,8BAA8B,SAAS,GAAG,UAAU,IAAI,WAAW,eAAe,MAAM,IAAI"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,113 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
//#region src/schema/index.d.ts
|
|
6
|
-
declare class Schema<T> {
|
|
7
|
-
readonly table_name: string;
|
|
8
|
-
readonly clustering_order: any;
|
|
9
|
-
readonly keys: TableKeys;
|
|
10
|
-
readonly fields: T;
|
|
11
|
-
constructor(params: any, fields: T);
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/operations/tableExists.d.ts
|
|
15
|
-
declare function export_default(this: Model): Promise<boolean>;
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/operations/sync.d.ts
|
|
18
|
-
declare function syncOP(this: Model): Promise<void>;
|
|
19
|
-
//#endregion
|
|
20
|
-
//#region src/model/index.d.ts
|
|
21
|
-
declare class Model<TDoc = any> {
|
|
22
|
-
name: string;
|
|
23
|
-
schema: Schema<any>;
|
|
24
|
-
driver: ScyllaClient;
|
|
25
|
-
mapper: mapping$1.ModelMapper;
|
|
26
|
-
constructor(name: string, schema: Schema<any>);
|
|
27
|
-
create: (data: Partial<TDoc>) => DocumentResult<TDoc>;
|
|
28
|
-
find: {
|
|
29
|
-
(query: Query<TDoc>, options: QueryOptions & {
|
|
30
|
-
raw: true;
|
|
31
|
-
}): Promise<TDoc[]>;
|
|
32
|
-
(query?: Query<TDoc>, options?: QueryOptions): Promise<DocumentResult<TDoc>[]>;
|
|
33
|
-
};
|
|
34
|
-
findOne: {
|
|
35
|
-
(query: Query<TDoc>, options: QueryOptions & {
|
|
36
|
-
raw: true;
|
|
37
|
-
}): Promise<TDoc>;
|
|
38
|
-
(query?: Query<TDoc>, options?: QueryOptions): Promise<DocumentResult<TDoc>>;
|
|
39
|
-
};
|
|
40
|
-
update: (query: Query<TDoc>) => Promise<DocumentResult<TDoc>>;
|
|
41
|
-
delete: (query: Query<TDoc>) => Promise<mapping$1.Result>;
|
|
42
|
-
countAll: () => Promise<number>;
|
|
43
|
-
_sync: typeof syncOP;
|
|
44
|
-
_tableExists: typeof export_default;
|
|
45
|
-
_wrap(row: any): DocumentResult<TDoc> | null;
|
|
46
|
-
_connect(driver: ScyllaClient): void;
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/result/index.d.ts
|
|
50
|
-
declare class Result<TDoc = any> {
|
|
51
|
-
constructor(data: TDoc, model: Model<TDoc>);
|
|
52
|
-
_model: Model<TDoc>;
|
|
53
|
-
save(): Promise<DocumentResult<TDoc>>;
|
|
54
|
-
delete(): Promise<_$cassandra_driver0.mapping.Result<any>>;
|
|
55
|
-
toRaw(): TDoc;
|
|
56
|
-
isValid(): boolean;
|
|
57
|
-
getChangedFields(original: Partial<TDoc>): (keyof TDoc)[];
|
|
58
|
-
}
|
|
59
|
-
//#endregion
|
|
60
|
-
//#region src/types.d.ts
|
|
61
|
-
type ClientConfig = {
|
|
62
|
-
modelsPath?: string;
|
|
63
|
-
contactPoints?: string[];
|
|
64
|
-
localDataCenter?: string;
|
|
65
|
-
keyspace?: string;
|
|
66
|
-
port?: number;
|
|
67
|
-
maxRetries?: number;
|
|
68
|
-
retryDelay?: number;
|
|
69
|
-
pooling?: {
|
|
70
|
-
coreConnectionsPerHost?: Record<string, number>;
|
|
71
|
-
maxRequestsPerConnection?: number;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
type QueryOperators<TValue> = {
|
|
75
|
-
$eq?: TValue;
|
|
76
|
-
$ne?: TValue;
|
|
77
|
-
$in?: TValue[];
|
|
78
|
-
$gt?: TValue;
|
|
79
|
-
$gte?: TValue;
|
|
80
|
-
$lt?: TValue;
|
|
81
|
-
$lte?: TValue;
|
|
82
|
-
};
|
|
83
|
-
type TableKeys = (string | TableKeys)[];
|
|
84
|
-
type DocumentResult<TDoc> = Result<TDoc> & TDoc;
|
|
85
|
-
type QueryOptions = {
|
|
86
|
-
raw?: boolean;
|
|
87
|
-
};
|
|
88
|
-
type OrderBy<TDoc> = { [K in keyof TDoc]?: "asc" | "desc" };
|
|
89
|
-
type Query<TDoc> = { [K in keyof TDoc]?: TDoc[K] | QueryOperators<TDoc[K]> } & {
|
|
90
|
-
$and?: Query<TDoc>[];
|
|
91
|
-
$limit?: number;
|
|
92
|
-
$orderby?: OrderBy<TDoc>;
|
|
93
|
-
};
|
|
94
|
-
//#endregion
|
|
95
|
-
//#region src/index.d.ts
|
|
96
|
-
declare class ScyllaClient {
|
|
97
|
-
constructor(config?: ClientConfig);
|
|
98
|
-
config: ClientConfig;
|
|
99
|
-
client: Client;
|
|
100
|
-
mapper: mapping.Mapper;
|
|
101
|
-
models: Map<string, Model<any>>;
|
|
102
|
-
initialize(options?: {
|
|
103
|
-
sync?: boolean;
|
|
104
|
-
}): Promise<void>;
|
|
105
|
-
private connectWithRetry;
|
|
106
|
-
private delay;
|
|
107
|
-
shutdown(): Promise<void>;
|
|
108
|
-
executeWithRetry<T>(operation: () => Promise<T>, operationName?: string): Promise<T>;
|
|
109
|
-
private isRetryableError;
|
|
110
|
-
}
|
|
111
|
-
//#endregion
|
|
112
|
-
export { ScyllaClient as default };
|
|
113
|
-
//# sourceMappingURL=index.d.mts.map
|
|
1
|
+
import { Schema } from "./schema/index.mjs";
|
|
2
|
+
import { Model } from "./model/index.mjs";
|
|
3
|
+
import { Client } from "./client.mjs";
|
|
4
|
+
export { Client, Client as default, Model, Schema };
|