@astrojs/db 0.17.2 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/runtime/utils.d.ts +2 -0
- package/dist/core/cli/commands/execute/index.js +6 -4
- package/dist/core/cli/commands/push/index.js +2 -2
- package/dist/core/cli/commands/shell/index.js +3 -5
- package/dist/core/cli/migration-queries.js +4 -4
- package/dist/core/cli/print-help.js +6 -6
- package/dist/core/consts.d.ts +6 -0
- package/dist/core/consts.js +8 -0
- package/dist/core/db-client/libsql-local.d.ts +6 -0
- package/dist/core/db-client/libsql-local.js +12 -0
- package/dist/core/db-client/libsql-node.d.ts +8 -0
- package/dist/core/db-client/libsql-node.js +21 -0
- package/dist/core/db-client/libsql-web.d.ts +8 -0
- package/dist/core/db-client/libsql-web.js +22 -0
- package/dist/core/db-client/utils.d.ts +2 -0
- package/dist/core/db-client/utils.js +46 -0
- package/dist/core/errors.js +12 -12
- package/dist/core/integration/index.d.ts +18 -1
- package/dist/core/integration/index.js +25 -6
- package/dist/core/integration/vite-plugin-db-client.d.ts +7 -0
- package/dist/core/integration/vite-plugin-db-client.js +42 -0
- package/dist/core/integration/vite-plugin-db.d.ts +18 -2
- package/dist/core/integration/vite-plugin-db.js +36 -13
- package/dist/core/queries.js +3 -3
- package/dist/db-client.d.js +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/runtime/errors.js +5 -5
- package/dist/runtime/index.d.ts +2 -3
- package/dist/runtime/index.js +3 -8
- package/dist/runtime/utils.d.ts +2 -0
- package/dist/runtime/utils.js +4 -0
- package/package.json +8 -7
- package/dist/runtime/db-client.d.ts +0 -15
- package/dist/runtime/db-client.js +0 -40
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { LibsqlError } from '@libsql/client';
|
|
2
2
|
import { AstroError } from 'astro/errors';
|
|
3
|
+
import type { DBColumn } from '../core/types.js';
|
|
4
|
+
export declare function hasPrimaryKey(column: DBColumn): boolean;
|
|
3
5
|
export declare class AstroDbError extends AstroError {
|
|
4
6
|
name: string;
|
|
5
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import
|
|
2
|
+
import colors from "picocolors";
|
|
3
3
|
import { isDbError } from "../../../../runtime/utils.js";
|
|
4
4
|
import {
|
|
5
5
|
EXEC_DEFAULT_EXPORT_ERROR,
|
|
@@ -35,12 +35,14 @@ async function cmd({
|
|
|
35
35
|
tables: dbConfig.tables ?? {},
|
|
36
36
|
appToken: flags.token ?? dbInfo.token,
|
|
37
37
|
isBuild: false,
|
|
38
|
-
output: "server"
|
|
38
|
+
output: "server",
|
|
39
|
+
localExecution: true
|
|
39
40
|
});
|
|
40
41
|
} else {
|
|
41
42
|
virtualModContents = getLocalVirtualModContents({
|
|
42
43
|
tables: dbConfig.tables ?? {},
|
|
43
|
-
root: astroConfig.root
|
|
44
|
+
root: astroConfig.root,
|
|
45
|
+
localExecution: true
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
const { code } = await bundleFile({ virtualModContents, root: astroConfig.root, fileUrl });
|
|
@@ -51,7 +53,7 @@ async function cmd({
|
|
|
51
53
|
}
|
|
52
54
|
try {
|
|
53
55
|
await mod.default();
|
|
54
|
-
console.info(`${green("\u2714")} File run successfully.`);
|
|
56
|
+
console.info(`${colors.green("\u2714")} File run successfully.`);
|
|
55
57
|
} catch (e) {
|
|
56
58
|
if (isDbError(e)) throw new Error(EXEC_ERROR(e.message));
|
|
57
59
|
else throw e;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sql } from "drizzle-orm";
|
|
2
2
|
import prompts from "prompts";
|
|
3
|
-
import { createRemoteDatabaseClient } from "../../../../runtime/index.js";
|
|
4
3
|
import { MIGRATION_VERSION } from "../../../consts.js";
|
|
4
|
+
import { createClient } from "../../../db-client/libsql-node.js";
|
|
5
5
|
import { getRemoteDatabaseInfo } from "../../../utils.js";
|
|
6
6
|
import {
|
|
7
7
|
createCurrentSnapshot,
|
|
@@ -79,7 +79,7 @@ async function pushSchema({
|
|
|
79
79
|
return pushToDb(requestBody, appToken, dbInfo.url);
|
|
80
80
|
}
|
|
81
81
|
async function pushToDb(requestBody, appToken, remoteUrl) {
|
|
82
|
-
const client =
|
|
82
|
+
const client = createClient({
|
|
83
83
|
token: appToken,
|
|
84
84
|
url: remoteUrl
|
|
85
85
|
});
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { sql } from "drizzle-orm";
|
|
2
|
-
import {
|
|
3
|
-
createLocalDatabaseClient,
|
|
4
|
-
createRemoteDatabaseClient
|
|
5
|
-
} from "../../../../runtime/db-client.js";
|
|
6
2
|
import { normalizeDatabaseUrl } from "../../../../runtime/index.js";
|
|
7
3
|
import { DB_PATH } from "../../../consts.js";
|
|
4
|
+
import { createClient as createLocalDatabaseClient } from "../../../db-client/libsql-local.js";
|
|
5
|
+
import { createClient as createRemoteDatabaseClient } from "../../../db-client/libsql-node.js";
|
|
8
6
|
import { SHELL_QUERY_MISSING_ERROR } from "../../../errors.js";
|
|
9
7
|
import { getAstroEnv, getRemoteDatabaseInfo } from "../../../utils.js";
|
|
10
8
|
async function cmd({
|
|
@@ -27,7 +25,7 @@ async function cmd({
|
|
|
27
25
|
ASTRO_DATABASE_FILE,
|
|
28
26
|
new URL(DB_PATH, astroConfig.root).href
|
|
29
27
|
);
|
|
30
|
-
const db = createLocalDatabaseClient({ dbUrl });
|
|
28
|
+
const db = createLocalDatabaseClient({ url: dbUrl });
|
|
31
29
|
const result = await db.run(sql.raw(query));
|
|
32
30
|
console.log(result);
|
|
33
31
|
}
|
|
@@ -2,12 +2,12 @@ import { stripVTControlCharacters } from "node:util";
|
|
|
2
2
|
import deepDiff from "deep-diff";
|
|
3
3
|
import { sql } from "drizzle-orm";
|
|
4
4
|
import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
|
|
5
|
-
import * as color from "kleur/colors";
|
|
6
5
|
import { customAlphabet } from "nanoid";
|
|
7
|
-
import
|
|
6
|
+
import color from "picocolors";
|
|
8
7
|
import { isSerializedSQL } from "../../runtime/types.js";
|
|
9
|
-
import { isDbError } from "../../runtime/utils.js";
|
|
8
|
+
import { hasPrimaryKey, isDbError } from "../../runtime/utils.js";
|
|
10
9
|
import { MIGRATION_VERSION } from "../consts.js";
|
|
10
|
+
import { createClient } from "../db-client/libsql-node.js";
|
|
11
11
|
import { RENAME_COLUMN_ERROR, RENAME_TABLE_ERROR } from "../errors.js";
|
|
12
12
|
import {
|
|
13
13
|
getCreateIndexQueries,
|
|
@@ -309,7 +309,7 @@ function getProductionCurrentSnapshot({
|
|
|
309
309
|
return getDbCurrentSnapshot(token, url);
|
|
310
310
|
}
|
|
311
311
|
async function getDbCurrentSnapshot(appToken, remoteUrl) {
|
|
312
|
-
const client =
|
|
312
|
+
const client = createClient({
|
|
313
313
|
token: appToken,
|
|
314
314
|
url: remoteUrl
|
|
315
315
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import colors from "picocolors";
|
|
2
2
|
function printHelp({
|
|
3
3
|
commandName,
|
|
4
4
|
headline,
|
|
@@ -7,7 +7,7 @@ function printHelp({
|
|
|
7
7
|
description
|
|
8
8
|
}) {
|
|
9
9
|
const linebreak = () => "";
|
|
10
|
-
const title = (label) => ` ${bgWhite(black(` ${label} `))}`;
|
|
10
|
+
const title = (label) => ` ${colors.bgWhite(colors.black(` ${label} `))}`;
|
|
11
11
|
const table = (rows, { padding }) => {
|
|
12
12
|
const split = process.stdout.columns < 60;
|
|
13
13
|
let raw = "";
|
|
@@ -18,7 +18,7 @@ function printHelp({
|
|
|
18
18
|
} else {
|
|
19
19
|
raw += `${`${row[0]}`.padStart(padding)}`;
|
|
20
20
|
}
|
|
21
|
-
raw += " " + dim(row[1]) + "\n";
|
|
21
|
+
raw += " " + colors.dim(row[1]) + "\n";
|
|
22
22
|
}
|
|
23
23
|
return raw.slice(0, -1);
|
|
24
24
|
};
|
|
@@ -26,13 +26,13 @@ function printHelp({
|
|
|
26
26
|
if (headline) {
|
|
27
27
|
message.push(
|
|
28
28
|
linebreak(),
|
|
29
|
-
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
30
|
-
`v${"0.
|
|
29
|
+
` ${colors.bgGreen(colors.black(` ${commandName} `))} ${colors.green(
|
|
30
|
+
`v${"0.18.1"}`
|
|
31
31
|
)} ${headline}`
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
if (usage) {
|
|
35
|
-
message.push(linebreak(), ` ${green(commandName)} ${bold(usage)}`);
|
|
35
|
+
message.push(linebreak(), ` ${colors.green(commandName)} ${colors.bold(usage)}`);
|
|
36
36
|
}
|
|
37
37
|
if (tables) {
|
|
38
38
|
let calculateTablePadding2 = function(rows) {
|
package/dist/core/consts.d.ts
CHANGED
|
@@ -4,3 +4,9 @@ export declare const VIRTUAL_MODULE_ID = "astro:db";
|
|
|
4
4
|
export declare const DB_PATH = ".astro/content.db";
|
|
5
5
|
export declare const CONFIG_FILE_NAMES: string[];
|
|
6
6
|
export declare const MIGRATION_VERSION = "2024-03-12";
|
|
7
|
+
export declare const VIRTUAL_CLIENT_MODULE_ID = "virtual:astro:db-client";
|
|
8
|
+
export declare const DB_CLIENTS: {
|
|
9
|
+
node: string;
|
|
10
|
+
web: string;
|
|
11
|
+
local: string;
|
|
12
|
+
};
|
package/dist/core/consts.js
CHANGED
|
@@ -8,11 +8,19 @@ const VIRTUAL_MODULE_ID = "astro:db";
|
|
|
8
8
|
const DB_PATH = ".astro/content.db";
|
|
9
9
|
const CONFIG_FILE_NAMES = ["config.ts", "config.js", "config.mts", "config.mjs"];
|
|
10
10
|
const MIGRATION_VERSION = "2024-03-12";
|
|
11
|
+
const VIRTUAL_CLIENT_MODULE_ID = "virtual:astro:db-client";
|
|
12
|
+
const DB_CLIENTS = {
|
|
13
|
+
node: `${PACKAGE_NAME}/db-client/libsql-node.js`,
|
|
14
|
+
web: `${PACKAGE_NAME}/db-client/libsql-web.js`,
|
|
15
|
+
local: `${PACKAGE_NAME}/db-client/libsql-local.js`
|
|
16
|
+
};
|
|
11
17
|
export {
|
|
12
18
|
CONFIG_FILE_NAMES,
|
|
19
|
+
DB_CLIENTS,
|
|
13
20
|
DB_PATH,
|
|
14
21
|
MIGRATION_VERSION,
|
|
15
22
|
RUNTIME_IMPORT,
|
|
16
23
|
RUNTIME_VIRTUAL_IMPORT,
|
|
24
|
+
VIRTUAL_CLIENT_MODULE_ID,
|
|
17
25
|
VIRTUAL_MODULE_ID
|
|
18
26
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createClient as createLibsqlClient } from "@libsql/client";
|
|
2
|
+
import { drizzle as drizzleLibsql } from "drizzle-orm/libsql";
|
|
3
|
+
const isWebContainer = !!process.versions?.webcontainer;
|
|
4
|
+
function createClient(options) {
|
|
5
|
+
const url = isWebContainer ? "file:content.db" : options.url;
|
|
6
|
+
const client = createLibsqlClient({ url });
|
|
7
|
+
const db = drizzleLibsql(client);
|
|
8
|
+
return db;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
createClient
|
|
12
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type RemoteDbClientOptions = {
|
|
2
|
+
token: string;
|
|
3
|
+
url: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function createClient(opts: RemoteDbClientOptions): import("drizzle-orm/libsql").LibSQLDatabase<Record<string, never>> & {
|
|
6
|
+
$client: import("@libsql/client").Client;
|
|
7
|
+
};
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createClient as createLibsqlClient } from "@libsql/client";
|
|
2
|
+
import { drizzle as drizzleLibsql } from "drizzle-orm/libsql";
|
|
3
|
+
import { parseLibSQLConfig } from "./utils.js";
|
|
4
|
+
function createClient(opts) {
|
|
5
|
+
const { token, url: rawUrl } = opts;
|
|
6
|
+
let parsedUrl = new URL(rawUrl);
|
|
7
|
+
const options = Object.fromEntries(parsedUrl.searchParams.entries());
|
|
8
|
+
parsedUrl.search = "";
|
|
9
|
+
let url = parsedUrl.toString();
|
|
10
|
+
if (parsedUrl.protocol === "memory:") {
|
|
11
|
+
url = ":memory:";
|
|
12
|
+
} else if (parsedUrl.protocol === "file:" && parsedUrl.pathname.startsWith("/") && !rawUrl.startsWith("file:/")) {
|
|
13
|
+
url = "file:" + parsedUrl.pathname.substring(1);
|
|
14
|
+
}
|
|
15
|
+
const libSQLOptions = parseLibSQLConfig(options);
|
|
16
|
+
const client = createLibsqlClient({ ...libSQLOptions, url, authToken: token });
|
|
17
|
+
return drizzleLibsql(client);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
createClient
|
|
21
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type RemoteDbClientOptions = {
|
|
2
|
+
token: string;
|
|
3
|
+
url: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function createClient(opts: RemoteDbClientOptions): import("drizzle-orm/libsql").LibSQLDatabase<Record<string, never>> & {
|
|
6
|
+
$client: import("@libsql/client/web").Client;
|
|
7
|
+
};
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createClient as createLibsqlClient } from "@libsql/client/web";
|
|
2
|
+
import { drizzle as drizzleLibsql } from "drizzle-orm/libsql/web";
|
|
3
|
+
import { parseLibSQLConfig } from "./utils.js";
|
|
4
|
+
function createClient(opts) {
|
|
5
|
+
const { token, url: rawUrl } = opts;
|
|
6
|
+
let parsedUrl = new URL(rawUrl);
|
|
7
|
+
const options = Object.fromEntries(parsedUrl.searchParams.entries());
|
|
8
|
+
parsedUrl.search = "";
|
|
9
|
+
let url = parsedUrl.toString();
|
|
10
|
+
const supportedProtocols = ["http:", "https:", "libsql:"];
|
|
11
|
+
if (!supportedProtocols.includes(parsedUrl.protocol)) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Unsupported protocol "${parsedUrl.protocol}" for libSQL web client. Supported protocols are: ${supportedProtocols.join(", ")}.`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
const libSQLOptions = parseLibSQLConfig(options);
|
|
17
|
+
const client = createLibsqlClient({ ...libSQLOptions, url, authToken: token });
|
|
18
|
+
return drizzleLibsql(client);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
createClient
|
|
22
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
const rawLibSQLOptions = z.record(z.string());
|
|
3
|
+
const parseNumber = (value) => z.coerce.number().parse(value);
|
|
4
|
+
const parseBoolean = (value) => z.coerce.boolean().parse(value);
|
|
5
|
+
const booleanValues = ["true", "false"];
|
|
6
|
+
const parseOptionalBoolean = (value) => {
|
|
7
|
+
if (booleanValues.includes(value)) {
|
|
8
|
+
return parseBoolean(value);
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
};
|
|
12
|
+
const libSQLConfigTransformed = rawLibSQLOptions.transform((raw) => {
|
|
13
|
+
const parsed = {};
|
|
14
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
15
|
+
switch (key) {
|
|
16
|
+
case "syncInterval":
|
|
17
|
+
case "concurrency":
|
|
18
|
+
parsed[key] = parseNumber(value);
|
|
19
|
+
break;
|
|
20
|
+
case "readYourWrites":
|
|
21
|
+
case "offline":
|
|
22
|
+
case "tls":
|
|
23
|
+
parsed[key] = parseOptionalBoolean(value);
|
|
24
|
+
break;
|
|
25
|
+
case "authToken":
|
|
26
|
+
case "encryptionKey":
|
|
27
|
+
case "syncUrl":
|
|
28
|
+
parsed[key] = value;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
});
|
|
34
|
+
const parseLibSQLConfig = (config) => {
|
|
35
|
+
try {
|
|
36
|
+
return libSQLConfigTransformed.parse(config);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error instanceof z.ZodError) {
|
|
39
|
+
throw new Error(`Invalid LibSQL config: ${error.errors.map((e) => e.message).join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
export {
|
|
45
|
+
parseLibSQLConfig
|
|
46
|
+
};
|
package/dist/core/errors.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
const MISSING_EXECUTE_PATH_ERROR = `${red(
|
|
1
|
+
import colors from "picocolors";
|
|
2
|
+
const MISSING_EXECUTE_PATH_ERROR = `${colors.red(
|
|
3
3
|
"\u25B6 No file path provided."
|
|
4
|
-
)} Provide a path by running ${cyan("astro db execute <path>")}
|
|
4
|
+
)} Provide a path by running ${colors.cyan("astro db execute <path>")}
|
|
5
5
|
`;
|
|
6
6
|
const RENAME_TABLE_ERROR = (oldTable, newTable) => {
|
|
7
|
-
return red("\u25B6 Potential table rename detected: " + oldTable + " -> " + newTable) + `
|
|
7
|
+
return colors.red("\u25B6 Potential table rename detected: " + oldTable + " -> " + newTable) + `
|
|
8
8
|
You cannot add and remove tables in the same schema update batch.
|
|
9
9
|
|
|
10
10
|
1. Use "deprecated: true" to deprecate a table before renaming.
|
|
@@ -13,28 +13,28 @@ const RENAME_TABLE_ERROR = (oldTable, newTable) => {
|
|
|
13
13
|
Visit https://docs.astro.build/en/guides/astro-db/#renaming-tables to learn more.`;
|
|
14
14
|
};
|
|
15
15
|
const RENAME_COLUMN_ERROR = (oldSelector, newSelector) => {
|
|
16
|
-
return red("\u25B6 Potential column rename detected: " + oldSelector + ", " + newSelector) + `
|
|
16
|
+
return colors.red("\u25B6 Potential column rename detected: " + oldSelector + ", " + newSelector) + `
|
|
17
17
|
You cannot add and remove columns in the same table.
|
|
18
18
|
To resolve, add a 'deprecated: true' flag to '${oldSelector}' instead.`;
|
|
19
19
|
};
|
|
20
|
-
const FILE_NOT_FOUND_ERROR = (path) => `${red("\u25B6 File not found:")} ${bold(path)}
|
|
20
|
+
const FILE_NOT_FOUND_ERROR = (path) => `${colors.red("\u25B6 File not found:")} ${colors.bold(path)}
|
|
21
21
|
`;
|
|
22
|
-
const SHELL_QUERY_MISSING_ERROR = `${red(
|
|
22
|
+
const SHELL_QUERY_MISSING_ERROR = `${colors.red(
|
|
23
23
|
"\u25B6 Please provide a query to execute using the --query flag."
|
|
24
24
|
)}
|
|
25
25
|
`;
|
|
26
26
|
const EXEC_ERROR = (error) => {
|
|
27
|
-
return `${red(`Error while executing file:`)}
|
|
27
|
+
return `${colors.red(`Error while executing file:`)}
|
|
28
28
|
|
|
29
29
|
${error}`;
|
|
30
30
|
};
|
|
31
31
|
const EXEC_DEFAULT_EXPORT_ERROR = (fileName) => {
|
|
32
|
-
return EXEC_ERROR(`Missing default function export in ${bold(fileName)}`);
|
|
32
|
+
return EXEC_ERROR(`Missing default function export in ${colors.bold(fileName)}`);
|
|
33
33
|
};
|
|
34
34
|
const INTEGRATION_TABLE_CONFLICT_ERROR = (integrationName, tableName, isUserConflict) => {
|
|
35
|
-
return red("\u25B6 Conflicting table name in integration " + bold(integrationName)) + isUserConflict ? `
|
|
36
|
-
A user-defined table named ${bold(tableName)} already exists` : `
|
|
37
|
-
Another integration already added a table named ${bold(tableName)}`;
|
|
35
|
+
return colors.red("\u25B6 Conflicting table name in integration " + colors.bold(integrationName)) + isUserConflict ? `
|
|
36
|
+
A user-defined table named ${colors.bold(tableName)} already exists` : `
|
|
37
|
+
Another integration already added a table named ${colors.bold(tableName)}`;
|
|
38
38
|
};
|
|
39
39
|
export {
|
|
40
40
|
EXEC_DEFAULT_EXPORT_ERROR,
|
|
@@ -1,2 +1,19 @@
|
|
|
1
1
|
import type { AstroIntegration } from 'astro';
|
|
2
|
-
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const astroDBConfigSchema: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
4
|
+
/**
|
|
5
|
+
* Sets the mode of the underlying `@libsql/client` connection.
|
|
6
|
+
*
|
|
7
|
+
* In most cases, the default 'node' mode is sufficient. On platforms like Cloudflare, or Deno, you may need to set this to 'web'.
|
|
8
|
+
*
|
|
9
|
+
* @default 'node'
|
|
10
|
+
*/
|
|
11
|
+
mode: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"node">, z.ZodLiteral<"web">]>>>;
|
|
12
|
+
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
mode: "node" | "web";
|
|
14
|
+
}, {
|
|
15
|
+
mode?: "node" | "web" | undefined;
|
|
16
|
+
}>>>;
|
|
17
|
+
export type AstroDBConfig = z.infer<typeof astroDBConfigSchema>;
|
|
18
|
+
export declare function integration(options?: AstroDBConfig): AstroIntegration[];
|
|
19
|
+
export {};
|
|
@@ -2,13 +2,14 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import
|
|
5
|
+
import colors from "picocolors";
|
|
6
6
|
import {
|
|
7
7
|
createServer,
|
|
8
8
|
loadEnv,
|
|
9
9
|
mergeConfig
|
|
10
10
|
} from "vite";
|
|
11
11
|
import parseArgs from "yargs-parser";
|
|
12
|
+
import { z } from "zod";
|
|
12
13
|
import { AstroDbError, isDbError } from "../../runtime/utils.js";
|
|
13
14
|
import { CONFIG_FILE_NAMES, DB_PATH, VIRTUAL_MODULE_ID } from "../consts.js";
|
|
14
15
|
import { EXEC_DEFAULT_EXPORT_ERROR, EXEC_ERROR } from "../errors.js";
|
|
@@ -20,7 +21,19 @@ import { getDtsContent } from "./typegen.js";
|
|
|
20
21
|
import {
|
|
21
22
|
vitePluginDb
|
|
22
23
|
} from "./vite-plugin-db.js";
|
|
23
|
-
|
|
24
|
+
import { vitePluginDbClient } from "./vite-plugin-db-client.js";
|
|
25
|
+
const astroDBConfigSchema = z.object({
|
|
26
|
+
/**
|
|
27
|
+
* Sets the mode of the underlying `@libsql/client` connection.
|
|
28
|
+
*
|
|
29
|
+
* In most cases, the default 'node' mode is sufficient. On platforms like Cloudflare, or Deno, you may need to set this to 'web'.
|
|
30
|
+
*
|
|
31
|
+
* @default 'node'
|
|
32
|
+
*/
|
|
33
|
+
mode: z.union([z.literal("node"), z.literal("web")]).optional().default("node")
|
|
34
|
+
}).optional().default({});
|
|
35
|
+
function astroDBIntegration(options) {
|
|
36
|
+
const resolvedConfig = astroDBConfigSchema.parse(options);
|
|
24
37
|
let connectToRemote = false;
|
|
25
38
|
let configFileDependencies = [];
|
|
26
39
|
let root;
|
|
@@ -53,6 +66,10 @@ function astroDBIntegration() {
|
|
|
53
66
|
let dbPlugin = void 0;
|
|
54
67
|
const args = parseArgs(process.argv.slice(3));
|
|
55
68
|
connectToRemote = process.env.ASTRO_INTERNAL_TEST_REMOTE || args["remote"];
|
|
69
|
+
const dbClientPlugin = vitePluginDbClient({
|
|
70
|
+
connectToRemote,
|
|
71
|
+
mode: resolvedConfig.mode
|
|
72
|
+
});
|
|
56
73
|
if (connectToRemote) {
|
|
57
74
|
dbPlugin = vitePluginDb({
|
|
58
75
|
connectToRemote,
|
|
@@ -78,7 +95,7 @@ function astroDBIntegration() {
|
|
|
78
95
|
updateConfig({
|
|
79
96
|
vite: {
|
|
80
97
|
assetsInclude: [DB_PATH],
|
|
81
|
-
plugins: [dbPlugin]
|
|
98
|
+
plugins: [dbClientPlugin, dbPlugin]
|
|
82
99
|
}
|
|
83
100
|
});
|
|
84
101
|
},
|
|
@@ -134,7 +151,9 @@ function astroDBIntegration() {
|
|
|
134
151
|
const hint = "Learn more connecting to libSQL: https://docs.astro.build/en/guides/astro-db/#connect-a-libsql-database-for-production";
|
|
135
152
|
throw new AstroDbError(message, hint);
|
|
136
153
|
}
|
|
137
|
-
logger.info(
|
|
154
|
+
logger.info(
|
|
155
|
+
"database: " + (connectToRemote ? colors.yellow("remote") : colors.blue("local database."))
|
|
156
|
+
);
|
|
138
157
|
},
|
|
139
158
|
"astro:build:setup": async ({ vite }) => {
|
|
140
159
|
tempViteServer = await getTempViteServer({ viteConfig: vite });
|
|
@@ -152,8 +171,8 @@ function databaseFileEnvDefined() {
|
|
|
152
171
|
const env = loadEnv("", process.cwd());
|
|
153
172
|
return env.ASTRO_DATABASE_FILE != null || process.env.ASTRO_DATABASE_FILE != null;
|
|
154
173
|
}
|
|
155
|
-
function integration() {
|
|
156
|
-
return [astroDBIntegration(), fileURLIntegration()];
|
|
174
|
+
function integration(options) {
|
|
175
|
+
return [astroDBIntegration(options), fileURLIntegration()];
|
|
157
176
|
}
|
|
158
177
|
async function executeSeedFile({
|
|
159
178
|
fileUrl,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DB_CLIENTS, VIRTUAL_CLIENT_MODULE_ID } from "../consts.js";
|
|
2
|
+
function getRemoteClientModule(mode) {
|
|
3
|
+
switch (mode) {
|
|
4
|
+
case "web":
|
|
5
|
+
return `export { createClient } from '${DB_CLIENTS.web}';`;
|
|
6
|
+
case "node":
|
|
7
|
+
default:
|
|
8
|
+
return `export { createClient } from '${DB_CLIENTS.node}';`;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function getLocalClientModule(mode) {
|
|
12
|
+
switch (mode) {
|
|
13
|
+
case "node":
|
|
14
|
+
case "web":
|
|
15
|
+
default:
|
|
16
|
+
return `export { createClient } from '${DB_CLIENTS.local}';`;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const resolved = "\0" + VIRTUAL_CLIENT_MODULE_ID;
|
|
20
|
+
function vitePluginDbClient(params) {
|
|
21
|
+
return {
|
|
22
|
+
name: "virtual:astro:db-client",
|
|
23
|
+
enforce: "pre",
|
|
24
|
+
async resolveId(id) {
|
|
25
|
+
if (id !== VIRTUAL_CLIENT_MODULE_ID) return;
|
|
26
|
+
return resolved;
|
|
27
|
+
},
|
|
28
|
+
async load(id) {
|
|
29
|
+
if (id !== resolved) return;
|
|
30
|
+
switch (params.connectToRemote) {
|
|
31
|
+
case true:
|
|
32
|
+
return getRemoteClientModule(params.mode);
|
|
33
|
+
case false:
|
|
34
|
+
default:
|
|
35
|
+
return getLocalClientModule(params.mode);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
vitePluginDbClient
|
|
42
|
+
};
|
|
@@ -31,14 +31,30 @@ type VitePluginDBParams = {
|
|
|
31
31
|
};
|
|
32
32
|
export declare function vitePluginDb(params: VitePluginDBParams): VitePlugin;
|
|
33
33
|
export declare function getConfigVirtualModContents(): string;
|
|
34
|
-
export declare function getLocalVirtualModContents({ tables, root }: {
|
|
34
|
+
export declare function getLocalVirtualModContents({ tables, root, localExecution, }: {
|
|
35
35
|
tables: DBTables;
|
|
36
36
|
root: URL;
|
|
37
|
+
/**
|
|
38
|
+
* Used for the execute command to import the client directly.
|
|
39
|
+
* In other cases, we use the runtime only vite virtual module.
|
|
40
|
+
*
|
|
41
|
+
* This is used to ensure that the client is imported correctly
|
|
42
|
+
* when executing commands like `astro db execute`.
|
|
43
|
+
*/
|
|
44
|
+
localExecution: boolean;
|
|
37
45
|
}): string;
|
|
38
|
-
export declare function getRemoteVirtualModContents({ tables, appToken, isBuild, output, }: {
|
|
46
|
+
export declare function getRemoteVirtualModContents({ tables, appToken, isBuild, output, localExecution, }: {
|
|
39
47
|
tables: DBTables;
|
|
40
48
|
appToken: string;
|
|
41
49
|
isBuild: boolean;
|
|
42
50
|
output: AstroConfig['output'];
|
|
51
|
+
/**
|
|
52
|
+
* Used for the execute command to import the client directly.
|
|
53
|
+
* In other cases, we use the runtime only vite virtual module.
|
|
54
|
+
*
|
|
55
|
+
* This is used to ensure that the client is imported correctly
|
|
56
|
+
* when executing commands like `astro db execute`.
|
|
57
|
+
*/
|
|
58
|
+
localExecution: boolean;
|
|
43
59
|
}): string;
|
|
44
60
|
export {};
|
|
@@ -2,9 +2,16 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { sql } from "drizzle-orm";
|
|
4
4
|
import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
|
|
5
|
-
import { createLocalDatabaseClient } from "../../runtime/db-client.js";
|
|
6
5
|
import { normalizeDatabaseUrl } from "../../runtime/index.js";
|
|
7
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DB_CLIENTS,
|
|
8
|
+
DB_PATH,
|
|
9
|
+
RUNTIME_IMPORT,
|
|
10
|
+
RUNTIME_VIRTUAL_IMPORT,
|
|
11
|
+
VIRTUAL_CLIENT_MODULE_ID,
|
|
12
|
+
VIRTUAL_MODULE_ID
|
|
13
|
+
} from "../consts.js";
|
|
14
|
+
import { createClient } from "../db-client/libsql-local.js";
|
|
8
15
|
import { getResolvedFileUrl } from "../load-file.js";
|
|
9
16
|
import { getCreateIndexQueries, getCreateTableQuery, SEED_DEV_FILE_NAME } from "../queries.js";
|
|
10
17
|
import {
|
|
@@ -38,13 +45,15 @@ function vitePluginDb(params) {
|
|
|
38
45
|
appToken: params.appToken,
|
|
39
46
|
tables: params.tables.get(),
|
|
40
47
|
isBuild: command === "build",
|
|
41
|
-
output: params.output
|
|
48
|
+
output: params.output,
|
|
49
|
+
localExecution: false
|
|
42
50
|
});
|
|
43
51
|
}
|
|
44
52
|
if (id === resolved.importedFromSeedFile) {
|
|
45
53
|
return getLocalVirtualModContents({
|
|
46
54
|
root: params.root,
|
|
47
|
-
tables: params.tables.get()
|
|
55
|
+
tables: params.tables.get(),
|
|
56
|
+
localExecution: false
|
|
48
57
|
});
|
|
49
58
|
}
|
|
50
59
|
await recreateTables(params);
|
|
@@ -62,7 +71,8 @@ function vitePluginDb(params) {
|
|
|
62
71
|
}
|
|
63
72
|
return getLocalVirtualModContents({
|
|
64
73
|
root: params.root,
|
|
65
|
-
tables: params.tables.get()
|
|
74
|
+
tables: params.tables.get(),
|
|
75
|
+
localExecution: false
|
|
66
76
|
});
|
|
67
77
|
}
|
|
68
78
|
};
|
|
@@ -70,15 +80,24 @@ function vitePluginDb(params) {
|
|
|
70
80
|
function getConfigVirtualModContents() {
|
|
71
81
|
return `export * from ${RUNTIME_VIRTUAL_IMPORT}`;
|
|
72
82
|
}
|
|
73
|
-
function
|
|
83
|
+
function getDBModule(localExecution) {
|
|
84
|
+
return localExecution ? `import { createClient } from '${DB_CLIENTS.node}';` : `import { createClient } from '${VIRTUAL_CLIENT_MODULE_ID}';`;
|
|
85
|
+
}
|
|
86
|
+
function getLocalVirtualModContents({
|
|
87
|
+
tables,
|
|
88
|
+
root,
|
|
89
|
+
localExecution
|
|
90
|
+
}) {
|
|
74
91
|
const { ASTRO_DATABASE_FILE } = getAstroEnv();
|
|
75
|
-
const dbInfo = getRemoteDatabaseInfo();
|
|
76
92
|
const dbUrl = new URL(DB_PATH, root);
|
|
93
|
+
const clientImport = getDBModule(localExecution);
|
|
77
94
|
return `
|
|
78
|
-
import { asDrizzleTable,
|
|
95
|
+
import { asDrizzleTable, normalizeDatabaseUrl } from ${RUNTIME_IMPORT};
|
|
96
|
+
|
|
97
|
+
${clientImport}
|
|
79
98
|
|
|
80
99
|
const dbUrl = normalizeDatabaseUrl(${JSON.stringify(ASTRO_DATABASE_FILE)}, ${JSON.stringify(dbUrl)});
|
|
81
|
-
export const db =
|
|
100
|
+
export const db = createClient({ url: dbUrl });
|
|
82
101
|
|
|
83
102
|
export * from ${RUNTIME_VIRTUAL_IMPORT};
|
|
84
103
|
|
|
@@ -88,7 +107,8 @@ function getRemoteVirtualModContents({
|
|
|
88
107
|
tables,
|
|
89
108
|
appToken,
|
|
90
109
|
isBuild,
|
|
91
|
-
output
|
|
110
|
+
output,
|
|
111
|
+
localExecution
|
|
92
112
|
}) {
|
|
93
113
|
const dbInfo = getRemoteDatabaseInfo();
|
|
94
114
|
function appTokenArg() {
|
|
@@ -110,10 +130,13 @@ function getRemoteVirtualModContents({
|
|
|
110
130
|
return dbStr;
|
|
111
131
|
}
|
|
112
132
|
}
|
|
133
|
+
const clientImport = getDBModule(localExecution);
|
|
113
134
|
return `
|
|
114
|
-
import {asDrizzleTable
|
|
135
|
+
import {asDrizzleTable} from ${RUNTIME_IMPORT};
|
|
136
|
+
|
|
137
|
+
${clientImport}
|
|
115
138
|
|
|
116
|
-
export const db = await
|
|
139
|
+
export const db = await createClient({
|
|
117
140
|
url: ${dbUrlArg()},
|
|
118
141
|
token: ${appTokenArg()},
|
|
119
142
|
});
|
|
@@ -134,7 +157,7 @@ const sqlite = new SQLiteAsyncDialect();
|
|
|
134
157
|
async function recreateTables({ tables, root }) {
|
|
135
158
|
const { ASTRO_DATABASE_FILE } = getAstroEnv();
|
|
136
159
|
const dbUrl = normalizeDatabaseUrl(ASTRO_DATABASE_FILE, new URL(DB_PATH, root).href);
|
|
137
|
-
const db =
|
|
160
|
+
const db = createClient({ url: dbUrl });
|
|
138
161
|
const setupQueries = [];
|
|
139
162
|
for (const [name, table] of Object.entries(tables.get() ?? {})) {
|
|
140
163
|
const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${sqlite.escapeName(name)}`);
|
package/dist/core/queries.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
|
|
2
|
-
import
|
|
2
|
+
import colors from "picocolors";
|
|
3
3
|
import {
|
|
4
4
|
FOREIGN_KEY_DNE_ERROR,
|
|
5
5
|
FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
|
|
6
6
|
FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
|
|
7
7
|
REFERENCE_DNE_ERROR
|
|
8
8
|
} from "../runtime/errors.js";
|
|
9
|
-
import { hasPrimaryKey } from "../runtime/index.js";
|
|
10
9
|
import { isSerializedSQL } from "../runtime/types.js";
|
|
10
|
+
import { hasPrimaryKey } from "../runtime/utils.js";
|
|
11
11
|
const sqlite = new SQLiteAsyncDialect();
|
|
12
12
|
const SEED_DEV_FILE_NAME = ["seed.ts", "seed.js", "seed.mjs", "seed.mts"];
|
|
13
13
|
function getDropTableIfExistsQuery(tableName) {
|
|
@@ -144,7 +144,7 @@ function getDefaultValueSql(columnName, column) {
|
|
|
144
144
|
stringified = JSON.stringify(column.schema.default);
|
|
145
145
|
} catch {
|
|
146
146
|
console.log(
|
|
147
|
-
`Invalid default value for column ${bold(
|
|
147
|
+
`Invalid default value for column ${colors.bold(
|
|
148
148
|
columnName
|
|
149
149
|
)}. Defaults must be valid JSON when using the \`json()\` type.`
|
|
150
150
|
);
|
|
File without changes
|
package/dist/index.d.ts
CHANGED
package/dist/runtime/errors.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import colors from "picocolors";
|
|
2
2
|
const FOREIGN_KEY_DNE_ERROR = (tableName) => {
|
|
3
|
-
return `Table ${bold(
|
|
3
|
+
return `Table ${colors.bold(
|
|
4
4
|
tableName
|
|
5
5
|
)} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
|
|
6
6
|
};
|
|
7
7
|
const FOREIGN_KEY_REFERENCES_LENGTH_ERROR = (tableName) => {
|
|
8
|
-
return `Foreign key on ${bold(
|
|
8
|
+
return `Foreign key on ${colors.bold(
|
|
9
9
|
tableName
|
|
10
10
|
)} is misconfigured. \`columns\` and \`references\` must be the same length.`;
|
|
11
11
|
};
|
|
12
12
|
const FOREIGN_KEY_REFERENCES_EMPTY_ERROR = (tableName) => {
|
|
13
|
-
return `Foreign key on ${bold(
|
|
13
|
+
return `Foreign key on ${colors.bold(
|
|
14
14
|
tableName
|
|
15
15
|
)} is misconfigured. \`references\` array cannot be empty.`;
|
|
16
16
|
};
|
|
17
17
|
const REFERENCE_DNE_ERROR = (columnName) => {
|
|
18
|
-
return `Column ${bold(
|
|
18
|
+
return `Column ${colors.bold(
|
|
19
19
|
columnName
|
|
20
20
|
)} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
|
|
21
21
|
};
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { type ColumnDataType } from 'drizzle-orm';
|
|
2
2
|
import type { LibSQLDatabase } from 'drizzle-orm/libsql';
|
|
3
|
-
import type {
|
|
3
|
+
import type { DBTable } from '../core/types.js';
|
|
4
4
|
export type Database = LibSQLDatabase;
|
|
5
|
-
export { createLocalDatabaseClient, createRemoteDatabaseClient } from './db-client.js';
|
|
6
5
|
export type { Table } from './types.js';
|
|
7
|
-
export
|
|
6
|
+
export { hasPrimaryKey } from './utils.js';
|
|
8
7
|
export declare function asDrizzleTable(name: string, table: DBTable): import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
9
8
|
name: string;
|
|
10
9
|
schema: undefined;
|
package/dist/runtime/index.js
CHANGED
|
@@ -7,11 +7,8 @@ import {
|
|
|
7
7
|
text
|
|
8
8
|
} from "drizzle-orm/sqlite-core";
|
|
9
9
|
import { isSerializedSQL } from "./types.js";
|
|
10
|
-
import { pathToFileURL } from "./utils.js";
|
|
11
|
-
import {
|
|
12
|
-
function hasPrimaryKey(column) {
|
|
13
|
-
return "primaryKey" in column.schema && !!column.schema.primaryKey;
|
|
14
|
-
}
|
|
10
|
+
import { hasPrimaryKey, pathToFileURL } from "./utils.js";
|
|
11
|
+
import { hasPrimaryKey as hasPrimaryKey2 } from "./utils.js";
|
|
15
12
|
const isISODateString = (str) => /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(str);
|
|
16
13
|
const dateType = customType({
|
|
17
14
|
dataType() {
|
|
@@ -119,8 +116,6 @@ function normalizeDatabaseUrl(envDbUrl, defaultDbUrl) {
|
|
|
119
116
|
}
|
|
120
117
|
export {
|
|
121
118
|
asDrizzleTable,
|
|
122
|
-
|
|
123
|
-
createRemoteDatabaseClient,
|
|
124
|
-
hasPrimaryKey,
|
|
119
|
+
hasPrimaryKey2 as hasPrimaryKey,
|
|
125
120
|
normalizeDatabaseUrl
|
|
126
121
|
};
|
package/dist/runtime/utils.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { LibsqlError } from '@libsql/client';
|
|
2
2
|
import { AstroError } from 'astro/errors';
|
|
3
|
+
import type { DBColumn } from '../core/types.js';
|
|
4
|
+
export declare function hasPrimaryKey(column: DBColumn): boolean;
|
|
3
5
|
export declare class AstroDbError extends AstroError {
|
|
4
6
|
name: string;
|
|
5
7
|
}
|
package/dist/runtime/utils.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { LibsqlError } from "@libsql/client";
|
|
2
2
|
import { AstroError } from "astro/errors";
|
|
3
|
+
function hasPrimaryKey(column) {
|
|
4
|
+
return "primaryKey" in column.schema && !!column.schema.primaryKey;
|
|
5
|
+
}
|
|
3
6
|
const isWindows = process?.platform === "win32";
|
|
4
7
|
class AstroDbError extends AstroError {
|
|
5
8
|
name = "Astro DB Error";
|
|
@@ -26,6 +29,7 @@ function pathToFileURL(path) {
|
|
|
26
29
|
}
|
|
27
30
|
export {
|
|
28
31
|
AstroDbError,
|
|
32
|
+
hasPrimaryKey,
|
|
29
33
|
isDbError,
|
|
30
34
|
pathToFileURL
|
|
31
35
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/db",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "Add libSQL support to your Astro site",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"types": "./dist/runtime/index.d.ts",
|
|
28
28
|
"default": "./dist/runtime/index.js"
|
|
29
29
|
},
|
|
30
|
+
"./db-client/*": "./dist/core/db-client/*",
|
|
30
31
|
"./dist/runtime/virtual.js": {
|
|
31
32
|
"default": "./dist/runtime/virtual.js"
|
|
32
33
|
},
|
|
@@ -62,11 +63,11 @@
|
|
|
62
63
|
"astro-integration"
|
|
63
64
|
],
|
|
64
65
|
"dependencies": {
|
|
65
|
-
"@libsql/client": "^0.15.
|
|
66
|
+
"@libsql/client": "^0.15.15",
|
|
66
67
|
"deep-diff": "^1.0.2",
|
|
67
68
|
"drizzle-orm": "^0.42.0",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
69
|
+
"nanoid": "^5.1.6",
|
|
70
|
+
"picocolors": "^1.1.1",
|
|
70
71
|
"prompts": "^2.4.2",
|
|
71
72
|
"yargs-parser": "^21.1.1",
|
|
72
73
|
"zod": "^3.25.76"
|
|
@@ -77,9 +78,9 @@
|
|
|
77
78
|
"@types/yargs-parser": "^21.0.3",
|
|
78
79
|
"cheerio": "1.1.2",
|
|
79
80
|
"expect-type": "^1.2.2",
|
|
80
|
-
"typescript": "^5.9.
|
|
81
|
-
"vite": "^6.
|
|
82
|
-
"astro": "5.
|
|
81
|
+
"typescript": "^5.9.3",
|
|
82
|
+
"vite": "^6.4.0",
|
|
83
|
+
"astro": "5.15.0",
|
|
83
84
|
"astro-scripts": "0.0.14"
|
|
84
85
|
},
|
|
85
86
|
"scripts": {
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type Config as LibSQLConfig } from '@libsql/client';
|
|
2
|
-
import type { LibSQLDatabase } from 'drizzle-orm/libsql';
|
|
3
|
-
type LocalDbClientOptions = {
|
|
4
|
-
dbUrl: string;
|
|
5
|
-
};
|
|
6
|
-
export declare function createLocalDatabaseClient(options: LocalDbClientOptions): LibSQLDatabase;
|
|
7
|
-
type RemoteDbClientOptions = {
|
|
8
|
-
token: string;
|
|
9
|
-
url: string | URL;
|
|
10
|
-
};
|
|
11
|
-
export declare function createRemoteDatabaseClient(options: RemoteDbClientOptions): LibSQLDatabase<Record<string, never>> & {
|
|
12
|
-
$client: import("@libsql/client").Client;
|
|
13
|
-
};
|
|
14
|
-
export declare function parseOpts(config: Record<string, string>): Partial<LibSQLConfig>;
|
|
15
|
-
export {};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { createClient } from "@libsql/client";
|
|
2
|
-
import { drizzle as drizzleLibsql } from "drizzle-orm/libsql";
|
|
3
|
-
const isWebContainer = !!process.versions?.webcontainer;
|
|
4
|
-
function createLocalDatabaseClient(options) {
|
|
5
|
-
const url = isWebContainer ? "file:content.db" : options.dbUrl;
|
|
6
|
-
const client = createClient({ url });
|
|
7
|
-
const db = drizzleLibsql(client);
|
|
8
|
-
return db;
|
|
9
|
-
}
|
|
10
|
-
function createRemoteDatabaseClient(options) {
|
|
11
|
-
const url = new URL(options.url);
|
|
12
|
-
return createRemoteLibSQLClient(options.token, url, options.url.toString());
|
|
13
|
-
}
|
|
14
|
-
function parseOpts(config) {
|
|
15
|
-
return {
|
|
16
|
-
...config,
|
|
17
|
-
...config.syncInterval ? { syncInterval: parseInt(config.syncInterval) } : {},
|
|
18
|
-
..."readYourWrites" in config ? { readYourWrites: config.readYourWrites !== "false" } : {},
|
|
19
|
-
..."offline" in config ? { offline: config.offline !== "false" } : {},
|
|
20
|
-
..."tls" in config ? { tls: config.tls !== "false" } : {},
|
|
21
|
-
...config.concurrency ? { concurrency: parseInt(config.concurrency) } : {}
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function createRemoteLibSQLClient(authToken, dbURL, rawUrl) {
|
|
25
|
-
const options = Object.fromEntries(dbURL.searchParams.entries());
|
|
26
|
-
dbURL.search = "";
|
|
27
|
-
let url = dbURL.toString();
|
|
28
|
-
if (dbURL.protocol === "memory:") {
|
|
29
|
-
url = ":memory:";
|
|
30
|
-
} else if (dbURL.protocol === "file:" && dbURL.pathname.startsWith("/") && !rawUrl.startsWith("file:/")) {
|
|
31
|
-
url = "file:" + dbURL.pathname.substring(1);
|
|
32
|
-
}
|
|
33
|
-
const client = createClient({ ...parseOpts(options), url, authToken });
|
|
34
|
-
return drizzleLibsql(client);
|
|
35
|
-
}
|
|
36
|
-
export {
|
|
37
|
-
createLocalDatabaseClient,
|
|
38
|
-
createRemoteDatabaseClient,
|
|
39
|
-
parseOpts
|
|
40
|
-
};
|