Initial commit: New MoreminiMore website with fresh design
This commit is contained in:
20
node_modules/@libsql/core/lib-cjs/api.js
generated
vendored
Normal file
20
node_modules/@libsql/core/lib-cjs/api.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
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, rawCode, cause) {
|
||||
if (code !== undefined) {
|
||||
message = `${code}: ${message}`;
|
||||
}
|
||||
super(message, { cause });
|
||||
this.code = code;
|
||||
this.rawCode = rawCode;
|
||||
this.name = "LibsqlError";
|
||||
}
|
||||
}
|
||||
exports.LibsqlError = LibsqlError;
|
||||
141
node_modules/@libsql/core/lib-cjs/config.js
generated
vendored
Normal file
141
node_modules/@libsql/core/lib-cjs/config.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.expandConfig = exports.isInMemoryConfig = void 0;
|
||||
const api_js_1 = require("./api.js");
|
||||
const uri_js_1 = require("./uri.js");
|
||||
const util_js_1 = require("./util.js");
|
||||
const inMemoryMode = ":memory:";
|
||||
function isInMemoryConfig(config) {
|
||||
return (config.scheme === "file" &&
|
||||
(config.path === ":memory:" || config.path.startsWith(":memory:?")));
|
||||
}
|
||||
exports.isInMemoryConfig = isInMemoryConfig;
|
||||
function expandConfig(config, preferHttp) {
|
||||
if (typeof config !== "object") {
|
||||
// produce a reasonable error message in the common case where users type
|
||||
// `createClient("libsql://...")` instead of `createClient({url: "libsql://..."})`
|
||||
throw new TypeError(`Expected client configuration as object, got ${typeof config}`);
|
||||
}
|
||||
let { url, authToken, tls, intMode, concurrency } = config;
|
||||
// fill simple defaults right here
|
||||
concurrency = Math.max(0, concurrency || 20);
|
||||
intMode ??= "number";
|
||||
let connectionQueryParams = []; // recognized query parameters which we sanitize through white list of valid key-value pairs
|
||||
// convert plain :memory: url to URI format to make logic more uniform
|
||||
if (url === inMemoryMode) {
|
||||
url = "file::memory:";
|
||||
}
|
||||
// parse url parameters first and override config with update values
|
||||
const uri = (0, uri_js_1.parseUri)(url);
|
||||
const originalUriScheme = uri.scheme.toLowerCase();
|
||||
const isInMemoryMode = originalUriScheme === "file" &&
|
||||
uri.path === inMemoryMode &&
|
||||
uri.authority === undefined;
|
||||
let queryParamsDef;
|
||||
if (isInMemoryMode) {
|
||||
queryParamsDef = {
|
||||
cache: {
|
||||
values: ["shared", "private"],
|
||||
update: (key, value) => connectionQueryParams.push(`${key}=${value}`),
|
||||
},
|
||||
};
|
||||
}
|
||||
else {
|
||||
queryParamsDef = {
|
||||
tls: {
|
||||
values: ["0", "1"],
|
||||
update: (_, value) => (tls = value === "1"),
|
||||
},
|
||||
authToken: {
|
||||
update: (_, value) => (authToken = value),
|
||||
},
|
||||
};
|
||||
}
|
||||
for (const { key, value } of uri.query?.pairs ?? []) {
|
||||
if (!Object.hasOwn(queryParamsDef, key)) {
|
||||
throw new api_js_1.LibsqlError(`Unsupported URL query parameter ${JSON.stringify(key)}`, "URL_PARAM_NOT_SUPPORTED");
|
||||
}
|
||||
const queryParamDef = queryParamsDef[key];
|
||||
if (queryParamDef.values !== undefined &&
|
||||
!queryParamDef.values.includes(value)) {
|
||||
throw new api_js_1.LibsqlError(`Unknown value for the "${key}" query argument: ${JSON.stringify(value)}. Supported values are: [${queryParamDef.values.map((x) => '"' + x + '"').join(", ")}]`, "URL_INVALID");
|
||||
}
|
||||
if (queryParamDef.update !== undefined) {
|
||||
queryParamDef?.update(key, value);
|
||||
}
|
||||
}
|
||||
// fill complex defaults & validate config
|
||||
const connectionQueryParamsString = connectionQueryParams.length === 0
|
||||
? ""
|
||||
: `?${connectionQueryParams.join("&")}`;
|
||||
const path = uri.path + connectionQueryParamsString;
|
||||
let scheme;
|
||||
if (originalUriScheme === "libsql") {
|
||||
if (tls === false) {
|
||||
if (uri.authority?.port === undefined) {
|
||||
throw new api_js_1.LibsqlError('A "libsql:" URL with ?tls=0 must specify an explicit port', "URL_INVALID");
|
||||
}
|
||||
scheme = preferHttp ? "http" : "ws";
|
||||
}
|
||||
else {
|
||||
scheme = preferHttp ? "https" : "wss";
|
||||
}
|
||||
}
|
||||
else {
|
||||
scheme = originalUriScheme;
|
||||
}
|
||||
if (scheme === "http" || scheme === "ws") {
|
||||
tls ??= false;
|
||||
}
|
||||
else {
|
||||
tls ??= true;
|
||||
}
|
||||
if (scheme !== "http" &&
|
||||
scheme !== "ws" &&
|
||||
scheme !== "https" &&
|
||||
scheme !== "wss" &&
|
||||
scheme !== "file") {
|
||||
throw new api_js_1.LibsqlError('The client supports only "libsql:", "wss:", "ws:", "https:", "http:" and "file:" URLs, ' +
|
||||
`got ${JSON.stringify(uri.scheme + ":")}. ` +
|
||||
`For more information, please read ${util_js_1.supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
|
||||
}
|
||||
if (intMode !== "number" && intMode !== "bigint" && intMode !== "string") {
|
||||
throw new TypeError(`Invalid value for intMode, expected "number", "bigint" or "string", got ${JSON.stringify(intMode)}`);
|
||||
}
|
||||
if (uri.fragment !== undefined) {
|
||||
throw new api_js_1.LibsqlError(`URL fragments are not supported: ${JSON.stringify("#" + uri.fragment)}`, "URL_INVALID");
|
||||
}
|
||||
if (isInMemoryMode) {
|
||||
return {
|
||||
scheme: "file",
|
||||
tls: false,
|
||||
path,
|
||||
intMode,
|
||||
concurrency,
|
||||
syncUrl: config.syncUrl,
|
||||
syncInterval: config.syncInterval,
|
||||
readYourWrites: config.readYourWrites,
|
||||
offline: config.offline,
|
||||
fetch: config.fetch,
|
||||
authToken: undefined,
|
||||
encryptionKey: undefined,
|
||||
authority: undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
scheme,
|
||||
tls,
|
||||
authority: uri.authority,
|
||||
path,
|
||||
authToken,
|
||||
intMode,
|
||||
concurrency,
|
||||
encryptionKey: config.encryptionKey,
|
||||
syncUrl: config.syncUrl,
|
||||
syncInterval: config.syncInterval,
|
||||
readYourWrites: config.readYourWrites,
|
||||
offline: config.offline,
|
||||
fetch: config.fetch,
|
||||
};
|
||||
}
|
||||
exports.expandConfig = expandConfig;
|
||||
3
node_modules/@libsql/core/lib-cjs/package.json
generated
vendored
Normal file
3
node_modules/@libsql/core/lib-cjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
125
node_modules/@libsql/core/lib-cjs/uri.js
generated
vendored
Normal file
125
node_modules/@libsql/core/lib-cjs/uri.js
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
"use strict";
|
||||
// URI parser based on RFC 3986
|
||||
// We can't use the standard `URL` object, because we want to support relative `file:` URLs like
|
||||
// `file:relative/path/database.db`, which are not correct according to RFC 8089, which standardizes the
|
||||
// `file` scheme.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.encodeBaseUrl = exports.parseUri = void 0;
|
||||
const api_js_1 = require("./api.js");
|
||||
function parseUri(text) {
|
||||
const match = URI_RE.exec(text);
|
||||
if (match === null) {
|
||||
throw new api_js_1.LibsqlError(`The URL '${text}' is not in a valid format`, "URL_INVALID");
|
||||
}
|
||||
const groups = match.groups;
|
||||
const scheme = groups["scheme"];
|
||||
const authority = groups["authority"] !== undefined
|
||||
? parseAuthority(groups["authority"])
|
||||
: undefined;
|
||||
const path = percentDecode(groups["path"]);
|
||||
const query = groups["query"] !== undefined ? parseQuery(groups["query"]) : undefined;
|
||||
const fragment = groups["fragment"] !== undefined
|
||||
? percentDecode(groups["fragment"])
|
||||
: undefined;
|
||||
return { scheme, authority, path, query, fragment };
|
||||
}
|
||||
exports.parseUri = parseUri;
|
||||
const URI_RE = (() => {
|
||||
const SCHEME = "(?<scheme>[A-Za-z][A-Za-z.+-]*)";
|
||||
const AUTHORITY = "(?<authority>[^/?#]*)";
|
||||
const PATH = "(?<path>[^?#]*)";
|
||||
const QUERY = "(?<query>[^#]*)";
|
||||
const FRAGMENT = "(?<fragment>.*)";
|
||||
return new RegExp(`^${SCHEME}:(//${AUTHORITY})?${PATH}(\\?${QUERY})?(#${FRAGMENT})?$`, "su");
|
||||
})();
|
||||
function parseAuthority(text) {
|
||||
const match = AUTHORITY_RE.exec(text);
|
||||
if (match === null) {
|
||||
throw new api_js_1.LibsqlError("The authority part of the URL is not in a valid format", "URL_INVALID");
|
||||
}
|
||||
const groups = match.groups;
|
||||
const host = percentDecode(groups["host_br"] ?? groups["host"]);
|
||||
const port = groups["port"] ? parseInt(groups["port"], 10) : undefined;
|
||||
const userinfo = groups["username"] !== undefined
|
||||
? {
|
||||
username: percentDecode(groups["username"]),
|
||||
password: groups["password"] !== undefined
|
||||
? percentDecode(groups["password"])
|
||||
: undefined,
|
||||
}
|
||||
: undefined;
|
||||
return { host, port, userinfo };
|
||||
}
|
||||
const AUTHORITY_RE = (() => {
|
||||
return new RegExp(`^((?<username>[^:]*)(:(?<password>.*))?@)?((?<host>[^:\\[\\]]*)|(\\[(?<host_br>[^\\[\\]]*)\\]))(:(?<port>[0-9]*))?$`, "su");
|
||||
})();
|
||||
// Query string is parsed as application/x-www-form-urlencoded according to the Web URL standard:
|
||||
// https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
function parseQuery(text) {
|
||||
const sequences = text.split("&");
|
||||
const pairs = [];
|
||||
for (const sequence of sequences) {
|
||||
if (sequence === "") {
|
||||
continue;
|
||||
}
|
||||
let key;
|
||||
let value;
|
||||
const splitIdx = sequence.indexOf("=");
|
||||
if (splitIdx < 0) {
|
||||
key = sequence;
|
||||
value = "";
|
||||
}
|
||||
else {
|
||||
key = sequence.substring(0, splitIdx);
|
||||
value = sequence.substring(splitIdx + 1);
|
||||
}
|
||||
pairs.push({
|
||||
key: percentDecode(key.replaceAll("+", " ")),
|
||||
value: percentDecode(value.replaceAll("+", " ")),
|
||||
});
|
||||
}
|
||||
return { pairs };
|
||||
}
|
||||
function percentDecode(text) {
|
||||
try {
|
||||
return decodeURIComponent(text);
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof URIError) {
|
||||
throw new api_js_1.LibsqlError(`URL component has invalid percent encoding: ${e}`, "URL_INVALID", undefined, e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
function encodeBaseUrl(scheme, authority, path) {
|
||||
if (authority === undefined) {
|
||||
throw new api_js_1.LibsqlError(`URL with scheme ${JSON.stringify(scheme + ":")} requires authority (the "//" part)`, "URL_INVALID");
|
||||
}
|
||||
const schemeText = `${scheme}:`;
|
||||
const hostText = encodeHost(authority.host);
|
||||
const portText = encodePort(authority.port);
|
||||
const userinfoText = encodeUserinfo(authority.userinfo);
|
||||
const authorityText = `//${userinfoText}${hostText}${portText}`;
|
||||
let pathText = path.split("/").map(encodeURIComponent).join("/");
|
||||
if (pathText !== "" && !pathText.startsWith("/")) {
|
||||
pathText = "/" + pathText;
|
||||
}
|
||||
return new URL(`${schemeText}${authorityText}${pathText}`);
|
||||
}
|
||||
exports.encodeBaseUrl = encodeBaseUrl;
|
||||
function encodeHost(host) {
|
||||
return host.includes(":") ? `[${encodeURI(host)}]` : encodeURI(host);
|
||||
}
|
||||
function encodePort(port) {
|
||||
return port !== undefined ? `:${port}` : "";
|
||||
}
|
||||
function encodeUserinfo(userinfo) {
|
||||
if (userinfo === undefined) {
|
||||
return "";
|
||||
}
|
||||
const usernameText = encodeURIComponent(userinfo.username);
|
||||
const passwordText = userinfo.password !== undefined
|
||||
? `:${encodeURIComponent(userinfo.password)}`
|
||||
: "";
|
||||
return `${usernameText}${passwordText}@`;
|
||||
}
|
||||
60
node_modules/@libsql/core/lib-cjs/util.js
generated
vendored
Normal file
60
node_modules/@libsql/core/lib-cjs/util.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ResultSetImpl = exports.transactionModeToBegin = exports.supportedUrlLink = void 0;
|
||||
const js_base64_1 = require("js-base64");
|
||||
exports.supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
|
||||
function transactionModeToBegin(mode) {
|
||||
if (mode === "write") {
|
||||
return "BEGIN IMMEDIATE";
|
||||
}
|
||||
else if (mode === "read") {
|
||||
return "BEGIN TRANSACTION READONLY";
|
||||
}
|
||||
else if (mode === "deferred") {
|
||||
return "BEGIN DEFERRED";
|
||||
}
|
||||
else {
|
||||
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
|
||||
}
|
||||
}
|
||||
exports.transactionModeToBegin = transactionModeToBegin;
|
||||
class ResultSetImpl {
|
||||
columns;
|
||||
columnTypes;
|
||||
rows;
|
||||
rowsAffected;
|
||||
lastInsertRowid;
|
||||
constructor(columns, columnTypes, rows, rowsAffected, lastInsertRowid) {
|
||||
this.columns = columns;
|
||||
this.columnTypes = columnTypes;
|
||||
this.rows = rows;
|
||||
this.rowsAffected = rowsAffected;
|
||||
this.lastInsertRowid = lastInsertRowid;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
columns: this.columns,
|
||||
columnTypes: this.columnTypes,
|
||||
rows: this.rows.map(rowToJson),
|
||||
rowsAffected: this.rowsAffected,
|
||||
lastInsertRowid: this.lastInsertRowid !== undefined
|
||||
? "" + this.lastInsertRowid
|
||||
: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.ResultSetImpl = ResultSetImpl;
|
||||
function rowToJson(row) {
|
||||
return Array.prototype.map.call(row, valueToJson);
|
||||
}
|
||||
function valueToJson(value) {
|
||||
if (typeof value === "bigint") {
|
||||
return "" + value;
|
||||
}
|
||||
else if (value instanceof ArrayBuffer) {
|
||||
return js_base64_1.Base64.fromUint8Array(new Uint8Array(value));
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
449
node_modules/@libsql/core/lib-esm/api.d.ts
generated
vendored
Normal file
449
node_modules/@libsql/core/lib-esm/api.d.ts
generated
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
/** Configuration object for {@link createClient}. */
|
||||
export interface Config {
|
||||
/** The database URL.
|
||||
*
|
||||
* The client supports `libsql:`, `http:`/`https:`, `ws:`/`wss:` and `file:` URL. For more infomation,
|
||||
* please refer to the project README:
|
||||
*
|
||||
* https://github.com/libsql/libsql-client-ts#supported-urls
|
||||
*/
|
||||
url: string;
|
||||
/** Authentication token for the database. */
|
||||
authToken?: string;
|
||||
/** Encryption key for the database. */
|
||||
encryptionKey?: string;
|
||||
/** URL of a remote server to synchronize database with. */
|
||||
syncUrl?: string;
|
||||
/** Sync interval in seconds. */
|
||||
syncInterval?: number;
|
||||
/** Read your writes */
|
||||
readYourWrites?: boolean;
|
||||
/** Enable offline writes */
|
||||
offline?: boolean;
|
||||
/** Enables or disables TLS for `libsql:` URLs.
|
||||
*
|
||||
* By default, `libsql:` URLs use TLS. You can set this option to `false` to disable TLS.
|
||||
*/
|
||||
tls?: boolean;
|
||||
/** How to convert SQLite integers to JavaScript values:
|
||||
*
|
||||
* - `"number"` (default): returns SQLite integers as JavaScript `number`-s (double precision floats).
|
||||
* `number` cannot precisely represent integers larger than 2^53-1 in absolute value, so attempting to read
|
||||
* larger integers will throw a `RangeError`.
|
||||
* - `"bigint"`: returns SQLite integers as JavaScript `bigint`-s (arbitrary precision integers). Bigints can
|
||||
* precisely represent all SQLite integers.
|
||||
* - `"string"`: returns SQLite integers as strings.
|
||||
*/
|
||||
intMode?: IntMode;
|
||||
/** Custom `fetch` function to use for the HTTP client.
|
||||
*
|
||||
* By default, the HTTP client uses `fetch` from the `@libsql/isomorphic-fetch` package, but you can pass
|
||||
* your own function here. The argument to this function will be `Request` from
|
||||
* `@libsql/isomorphic-fetch`, and it must return a promise that resolves to an object that is compatible
|
||||
* with the Web `Response`.
|
||||
*/
|
||||
fetch?: Function;
|
||||
/** Concurrency limit.
|
||||
*
|
||||
* By default, the client performs up to 20 concurrent requests. You can set this option to a higher
|
||||
* number to increase the concurrency limit or set it to 0 to disable concurrency limits completely.
|
||||
*/
|
||||
concurrency?: number | undefined;
|
||||
}
|
||||
/** Representation of integers from database as JavaScript values. See {@link Config.intMode}. */
|
||||
export type IntMode = "number" | "bigint" | "string";
|
||||
/** Client object for a remote or local database.
|
||||
*
|
||||
* After you are done with the client, you **should** close it by calling {@link close}.
|
||||
*/
|
||||
export interface Client {
|
||||
/** 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} or the {@link
|
||||
* transaction} methods.
|
||||
*
|
||||
* ```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: InStatement): Promise<ResultSet>;
|
||||
execute(sql: string, args?: InArgs): Promise<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. If you need interactive transactions, please use the
|
||||
* {@link transaction} method.
|
||||
*
|
||||
* ```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(stmts: Array<InStatement | [string, InArgs?]>, mode?: TransactionMode): Promise<Array<ResultSet>>;
|
||||
/** Execute a batch of SQL statements in a transaction with PRAGMA foreign_keys=off; before and PRAGMA foreign_keys=on; after.
|
||||
*
|
||||
* 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 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.
|
||||
*
|
||||
* ```javascript
|
||||
* const rss = await client.migrate([
|
||||
* // statement without arguments
|
||||
* "CREATE TABLE test (a INT)",
|
||||
*
|
||||
* // statement with positional arguments
|
||||
* {
|
||||
* sql: "INSERT INTO books (name, author, published_at) VALUES (?, ?, ?)",
|
||||
* args: ["First Impressions", "Jane Austen", 1813],
|
||||
* },
|
||||
*
|
||||
* // statement with named arguments
|
||||
* {
|
||||
* sql: "UPDATE books SET name = $new WHERE name = $old",
|
||||
* args: {old: "First Impressions", new: "Pride and Prejudice"},
|
||||
* },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
migrate(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
|
||||
/** Start an interactive transaction.
|
||||
*
|
||||
* Interactive transactions allow you to interleave execution of SQL statements with your application
|
||||
* logic. They can be used if the {@link batch} method is too restrictive, but please note that
|
||||
* interactive transactions have higher latency.
|
||||
*
|
||||
* The `mode` parameter selects the transaction mode for the interactive transaction; please see {@link
|
||||
* TransactionMode} for details. The default transaction mode is `"deferred"`.
|
||||
*
|
||||
* You **must** make sure that the returned {@link Transaction} object is closed, by calling {@link
|
||||
* Transaction.close}, {@link Transaction.commit} or {@link Transaction.rollback}. The best practice is
|
||||
* to call {@link Transaction.close} in a `finally` block, as follows:
|
||||
*
|
||||
* ```javascript
|
||||
* const transaction = client.transaction("write");
|
||||
* try {
|
||||
* // do some operations with the transaction here
|
||||
* await transaction.execute({
|
||||
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
|
||||
* args: ["First Impressions", "Jane Austen"],
|
||||
* });
|
||||
* await transaction.execute({
|
||||
* sql: "UPDATE books SET name = ? WHERE name = ?",
|
||||
* args: ["Pride and Prejudice", "First Impressions"],
|
||||
* });
|
||||
*
|
||||
* // if all went well, commit the transaction
|
||||
* await transaction.commit();
|
||||
* } finally {
|
||||
* // make sure to close the transaction, even if an exception was thrown
|
||||
* transaction.close();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
transaction(mode?: TransactionMode): Promise<Transaction>;
|
||||
/** Start an interactive transaction in `"write"` mode.
|
||||
*
|
||||
* Please see {@link transaction} for details.
|
||||
*
|
||||
* @deprecated Please specify the `mode` explicitly. The default `"write"` will be removed in the next
|
||||
* major release.
|
||||
*/
|
||||
transaction(): Promise<Transaction>;
|
||||
/** 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<Replicated>;
|
||||
/** Close the client and release resources.
|
||||
*
|
||||
* This method closes the client (aborting any operations that are currently in progress) and releases any
|
||||
* resources associated with the client (such as a WebSocket connection).
|
||||
*/
|
||||
close(): void;
|
||||
/** Reconnect after the client has been closed.
|
||||
*/
|
||||
reconnect(): void;
|
||||
/** Is the client closed?
|
||||
*
|
||||
* This is set to `true` after a call to {@link close} or if the client encounters an unrecoverable
|
||||
* error.
|
||||
*/
|
||||
closed: boolean;
|
||||
/** 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
|
||||
*/
|
||||
protocol: string;
|
||||
}
|
||||
/** Interactive transaction.
|
||||
*
|
||||
* A transaction groups multiple SQL statements together, so that they are applied atomically: either all
|
||||
* changes are applied, or none are. Other SQL statements on the database (including statements executed on
|
||||
* the same {@link Client} object outside of this transaction) will not see any changes from the transaction
|
||||
* until the transaction is committed by calling {@link commit}. You can also use {@link rollback} to abort
|
||||
* the transaction and roll back the changes.
|
||||
*
|
||||
* You **must** make sure that the {@link Transaction} object is closed, by calling {@link close}, {@link
|
||||
* commit} or {@link rollback}. The best practice is to call {@link close} in a `finally` block, as follows:
|
||||
*
|
||||
* ```javascript
|
||||
* const transaction = client.transaction("write");
|
||||
* try {
|
||||
* // do some operations with the transaction here
|
||||
* await transaction.execute({
|
||||
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
|
||||
* args: ["First Impressions", "Jane Austen"],
|
||||
* });
|
||||
* await transaction.execute({
|
||||
* sql: "UPDATE books SET name = ? WHERE name = ?",
|
||||
* args: ["Pride and Prejudice", "First Impressions"],
|
||||
* });
|
||||
*
|
||||
* // if all went well, commit the transaction
|
||||
* await transaction.commit();
|
||||
* } finally {
|
||||
* // make sure to close the transaction, even if an exception was thrown
|
||||
* transaction.close();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface Transaction {
|
||||
/** Execute an SQL statement in this transaction.
|
||||
*
|
||||
* If the statement makes any changes to the database, these changes won't be visible to statements
|
||||
* outside of this transaction until you call {@link rollback}.
|
||||
*
|
||||
* ```javascript
|
||||
* await transaction.execute({
|
||||
* sql: "INSERT INTO books (name, author) VALUES (?, ?)",
|
||||
* args: ["First Impressions", "Jane Austen"],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
execute(stmt: InStatement): Promise<ResultSet>;
|
||||
/** Execute a batch of SQL statements in this transaction.
|
||||
*
|
||||
* If any of the statements in the batch fails with an error, further statements are not executed and the
|
||||
* returned promise is rejected with an error, but the transaction is not rolled back.
|
||||
*/
|
||||
batch(stmts: Array<InStatement>): Promise<Array<ResultSet>>;
|
||||
/** Execute a sequence of SQL statements separated by semicolons.
|
||||
*
|
||||
* The statements are executed sequentially in the transaction. If a statement fails, further statements
|
||||
* are not executed and this method throws an error, but the transaction won't be rolled back. All results
|
||||
* from the statements are ignored.
|
||||
*
|
||||
* This method is intended to be used with existing SQL scripts, such as migrations or small database
|
||||
* dumps. If you want to execute statements programmatically, please use {@link batch} instead.
|
||||
*/
|
||||
executeMultiple(sql: string): Promise<void>;
|
||||
/** Roll back any changes from this transaction.
|
||||
*
|
||||
* This method closes the transaction and undoes any changes done by the previous SQL statements on this
|
||||
* transaction. You cannot call this method after calling {@link commit}, though.
|
||||
*/
|
||||
rollback(): Promise<void>;
|
||||
/** Commit changes from this transaction to the database.
|
||||
*
|
||||
* This method closes the transaction and applies all changes done by the previous SQL statement on this
|
||||
* transaction. Once the returned promise is resolved successfully, the database guarantees that the
|
||||
* changes were applied.
|
||||
*/
|
||||
commit(): Promise<void>;
|
||||
/** Close the transaction.
|
||||
*
|
||||
* This method closes the transaction and releases any resources associated with the transaction. If the
|
||||
* transaction is already closed (perhaps by a previous call to {@link commit} or {@link rollback}), then
|
||||
* this method does nothing.
|
||||
*
|
||||
* If the transaction wasn't already committed by calling {@link commit}, the transaction is rolled
|
||||
* back.
|
||||
*/
|
||||
close(): void;
|
||||
/** Is the transaction closed?
|
||||
*
|
||||
* This is set to `true` after a call to {@link close}, {@link commit} or {@link rollback}, or if we
|
||||
* encounter an unrecoverable error.
|
||||
*/
|
||||
closed: boolean;
|
||||
}
|
||||
/** 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";
|
||||
/** Result of executing an SQL statement.
|
||||
*
|
||||
* ```javascript
|
||||
* const rs = await client.execute("SELECT name, title FROM books");
|
||||
* console.log(`Found ${rs.rows.length} books`);
|
||||
* for (const row in rs.rows) {
|
||||
* console.log(`Book ${row[0]} by ${row[1]}`);
|
||||
* }
|
||||
*
|
||||
* const rs = await client.execute("DELETE FROM books WHERE author = 'Jane Austen'");
|
||||
* console.log(`Deleted ${rs.rowsAffected} books`);
|
||||
* ```
|
||||
*/
|
||||
export interface ResultSet {
|
||||
/** Names of columns.
|
||||
*
|
||||
* Names of columns can be defined using the `AS` keyword in SQL:
|
||||
*
|
||||
* ```sql
|
||||
* SELECT author AS author, COUNT(*) AS count FROM books GROUP BY author
|
||||
* ```
|
||||
*/
|
||||
columns: Array<string>;
|
||||
/** Types of columns.
|
||||
*
|
||||
* The types are currently shown for types declared in a SQL table. For
|
||||
* column types of function calls, for example, an empty string is
|
||||
* returned.
|
||||
*/
|
||||
columnTypes: Array<string>;
|
||||
/** Rows produced by the statement. */
|
||||
rows: Array<Row>;
|
||||
/** Number of rows that were affected by an UPDATE, INSERT or DELETE operation.
|
||||
*
|
||||
* This value is not specified for other SQL statements.
|
||||
*/
|
||||
rowsAffected: number;
|
||||
/** ROWID of the last inserted row.
|
||||
*
|
||||
* This value is not specified if the SQL statement was not an INSERT or if the table was not a ROWID
|
||||
* table.
|
||||
*/
|
||||
lastInsertRowid: bigint | undefined;
|
||||
/** Converts the result set to JSON.
|
||||
*
|
||||
* This is used automatically by `JSON.stringify()`, but you can also call it explicitly.
|
||||
*/
|
||||
toJSON(): any;
|
||||
}
|
||||
/** Row returned from an SQL statement.
|
||||
*
|
||||
* The row object can be used as an `Array` or as an object:
|
||||
*
|
||||
* ```javascript
|
||||
* const rs = await client.execute("SELECT name, title FROM books");
|
||||
* for (const row in rs.rows) {
|
||||
* // Get the value from column `name`
|
||||
* console.log(row.name);
|
||||
* // Get the value from second column (`title`)
|
||||
* console.log(row[1]);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface Row {
|
||||
/** Number of columns in this row.
|
||||
*
|
||||
* All rows in one {@link ResultSet} have the same number and names of columns.
|
||||
*/
|
||||
length: number;
|
||||
/** Columns can be accessed like an array by numeric indexes. */
|
||||
[index: number]: Value;
|
||||
/** Columns can be accessed like an object by column names. */
|
||||
[name: string]: Value;
|
||||
}
|
||||
export type Replicated = {
|
||||
frame_no: number;
|
||||
frames_synced: number;
|
||||
} | undefined;
|
||||
export type Value = null | string | number | bigint | ArrayBuffer;
|
||||
export type InValue = Value | boolean | Uint8Array | Date;
|
||||
export type InStatement = {
|
||||
sql: string;
|
||||
args?: InArgs;
|
||||
} | string;
|
||||
export type InArgs = Array<InValue> | Record<string, InValue>;
|
||||
/** 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);
|
||||
}
|
||||
16
node_modules/@libsql/core/lib-esm/api.js
generated
vendored
Normal file
16
node_modules/@libsql/core/lib-esm/api.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/** 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";
|
||||
}
|
||||
}
|
||||
20
node_modules/@libsql/core/lib-esm/config.d.ts
generated
vendored
Normal file
20
node_modules/@libsql/core/lib-esm/config.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { Config, IntMode } from "./api.js";
|
||||
import type { Authority } from "./uri.js";
|
||||
export interface ExpandedConfig {
|
||||
scheme: ExpandedScheme;
|
||||
tls: boolean;
|
||||
authority: Authority | undefined;
|
||||
path: string;
|
||||
authToken: string | undefined;
|
||||
encryptionKey: string | undefined;
|
||||
syncUrl: string | undefined;
|
||||
syncInterval: number | undefined;
|
||||
readYourWrites: boolean | undefined;
|
||||
offline: boolean | undefined;
|
||||
intMode: IntMode;
|
||||
fetch: Function | undefined;
|
||||
concurrency: number;
|
||||
}
|
||||
export type ExpandedScheme = "wss" | "ws" | "https" | "http" | "file";
|
||||
export declare function isInMemoryConfig(config: ExpandedConfig): boolean;
|
||||
export declare function expandConfig(config: Readonly<Config>, preferHttp: boolean): ExpandedConfig;
|
||||
136
node_modules/@libsql/core/lib-esm/config.js
generated
vendored
Normal file
136
node_modules/@libsql/core/lib-esm/config.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
import { LibsqlError } from "./api.js";
|
||||
import { parseUri } from "./uri.js";
|
||||
import { supportedUrlLink } from "./util.js";
|
||||
const inMemoryMode = ":memory:";
|
||||
export function isInMemoryConfig(config) {
|
||||
return (config.scheme === "file" &&
|
||||
(config.path === ":memory:" || config.path.startsWith(":memory:?")));
|
||||
}
|
||||
export function expandConfig(config, preferHttp) {
|
||||
if (typeof config !== "object") {
|
||||
// produce a reasonable error message in the common case where users type
|
||||
// `createClient("libsql://...")` instead of `createClient({url: "libsql://..."})`
|
||||
throw new TypeError(`Expected client configuration as object, got ${typeof config}`);
|
||||
}
|
||||
let { url, authToken, tls, intMode, concurrency } = config;
|
||||
// fill simple defaults right here
|
||||
concurrency = Math.max(0, concurrency || 20);
|
||||
intMode ??= "number";
|
||||
let connectionQueryParams = []; // recognized query parameters which we sanitize through white list of valid key-value pairs
|
||||
// convert plain :memory: url to URI format to make logic more uniform
|
||||
if (url === inMemoryMode) {
|
||||
url = "file::memory:";
|
||||
}
|
||||
// parse url parameters first and override config with update values
|
||||
const uri = parseUri(url);
|
||||
const originalUriScheme = uri.scheme.toLowerCase();
|
||||
const isInMemoryMode = originalUriScheme === "file" &&
|
||||
uri.path === inMemoryMode &&
|
||||
uri.authority === undefined;
|
||||
let queryParamsDef;
|
||||
if (isInMemoryMode) {
|
||||
queryParamsDef = {
|
||||
cache: {
|
||||
values: ["shared", "private"],
|
||||
update: (key, value) => connectionQueryParams.push(`${key}=${value}`),
|
||||
},
|
||||
};
|
||||
}
|
||||
else {
|
||||
queryParamsDef = {
|
||||
tls: {
|
||||
values: ["0", "1"],
|
||||
update: (_, value) => (tls = value === "1"),
|
||||
},
|
||||
authToken: {
|
||||
update: (_, value) => (authToken = value),
|
||||
},
|
||||
};
|
||||
}
|
||||
for (const { key, value } of uri.query?.pairs ?? []) {
|
||||
if (!Object.hasOwn(queryParamsDef, key)) {
|
||||
throw new LibsqlError(`Unsupported URL query parameter ${JSON.stringify(key)}`, "URL_PARAM_NOT_SUPPORTED");
|
||||
}
|
||||
const queryParamDef = queryParamsDef[key];
|
||||
if (queryParamDef.values !== undefined &&
|
||||
!queryParamDef.values.includes(value)) {
|
||||
throw new LibsqlError(`Unknown value for the "${key}" query argument: ${JSON.stringify(value)}. Supported values are: [${queryParamDef.values.map((x) => '"' + x + '"').join(", ")}]`, "URL_INVALID");
|
||||
}
|
||||
if (queryParamDef.update !== undefined) {
|
||||
queryParamDef?.update(key, value);
|
||||
}
|
||||
}
|
||||
// fill complex defaults & validate config
|
||||
const connectionQueryParamsString = connectionQueryParams.length === 0
|
||||
? ""
|
||||
: `?${connectionQueryParams.join("&")}`;
|
||||
const path = uri.path + connectionQueryParamsString;
|
||||
let scheme;
|
||||
if (originalUriScheme === "libsql") {
|
||||
if (tls === false) {
|
||||
if (uri.authority?.port === undefined) {
|
||||
throw new LibsqlError('A "libsql:" URL with ?tls=0 must specify an explicit port', "URL_INVALID");
|
||||
}
|
||||
scheme = preferHttp ? "http" : "ws";
|
||||
}
|
||||
else {
|
||||
scheme = preferHttp ? "https" : "wss";
|
||||
}
|
||||
}
|
||||
else {
|
||||
scheme = originalUriScheme;
|
||||
}
|
||||
if (scheme === "http" || scheme === "ws") {
|
||||
tls ??= false;
|
||||
}
|
||||
else {
|
||||
tls ??= true;
|
||||
}
|
||||
if (scheme !== "http" &&
|
||||
scheme !== "ws" &&
|
||||
scheme !== "https" &&
|
||||
scheme !== "wss" &&
|
||||
scheme !== "file") {
|
||||
throw new LibsqlError('The client supports only "libsql:", "wss:", "ws:", "https:", "http:" and "file:" URLs, ' +
|
||||
`got ${JSON.stringify(uri.scheme + ":")}. ` +
|
||||
`For more information, please read ${supportedUrlLink}`, "URL_SCHEME_NOT_SUPPORTED");
|
||||
}
|
||||
if (intMode !== "number" && intMode !== "bigint" && intMode !== "string") {
|
||||
throw new TypeError(`Invalid value for intMode, expected "number", "bigint" or "string", got ${JSON.stringify(intMode)}`);
|
||||
}
|
||||
if (uri.fragment !== undefined) {
|
||||
throw new LibsqlError(`URL fragments are not supported: ${JSON.stringify("#" + uri.fragment)}`, "URL_INVALID");
|
||||
}
|
||||
if (isInMemoryMode) {
|
||||
return {
|
||||
scheme: "file",
|
||||
tls: false,
|
||||
path,
|
||||
intMode,
|
||||
concurrency,
|
||||
syncUrl: config.syncUrl,
|
||||
syncInterval: config.syncInterval,
|
||||
readYourWrites: config.readYourWrites,
|
||||
offline: config.offline,
|
||||
fetch: config.fetch,
|
||||
authToken: undefined,
|
||||
encryptionKey: undefined,
|
||||
authority: undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
scheme,
|
||||
tls,
|
||||
authority: uri.authority,
|
||||
path,
|
||||
authToken,
|
||||
intMode,
|
||||
concurrency,
|
||||
encryptionKey: config.encryptionKey,
|
||||
syncUrl: config.syncUrl,
|
||||
syncInterval: config.syncInterval,
|
||||
readYourWrites: config.readYourWrites,
|
||||
offline: config.offline,
|
||||
fetch: config.fetch,
|
||||
};
|
||||
}
|
||||
30
node_modules/@libsql/core/lib-esm/uri.d.ts
generated
vendored
Normal file
30
node_modules/@libsql/core/lib-esm/uri.d.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/// <reference types="node" />
|
||||
export interface Uri {
|
||||
scheme: string;
|
||||
authority: Authority | undefined;
|
||||
path: string;
|
||||
query: Query | undefined;
|
||||
fragment: string | undefined;
|
||||
}
|
||||
export interface HierPart {
|
||||
authority: Authority | undefined;
|
||||
path: string;
|
||||
}
|
||||
export interface Authority {
|
||||
host: string;
|
||||
port: number | undefined;
|
||||
userinfo: Userinfo | undefined;
|
||||
}
|
||||
export interface Userinfo {
|
||||
username: string;
|
||||
password: string | undefined;
|
||||
}
|
||||
export interface Query {
|
||||
pairs: Array<KeyValue>;
|
||||
}
|
||||
export interface KeyValue {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
export declare function parseUri(text: string): Uri;
|
||||
export declare function encodeBaseUrl(scheme: string, authority: Authority | undefined, path: string): URL;
|
||||
120
node_modules/@libsql/core/lib-esm/uri.js
generated
vendored
Normal file
120
node_modules/@libsql/core/lib-esm/uri.js
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// URI parser based on RFC 3986
|
||||
// We can't use the standard `URL` object, because we want to support relative `file:` URLs like
|
||||
// `file:relative/path/database.db`, which are not correct according to RFC 8089, which standardizes the
|
||||
// `file` scheme.
|
||||
import { LibsqlError } from "./api.js";
|
||||
export function parseUri(text) {
|
||||
const match = URI_RE.exec(text);
|
||||
if (match === null) {
|
||||
throw new LibsqlError(`The URL '${text}' is not in a valid format`, "URL_INVALID");
|
||||
}
|
||||
const groups = match.groups;
|
||||
const scheme = groups["scheme"];
|
||||
const authority = groups["authority"] !== undefined
|
||||
? parseAuthority(groups["authority"])
|
||||
: undefined;
|
||||
const path = percentDecode(groups["path"]);
|
||||
const query = groups["query"] !== undefined ? parseQuery(groups["query"]) : undefined;
|
||||
const fragment = groups["fragment"] !== undefined
|
||||
? percentDecode(groups["fragment"])
|
||||
: undefined;
|
||||
return { scheme, authority, path, query, fragment };
|
||||
}
|
||||
const URI_RE = (() => {
|
||||
const SCHEME = "(?<scheme>[A-Za-z][A-Za-z.+-]*)";
|
||||
const AUTHORITY = "(?<authority>[^/?#]*)";
|
||||
const PATH = "(?<path>[^?#]*)";
|
||||
const QUERY = "(?<query>[^#]*)";
|
||||
const FRAGMENT = "(?<fragment>.*)";
|
||||
return new RegExp(`^${SCHEME}:(//${AUTHORITY})?${PATH}(\\?${QUERY})?(#${FRAGMENT})?$`, "su");
|
||||
})();
|
||||
function parseAuthority(text) {
|
||||
const match = AUTHORITY_RE.exec(text);
|
||||
if (match === null) {
|
||||
throw new LibsqlError("The authority part of the URL is not in a valid format", "URL_INVALID");
|
||||
}
|
||||
const groups = match.groups;
|
||||
const host = percentDecode(groups["host_br"] ?? groups["host"]);
|
||||
const port = groups["port"] ? parseInt(groups["port"], 10) : undefined;
|
||||
const userinfo = groups["username"] !== undefined
|
||||
? {
|
||||
username: percentDecode(groups["username"]),
|
||||
password: groups["password"] !== undefined
|
||||
? percentDecode(groups["password"])
|
||||
: undefined,
|
||||
}
|
||||
: undefined;
|
||||
return { host, port, userinfo };
|
||||
}
|
||||
const AUTHORITY_RE = (() => {
|
||||
return new RegExp(`^((?<username>[^:]*)(:(?<password>.*))?@)?((?<host>[^:\\[\\]]*)|(\\[(?<host_br>[^\\[\\]]*)\\]))(:(?<port>[0-9]*))?$`, "su");
|
||||
})();
|
||||
// Query string is parsed as application/x-www-form-urlencoded according to the Web URL standard:
|
||||
// https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
function parseQuery(text) {
|
||||
const sequences = text.split("&");
|
||||
const pairs = [];
|
||||
for (const sequence of sequences) {
|
||||
if (sequence === "") {
|
||||
continue;
|
||||
}
|
||||
let key;
|
||||
let value;
|
||||
const splitIdx = sequence.indexOf("=");
|
||||
if (splitIdx < 0) {
|
||||
key = sequence;
|
||||
value = "";
|
||||
}
|
||||
else {
|
||||
key = sequence.substring(0, splitIdx);
|
||||
value = sequence.substring(splitIdx + 1);
|
||||
}
|
||||
pairs.push({
|
||||
key: percentDecode(key.replaceAll("+", " ")),
|
||||
value: percentDecode(value.replaceAll("+", " ")),
|
||||
});
|
||||
}
|
||||
return { pairs };
|
||||
}
|
||||
function percentDecode(text) {
|
||||
try {
|
||||
return decodeURIComponent(text);
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof URIError) {
|
||||
throw new LibsqlError(`URL component has invalid percent encoding: ${e}`, "URL_INVALID", undefined, e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
export function encodeBaseUrl(scheme, authority, path) {
|
||||
if (authority === undefined) {
|
||||
throw new LibsqlError(`URL with scheme ${JSON.stringify(scheme + ":")} requires authority (the "//" part)`, "URL_INVALID");
|
||||
}
|
||||
const schemeText = `${scheme}:`;
|
||||
const hostText = encodeHost(authority.host);
|
||||
const portText = encodePort(authority.port);
|
||||
const userinfoText = encodeUserinfo(authority.userinfo);
|
||||
const authorityText = `//${userinfoText}${hostText}${portText}`;
|
||||
let pathText = path.split("/").map(encodeURIComponent).join("/");
|
||||
if (pathText !== "" && !pathText.startsWith("/")) {
|
||||
pathText = "/" + pathText;
|
||||
}
|
||||
return new URL(`${schemeText}${authorityText}${pathText}`);
|
||||
}
|
||||
function encodeHost(host) {
|
||||
return host.includes(":") ? `[${encodeURI(host)}]` : encodeURI(host);
|
||||
}
|
||||
function encodePort(port) {
|
||||
return port !== undefined ? `:${port}` : "";
|
||||
}
|
||||
function encodeUserinfo(userinfo) {
|
||||
if (userinfo === undefined) {
|
||||
return "";
|
||||
}
|
||||
const usernameText = encodeURIComponent(userinfo.username);
|
||||
const passwordText = userinfo.password !== undefined
|
||||
? `:${encodeURIComponent(userinfo.password)}`
|
||||
: "";
|
||||
return `${usernameText}${passwordText}@`;
|
||||
}
|
||||
12
node_modules/@libsql/core/lib-esm/util.d.ts
generated
vendored
Normal file
12
node_modules/@libsql/core/lib-esm/util.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ResultSet, Row, TransactionMode } from "./api";
|
||||
export declare const supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
|
||||
export declare function transactionModeToBegin(mode: TransactionMode): string;
|
||||
export declare class ResultSetImpl implements ResultSet {
|
||||
columns: Array<string>;
|
||||
columnTypes: Array<string>;
|
||||
rows: Array<Row>;
|
||||
rowsAffected: number;
|
||||
lastInsertRowid: bigint | undefined;
|
||||
constructor(columns: Array<string>, columnTypes: Array<string>, rows: Array<Row>, rowsAffected: number, lastInsertRowid: bigint | undefined);
|
||||
toJSON(): any;
|
||||
}
|
||||
55
node_modules/@libsql/core/lib-esm/util.js
generated
vendored
Normal file
55
node_modules/@libsql/core/lib-esm/util.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Base64 } from "js-base64";
|
||||
export const supportedUrlLink = "https://github.com/libsql/libsql-client-ts#supported-urls";
|
||||
export function transactionModeToBegin(mode) {
|
||||
if (mode === "write") {
|
||||
return "BEGIN IMMEDIATE";
|
||||
}
|
||||
else if (mode === "read") {
|
||||
return "BEGIN TRANSACTION READONLY";
|
||||
}
|
||||
else if (mode === "deferred") {
|
||||
return "BEGIN DEFERRED";
|
||||
}
|
||||
else {
|
||||
throw RangeError('Unknown transaction mode, supported values are "write", "read" and "deferred"');
|
||||
}
|
||||
}
|
||||
export class ResultSetImpl {
|
||||
columns;
|
||||
columnTypes;
|
||||
rows;
|
||||
rowsAffected;
|
||||
lastInsertRowid;
|
||||
constructor(columns, columnTypes, rows, rowsAffected, lastInsertRowid) {
|
||||
this.columns = columns;
|
||||
this.columnTypes = columnTypes;
|
||||
this.rows = rows;
|
||||
this.rowsAffected = rowsAffected;
|
||||
this.lastInsertRowid = lastInsertRowid;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
columns: this.columns,
|
||||
columnTypes: this.columnTypes,
|
||||
rows: this.rows.map(rowToJson),
|
||||
rowsAffected: this.rowsAffected,
|
||||
lastInsertRowid: this.lastInsertRowid !== undefined
|
||||
? "" + this.lastInsertRowid
|
||||
: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
function rowToJson(row) {
|
||||
return Array.prototype.map.call(row, valueToJson);
|
||||
}
|
||||
function valueToJson(value) {
|
||||
if (typeof value === "bigint") {
|
||||
return "" + value;
|
||||
}
|
||||
else if (value instanceof ArrayBuffer) {
|
||||
return Base64.fromUint8Array(new Uint8Array(value));
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
91
node_modules/@libsql/core/package.json
generated
vendored
Normal file
91
node_modules/@libsql/core/package.json
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"name": "@libsql/core",
|
||||
"version": "0.15.15",
|
||||
"keywords": [
|
||||
"libsql",
|
||||
"database",
|
||||
"sqlite",
|
||||
"serverless",
|
||||
"vercel",
|
||||
"netlify",
|
||||
"lambda"
|
||||
],
|
||||
"description": "libSQL driver for TypeScript and JavaScript",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/libsql/libsql-client-ts",
|
||||
"directory": "packages/libsql-core"
|
||||
},
|
||||
"authors": [
|
||||
"Jan Špaček <honza@chiselstrike.com>",
|
||||
"Pekka Enberg <penberg@chiselstrike.com>",
|
||||
"Jan Plhak <jp@chiselstrike.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./api": {
|
||||
"types": "./lib-esm/api.d.ts",
|
||||
"import": "./lib-esm/api.js",
|
||||
"require": "./lib-cjs/api.js"
|
||||
},
|
||||
"./config": {
|
||||
"types": "./lib-esm/config.d.ts",
|
||||
"import": "./lib-esm/config.js",
|
||||
"require": "./lib-cjs/config.js"
|
||||
},
|
||||
"./uri": {
|
||||
"types": "./lib-esm/uri.d.ts",
|
||||
"import": "./lib-esm/uri.js",
|
||||
"require": "./lib-cjs/uri.js"
|
||||
},
|
||||
"./util": {
|
||||
"types": "./lib-esm/util.d.ts",
|
||||
"import": "./lib-esm/util.js",
|
||||
"require": "./lib-cjs/util.js"
|
||||
}
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"api": [
|
||||
"./lib-esm/api.d.ts"
|
||||
],
|
||||
"config": [
|
||||
"./lib-esm/config.d.ts"
|
||||
],
|
||||
"uri": [
|
||||
"./lib-esm/uri.d.ts"
|
||||
],
|
||||
"util": [
|
||||
"./lib-esm/util.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"lib-cjs/**",
|
||||
"lib-esm/**"
|
||||
],
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run build",
|
||||
"prebuild": "rm -rf ./lib-cjs ./lib-esm",
|
||||
"build": "npm run build:cjs && npm run build:esm",
|
||||
"build:cjs": "tsc -p tsconfig.build-cjs.json",
|
||||
"build:esm": "tsc -p tsconfig.build-esm.json",
|
||||
"format:check": "prettier --check .",
|
||||
"postbuild": "cp package-cjs.json ./lib-cjs/package.json",
|
||||
"test": "jest --runInBand",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"typedoc": "rm -rf ./docs && typedoc"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-base64": "^3.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.2.5",
|
||||
"@types/node": "^18.15.5",
|
||||
"jest": "^29.3.1",
|
||||
"ts-jest": "^29.0.5",
|
||||
"typedoc": "^0.23.28",
|
||||
"typescript": "^4.9.4"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user