mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
inlined libsql dialect, rewrote d1 to use generic sqlite
This commit is contained in:
@@ -65,6 +65,7 @@
|
|||||||
"json-schema-form-react": "^0.0.2",
|
"json-schema-form-react": "^0.0.2",
|
||||||
"json-schema-library": "10.0.0-rc7",
|
"json-schema-library": "10.0.0-rc7",
|
||||||
"json-schema-to-ts": "^3.1.1",
|
"json-schema-to-ts": "^3.1.1",
|
||||||
|
"jsonv-ts": "^0.1.0",
|
||||||
"kysely": "^0.27.6",
|
"kysely": "^0.27.6",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"oauth4webapi": "^2.11.1",
|
"oauth4webapi": "^2.11.1",
|
||||||
@@ -82,7 +83,6 @@
|
|||||||
"@hono/vite-dev-server": "^0.19.1",
|
"@hono/vite-dev-server": "^0.19.1",
|
||||||
"@hookform/resolvers": "^4.1.3",
|
"@hookform/resolvers": "^4.1.3",
|
||||||
"@libsql/client": "^0.15.9",
|
"@libsql/client": "^0.15.9",
|
||||||
"@libsql/kysely-libsql": "^0.4.1",
|
|
||||||
"@mantine/modals": "^7.17.1",
|
"@mantine/modals": "^7.17.1",
|
||||||
"@mantine/notifications": "^7.17.1",
|
"@mantine/notifications": "^7.17.1",
|
||||||
"@playwright/test": "^1.51.1",
|
"@playwright/test": "^1.51.1",
|
||||||
@@ -102,7 +102,6 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"jotai": "^2.12.2",
|
"jotai": "^2.12.2",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
"jsonv-ts": "^0.1.0",
|
|
||||||
"kysely-d1": "^0.3.0",
|
"kysely-d1": "^0.3.0",
|
||||||
"kysely-generic-sqlite": "^1.2.1",
|
"kysely-generic-sqlite": "^1.2.1",
|
||||||
"libsql-stateless-easy": "^1.8.0",
|
"libsql-stateless-easy": "^1.8.0",
|
||||||
|
|||||||
@@ -1,42 +1,76 @@
|
|||||||
/// <reference types="@cloudflare/workers-types" />
|
/// <reference types="@cloudflare/workers-types" />
|
||||||
|
|
||||||
import { SqliteConnection } from "bknd/data";
|
import {
|
||||||
import type { ConnQuery, ConnQueryResults } from "data/connection/Connection";
|
genericSqlite,
|
||||||
import { D1Dialect } from "kysely-d1";
|
type GenericSqliteConnection,
|
||||||
|
} from "data/connection/sqlite/GenericSqliteConnection";
|
||||||
|
import type { QueryResult } from "kysely";
|
||||||
|
|
||||||
|
export type D1SqliteConnection = GenericSqliteConnection<D1Database>;
|
||||||
|
|
||||||
export type D1ConnectionConfig<DB extends D1Database | D1DatabaseSession = D1Database> = {
|
export type D1ConnectionConfig<DB extends D1Database | D1DatabaseSession = D1Database> = {
|
||||||
binding: DB;
|
binding: DB;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class D1Connection<
|
export function d1Sqlite(config: D1ConnectionConfig<D1Database>) {
|
||||||
DB extends D1Database | D1DatabaseSession = D1Database,
|
const db = config.binding;
|
||||||
> extends SqliteConnection<DB> {
|
|
||||||
override name = "sqlite-d1";
|
|
||||||
|
|
||||||
protected override readonly supported = {
|
return genericSqlite(
|
||||||
batching: true,
|
"d1-sqlite",
|
||||||
softscans: false,
|
db,
|
||||||
|
(utils) => {
|
||||||
|
const getStmt = (sql: string, parameters?: any[] | readonly any[]) =>
|
||||||
|
db.prepare(sql).bind(...(parameters || []));
|
||||||
|
|
||||||
|
const mapResult = (res: D1Result<any>): QueryResult<any> => {
|
||||||
|
if (res.error) {
|
||||||
|
throw new Error(res.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numAffectedRows =
|
||||||
|
res.meta.changes > 0 ? utils.parseBigInt(res.meta.changes) : undefined;
|
||||||
|
const insertId = res.meta.last_row_id
|
||||||
|
? utils.parseBigInt(res.meta.last_row_id)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
insertId,
|
||||||
|
numAffectedRows,
|
||||||
|
rows: res.results,
|
||||||
|
// @ts-ignore
|
||||||
|
meta: res.meta,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private config: D1ConnectionConfig<DB>) {
|
return {
|
||||||
super({
|
db,
|
||||||
excludeTables: ["_cf_KV", "_cf_METADATA"],
|
batch: async (stmts) => {
|
||||||
dialect: D1Dialect,
|
|
||||||
dialectArgs: [{ database: config.binding as D1Database }],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
override async executeQueries<O extends ConnQuery[]>(...qbs: O): Promise<ConnQueryResults<O>> {
|
|
||||||
const compiled = this.getCompiled(...qbs);
|
|
||||||
|
|
||||||
const db = this.config.binding;
|
|
||||||
|
|
||||||
const res = await db.batch(
|
const res = await db.batch(
|
||||||
compiled.map(({ sql, parameters }) => {
|
stmts.map(({ sql, parameters }) => {
|
||||||
return db.prepare(sql).bind(...parameters);
|
return getStmt(sql, parameters);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
return res.map(mapResult);
|
||||||
return this.withTransformedRows(res, "results") as any;
|
},
|
||||||
}
|
query: utils.buildQueryFn({
|
||||||
|
all: async (sql, parameters) => {
|
||||||
|
const prep = getStmt(sql, parameters);
|
||||||
|
return mapResult(await prep.all()).rows;
|
||||||
|
},
|
||||||
|
run: async (sql, parameters) => {
|
||||||
|
const prep = getStmt(sql, parameters);
|
||||||
|
return mapResult(await prep.run());
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
close: () => {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
supports: {
|
||||||
|
batching: true,
|
||||||
|
softscans: false,
|
||||||
|
},
|
||||||
|
excludeTables: ["_cf_KV", "_cf_METADATA"],
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
54
app/src/adapter/cloudflare/connection/D1Connection.vitest.ts
Normal file
54
app/src/adapter/cloudflare/connection/D1Connection.vitest.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { describe, test, expect } from "vitest";
|
||||||
|
|
||||||
|
import { viTestRunner } from "adapter/node/vitest";
|
||||||
|
import { connectionTestSuite } from "data/connection/connection-test-suite";
|
||||||
|
import { Miniflare } from "miniflare";
|
||||||
|
import { d1Sqlite } from "./D1Connection";
|
||||||
|
import { sql } from "kysely";
|
||||||
|
|
||||||
|
describe("d1Sqlite", async () => {
|
||||||
|
const mf = new Miniflare({
|
||||||
|
modules: true,
|
||||||
|
script: "export default { async fetch() { return new Response(null); } }",
|
||||||
|
d1Databases: ["DB"],
|
||||||
|
});
|
||||||
|
const binding = (await mf.getD1Database("DB")) as D1Database;
|
||||||
|
|
||||||
|
test("connection", async () => {
|
||||||
|
const conn = d1Sqlite({ binding });
|
||||||
|
expect(conn.supports("batching")).toBe(true);
|
||||||
|
expect(conn.supports("softscans")).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("query details", async () => {
|
||||||
|
const conn = d1Sqlite({ binding });
|
||||||
|
|
||||||
|
const res = await conn.executeQuery(sql`select 1`.compile(conn.kysely));
|
||||||
|
expect(res.rows).toEqual([{ "1": 1 }]);
|
||||||
|
expect(res.numAffectedRows).toBe(undefined);
|
||||||
|
expect(res.insertId).toBe(undefined);
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(res.meta.changed_db).toBe(false);
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(res.meta.rows_read).toBe(0);
|
||||||
|
|
||||||
|
const batchResult = await conn.executeQueries(
|
||||||
|
sql`select 1`.compile(conn.kysely),
|
||||||
|
sql`select 2`.compile(conn.kysely),
|
||||||
|
);
|
||||||
|
|
||||||
|
// rewrite to get index
|
||||||
|
for (const [index, result] of batchResult.entries()) {
|
||||||
|
expect(result.rows).toEqual([{ [String(index + 1)]: index + 1 }]);
|
||||||
|
expect(result.numAffectedRows).toBe(undefined);
|
||||||
|
expect(result.insertId).toBe(undefined);
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(result.meta.changed_db).toBe(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectionTestSuite(viTestRunner, {
|
||||||
|
makeConnection: () => d1Sqlite({ binding }),
|
||||||
|
rawDialectDetails: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
138
app/src/adapter/cloudflare/connection/D1Dialect.ts
Normal file
138
app/src/adapter/cloudflare/connection/D1Dialect.ts
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import {
|
||||||
|
SqliteAdapter,
|
||||||
|
SqliteIntrospector,
|
||||||
|
SqliteQueryCompiler,
|
||||||
|
type CompiledQuery,
|
||||||
|
type DatabaseConnection,
|
||||||
|
type DatabaseIntrospector,
|
||||||
|
type Dialect,
|
||||||
|
type Driver,
|
||||||
|
type Kysely,
|
||||||
|
type QueryCompiler,
|
||||||
|
type QueryResult,
|
||||||
|
} from "kysely";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config for the D1 dialect. Pass your D1 instance to this object that you bound in `wrangler.toml`.
|
||||||
|
*/
|
||||||
|
export interface D1DialectConfig {
|
||||||
|
database: D1Database;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* D1 dialect that adds support for [Cloudflare D1][0] in [Kysely][1].
|
||||||
|
* The constructor takes the instance of your D1 database that you bound in `wrangler.toml`.
|
||||||
|
*
|
||||||
|
* ```typescript
|
||||||
|
* new D1Dialect({
|
||||||
|
* database: env.DB,
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* [0]: https://blog.cloudflare.com/introducing-d1/
|
||||||
|
* [1]: https://github.com/koskimas/kysely
|
||||||
|
*/
|
||||||
|
export class D1Dialect implements Dialect {
|
||||||
|
#config: D1DialectConfig;
|
||||||
|
|
||||||
|
constructor(config: D1DialectConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
createAdapter() {
|
||||||
|
return new SqliteAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
createDriver(): Driver {
|
||||||
|
return new D1Driver(this.#config);
|
||||||
|
}
|
||||||
|
|
||||||
|
createQueryCompiler(): QueryCompiler {
|
||||||
|
return new SqliteQueryCompiler();
|
||||||
|
}
|
||||||
|
|
||||||
|
createIntrospector(db: Kysely<any>): DatabaseIntrospector {
|
||||||
|
return new SqliteIntrospector(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D1Driver implements Driver {
|
||||||
|
#config: D1DialectConfig;
|
||||||
|
|
||||||
|
constructor(config: D1DialectConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(): Promise<void> {}
|
||||||
|
|
||||||
|
async acquireConnection(): Promise<DatabaseConnection> {
|
||||||
|
return new D1Connection(this.#config);
|
||||||
|
}
|
||||||
|
|
||||||
|
async beginTransaction(conn: D1Connection): Promise<void> {
|
||||||
|
return await conn.beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async commitTransaction(conn: D1Connection): Promise<void> {
|
||||||
|
return await conn.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollbackTransaction(conn: D1Connection): Promise<void> {
|
||||||
|
return await conn.rollbackTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async releaseConnection(_conn: D1Connection): Promise<void> {}
|
||||||
|
|
||||||
|
async destroy(): Promise<void> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D1Connection implements DatabaseConnection {
|
||||||
|
#config: D1DialectConfig;
|
||||||
|
|
||||||
|
constructor(config: D1DialectConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
async executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>> {
|
||||||
|
const results = await this.#config.database
|
||||||
|
.prepare(compiledQuery.sql)
|
||||||
|
.bind(...compiledQuery.parameters)
|
||||||
|
.all();
|
||||||
|
if (results.error) {
|
||||||
|
throw new Error(results.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numAffectedRows = results.meta.changes > 0 ? BigInt(results.meta.changes) : undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
insertId:
|
||||||
|
results.meta.last_row_id === undefined || results.meta.last_row_id === null
|
||||||
|
? undefined
|
||||||
|
: BigInt(results.meta.last_row_id),
|
||||||
|
rows: (results?.results as O[]) || [],
|
||||||
|
numAffectedRows,
|
||||||
|
// @ts-ignore deprecated in kysely >= 0.23, keep for backward compatibility.
|
||||||
|
numUpdatedOrDeletedRows: numAffectedRows,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async beginTransaction() {
|
||||||
|
throw new Error("Transactions are not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async commitTransaction() {
|
||||||
|
throw new Error("Transactions are not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollbackTransaction() {
|
||||||
|
throw new Error("Transactions are not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/useYield: <explanation>
|
||||||
|
async *streamQuery<O>(
|
||||||
|
_compiledQuery: CompiledQuery,
|
||||||
|
_chunkSize: number,
|
||||||
|
): AsyncIterableIterator<QueryResult<O>> {
|
||||||
|
throw new Error("D1 Driver does not support streaming");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,10 @@ export function nodeSqlite(config?: NodeSqliteConnectionConfig | { url: string }
|
|||||||
db = new DatabaseSync(":memory:");
|
db = new DatabaseSync(":memory:");
|
||||||
}
|
}
|
||||||
|
|
||||||
return genericSqlite("node-sqlite", db, (utils) => {
|
return genericSqlite(
|
||||||
|
"node-sqlite",
|
||||||
|
db,
|
||||||
|
(utils) => {
|
||||||
const getStmt = (sql: string) => {
|
const getStmt = (sql: string) => {
|
||||||
const stmt = db.prepare(sql);
|
const stmt = db.prepare(sql);
|
||||||
//stmt.setReadBigInts(true);
|
//stmt.setReadBigInts(true);
|
||||||
@@ -44,5 +47,11 @@ export function nodeSqlite(config?: NodeSqliteConnectionConfig | { url: string }
|
|||||||
return getStmt(sql).iterate(...parameters) as any;
|
return getStmt(sql).iterate(...parameters) as any;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
supports: {
|
||||||
|
batching: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Connection } from "bknd/data";
|
import type { Connection } from "bknd/data";
|
||||||
import { libsql } from "../../data/connection/sqlite/LibsqlConnection";
|
import { libsql } from "../../data/connection/sqlite/libsql/LibsqlConnection";
|
||||||
|
|
||||||
export function sqlite(config: { url: string }): Connection {
|
export function sqlite(config: { url: string }): Connection {
|
||||||
return libsql(config);
|
return libsql(config);
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import type { Connection } from "bknd/data";
|
|
||||||
|
|
||||||
export type SqliteConnection = (config: { url: string }) => Connection;
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { KyselyPlugin } from "kysely";
|
import type { KyselyPlugin, QueryResult } from "kysely";
|
||||||
import {
|
import {
|
||||||
type IGenericSqlite,
|
type IGenericSqlite,
|
||||||
type OnCreateConnection,
|
type OnCreateConnection,
|
||||||
@@ -8,11 +8,16 @@ import {
|
|||||||
GenericSqliteDialect,
|
GenericSqliteDialect,
|
||||||
} from "kysely-generic-sqlite";
|
} from "kysely-generic-sqlite";
|
||||||
import { SqliteConnection } from "./SqliteConnection";
|
import { SqliteConnection } from "./SqliteConnection";
|
||||||
import type { Features } from "../Connection";
|
import type { ConnQuery, ConnQueryResults, Features } from "../Connection";
|
||||||
|
|
||||||
export type { IGenericSqlite };
|
export type { IGenericSqlite };
|
||||||
|
export type TStatement = { sql: string; parameters?: any[] | readonly any[] };
|
||||||
|
export interface IGenericCustomSqlite<DB = unknown> extends IGenericSqlite<DB> {
|
||||||
|
batch?: (stmts: TStatement[]) => Promisable<QueryResult<any>[]>;
|
||||||
|
}
|
||||||
|
|
||||||
export type GenericSqliteConnectionConfig = {
|
export type GenericSqliteConnectionConfig = {
|
||||||
name: string;
|
name?: string;
|
||||||
additionalPlugins?: KyselyPlugin[];
|
additionalPlugins?: KyselyPlugin[];
|
||||||
excludeTables?: string[];
|
excludeTables?: string[];
|
||||||
onCreateConnection?: OnCreateConnection;
|
onCreateConnection?: OnCreateConnection;
|
||||||
@@ -21,10 +26,11 @@ export type GenericSqliteConnectionConfig = {
|
|||||||
|
|
||||||
export class GenericSqliteConnection<DB = unknown> extends SqliteConnection<DB> {
|
export class GenericSqliteConnection<DB = unknown> extends SqliteConnection<DB> {
|
||||||
override name = "generic-sqlite";
|
override name = "generic-sqlite";
|
||||||
|
#executor: IGenericCustomSqlite<DB> | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
db: DB,
|
public db: DB,
|
||||||
executor: () => Promisable<IGenericSqlite>,
|
private executor: () => Promisable<IGenericCustomSqlite<DB>>,
|
||||||
config?: GenericSqliteConnectionConfig,
|
config?: GenericSqliteConnectionConfig,
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
@@ -39,18 +45,43 @@ export class GenericSqliteConnection<DB = unknown> extends SqliteConnection<DB>
|
|||||||
}
|
}
|
||||||
if (config?.supports) {
|
if (config?.supports) {
|
||||||
for (const [key, value] of Object.entries(config.supports)) {
|
for (const [key, value] of Object.entries(config.supports)) {
|
||||||
if (value) {
|
if (value !== undefined) {
|
||||||
this.supported[key] = value;
|
this.supported[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private async getExecutor() {
|
||||||
|
if (!this.#executor) {
|
||||||
|
this.#executor = await this.executor();
|
||||||
|
}
|
||||||
|
return this.#executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
override async executeQueries<O extends ConnQuery[]>(...qbs: O): Promise<ConnQueryResults<O>> {
|
||||||
|
const executor = await this.getExecutor();
|
||||||
|
if (!executor.batch) {
|
||||||
|
console.warn("Batching is not supported by this database");
|
||||||
|
return super.executeQueries(...qbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const compiled = this.getCompiled(...qbs);
|
||||||
|
const stms: TStatement[] = compiled.map((q) => {
|
||||||
|
return {
|
||||||
|
sql: q.sql,
|
||||||
|
parameters: q.parameters as any[],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await executor.batch(stms);
|
||||||
|
return this.withTransformedRows(results) as any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function genericSqlite<DB>(
|
export function genericSqlite<DB>(
|
||||||
name: string,
|
name: string,
|
||||||
db: DB,
|
db: DB,
|
||||||
executor: (utils: typeof genericSqliteUtils) => Promisable<IGenericSqlite<DB>>,
|
executor: (utils: typeof genericSqliteUtils) => Promisable<IGenericCustomSqlite<DB>>,
|
||||||
config?: GenericSqliteConnectionConfig,
|
config?: GenericSqliteConnectionConfig,
|
||||||
) {
|
) {
|
||||||
return new GenericSqliteConnection(db, () => executor(genericSqliteUtils), {
|
return new GenericSqliteConnection(db, () => executor(genericSqliteUtils), {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { connectionTestSuite } from "../connection-test-suite";
|
import { connectionTestSuite } from "../../connection-test-suite";
|
||||||
import { LibsqlConnection } from "./LibsqlConnection";
|
import { LibsqlConnection } from "./LibsqlConnection";
|
||||||
import { bunTestRunner } from "adapter/bun/test";
|
import { bunTestRunner } from "adapter/bun/test";
|
||||||
import { describe } from "bun:test";
|
import { describe } from "bun:test";
|
||||||
@@ -1,23 +1,14 @@
|
|||||||
import type { Client, Config, InStatement } from "@libsql/client";
|
import type { Client, Config, InStatement } from "@libsql/client";
|
||||||
import { createClient } from "libsql-stateless-easy";
|
import { createClient } from "libsql-stateless-easy";
|
||||||
import { LibsqlDialect } from "@libsql/kysely-libsql";
|
import { LibsqlDialect } from "./LibsqlDialect";
|
||||||
import { FilterNumericKeysPlugin } from "data/plugins/FilterNumericKeysPlugin";
|
import { FilterNumericKeysPlugin } from "data/plugins/FilterNumericKeysPlugin";
|
||||||
import { type ConnQuery, type ConnQueryResults, SqliteConnection } from "bknd/data";
|
import { type ConnQuery, type ConnQueryResults, SqliteConnection } from "bknd/data";
|
||||||
|
|
||||||
export const LIBSQL_PROTOCOLS = ["wss", "https", "libsql"] as const;
|
export type LibSqlCredentials = Config;
|
||||||
export type LibSqlCredentials = Config & {
|
|
||||||
protocol?: (typeof LIBSQL_PROTOCOLS)[number];
|
|
||||||
};
|
|
||||||
|
|
||||||
function getClient(clientOrCredentials: Client | LibSqlCredentials): Client {
|
function getClient(clientOrCredentials: Client | LibSqlCredentials): Client {
|
||||||
if (clientOrCredentials && "url" in clientOrCredentials) {
|
if (clientOrCredentials && "url" in clientOrCredentials) {
|
||||||
let { url, authToken, protocol } = clientOrCredentials;
|
const { url, authToken } = clientOrCredentials;
|
||||||
if (protocol && LIBSQL_PROTOCOLS.includes(protocol)) {
|
|
||||||
console.info("changing protocol to", protocol);
|
|
||||||
const [, rest] = url.split("://");
|
|
||||||
url = `${protocol}://${rest}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return createClient({ url, authToken });
|
return createClient({ url, authToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
145
app/src/data/connection/sqlite/libsql/LibsqlDialect.ts
Normal file
145
app/src/data/connection/sqlite/libsql/LibsqlDialect.ts
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import type { Client, Transaction, InValue } from "@libsql/client";
|
||||||
|
import {
|
||||||
|
SqliteAdapter,
|
||||||
|
SqliteIntrospector,
|
||||||
|
SqliteQueryCompiler,
|
||||||
|
type Kysely,
|
||||||
|
type Dialect,
|
||||||
|
type DialectAdapter,
|
||||||
|
type Driver,
|
||||||
|
type DatabaseIntrospector,
|
||||||
|
type QueryCompiler,
|
||||||
|
type TransactionSettings,
|
||||||
|
type DatabaseConnection,
|
||||||
|
type QueryResult,
|
||||||
|
type CompiledQuery,
|
||||||
|
} from "kysely";
|
||||||
|
|
||||||
|
export type LibsqlDialectConfig = {
|
||||||
|
client: Client;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class LibsqlDialect implements Dialect {
|
||||||
|
#config: LibsqlDialectConfig;
|
||||||
|
|
||||||
|
constructor(config: LibsqlDialectConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
createAdapter(): DialectAdapter {
|
||||||
|
return new SqliteAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
createDriver(): Driver {
|
||||||
|
let client: Client;
|
||||||
|
let closeClient: boolean;
|
||||||
|
if ("client" in this.#config) {
|
||||||
|
client = this.#config.client;
|
||||||
|
closeClient = false;
|
||||||
|
} else {
|
||||||
|
throw new Error("Please specify either `client` or `url` in the LibsqlDialect config");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LibsqlDriver(client, closeClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
createIntrospector(db: Kysely<any>): DatabaseIntrospector {
|
||||||
|
return new SqliteIntrospector(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
createQueryCompiler(): QueryCompiler {
|
||||||
|
return new SqliteQueryCompiler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LibsqlDriver implements Driver {
|
||||||
|
client: Client;
|
||||||
|
#closeClient: boolean;
|
||||||
|
|
||||||
|
constructor(client: Client, closeClient: boolean) {
|
||||||
|
this.client = client;
|
||||||
|
this.#closeClient = closeClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(): Promise<void> {}
|
||||||
|
|
||||||
|
async acquireConnection(): Promise<LibsqlConnection> {
|
||||||
|
return new LibsqlConnection(this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
async beginTransaction(
|
||||||
|
connection: LibsqlConnection,
|
||||||
|
_settings: TransactionSettings,
|
||||||
|
): Promise<void> {
|
||||||
|
await connection.beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async commitTransaction(connection: LibsqlConnection): Promise<void> {
|
||||||
|
await connection.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollbackTransaction(connection: LibsqlConnection): Promise<void> {
|
||||||
|
await connection.rollbackTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async releaseConnection(_conn: LibsqlConnection): Promise<void> {}
|
||||||
|
|
||||||
|
async destroy(): Promise<void> {
|
||||||
|
if (this.#closeClient) {
|
||||||
|
this.client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LibsqlConnection implements DatabaseConnection {
|
||||||
|
client: Client;
|
||||||
|
#transaction?: Transaction;
|
||||||
|
|
||||||
|
constructor(client: Client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
async executeQuery<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>> {
|
||||||
|
const target = this.#transaction ?? this.client;
|
||||||
|
const result = await target.execute({
|
||||||
|
sql: compiledQuery.sql,
|
||||||
|
args: compiledQuery.parameters as Array<InValue>,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
insertId: result.lastInsertRowid,
|
||||||
|
numAffectedRows: BigInt(result.rowsAffected),
|
||||||
|
rows: result.rows as Array<R>,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async beginTransaction() {
|
||||||
|
if (this.#transaction) {
|
||||||
|
throw new Error("Transaction already in progress");
|
||||||
|
}
|
||||||
|
this.#transaction = await this.client.transaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
async commitTransaction() {
|
||||||
|
if (!this.#transaction) {
|
||||||
|
throw new Error("No transaction to commit");
|
||||||
|
}
|
||||||
|
await this.#transaction.commit();
|
||||||
|
this.#transaction = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollbackTransaction() {
|
||||||
|
if (!this.#transaction) {
|
||||||
|
throw new Error("No transaction to rollback");
|
||||||
|
}
|
||||||
|
await this.#transaction.rollback();
|
||||||
|
this.#transaction = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/useYield: <explanation>
|
||||||
|
async *streamQuery<R>(
|
||||||
|
_compiledQuery: CompiledQuery,
|
||||||
|
_chunkSize: number,
|
||||||
|
): AsyncIterableIterator<QueryResult<R>> {
|
||||||
|
throw new Error("Libsql Driver does not support streaming yet");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,7 +57,7 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getValidOptions(options?: RepoQuery): RepoQuery {
|
getValidOptions(options?: Partial<RepoQuery>): RepoQuery {
|
||||||
const entity = this.entity;
|
const entity = this.entity;
|
||||||
// @todo: if not cloned deep, it will keep references and error if multiple requests come in
|
// @todo: if not cloned deep, it will keep references and error if multiple requests come in
|
||||||
const validated = {
|
const validated = {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export * as DataPermissions from "./permissions";
|
|||||||
|
|
||||||
export { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField";
|
export { MediaField, type MediaFieldConfig, type MediaItem } from "media/MediaField";
|
||||||
|
|
||||||
export { libsql } from "./connection/sqlite/LibsqlConnection";
|
export { libsql } from "./connection/sqlite/libsql/LibsqlConnection";
|
||||||
export {
|
export {
|
||||||
genericSqlite,
|
genericSqlite,
|
||||||
genericSqliteUtils,
|
genericSqliteUtils,
|
||||||
|
|||||||
@@ -150,4 +150,6 @@ export type RepoQueryIn = {
|
|||||||
join?: string[];
|
join?: string[];
|
||||||
where?: WhereQuery;
|
where?: WhereQuery;
|
||||||
};
|
};
|
||||||
export type RepoQuery = s.StaticCoerced<typeof repoQuery>;
|
export type RepoQuery = s.StaticCoerced<typeof repoQuery> & {
|
||||||
|
sort: SortSchema;
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { StorageLocalAdapter } from "./src/adapter/node";
|
|||||||
import type { Connection } from "./src/data/connection/Connection";
|
import type { Connection } from "./src/data/connection/Connection";
|
||||||
import { __bknd } from "modules/ModuleManager";
|
import { __bknd } from "modules/ModuleManager";
|
||||||
import { nodeSqlite } from "./src/adapter/node/connection/NodeSqliteConnection";
|
import { nodeSqlite } from "./src/adapter/node/connection/NodeSqliteConnection";
|
||||||
import { libsql } from "./src/data/connection/sqlite/LibsqlConnection";
|
import { libsql } from "./src/data/connection/sqlite/libsql/LibsqlConnection";
|
||||||
import { $console } from "core";
|
import { $console } from "core";
|
||||||
import { createClient } from "@libsql/client";
|
import { createClient } from "@libsql/client";
|
||||||
|
|
||||||
|
|||||||
39
bun.lock
39
bun.lock
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"name": "bknd",
|
"name": "bknd",
|
||||||
"version": "0.15.0-rc.2",
|
"version": "0.15.0-rc.3",
|
||||||
"bin": "./dist/cli/index.js",
|
"bin": "./dist/cli/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cfworker/json-schema": "^4.1.1",
|
"@cfworker/json-schema": "^4.1.1",
|
||||||
@@ -37,13 +37,13 @@
|
|||||||
"json-schema-form-react": "^0.0.2",
|
"json-schema-form-react": "^0.0.2",
|
||||||
"json-schema-library": "10.0.0-rc7",
|
"json-schema-library": "10.0.0-rc7",
|
||||||
"json-schema-to-ts": "^3.1.1",
|
"json-schema-to-ts": "^3.1.1",
|
||||||
|
"jsonv-ts": "^0.1.0",
|
||||||
"kysely": "^0.27.6",
|
"kysely": "^0.27.6",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"oauth4webapi": "^2.11.1",
|
"oauth4webapi": "^2.11.1",
|
||||||
"object-path-immutable": "^4.1.2",
|
"object-path-immutable": "^4.1.2",
|
||||||
"radix-ui": "^1.1.3",
|
"radix-ui": "^1.1.3",
|
||||||
"swr": "^2.3.3",
|
"swr": "^2.3.3",
|
||||||
"uuid": "^11.1.0",
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.758.0",
|
"@aws-sdk/client-s3": "^3.758.0",
|
||||||
@@ -55,7 +55,6 @@
|
|||||||
"@hono/vite-dev-server": "^0.19.1",
|
"@hono/vite-dev-server": "^0.19.1",
|
||||||
"@hookform/resolvers": "^4.1.3",
|
"@hookform/resolvers": "^4.1.3",
|
||||||
"@libsql/client": "^0.15.9",
|
"@libsql/client": "^0.15.9",
|
||||||
"@libsql/kysely-libsql": "^0.4.1",
|
|
||||||
"@mantine/modals": "^7.17.1",
|
"@mantine/modals": "^7.17.1",
|
||||||
"@mantine/notifications": "^7.17.1",
|
"@mantine/notifications": "^7.17.1",
|
||||||
"@playwright/test": "^1.51.1",
|
"@playwright/test": "^1.51.1",
|
||||||
@@ -75,7 +74,6 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"jotai": "^2.12.2",
|
"jotai": "^2.12.2",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
"jsonv-ts": "^0.1.0",
|
|
||||||
"kysely-d1": "^0.3.0",
|
"kysely-d1": "^0.3.0",
|
||||||
"kysely-generic-sqlite": "^1.2.1",
|
"kysely-generic-sqlite": "^1.2.1",
|
||||||
"libsql-stateless-easy": "^1.8.0",
|
"libsql-stateless-easy": "^1.8.0",
|
||||||
@@ -98,6 +96,7 @@
|
|||||||
"tsc-alias": "^1.8.11",
|
"tsc-alias": "^1.8.11",
|
||||||
"tsup": "^8.4.0",
|
"tsup": "^8.4.0",
|
||||||
"tsx": "^4.19.3",
|
"tsx": "^4.19.3",
|
||||||
|
"uuid": "^11.1.0",
|
||||||
"vite": "^6.3.5",
|
"vite": "^6.3.5",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^3.0.9",
|
"vitest": "^3.0.9",
|
||||||
@@ -754,8 +753,6 @@
|
|||||||
|
|
||||||
"@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="],
|
"@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="],
|
||||||
|
|
||||||
"@libsql/kysely-libsql": ["@libsql/kysely-libsql@0.4.1", "", { "dependencies": { "@libsql/client": "^0.8.0" }, "peerDependencies": { "kysely": "*" } }, "sha512-mCTa6OWgoME8LNu22COM6XjKBmcMAvNtIO6DYM10jSAFq779fVlrTKQEmXIB8TwJVU65dA5jGCpT8gkDdWS0HQ=="],
|
|
||||||
|
|
||||||
"@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.13", "", { "os": "linux", "cpu": "arm" }, "sha512-UEW+VZN2r0mFkfztKOS7cqfS8IemuekbjUXbXCwULHtusww2QNCXvM5KU9eJCNE419SZCb0qaEWYytcfka8qeA=="],
|
"@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.13", "", { "os": "linux", "cpu": "arm" }, "sha512-UEW+VZN2r0mFkfztKOS7cqfS8IemuekbjUXbXCwULHtusww2QNCXvM5KU9eJCNE419SZCb0qaEWYytcfka8qeA=="],
|
||||||
|
|
||||||
"@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.13", "", { "os": "linux", "cpu": "arm" }, "sha512-NMDgLqryYBv4Sr3WoO/m++XDjR5KLlw9r/JK4Ym6A1XBv2bxQQNhH0Lxx3bjLW8qqhBD4+0xfms4d2cOlexPyA=="],
|
"@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.13", "", { "os": "linux", "cpu": "arm" }, "sha512-NMDgLqryYBv4Sr3WoO/m++XDjR5KLlw9r/JK4Ym6A1XBv2bxQQNhH0Lxx3bjLW8qqhBD4+0xfms4d2cOlexPyA=="],
|
||||||
@@ -1222,7 +1219,7 @@
|
|||||||
|
|
||||||
"@types/babel__traverse": ["@types/babel__traverse@7.20.6", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg=="],
|
"@types/babel__traverse": ["@types/babel__traverse@7.20.6", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.16", "", { "dependencies": { "bun-types": "1.2.16" } }, "sha512-1aCZJ/6nSiViw339RsaNhkNoEloLaPzZhxMOYEa7OzRzO41IGg5n/7I43/ZIAW/c+Q6cT12Vf7fOZOoVIzb5BQ=="],
|
"@types/bun": ["@types/bun@1.2.17", "", { "dependencies": { "bun-types": "1.2.17" } }, "sha512-l/BYs/JYt+cXA/0+wUhulYJB6a6p//GTPiJ7nV+QHa8iiId4HZmnu/3J/SowP5g0rTiERY2kfGKXEK5Ehltx4Q=="],
|
||||||
|
|
||||||
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||||
|
|
||||||
@@ -3878,8 +3875,6 @@
|
|||||||
|
|
||||||
"@libsql/hrana-client/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
"@libsql/hrana-client/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client": ["@libsql/client@0.8.1", "", { "dependencies": { "@libsql/core": "^0.8.1", "@libsql/hrana-client": "^0.6.2", "js-base64": "^3.7.5", "libsql": "^0.3.10", "promise-limit": "^2.7.0" } }, "sha512-xGg0F4iTDFpeBZ0r4pA6icGsYa5rG6RAG+i/iLDnpCAnSuTqEWMDdPlVseiq4Z/91lWI9jvvKKiKpovqJ1kZWA=="],
|
|
||||||
|
|
||||||
"@neondatabase/serverless/@types/pg": ["@types/pg@8.6.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw=="],
|
"@neondatabase/serverless/@types/pg": ["@types/pg@8.6.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw=="],
|
||||||
|
|
||||||
"@plasmicapp/query/swr": ["swr@1.3.0", "", { "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0" } }, "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw=="],
|
"@plasmicapp/query/swr": ["swr@1.3.0", "", { "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0" } }, "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw=="],
|
||||||
@@ -4020,7 +4015,7 @@
|
|||||||
|
|
||||||
"@testing-library/jest-dom/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
|
"@testing-library/jest-dom/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
|
||||||
|
|
||||||
"@types/bun/bun-types": ["bun-types@1.2.16", "", { "dependencies": { "@types/node": "*" } }, "sha512-ciXLrHV4PXax9vHvUrkvun9VPVGOVwbbbBF/Ev1cXz12lyEZMoJpIJABOfPcN9gDJRaiKF9MVbSygLg4NXu3/A=="],
|
"@types/bun/bun-types": ["bun-types@1.2.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ElC7ItwT3SCQwYZDYoAH+q6KT4Fxjl8DtZ6qDulUFBmXA8YB4xo+l54J9ZJN+k2pphfn9vk7kfubeSd5QfTVJQ=="],
|
||||||
|
|
||||||
"@types/pg/pg-types": ["pg-types@4.0.2", "", { "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", "postgres-array": "~3.0.1", "postgres-bytea": "~3.0.0", "postgres-date": "~2.1.0", "postgres-interval": "^3.0.0", "postgres-range": "^1.1.1" } }, "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng=="],
|
"@types/pg/pg-types": ["pg-types@4.0.2", "", { "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", "postgres-array": "~3.0.1", "postgres-bytea": "~3.0.0", "postgres-date": "~2.1.0", "postgres-interval": "^3.0.0", "postgres-range": "^1.1.1" } }, "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng=="],
|
||||||
|
|
||||||
@@ -4630,12 +4625,6 @@
|
|||||||
|
|
||||||
"@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
"@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/@libsql/core": ["@libsql/core@0.8.1", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-u6nrj6HZMTPsgJ9EBhLzO2uhqhlHQJQmVHV+0yFLvfGf3oSP8w7TjZCNUgu1G8jHISx6KFi7bmcrdXW9lRt++A=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/@libsql/hrana-client": ["@libsql/hrana-client@0.6.2", "", { "dependencies": { "@libsql/isomorphic-fetch": "^0.2.1", "@libsql/isomorphic-ws": "^0.1.5", "js-base64": "^3.7.5", "node-fetch": "^3.3.2" } }, "sha512-MWxgD7mXLNf9FXXiM0bc90wCjZSpErWKr5mGza7ERy2FJNNMXd7JIOv+DepBA1FQTIfI8TFO4/QDYgaQC0goNw=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql": ["libsql@0.3.19", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2", "libsql": "^0.3.15" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.3.19", "@libsql/darwin-x64": "0.3.19", "@libsql/linux-arm64-gnu": "0.3.19", "@libsql/linux-arm64-musl": "0.3.19", "@libsql/linux-x64-gnu": "0.3.19", "@libsql/linux-x64-musl": "0.3.19", "@libsql/win32-x64-msvc": "0.3.19" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ] }, "sha512-Aj5cQ5uk/6fHdmeW0TiXK42FqUlwx7ytmMLPSaUQPin5HKKKuUPD62MAbN4OEweGBBI7q1BekoEN4gPUEL6MZA=="],
|
|
||||||
|
|
||||||
"@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
"@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
|
||||||
|
|
||||||
"@testing-library/dom/pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
|
"@testing-library/dom/pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
|
||||||
@@ -4986,24 +4975,6 @@
|
|||||||
|
|
||||||
"@cloudflare/vitest-pool-workers/miniflare/youch/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
"@cloudflare/vitest-pool-workers/miniflare/youch/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/@libsql/hrana-client/@libsql/isomorphic-fetch": ["@libsql/isomorphic-fetch@0.2.5", "", {}, "sha512-8s/B2TClEHms2yb+JGpsVRTPBfy1ih/Pq6h6gvyaNcYnMVJvgQRY7wAa8U2nD0dppbCuDU5evTNMEhrQ17ZKKg=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/@libsql/hrana-client/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.3.19", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rmOqsLcDI65zzxlUOoEiPJLhqmbFsZF6p4UJQ2kMqB+Kc0Rt5/A1OAdOZ/Wo8fQfJWjR1IbkbpEINFioyKf+nQ=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/darwin-x64": ["@libsql/darwin-x64@0.3.19", "", { "os": "darwin", "cpu": "x64" }, "sha512-q9O55B646zU+644SMmOQL3FIfpmEvdWpRpzubwFc2trsa+zoBlSkHuzU9v/C+UNoPHQVRMP7KQctJ455I/h/xw=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.3.19", "", { "os": "linux", "cpu": "arm64" }, "sha512-mgeAUU1oqqh57k7I3cQyU6Trpdsdt607eFyEmH5QO7dv303ti+LjUvh1pp21QWV6WX7wZyjeJV1/VzEImB+jRg=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.3.19", "", { "os": "linux", "cpu": "arm64" }, "sha512-VEZtxghyK6zwGzU9PHohvNxthruSxBEnRrX7BSL5jQ62tN4n2JNepJ6SdzXp70pdzTfwroOj/eMwiPt94gkVRg=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.3.19", "", { "os": "linux", "cpu": "x64" }, "sha512-2t/J7LD5w2f63wGihEO+0GxfTyYIyLGEvTFEsMO16XI5o7IS9vcSHrxsvAJs4w2Pf907uDjmc7fUfMg6L82BrQ=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.3.19", "", { "os": "linux", "cpu": "x64" }, "sha512-BLsXyJaL8gZD8+3W2LU08lDEd9MIgGds0yPy5iNPp8tfhXx3pV/Fge2GErN0FC+nzt4DYQtjL+A9GUMglQefXQ=="],
|
|
||||||
|
|
||||||
"@libsql/kysely-libsql/@libsql/client/libsql/@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.3.19", "", { "os": "win32", "cpu": "x64" }, "sha512-ay1X9AobE4BpzG0XPw1gplyLZPGHIgJOovvW23gUrukRegiUP62uzhpRbKNogLlUOynyXeq//prHgPXiebUfWg=="],
|
|
||||||
|
|
||||||
"@verdaccio/middleware/express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
"@verdaccio/middleware/express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||||
|
|
||||||
"@vitest/coverage-v8/vitest/vite/rollup": ["rollup@4.35.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.35.0", "@rollup/rollup-android-arm64": "4.35.0", "@rollup/rollup-darwin-arm64": "4.35.0", "@rollup/rollup-darwin-x64": "4.35.0", "@rollup/rollup-freebsd-arm64": "4.35.0", "@rollup/rollup-freebsd-x64": "4.35.0", "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", "@rollup/rollup-linux-arm-musleabihf": "4.35.0", "@rollup/rollup-linux-arm64-gnu": "4.35.0", "@rollup/rollup-linux-arm64-musl": "4.35.0", "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", "@rollup/rollup-linux-riscv64-gnu": "4.35.0", "@rollup/rollup-linux-s390x-gnu": "4.35.0", "@rollup/rollup-linux-x64-gnu": "4.35.0", "@rollup/rollup-linux-x64-musl": "4.35.0", "@rollup/rollup-win32-arm64-msvc": "4.35.0", "@rollup/rollup-win32-ia32-msvc": "4.35.0", "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg=="],
|
"@vitest/coverage-v8/vitest/vite/rollup": ["rollup@4.35.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.35.0", "@rollup/rollup-android-arm64": "4.35.0", "@rollup/rollup-darwin-arm64": "4.35.0", "@rollup/rollup-darwin-x64": "4.35.0", "@rollup/rollup-freebsd-arm64": "4.35.0", "@rollup/rollup-freebsd-x64": "4.35.0", "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", "@rollup/rollup-linux-arm-musleabihf": "4.35.0", "@rollup/rollup-linux-arm64-gnu": "4.35.0", "@rollup/rollup-linux-arm64-musl": "4.35.0", "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", "@rollup/rollup-linux-riscv64-gnu": "4.35.0", "@rollup/rollup-linux-s390x-gnu": "4.35.0", "@rollup/rollup-linux-x64-gnu": "4.35.0", "@rollup/rollup-linux-x64-musl": "4.35.0", "@rollup/rollup-win32-arm64-msvc": "4.35.0", "@rollup/rollup-win32-ia32-msvc": "4.35.0", "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg=="],
|
||||||
|
|||||||
Reference in New Issue
Block a user