Socket
Socket
Sign inDemoInstall

libsql-stateless-easy

Package Overview
Dependencies
Maintainers
1
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

libsql-stateless-easy - npm Package Compare versions

Comparing version 1.3.9 to 1.4.0

78

lib-cjs/builders.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.libsqlBatchReqStepExecCondBuilder = exports.libsqlBatchReqStepsBuilder = exports.libsqlStatementBuilder = exports.libsqlValueBuilder = void 0;
exports.libsqlTransactionBatchReqStepsBuilder = exports.libsqlTransactionEndStatements = exports.libsqlTransactionBeginStatement = exports.libsqlBatchReqStepsBuilder = exports.libsqlBatchReqStepExecCondBuilder = exports.libsqlStatementBuilder = exports.libsqlValueBuilder = void 0;
const js_base64_1 = require("js-base64");

@@ -52,13 +52,79 @@ const errors_js_1 = require("./errors.js");

//===========================================================
function libsqlBatchReqStepsBuilder(batch_queries) {
exports.libsqlBatchReqStepExecCondBuilder = {
ok: (step) => {
return {
type: "ok",
step //uint32: 0-based index in the steps array
};
},
error: (step) => {
return {
type: "error",
step //uint32: 0-based index in the steps array
};
},
not: (cond) => {
return {
type: "not",
cond,
};
},
and: (conds) => {
return {
type: "and",
conds
};
},
or: (conds) => {
return {
type: "or",
conds
};
},
is_autocommit: () => {
return {
type: "is_autocommit"
};
}
};
//===========================================================
function libsqlBatchReqStepsBuilder(batch_queries, batch_conditions) {
let p_stmts = [];
for (let i = 0; i < batch_queries.length; i++)
p_stmts.push({ stmt: libsqlStatementBuilder(batch_queries[i]) });
p_stmts.push({
stmt: libsqlStatementBuilder(batch_queries[i]),
condition: (batch_conditions) ? (batch_conditions[i] || undefined) : undefined
});
return p_stmts;
}
exports.libsqlBatchReqStepsBuilder = libsqlBatchReqStepsBuilder;
//========================================================
function libsqlTransactionBeginStatement(mode) {
if (mode === "write") {
return { stmt: { sql: "BEGIN IMMEDIATE" } };
}
else if (mode === "read") {
return { stmt: { sql: "BEGIN TRANSACTION READONLY" } };
}
else if (mode === "deferred") {
return { stmt: { sql: "BEGIN DEFERRED" } };
}
else {
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
}
}
exports.libsqlTransactionBeginStatement = libsqlTransactionBeginStatement;
//========================================================
function libsqlTransactionEndStatements(last_step_before_this) {
return [
{ stmt: { sql: "COMMIT" } },
{ stmt: { sql: "ROLLBACK" }, condition: { type: "not", cond: { type: "ok", step: last_step_before_this + 1 } } }
];
}
exports.libsqlTransactionEndStatements = libsqlTransactionEndStatements;
//===========================================================
function libsqlBatchReqStepExecCondBuilder(c) {
return c;
function libsqlTransactionBatchReqStepsBuilder(queries, mode) {
const main_steps = libsqlBatchReqStepsBuilder(queries);
return [libsqlTransactionBeginStatement(mode)].concat(main_steps).concat(libsqlTransactionEndStatements(main_steps.length));
}
exports.libsqlBatchReqStepExecCondBuilder = libsqlBatchReqStepExecCondBuilder;
exports.libsqlTransactionBatchReqStepsBuilder = libsqlTransactionBatchReqStepsBuilder;

@@ -5,13 +5,114 @@ "use strict";

const functions_1 = require("./functions");
const errors_js_1 = require("./errors.js");
class libsqlClient {
conf;
closed;
protocol;
constructor(conf) {
this.conf = conf;
this.closed = true;
this.protocol = "http";
}
/** Execute a single SQL statement.
*
* Every statement executed with this method is executed in its own logical database connection. If you
* want to execute a group of statements in a transaction, use the {@link batch} method.
*
* ```javascript
* // execute a statement without arguments
* const rs = await client.execute("SELECT * FROM books");
*
* // execute a statement with positional arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE author = ?",
* args: ["Jane Austen"],
* });
*
* // execute a statement with named arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE published_at > $year",
* args: {year: 1719},
* });
* ```
*/
async execute(stmt) {
return await (0, functions_1.libsqlExecute)(this.conf, stmt);
}
async batch(steps) {
return await (0, functions_1.libsqlBatch)(this.conf, steps);
/** Execute a batch of SQL statements in a transaction.
*
* The batch is executed in its own logical database connection and the statements are wrapped in a
* transaction. This ensures that the batch is applied atomically: either all or no changes are applied.
*
* The `mode` parameter selects the transaction mode for the batch; please see {@link TransactionMode} for
* details. The default transaction mode is `"deferred"`.
*
* If any of the statements in the batch fails with an error, the batch is aborted, the transaction is
* rolled back and the returned promise is rejected.
*
* This method provides non-interactive transactions.
*
* ```javascript
* const rss = await client.batch([
* // batch statement without arguments
* "DELETE FROM books WHERE name LIKE '%Crusoe'",
*
* // batch statement with positional arguments
* {
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
* args: ["First Impressions", "Jane Austen", 1813],
* },
*
* // batch statement with named arguments
* {
* sql: "UPDATE books SET name = $new WHERE name = $old",
* args: {old: "First Impressions", new: "Pride and Prejudice"},
* },
* ], "write");
* ```
*/
async batch(steps, mode) {
return await (0, functions_1.libsqlBatchTransaction)(this.conf, steps, mode);
}
async batchPrimitive(steps, step_conditions) {
return await (0, functions_1.libsqlBatch)(this.conf, steps, step_conditions);
}
async transaction(mode) {
if (mode) { }
throw new errors_js_1.InternalError("'libsql-stateless' is stateless and does not support interactive transactions. Use this.batch() instead.");
}
/** Execute a sequence of SQL statements separated by semicolons.
*
* The statements are executed sequentially on a new logical database connection. If a statement fails,
* further statements are not executed and this method throws an error. All results from the statements
* are ignored.
*
* We do not wrap the statements in a transaction, but the SQL can contain explicit transaction-control
* statements such as `BEGIN` and `COMMIT`.
*
* This method is intended to be used with existing SQL scripts, such as migrations or small database
* dumps. If you want to execute a sequence of statements programmatically, please use {@link batch}
* instead.
*
* ```javascript
* await client.executeMultiple(`
* CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT NOT NULL, author_id INTEGER NOT NULL);
* CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
* `);
* ```
*/
async executeMultiple(sql) {
return await (0, functions_1.libsqlExecuteMultiple)(this.conf, sql);
}
async sync() {
throw new errors_js_1.LibsqlError("sync not supported in http mode", "SYNC_NOT_SUPPORTED");
}
/** Which protocol does the client use?
*
* - `"http"` if the client connects over HTTP
* - `"ws"` if the client connects over WebSockets
* - `"file"` if the client works with a local file
*/
close() {
throw new errors_js_1.InternalError("'libsql-stateless' is stateless therefore no connection to close.");
}
async serverOk() {

@@ -18,0 +119,0 @@ return await (0, functions_1.libsqlServerCompatCheck)(this.conf);

137

lib-cjs/errors.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapHranaError = exports.LibsqlError = exports.MisuseError = exports.InternalError = exports.HttpServerError = exports.ResponseError = exports.ProtoError = exports.ClientError = void 0;
/** Generic error produced by the Hrana client. */
class ClientError extends Error {
/** @private */
constructor(message) {
super(message);
this.name = "ClientError";
exports.MisuseError = exports.InternalError = exports.HttpServerError = exports.ResponseError = exports.ProtoError = exports.LibsqlError = void 0;
/** Error thrown by the client. */
class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, cause) {
super(`${code}: ${message}`, { cause });
this.code = code;
this.rawCode = undefined;
this.name = "LibsqlError";
}
}
exports.ClientError = ClientError;
exports.LibsqlError = LibsqlError;
/** Error thrown when the server violates the protocol. */
class ProtoError extends ClientError {
/** @private */
class ProtoError extends LibsqlError {
constructor(message) {
super(message);
this.name = "ProtoError";
super(message, "HRANA_PROTO_ERROR", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "ProtoError";
}
}());
}

@@ -23,13 +32,15 @@ }

/** Error thrown when the server returns an error response. */
class ResponseError extends ClientError {
code;
/** @internal */
proto;
/** @private */
class ResponseError extends LibsqlError {
constructor(message, protoError) {
super(message);
this.name = "ResponseError";
this.code = protoError.code;
this.proto = protoError;
this.stack = undefined;
super(message, protoError.code || "UNKNOWN", new class extends Error {
/** @internal */
proto;
/** @private */
constructor() {
super(message);
this.name = "ResponseError";
this.proto = protoError;
this.stack = undefined;
}
}());
}

@@ -39,9 +50,13 @@ }

/** Error thrown when the HTTP server returns an error response. */
class HttpServerError extends ClientError {
status;
/** @private */
class HttpServerError extends LibsqlError {
constructor(message, status) {
super(message);
this.status = status;
this.name = "HttpServerError";
super(message, "SERVER_ERROR", new class extends Error {
status;
/** @private */
constructor() {
super(message);
this.status = status;
this.name = "HttpServerError";
}
}());
}

@@ -51,7 +66,11 @@ }

/** Error thrown when an internal client error happens. */
class InternalError extends ClientError {
/** @private */
class InternalError extends LibsqlError {
constructor(message) {
super(message);
this.name = "InternalError";
super(message, "INTERNAL_ERROR", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "InternalError";
}
}());
}

@@ -61,51 +80,13 @@ }

/** Error thrown when the API is misused. */
class MisuseError extends ClientError {
/** @private */
class MisuseError extends LibsqlError {
constructor(message) {
super(message);
this.name = "MisuseError";
super(message, "UNKNOWN", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "MisuseError";
}
}());
}
}
exports.MisuseError = MisuseError;
/** Error thrown by the client. */
class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, rawCode, cause) {
if (code !== undefined) {
message = `${code}: ${message}`;
}
super(message, { cause });
this.code = code;
this.rawCode = rawCode;
this.name = "LibsqlError";
}
}
exports.LibsqlError = LibsqlError;
function mapHranaErrorCode(e) {
if (e instanceof ResponseError && e.code !== undefined) {
return e.code;
}
else if (e instanceof ProtoError) {
return "HRANA_PROTO_ERROR";
}
else if (e instanceof HttpServerError) {
return "SERVER_ERROR";
}
else if (e instanceof InternalError) {
return "INTERNAL_ERROR";
}
else {
return "UNKNOWN";
}
}
function mapHranaError(e) {
if (e instanceof ClientError) {
const code = mapHranaErrorCode(e);
return new LibsqlError(e.message, code, undefined, e);
}
return e;
}
exports.mapHranaError = mapHranaError;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.libsqlServerCompatCheck = exports.libsqlBatch = exports.libsqlExecute = void 0;
exports.libsqlExecuteMultiple = exports.libsqlBatchTransaction = exports.libsqlServerCompatCheck = exports.libsqlBatch = exports.libsqlExecute = void 0;
const libsql_stateless_1 = require("libsql-stateless");

@@ -8,37 +8,44 @@ const builders_js_1 = require("./builders.js");

const errors_js_1 = require("./errors.js");
function CheckHttpUrl(url) {
const _url = (() => {
try {
return new URL(url);
}
catch (e) {
throw new errors_js_1.LibsqlError(e.message, "ERR_INVALID_URL", e);
}
})();
if (_url.protocol !== 'https:' &&
_url.protocol !== 'http:')
throw new errors_js_1.LibsqlError('This is a HTTP client and only supports "https:" and "http:" URLs, ' +
`got ${JSON.stringify(_url.protocol + ":")}`, "URL_SCHEME_NOT_SUPPORTED");
}
async function libsqlExecute(conf, stmt) {
try {
const res = await (0, libsql_stateless_1.libsqlExecute)(conf, (0, builders_js_1.libsqlStatementBuilder)(stmt));
if (res.isOk)
return (0, parsers_js_1.libsqlStatementResParser)(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
CheckHttpUrl(conf.db_url);
const res = await (0, libsql_stateless_1.libsqlExecute)(conf, (0, builders_js_1.libsqlStatementBuilder)(stmt));
if (res.isOk)
return (0, parsers_js_1.libsqlStatementResParser)(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
catch (e) {
throw (0, errors_js_1.mapHranaError)(e);
}
}
exports.libsqlExecute = libsqlExecute;
async function libsqlBatch(conf, steps) {
try {
const res = await (0, libsql_stateless_1.libsqlBatch)(conf, (0, builders_js_1.libsqlBatchReqStepsBuilder)(steps));
if (res.isOk)
return (0, parsers_js_1.libsqlBatchStreamResParser)(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
async function libsqlBatch(conf, steps, step_conditions) {
CheckHttpUrl(conf.db_url);
const res = await (0, libsql_stateless_1.libsqlBatch)(conf, (0, builders_js_1.libsqlBatchReqStepsBuilder)(steps, step_conditions));
if (res.isOk)
return (0, parsers_js_1.libsqlBatchStreamResParser)(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
catch (e) {
throw (0, errors_js_1.mapHranaError)(e);
}
}
exports.libsqlBatch = libsqlBatch;
async function libsqlServerCompatCheck(conf) {
CheckHttpUrl(conf.db_url);
const res = await (0, libsql_stateless_1.libsqlServerCompatCheck)(conf);

@@ -48,1 +55,29 @@ return (res.isOk) ? true : false;

exports.libsqlServerCompatCheck = libsqlServerCompatCheck;
async function libsqlBatchTransaction(conf, steps, mode = "deferred") {
CheckHttpUrl(conf.db_url);
const res = await (0, libsql_stateless_1.libsqlBatch)(conf, (0, builders_js_1.libsqlTransactionBatchReqStepsBuilder)(steps, mode));
if (res.isOk)
return (0, parsers_js_1.libsqlTransactionBatchStreamResParser)(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
}
exports.libsqlBatchTransaction = libsqlBatchTransaction;
async function libsqlExecuteMultiple(conf, sql) {
CheckHttpUrl(conf.db_url);
const sqlArr = sql.split(";").filter(s => s.trim() !== "").map(s => { return { stmt: { sql: s }, condition: builders_js_1.libsqlBatchReqStepExecCondBuilder.ok(0) }; });
for (let i = 1; i < sqlArr.length; i++)
sqlArr[i].condition = builders_js_1.libsqlBatchReqStepExecCondBuilder.ok(i - 1);
sqlArr[0].condition = undefined;
const res = await (0, libsql_stateless_1.libsqlBatch)(conf, sqlArr);
if (!res.isOk) {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new errors_js_1.HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new errors_js_1.ResponseError(res.err.data.message, res.err.data);
}
}
exports.libsqlExecuteMultiple = libsqlExecuteMultiple;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.libsqlBatchStreamResParser = exports.libsqlStatementResParser = exports.libsqlValueParser = void 0;
exports.libsqlTransactionBatchStreamResParser = exports.libsqlBatchStreamResParser = exports.libsqlStatementResParser = exports.libsqlValueParser = void 0;
const js_base64_1 = require("js-base64");

@@ -70,4 +70,6 @@ const errors_js_1 = require("./errors.js");

batchResults.push(libsqlStatementResParser(res.step_results[j]));
else if (res.step_errors[j])
throw new errors_js_1.ResponseError(res.step_errors[j]?.message, res.step_errors[j]);
else
throw new errors_js_1.ResponseError(res.step_errors[j]?.message, res.step_errors[j]);
batchResults.push(null);
}

@@ -77,1 +79,7 @@ return batchResults;

exports.libsqlBatchStreamResParser = libsqlBatchStreamResParser;
//========================================================
function libsqlTransactionBatchStreamResParser(res) {
const resResArr = libsqlBatchStreamResParser(res);
return resResArr.slice(1, resResArr.length - 2).filter(r => r !== null);
}
exports.libsqlTransactionBatchStreamResParser = libsqlTransactionBatchStreamResParser;

@@ -1,23 +0,16 @@

import { rawSQLStatement, rawValue } from './types.js';
import { TransactionMode, rawSQLStatement, rawValue } from './types.js';
import { libsqlBatchReqStep, libsqlBatchReqStepExecCond, libsqlSQLStatement, libsqlSQLValue } from 'libsql-stateless';
export declare function libsqlValueBuilder(value: rawValue): libsqlSQLValue;
export declare function libsqlStatementBuilder(s: rawSQLStatement): libsqlSQLStatement;
export declare function libsqlBatchReqStepsBuilder(batch_queries: Array<rawSQLStatement>): Array<libsqlBatchReqStep>;
export declare function libsqlBatchReqStepExecCondBuilder(c: {
type: "ok";
step: number;
} | {
type: "error";
step: number;
} | {
type: "not";
cond: libsqlBatchReqStepExecCond;
} | {
type: "and";
conds: Array<libsqlBatchReqStepExecCond>;
} | {
type: "or";
conds: Array<libsqlBatchReqStepExecCond>;
} | {
type: "is_autocommit";
}): libsqlBatchReqStepExecCond;
export declare const libsqlBatchReqStepExecCondBuilder: {
ok: (step: number) => libsqlBatchReqStepExecCond;
error: (step: number) => libsqlBatchReqStepExecCond;
not: (cond: libsqlBatchReqStepExecCond) => libsqlBatchReqStepExecCond;
and: (conds: Array<libsqlBatchReqStepExecCond>) => libsqlBatchReqStepExecCond;
or: (conds: Array<libsqlBatchReqStepExecCond>) => libsqlBatchReqStepExecCond;
is_autocommit: () => libsqlBatchReqStepExecCond;
};
export declare function libsqlBatchReqStepsBuilder(batch_queries: Array<rawSQLStatement>, batch_conditions?: Array<libsqlBatchReqStepExecCond | undefined | null>): Array<libsqlBatchReqStep>;
export declare function libsqlTransactionBeginStatement(mode: TransactionMode): libsqlBatchReqStep;
export declare function libsqlTransactionEndStatements(last_step_before_this: number): Array<libsqlBatchReqStep>;
export declare function libsqlTransactionBatchReqStepsBuilder(queries: Array<rawSQLStatement>, mode: TransactionMode): Array<libsqlBatchReqStep>;

@@ -47,11 +47,75 @@ import { Base64 } from 'js-base64';

//===========================================================
export function libsqlBatchReqStepsBuilder(batch_queries) {
export const libsqlBatchReqStepExecCondBuilder = {
ok: (step) => {
return {
type: "ok",
step //uint32: 0-based index in the steps array
};
},
error: (step) => {
return {
type: "error",
step //uint32: 0-based index in the steps array
};
},
not: (cond) => {
return {
type: "not",
cond,
};
},
and: (conds) => {
return {
type: "and",
conds
};
},
or: (conds) => {
return {
type: "or",
conds
};
},
is_autocommit: () => {
return {
type: "is_autocommit"
};
}
};
//===========================================================
export function libsqlBatchReqStepsBuilder(batch_queries, batch_conditions) {
let p_stmts = [];
for (let i = 0; i < batch_queries.length; i++)
p_stmts.push({ stmt: libsqlStatementBuilder(batch_queries[i]) });
p_stmts.push({
stmt: libsqlStatementBuilder(batch_queries[i]),
condition: (batch_conditions) ? (batch_conditions[i] || undefined) : undefined
});
return p_stmts;
}
//========================================================
export function libsqlTransactionBeginStatement(mode) {
if (mode === "write") {
return { stmt: { sql: "BEGIN IMMEDIATE" } };
}
else if (mode === "read") {
return { stmt: { sql: "BEGIN TRANSACTION READONLY" } };
}
else if (mode === "deferred") {
return { stmt: { sql: "BEGIN DEFERRED" } };
}
else {
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
}
}
//========================================================
export function libsqlTransactionEndStatements(last_step_before_this) {
return [
{ stmt: { sql: "COMMIT" } },
{ stmt: { sql: "ROLLBACK" }, condition: { type: "not", cond: { type: "ok", step: last_step_before_this + 1 } } }
];
}
//===========================================================
export function libsqlBatchReqStepExecCondBuilder(c) {
return c;
export function libsqlTransactionBatchReqStepsBuilder(queries, mode) {
const main_steps = libsqlBatchReqStepsBuilder(queries);
return [libsqlTransactionBeginStatement(mode)].concat(main_steps).concat(libsqlTransactionEndStatements(main_steps.length));
}

@@ -1,8 +0,95 @@

import { libsqlConfig } from "libsql-stateless";
import { rawSQLStatement } from "./types.js";
import { libsqlBatchReqStepExecCond, libsqlConfig } from "libsql-stateless";
import { TransactionMode, rawSQLStatement } from "./types.js";
declare class libsqlClient {
private readonly conf;
closed: boolean;
protocol: string;
constructor(conf: libsqlConfig);
/** Execute a single SQL statement.
*
* Every statement executed with this method is executed in its own logical database connection. If you
* want to execute a group of statements in a transaction, use the {@link batch} method.
*
* ```javascript
* // execute a statement without arguments
* const rs = await client.execute("SELECT * FROM books");
*
* // execute a statement with positional arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE author = ?",
* args: ["Jane Austen"],
* });
*
* // execute a statement with named arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE published_at > $year",
* args: {year: 1719},
* });
* ```
*/
execute(stmt: rawSQLStatement): Promise<import("./types.js").ResultSet>;
batch(steps: Array<rawSQLStatement>): Promise<import("./types.js").ResultSet[]>;
/** Execute a batch of SQL statements in a transaction.
*
* The batch is executed in its own logical database connection and the statements are wrapped in a
* transaction. This ensures that the batch is applied atomically: either all or no changes are applied.
*
* The `mode` parameter selects the transaction mode for the batch; please see {@link TransactionMode} for
* details. The default transaction mode is `"deferred"`.
*
* If any of the statements in the batch fails with an error, the batch is aborted, the transaction is
* rolled back and the returned promise is rejected.
*
* This method provides non-interactive transactions.
*
* ```javascript
* const rss = await client.batch([
* // batch statement without arguments
* "DELETE FROM books WHERE name LIKE '%Crusoe'",
*
* // batch statement with positional arguments
* {
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
* args: ["First Impressions", "Jane Austen", 1813],
* },
*
* // batch statement with named arguments
* {
* sql: "UPDATE books SET name = $new WHERE name = $old",
* args: {old: "First Impressions", new: "Pride and Prejudice"},
* },
* ], "write");
* ```
*/
batch(steps: Array<rawSQLStatement>, mode?: TransactionMode): Promise<import("./types.js").ResultSet[]>;
batchPrimitive(steps: Array<rawSQLStatement>, step_conditions?: Array<libsqlBatchReqStepExecCond | null | undefined>): Promise<(import("./types.js").ResultSet | null)[]>;
transaction(mode?: TransactionMode): Promise<void>;
/** Execute a sequence of SQL statements separated by semicolons.
*
* The statements are executed sequentially on a new logical database connection. If a statement fails,
* further statements are not executed and this method throws an error. All results from the statements
* are ignored.
*
* We do not wrap the statements in a transaction, but the SQL can contain explicit transaction-control
* statements such as `BEGIN` and `COMMIT`.
*
* This method is intended to be used with existing SQL scripts, such as migrations or small database
* dumps. If you want to execute a sequence of statements programmatically, please use {@link batch}
* instead.
*
* ```javascript
* await client.executeMultiple(`
* CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT NOT NULL, author_id INTEGER NOT NULL);
* CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
* `);
* ```
*/
executeMultiple(sql: string): Promise<void>;
sync(): Promise<void>;
/** Which protocol does the client use?
*
* - `"http"` if the client connects over HTTP
* - `"ws"` if the client connects over WebSockets
* - `"file"` if the client works with a local file
*/
close(): void;
serverOk(): Promise<boolean>;

@@ -9,0 +96,0 @@ }

@@ -1,13 +0,114 @@

import { libsqlBatch, libsqlExecute, libsqlServerCompatCheck } from "./functions";
import { libsqlBatch, libsqlBatchTransaction, libsqlExecute, libsqlExecuteMultiple, libsqlServerCompatCheck } from "./functions";
import { InternalError, LibsqlError } from "./errors.js";
class libsqlClient {
conf;
closed;
protocol;
constructor(conf) {
this.conf = conf;
this.closed = true;
this.protocol = "http";
}
/** Execute a single SQL statement.
*
* Every statement executed with this method is executed in its own logical database connection. If you
* want to execute a group of statements in a transaction, use the {@link batch} method.
*
* ```javascript
* // execute a statement without arguments
* const rs = await client.execute("SELECT * FROM books");
*
* // execute a statement with positional arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE author = ?",
* args: ["Jane Austen"],
* });
*
* // execute a statement with named arguments
* const rs = await client.execute({
* sql: "SELECT * FROM books WHERE published_at > $year",
* args: {year: 1719},
* });
* ```
*/
async execute(stmt) {
return await libsqlExecute(this.conf, stmt);
}
async batch(steps) {
return await libsqlBatch(this.conf, steps);
/** Execute a batch of SQL statements in a transaction.
*
* The batch is executed in its own logical database connection and the statements are wrapped in a
* transaction. This ensures that the batch is applied atomically: either all or no changes are applied.
*
* The `mode` parameter selects the transaction mode for the batch; please see {@link TransactionMode} for
* details. The default transaction mode is `"deferred"`.
*
* If any of the statements in the batch fails with an error, the batch is aborted, the transaction is
* rolled back and the returned promise is rejected.
*
* This method provides non-interactive transactions.
*
* ```javascript
* const rss = await client.batch([
* // batch statement without arguments
* "DELETE FROM books WHERE name LIKE '%Crusoe'",
*
* // batch statement with positional arguments
* {
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
* args: ["First Impressions", "Jane Austen", 1813],
* },
*
* // batch statement with named arguments
* {
* sql: "UPDATE books SET name = $new WHERE name = $old",
* args: {old: "First Impressions", new: "Pride and Prejudice"},
* },
* ], "write");
* ```
*/
async batch(steps, mode) {
return await libsqlBatchTransaction(this.conf, steps, mode);
}
async batchPrimitive(steps, step_conditions) {
return await libsqlBatch(this.conf, steps, step_conditions);
}
async transaction(mode) {
if (mode) { }
throw new InternalError("'libsql-stateless' is stateless and does not support interactive transactions. Use this.batch() instead.");
}
/** Execute a sequence of SQL statements separated by semicolons.
*
* The statements are executed sequentially on a new logical database connection. If a statement fails,
* further statements are not executed and this method throws an error. All results from the statements
* are ignored.
*
* We do not wrap the statements in a transaction, but the SQL can contain explicit transaction-control
* statements such as `BEGIN` and `COMMIT`.
*
* This method is intended to be used with existing SQL scripts, such as migrations or small database
* dumps. If you want to execute a sequence of statements programmatically, please use {@link batch}
* instead.
*
* ```javascript
* await client.executeMultiple(`
* CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT NOT NULL, author_id INTEGER NOT NULL);
* CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
* `);
* ```
*/
async executeMultiple(sql) {
return await libsqlExecuteMultiple(this.conf, sql);
}
async sync() {
throw new LibsqlError("sync not supported in http mode", "SYNC_NOT_SUPPORTED");
}
/** Which protocol does the client use?
*
* - `"http"` if the client connects over HTTP
* - `"ws"` if the client connects over WebSockets
* - `"file"` if the client works with a local file
*/
close() {
throw new InternalError("'libsql-stateless' is stateless therefore no connection to close.");
}
async serverOk() {

@@ -14,0 +115,0 @@ return await libsqlServerCompatCheck(this.conf);

import { libsqlStreamResErrData } from "libsql-stateless";
/** Generic error produced by the Hrana client. */
export declare class ClientError extends Error {
/** @private */
constructor(message: string);
/** Error thrown by the client. */
export declare class LibsqlError extends Error {
/** Machine-readable error code. */
code: string;
/** Raw numeric error code */
rawCode?: number;
constructor(message: string, code: string, cause?: Error);
}
/** Error thrown when the server violates the protocol. */
export declare class ProtoError extends ClientError {
/** @private */
export declare class ProtoError extends LibsqlError {
constructor(message: string);
}
/** Error thrown when the server returns an error response. */
export declare class ResponseError extends ClientError {
code: string | undefined;
/** @internal */
proto: libsqlStreamResErrData;
/** @private */
export declare class ResponseError extends LibsqlError {
constructor(message: string, protoError: libsqlStreamResErrData);
}
/** Error thrown when the HTTP server returns an error response. */
export declare class HttpServerError extends ClientError {
status: number;
/** @private */
export declare class HttpServerError extends LibsqlError {
constructor(message: string, status: number);
}
/** Error thrown when an internal client error happens. */
export declare class InternalError extends ClientError {
/** @private */
export declare class InternalError extends LibsqlError {
constructor(message: string);
}
/** Error thrown when the API is misused. */
export declare class MisuseError extends ClientError {
/** @private */
export declare class MisuseError extends LibsqlError {
constructor(message: string);
}
/** Error thrown by the client. */
export declare class LibsqlError extends Error {
/** Machine-readable error code. */
code: string;
/** Raw numeric error code */
rawCode?: number;
constructor(message: string, code: string, rawCode?: number, cause?: Error);
}
export declare function mapHranaError(e: unknown): unknown;

@@ -1,96 +0,79 @@

/** Generic error produced by the Hrana client. */
export class ClientError extends Error {
/** @private */
constructor(message) {
super(message);
this.name = "ClientError";
/** Error thrown by the client. */
export class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, cause) {
super(`${code}: ${message}`, { cause });
this.code = code;
this.rawCode = undefined;
this.name = "LibsqlError";
}
}
/** Error thrown when the server violates the protocol. */
export class ProtoError extends ClientError {
/** @private */
export class ProtoError extends LibsqlError {
constructor(message) {
super(message);
this.name = "ProtoError";
super(message, "HRANA_PROTO_ERROR", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "ProtoError";
}
}());
}
}
/** Error thrown when the server returns an error response. */
export class ResponseError extends ClientError {
code;
/** @internal */
proto;
/** @private */
export class ResponseError extends LibsqlError {
constructor(message, protoError) {
super(message);
this.name = "ResponseError";
this.code = protoError.code;
this.proto = protoError;
this.stack = undefined;
super(message, protoError.code || "UNKNOWN", new class extends Error {
/** @internal */
proto;
/** @private */
constructor() {
super(message);
this.name = "ResponseError";
this.proto = protoError;
this.stack = undefined;
}
}());
}
}
/** Error thrown when the HTTP server returns an error response. */
export class HttpServerError extends ClientError {
status;
/** @private */
export class HttpServerError extends LibsqlError {
constructor(message, status) {
super(message);
this.status = status;
this.name = "HttpServerError";
super(message, "SERVER_ERROR", new class extends Error {
status;
/** @private */
constructor() {
super(message);
this.status = status;
this.name = "HttpServerError";
}
}());
}
}
/** Error thrown when an internal client error happens. */
export class InternalError extends ClientError {
/** @private */
export class InternalError extends LibsqlError {
constructor(message) {
super(message);
this.name = "InternalError";
super(message, "INTERNAL_ERROR", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "InternalError";
}
}());
}
}
/** Error thrown when the API is misused. */
export class MisuseError extends ClientError {
/** @private */
export class MisuseError extends LibsqlError {
constructor(message) {
super(message);
this.name = "MisuseError";
super(message, "UNKNOWN", new class extends Error {
/** @private */
constructor() {
super(message);
this.name = "MisuseError";
}
}());
}
}
/** Error thrown by the client. */
export class LibsqlError extends Error {
/** Machine-readable error code. */
code;
/** Raw numeric error code */
rawCode;
constructor(message, code, rawCode, cause) {
if (code !== undefined) {
message = `${code}: ${message}`;
}
super(message, { cause });
this.code = code;
this.rawCode = rawCode;
this.name = "LibsqlError";
}
}
function mapHranaErrorCode(e) {
if (e instanceof ResponseError && e.code !== undefined) {
return e.code;
}
else if (e instanceof ProtoError) {
return "HRANA_PROTO_ERROR";
}
else if (e instanceof HttpServerError) {
return "SERVER_ERROR";
}
else if (e instanceof InternalError) {
return "INTERNAL_ERROR";
}
else {
return "UNKNOWN";
}
}
export function mapHranaError(e) {
if (e instanceof ClientError) {
const code = mapHranaErrorCode(e);
return new LibsqlError(e.message, code, undefined, e);
}
return e;
}

@@ -1,5 +0,7 @@

import { libsqlConfig } from "libsql-stateless";
import { ResultSet, rawSQLStatement } from "./types.js";
import { libsqlConfig, libsqlBatchReqStepExecCond } from "libsql-stateless";
import { ResultSet, TransactionMode, rawSQLStatement } from "./types.js";
export declare function libsqlExecute(conf: libsqlConfig, stmt: rawSQLStatement): Promise<ResultSet>;
export declare function libsqlBatch(conf: libsqlConfig, steps: Array<rawSQLStatement>): Promise<Array<ResultSet>>;
export declare function libsqlBatch(conf: libsqlConfig, steps: Array<rawSQLStatement>, step_conditions?: Array<libsqlBatchReqStepExecCond | null | undefined>): Promise<Array<ResultSet | null>>;
export declare function libsqlServerCompatCheck(conf: libsqlConfig): Promise<boolean>;
export declare function libsqlBatchTransaction(conf: libsqlConfig, steps: Array<rawSQLStatement>, mode?: TransactionMode): Promise<Array<ResultSet>>;
export declare function libsqlExecuteMultiple(conf: libsqlConfig, sql: string): Promise<void>;
import { libsqlExecute as LIBlibsqlExecute, libsqlBatch as LIBlibsqlBatch, libsqlServerCompatCheck as LIBlibsqlServerCompatCheck } from "libsql-stateless";
import { libsqlBatchReqStepsBuilder, libsqlStatementBuilder } from "./builders.js";
import { libsqlBatchStreamResParser, libsqlStatementResParser } from "./parsers.js";
import { HttpServerError, ResponseError, mapHranaError } from "./errors.js";
import { libsqlBatchReqStepExecCondBuilder, libsqlBatchReqStepsBuilder, libsqlStatementBuilder, libsqlTransactionBatchReqStepsBuilder } from "./builders.js";
import { libsqlBatchStreamResParser, libsqlStatementResParser, libsqlTransactionBatchStreamResParser } from "./parsers.js";
import { HttpServerError, LibsqlError, ResponseError } from "./errors.js";
function CheckHttpUrl(url) {
const _url = (() => {
try {
return new URL(url);
}
catch (e) {
throw new LibsqlError(e.message, "ERR_INVALID_URL", e);
}
})();
if (_url.protocol !== 'https:' &&
_url.protocol !== 'http:')
throw new LibsqlError('This is a HTTP client and only supports "https:" and "http:" URLs, ' +
`got ${JSON.stringify(_url.protocol + ":")}`, "URL_SCHEME_NOT_SUPPORTED");
}
export async function libsqlExecute(conf, stmt) {
try {
const res = await LIBlibsqlExecute(conf, libsqlStatementBuilder(stmt));
if (res.isOk)
return libsqlStatementResParser(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
CheckHttpUrl(conf.db_url);
const res = await LIBlibsqlExecute(conf, libsqlStatementBuilder(stmt));
if (res.isOk)
return libsqlStatementResParser(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
catch (e) {
throw mapHranaError(e);
}
}
export async function libsqlBatch(conf, steps) {
try {
const res = await LIBlibsqlBatch(conf, libsqlBatchReqStepsBuilder(steps));
if (res.isOk)
return libsqlBatchStreamResParser(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
export async function libsqlBatch(conf, steps, step_conditions) {
CheckHttpUrl(conf.db_url);
const res = await LIBlibsqlBatch(conf, libsqlBatchReqStepsBuilder(steps, step_conditions));
if (res.isOk)
return libsqlBatchStreamResParser(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
catch (e) {
throw mapHranaError(e);
}
}
export async function libsqlServerCompatCheck(conf) {
CheckHttpUrl(conf.db_url);
const res = await LIBlibsqlServerCompatCheck(conf);
return (res.isOk) ? true : false;
}
export async function libsqlBatchTransaction(conf, steps, mode = "deferred") {
CheckHttpUrl(conf.db_url);
const res = await LIBlibsqlBatch(conf, libsqlTransactionBatchReqStepsBuilder(steps, mode));
if (res.isOk)
return libsqlTransactionBatchStreamResParser(res.val);
else {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
}
export async function libsqlExecuteMultiple(conf, sql) {
CheckHttpUrl(conf.db_url);
const sqlArr = sql.split(";").filter(s => s.trim() !== "").map(s => { return { stmt: { sql: s }, condition: libsqlBatchReqStepExecCondBuilder.ok(0) }; });
for (let i = 1; i < sqlArr.length; i++)
sqlArr[i].condition = libsqlBatchReqStepExecCondBuilder.ok(i - 1);
sqlArr[0].condition = undefined;
const res = await LIBlibsqlBatch(conf, sqlArr);
if (!res.isOk) {
if (res.err.kind === "LIBSQL_SERVER_ERROR")
throw new HttpServerError(res.err.server_message || "Server encountered error.", res.err.http_status_code);
else
throw new ResponseError(res.err.data.message, res.err.data);
}
}

@@ -5,2 +5,3 @@ import { libsqlBatchStreamResOkData, libsqlSQLValue, libsqlStatementResOkData } from "libsql-stateless";

export declare function libsqlStatementResParser(res: libsqlStatementResOkData): ResultSet;
export declare function libsqlBatchStreamResParser(res: libsqlBatchStreamResOkData): Array<ResultSet>;
export declare function libsqlBatchStreamResParser(res: libsqlBatchStreamResOkData): Array<ResultSet | null>;
export declare function libsqlTransactionBatchStreamResParser(res: libsqlBatchStreamResOkData): Array<ResultSet>;

@@ -65,6 +65,13 @@ import { Base64 } from "js-base64";

batchResults.push(libsqlStatementResParser(res.step_results[j]));
else if (res.step_errors[j])
throw new ResponseError(res.step_errors[j]?.message, res.step_errors[j]);
else
throw new ResponseError(res.step_errors[j]?.message, res.step_errors[j]);
batchResults.push(null);
}
return batchResults;
}
//========================================================
export function libsqlTransactionBatchStreamResParser(res) {
const resResArr = libsqlBatchStreamResParser(res);
return resResArr.slice(1, resResArr.length - 2).filter(r => r !== null);
}

@@ -20,1 +20,29 @@ export type rawValue = null | bigint | number | string | Uint8Array;

};
/** Transaction mode.
*
* The client supports multiple modes for transactions:
*
* - `"write"` is a read-write transaction, started with `BEGIN IMMEDIATE`. This transaction mode supports
* both read statements (`SELECT`) and write statements (`INSERT`, `UPDATE`, `CREATE TABLE`, etc). The libSQL
* server cannot process multiple write transactions concurrently, so if there is another write transaction
* already started, our transaction will wait in a queue before it can begin.
*
* - `"read"` is a read-only transaction, started with `BEGIN TRANSACTION READONLY` (a libSQL extension). This
* transaction mode supports only reads (`SELECT`) and will not accept write statements. The libSQL server can
* handle multiple read transactions at the same time, so we don't need to wait for other transactions to
* complete. A read-only transaction can also be executed on a local replica, so it provides lower latency.
*
* - `"deferred"` is a transaction started with `BEGIN DEFERRED`, which starts as a read transaction, but the
* first write statement will try to upgrade it to a write transaction. However, this upgrade may fail if
* there already is a write transaction executing on the server, so you should be ready to handle these
* failures.
*
* If your transaction includes only read statements, `"read"` is always preferred over `"deferred"` or
* `"write"`, because `"read"` transactions can be executed more efficiently and don't block other
* transactions.
*
* If your transaction includes both read and write statements, you should be using the `"write"` mode most of
* the time. Use the `"deferred"` mode only if you prefer to fail the write transaction instead of waiting for
* the previous write transactions to complete.
*/
export type TransactionMode = "write" | "read" | "deferred";
{
"name": "libsql-stateless-easy",
"version": "1.3.9",
"version": "1.4.0",
"homepage": "https://github.com/DaBigBlob/libsql-stateless-easy#readme",

@@ -5,0 +5,0 @@ "repository": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc