@astrojs/db 0.17.2 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  }
@@ -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 });
@@ -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 = createRemoteDatabaseClient({
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
  }
@@ -4,10 +4,10 @@ import { sql } from "drizzle-orm";
4
4
  import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
5
5
  import * as color from "kleur/colors";
6
6
  import { customAlphabet } from "nanoid";
7
- import { createRemoteDatabaseClient, hasPrimaryKey } from "../../runtime/index.js";
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 = createRemoteDatabaseClient({
312
+ const client = createClient({
313
313
  token: appToken,
314
314
  url: remoteUrl
315
315
  });
@@ -27,7 +27,7 @@ function printHelp({
27
27
  message.push(
28
28
  linebreak(),
29
29
  ` ${bgGreen(black(` ${commandName} `))} ${green(
30
- `v${"0.17.2"}`
30
+ `v${"0.18.0"}`
31
31
  )} ${headline}`
32
32
  );
33
33
  }
@@ -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
+ };
@@ -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,6 @@
1
+ import { type LibSQLDatabase } from 'drizzle-orm/libsql';
2
+ type LocalDbClientOptions = {
3
+ url: string;
4
+ };
5
+ export declare function createClient(options: LocalDbClientOptions): LibSQLDatabase;
6
+ export {};
@@ -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,2 @@
1
+ import type { Config as LibSQLConfig } from '@libsql/client';
2
+ export declare const parseLibSQLConfig: (config: Record<string, string>) => Partial<LibSQLConfig>;
@@ -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
+ };
@@ -1,2 +1,19 @@
1
1
  import type { AstroIntegration } from 'astro';
2
- export declare function integration(): AstroIntegration[];
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 {};
@@ -9,6 +9,7 @@ import {
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
- function astroDBIntegration() {
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
  },
@@ -152,8 +169,8 @@ function databaseFileEnvDefined() {
152
169
  const env = loadEnv("", process.cwd());
153
170
  return env.ASTRO_DATABASE_FILE != null || process.env.ASTRO_DATABASE_FILE != null;
154
171
  }
155
- function integration() {
156
- return [astroDBIntegration(), fileURLIntegration()];
172
+ function integration(options) {
173
+ return [astroDBIntegration(options), fileURLIntegration()];
157
174
  }
158
175
  async function executeSeedFile({
159
176
  fileUrl,
@@ -0,0 +1,7 @@
1
+ import type { VitePlugin } from '../utils.js';
2
+ type VitePluginDBClientParams = {
3
+ connectToRemote: boolean;
4
+ mode: 'node' | 'web';
5
+ };
6
+ export declare function vitePluginDbClient(params: VitePluginDBClientParams): VitePlugin;
7
+ export {};
@@ -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 { DB_PATH, RUNTIME_IMPORT, RUNTIME_VIRTUAL_IMPORT, VIRTUAL_MODULE_ID } from "../consts.js";
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 getLocalVirtualModContents({ tables, root }) {
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, createLocalDatabaseClient, normalizeDatabaseUrl } from ${RUNTIME_IMPORT};
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 = createLocalDatabaseClient({ dbUrl, enableTransactions: ${dbInfo.url === "libsql"} });
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, createRemoteDatabaseClient} from ${RUNTIME_IMPORT};
135
+ import {asDrizzleTable} from ${RUNTIME_IMPORT};
136
+
137
+ ${clientImport}
115
138
 
116
- export const db = await createRemoteDatabaseClient({
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 = createLocalDatabaseClient({ dbUrl });
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)}`);
@@ -6,8 +6,8 @@ import {
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) {
File without changes
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { cli } from './core/cli/index.js';
2
- export { integration as default } from './core/integration/index.js';
2
+ export { type AstroDBConfig, integration as default } from './core/integration/index.js';
3
3
  export type { TableConfig } from './core/types.js';
@@ -1,10 +1,9 @@
1
1
  import { type ColumnDataType } from 'drizzle-orm';
2
2
  import type { LibSQLDatabase } from 'drizzle-orm/libsql';
3
- import type { DBColumn, DBTable } from '../core/types.js';
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 declare function hasPrimaryKey(column: DBColumn): boolean;
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;
@@ -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 { createLocalDatabaseClient, createRemoteDatabaseClient } from "./db-client.js";
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
- createLocalDatabaseClient,
123
- createRemoteDatabaseClient,
124
- hasPrimaryKey,
119
+ hasPrimaryKey2 as hasPrimaryKey,
125
120
  normalizeDatabaseUrl
126
121
  };
@@ -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,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.17.2",
3
+ "version": "0.18.0",
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,7 +63,7 @@
62
63
  "astro-integration"
63
64
  ],
64
65
  "dependencies": {
65
- "@libsql/client": "^0.15.14",
66
+ "@libsql/client": "^0.15.15",
66
67
  "deep-diff": "^1.0.2",
67
68
  "drizzle-orm": "^0.42.0",
68
69
  "kleur": "^4.1.5",
@@ -79,8 +80,8 @@
79
80
  "expect-type": "^1.2.2",
80
81
  "typescript": "^5.9.2",
81
82
  "vite": "^6.3.6",
82
- "astro": "5.13.6",
83
- "astro-scripts": "0.0.14"
83
+ "astro-scripts": "0.0.14",
84
+ "astro": "5.13.8"
84
85
  },
85
86
  "scripts": {
86
87
  "types:virtual": "tsc -p ./tsconfig.virtual.json",
@@ -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
- };