@astrojs/db 0.19.0-beta.2 → 0.19.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.
@@ -2,5 +2,5 @@
2
2
  * This is a modified version of Astro's error map. source:
3
3
  * https://github.com/withastro/astro/blob/main/packages/astro/src/content/error-map.ts
4
4
  */
5
- import type { z } from 'zod/v3';
5
+ import type { z } from 'astro/zod';
6
6
  export declare const errorMap: z.ZodErrorMap;
@@ -1,5 +1,5 @@
1
1
  import { SQL } from 'drizzle-orm';
2
- import { type ZodTypeDef, z } from 'zod/v3';
2
+ import { type ZodTypeDef, z } from 'zod';
3
3
  import { type SerializedSQL } from '../runtime/types.js';
4
4
  import type { NumberColumn, TextColumn } from './types.js';
5
5
  export type MaybeArray<T> = T | T[];
@@ -1,4 +1,4 @@
1
- import type { z } from 'zod/v3';
1
+ import type { z } from 'zod';
2
2
  import type { booleanColumnSchema, columnSchema, columnsSchema, dateColumnSchema, dbConfigSchema, indexSchema, jsonColumnSchema, MaybeArray, numberColumnOptsSchema, numberColumnSchema, referenceableColumnSchema, resolvedIndexSchema, tableSchema, textColumnOptsSchema, textColumnSchema } from './schemas.js';
3
3
  export type ResolvedIndexes = z.output<typeof dbConfigSchema>['tables'][string]['indexes'];
4
4
  export type BooleanColumn = z.infer<typeof booleanColumnSchema>;
@@ -1,4 +1,5 @@
1
1
  import type { AstroConfig, AstroIntegration } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
2
3
  import './types.js';
3
4
  export type VitePlugin = Required<AstroConfig['vite']>['plugins'][number];
4
5
  export declare function getAstroEnv(envMode?: string): Record<`ASTRO_${string}`, string>;
@@ -7,6 +8,8 @@ export type RemoteDatabaseInfo = {
7
8
  token: string;
8
9
  };
9
10
  export declare function getRemoteDatabaseInfo(): RemoteDatabaseInfo;
11
+ export declare function resolveDbAppToken(flags: Arguments, envToken: string): string;
12
+ export declare function resolveDbAppToken(flags: Arguments, envToken: string | undefined): string | undefined;
10
13
  export declare function getDbDirectoryUrl(root: URL | string): URL;
11
14
  export declare function defineDbIntegration(integration: AstroIntegration): AstroIntegration;
12
15
  /**
@@ -12,7 +12,7 @@ import {
12
12
  getRemoteVirtualModContents
13
13
  } from "../../../integration/vite-plugin-db.js";
14
14
  import { bundleFile, importBundledFile } from "../../../load-file.js";
15
- import { getRemoteDatabaseInfo } from "../../../utils.js";
15
+ import { getRemoteDatabaseInfo, resolveDbAppToken } from "../../../utils.js";
16
16
  async function cmd({
17
17
  astroConfig,
18
18
  dbConfig,
@@ -31,9 +31,10 @@ async function cmd({
31
31
  let virtualModContents;
32
32
  if (flags.remote) {
33
33
  const dbInfo = getRemoteDatabaseInfo();
34
+ const appToken = resolveDbAppToken(flags, dbInfo.token);
34
35
  virtualModContents = getRemoteVirtualModContents({
35
36
  tables: dbConfig.tables ?? {},
36
- appToken: flags.token ?? dbInfo.token,
37
+ appToken,
37
38
  isBuild: false,
38
39
  output: "server",
39
40
  localExecution: true
@@ -2,7 +2,10 @@ import { sql } from "drizzle-orm";
2
2
  import prompts from "prompts";
3
3
  import { MIGRATION_VERSION } from "../../../consts.js";
4
4
  import { createClient } from "../../../db-client/libsql-node.js";
5
- import { getRemoteDatabaseInfo } from "../../../utils.js";
5
+ import {
6
+ getRemoteDatabaseInfo,
7
+ resolveDbAppToken
8
+ } from "../../../utils.js";
6
9
  import {
7
10
  createCurrentSnapshot,
8
11
  createEmptySnapshot,
@@ -17,7 +20,8 @@ async function cmd({
17
20
  const isDryRun = flags.dryRun;
18
21
  const isForceReset = flags.forceReset;
19
22
  const dbInfo = getRemoteDatabaseInfo();
20
- const productionSnapshot = await getProductionCurrentSnapshot(dbInfo);
23
+ const appToken = resolveDbAppToken(flags, dbInfo.token);
24
+ const productionSnapshot = await getProductionCurrentSnapshot({ ...dbInfo, token: appToken });
21
25
  const currentSnapshot = createCurrentSnapshot(dbConfig);
22
26
  const isFromScratch = !productionSnapshot;
23
27
  const { queries: migrationQueries, confirmations } = await getMigrationQueries({
@@ -53,7 +57,7 @@ async function cmd({
53
57
  await pushSchema({
54
58
  statements: migrationQueries,
55
59
  dbInfo,
56
- appToken: flags.token ?? dbInfo.token,
60
+ appToken,
57
61
  isDryRun,
58
62
  currentSnapshot
59
63
  });
@@ -4,7 +4,7 @@ import { DB_PATH } from "../../../consts.js";
4
4
  import { createClient as createLocalDatabaseClient } from "../../../db-client/libsql-local.js";
5
5
  import { createClient as createRemoteDatabaseClient } from "../../../db-client/libsql-node.js";
6
6
  import { SHELL_QUERY_MISSING_ERROR } from "../../../errors.js";
7
- import { getAstroEnv, getRemoteDatabaseInfo } from "../../../utils.js";
7
+ import { getAstroEnv, getRemoteDatabaseInfo, resolveDbAppToken } from "../../../utils.js";
8
8
  async function cmd({
9
9
  flags,
10
10
  astroConfig
@@ -16,7 +16,8 @@ async function cmd({
16
16
  }
17
17
  const dbInfo = getRemoteDatabaseInfo();
18
18
  if (flags.remote) {
19
- const db = createRemoteDatabaseClient(dbInfo);
19
+ const appToken = resolveDbAppToken(flags, dbInfo.token);
20
+ const db = createRemoteDatabaseClient({ ...dbInfo, token: appToken });
20
21
  const result = await db.run(sql.raw(query));
21
22
  console.log(result);
22
23
  } else {
@@ -1,4 +1,4 @@
1
- import { getRemoteDatabaseInfo } from "../../../utils.js";
1
+ import { getRemoteDatabaseInfo, resolveDbAppToken } from "../../../utils.js";
2
2
  import {
3
3
  createCurrentSnapshot,
4
4
  createEmptySnapshot,
@@ -12,7 +12,8 @@ async function cmd({
12
12
  }) {
13
13
  const isJson = flags.json;
14
14
  const dbInfo = getRemoteDatabaseInfo();
15
- const productionSnapshot = await getProductionCurrentSnapshot(dbInfo);
15
+ const appToken = resolveDbAppToken(flags, dbInfo.token);
16
+ const productionSnapshot = await getProductionCurrentSnapshot({ ...dbInfo, token: appToken });
16
17
  const currentSnapshot = createCurrentSnapshot(dbConfig);
17
18
  const { queries: migrationQueries, confirmations } = await getMigrationQueries({
18
19
  oldSnapshot: productionSnapshot || createEmptySnapshot(),
@@ -6,6 +6,7 @@ async function cli({
6
6
  }) {
7
7
  const args = flags._;
8
8
  const command = args[2] === "db" ? args[3] : args[2];
9
+ validateDbAppTokenFlag(command, flags);
9
10
  const { dbConfig } = await resolveDbConfig(astroConfig);
10
11
  switch (command) {
11
12
  case "shell": {
@@ -59,6 +60,16 @@ async function cli({
59
60
  }
60
61
  }
61
62
  }
63
+ function validateDbAppTokenFlag(command, flags) {
64
+ if (command !== "execute" && command !== "push" && command !== "verify" && command !== "shell")
65
+ return;
66
+ const dbAppToken = flags.dbAppToken;
67
+ if (dbAppToken == null) return;
68
+ if (typeof dbAppToken !== "string") {
69
+ console.error(`Invalid value for --db-app-token; expected a string.`);
70
+ process.exit(1);
71
+ }
72
+ }
62
73
  export {
63
74
  cli
64
75
  };
@@ -27,7 +27,7 @@ function printHelp({
27
27
  message.push(
28
28
  linebreak(),
29
29
  ` ${colors.bgGreen(colors.black(` ${commandName} `))} ${colors.green(
30
- `v${"0.19.0-beta.2"}`
30
+ `v${"0.19.0"}`
31
31
  )} ${headline}`
32
32
  );
33
33
  }
@@ -1,4 +1,4 @@
1
- import z from "zod/v3";
1
+ import z from "zod";
2
2
  const rawLibSQLOptions = z.record(z.string());
3
3
  const parseNumber = (value) => z.coerce.number().parse(value);
4
4
  const parseBoolean = (value) => z.coerce.boolean().parse(value);
@@ -2,5 +2,5 @@
2
2
  * This is a modified version of Astro's error map. source:
3
3
  * https://github.com/withastro/astro/blob/main/packages/astro/src/content/error-map.ts
4
4
  */
5
- import type { z } from 'zod/v3';
5
+ import type { z } from 'astro/zod';
6
6
  export declare const errorMap: z.ZodErrorMap;
@@ -12,11 +12,8 @@ function fileURLIntegration() {
12
12
  return {
13
13
  name: "@astrojs/db/file-url",
14
14
  enforce: "pre",
15
- load: {
16
- filter: {
17
- id: /\?fileurl$/
18
- },
19
- async handler(id) {
15
+ async load(id) {
16
+ if (id.endsWith("?fileurl")) {
20
17
  const filePath = id.slice(0, id.indexOf("?"));
21
18
  if (command === "build") {
22
19
  const data = await fs.promises.readFile(filePath);
@@ -1,5 +1,5 @@
1
1
  import type { AstroIntegration } from 'astro';
2
- import { z } from 'zod/v3';
2
+ import { z } from 'zod';
3
3
  declare const astroDBConfigSchema: z.ZodDefault<z.ZodOptional<z.ZodObject<{
4
4
  /**
5
5
  * Sets the mode of the underlying `@libsql/client` connection.
@@ -9,7 +9,7 @@ import {
9
9
  mergeConfig
10
10
  } from "vite";
11
11
  import parseArgs from "yargs-parser";
12
- import { z } from "zod/v3";
12
+ import { z } from "zod";
13
13
  import { AstroDbError, isDbError } from "../../runtime/utils.js";
14
14
  import { CONFIG_FILE_NAMES, DB_PATH, VIRTUAL_MODULE_ID } from "../consts.js";
15
15
  import { EXEC_DEFAULT_EXPORT_ERROR, EXEC_ERROR } from "../errors.js";
@@ -117,9 +117,8 @@ function astroDBIntegration(options) {
117
117
  });
118
118
  },
119
119
  "astro:server:setup": async ({ server, logger }) => {
120
- const environment = server.environments.ssr;
121
120
  seedHandler.execute = async (fileUrl) => {
122
- await executeSeedFile({ fileUrl, environment });
121
+ await executeSeedFile({ fileUrl, viteServer: server });
123
122
  };
124
123
  const filesToWatch = [
125
124
  ...CONFIG_FILE_NAMES.map((c) => new URL(c, getDbDirectoryUrl(root))),
@@ -131,18 +130,20 @@ function astroDBIntegration(options) {
131
130
  server.restart();
132
131
  }
133
132
  });
134
- logger.info(
135
- connectToRemote ? "Connected to remote database." : "New local database created."
136
- );
137
- if (connectToRemote) return;
138
- const localSeedPaths = SEED_DEV_FILE_NAME.map(
139
- (name) => new URL(name, getDbDirectoryUrl(root))
140
- );
141
- if (seedFiles.get().length || localSeedPaths.find((path) => existsSync(path))) {
142
- await environment.runner.import(VIRTUAL_MODULE_ID).catch((e) => {
143
- logger.error(e instanceof Error ? e.message : String(e));
144
- });
145
- }
133
+ setTimeout(() => {
134
+ logger.info(
135
+ connectToRemote ? "Connected to remote database." : "New local database created."
136
+ );
137
+ if (connectToRemote) return;
138
+ const localSeedPaths = SEED_DEV_FILE_NAME.map(
139
+ (name) => new URL(name, getDbDirectoryUrl(root))
140
+ );
141
+ if (seedFiles.get().length || localSeedPaths.find((path) => existsSync(path))) {
142
+ server.ssrLoadModule(VIRTUAL_MODULE_ID).catch((e) => {
143
+ logger.error(e instanceof Error ? e.message : String(e));
144
+ });
145
+ }
146
+ }, 100);
146
147
  },
147
148
  "astro:build:start": async ({ logger }) => {
148
149
  if (!connectToRemote && !databaseFileEnvDefined() && finalBuildOutput === "server") {
@@ -156,9 +157,8 @@ function astroDBIntegration(options) {
156
157
  },
157
158
  "astro:build:setup": async ({ vite }) => {
158
159
  tempViteServer = await getTempViteServer({ viteConfig: vite });
159
- const environment = tempViteServer.environments.ssr;
160
160
  seedHandler.execute = async (fileUrl) => {
161
- await executeSeedFile({ fileUrl, environment });
161
+ await executeSeedFile({ fileUrl, viteServer: tempViteServer });
162
162
  };
163
163
  },
164
164
  "astro:build:done": async ({}) => {
@@ -176,10 +176,10 @@ function integration(options) {
176
176
  }
177
177
  async function executeSeedFile({
178
178
  fileUrl,
179
- environment
179
+ viteServer
180
180
  }) {
181
181
  const pathname = decodeURIComponent(fileUrl.pathname);
182
- const mod = await environment.runner.import(pathname);
182
+ const mod = await viteServer.ssrLoadModule(pathname);
183
183
  if (typeof mod.default !== "function") {
184
184
  throw new AstroDbError(EXEC_DEFAULT_EXPORT_ERROR(fileURLToPath(fileUrl)));
185
185
  }
@@ -201,8 +201,8 @@ async function getTempViteServer({ viteConfig }) {
201
201
  logLevel: "silent"
202
202
  })
203
203
  );
204
- const hotSend = tempViteServer.environments.client.hot.send;
205
- tempViteServer.environments.client.hot.send = (payload) => {
204
+ const hotSend = tempViteServer.hot.send;
205
+ tempViteServer.hot.send = (payload) => {
206
206
  if (payload.type === "error") {
207
207
  throw payload.err;
208
208
  }
@@ -21,26 +21,18 @@ function vitePluginDbClient(params) {
21
21
  return {
22
22
  name: "virtual:astro:db-client",
23
23
  enforce: "pre",
24
- resolveId: {
25
- filter: {
26
- id: new RegExp(`^${VIRTUAL_CLIENT_MODULE_ID}$`)
27
- },
28
- handler() {
29
- return resolved;
30
- }
24
+ async resolveId(id) {
25
+ if (id !== VIRTUAL_CLIENT_MODULE_ID) return;
26
+ return resolved;
31
27
  },
32
- load: {
33
- filter: {
34
- id: new RegExp(`^${resolved}$`)
35
- },
36
- handler() {
37
- switch (params.connectToRemote) {
38
- case true:
39
- return getRemoteClientModule(params.mode);
40
- case false:
41
- default:
42
- return getLocalClientModule(params.mode);
43
- }
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);
44
36
  }
45
37
  }
46
38
  };
@@ -31,57 +31,49 @@ function vitePluginDb(params) {
31
31
  configResolved(resolvedConfig) {
32
32
  command = resolvedConfig.command;
33
33
  },
34
- resolveId: {
35
- filter: {
36
- id: new RegExp(`^${VIRTUAL_MODULE_ID}$`)
37
- },
38
- handler() {
39
- if (params.seedHandler.inProgress) {
40
- return resolved.importedFromSeedFile;
41
- }
42
- return resolved.module;
34
+ async resolveId(id) {
35
+ if (id !== VIRTUAL_MODULE_ID) return;
36
+ if (params.seedHandler.inProgress) {
37
+ return resolved.importedFromSeedFile;
43
38
  }
39
+ return resolved.module;
44
40
  },
45
- load: {
46
- filter: {
47
- id: new RegExp(`^(${resolved.module}|${resolved.importedFromSeedFile})$`)
48
- },
49
- async handler(id) {
50
- if (params.connectToRemote) {
51
- return getRemoteVirtualModContents({
52
- appToken: params.appToken,
53
- tables: params.tables.get(),
54
- isBuild: command === "build",
55
- output: params.output,
56
- localExecution: false
57
- });
58
- }
59
- if (id === resolved.importedFromSeedFile) {
60
- return getLocalVirtualModContents({
61
- root: params.root,
62
- tables: params.tables.get(),
63
- localExecution: false
64
- });
65
- }
66
- await recreateTables(params);
67
- const seedFiles = getResolvedSeedFiles(params);
68
- for await (const seedFile of seedFiles) {
69
- this.addWatchFile(fileURLToPath(seedFile));
70
- if (existsSync(seedFile)) {
71
- params.seedHandler.inProgress = true;
72
- await params.seedHandler.execute(seedFile);
73
- }
74
- }
75
- if (params.seedHandler.inProgress) {
76
- (params.logger ?? console).info("Seeded database.");
77
- params.seedHandler.inProgress = false;
78
- }
41
+ async load(id) {
42
+ if (id !== resolved.module && id !== resolved.importedFromSeedFile) return;
43
+ if (params.connectToRemote) {
44
+ return getRemoteVirtualModContents({
45
+ appToken: params.appToken,
46
+ tables: params.tables.get(),
47
+ isBuild: command === "build",
48
+ output: params.output,
49
+ localExecution: false
50
+ });
51
+ }
52
+ if (id === resolved.importedFromSeedFile) {
79
53
  return getLocalVirtualModContents({
80
54
  root: params.root,
81
55
  tables: params.tables.get(),
82
56
  localExecution: false
83
57
  });
84
58
  }
59
+ await recreateTables(params);
60
+ const seedFiles = getResolvedSeedFiles(params);
61
+ for await (const seedFile of seedFiles) {
62
+ this.addWatchFile(fileURLToPath(seedFile));
63
+ if (existsSync(seedFile)) {
64
+ params.seedHandler.inProgress = true;
65
+ await params.seedHandler.execute(seedFile);
66
+ }
67
+ }
68
+ if (params.seedHandler.inProgress) {
69
+ (params.logger ?? console).info("Seeded database.");
70
+ params.seedHandler.inProgress = false;
71
+ }
72
+ return getLocalVirtualModContents({
73
+ root: params.root,
74
+ tables: params.tables.get(),
75
+ localExecution: false
76
+ });
85
77
  }
86
78
  };
87
79
  }
@@ -18,10 +18,10 @@ export declare function resolveDbConfig({ root, integrations, }: Pick<AstroConfi
18
18
  optional: boolean;
19
19
  unique: boolean;
20
20
  deprecated: boolean;
21
+ default?: boolean | import("../runtime/types.js").SerializedSQL | undefined;
21
22
  name?: string | undefined;
22
23
  label?: string | undefined;
23
24
  collection?: string | undefined;
24
- default?: boolean | import("../runtime/types.js").SerializedSQL | undefined;
25
25
  };
26
26
  } | {
27
27
  type: "number";
@@ -37,8 +37,8 @@ export declare function resolveDbConfig({ root, integrations, }: Pick<AstroConfi
37
37
  default?: number | import("../runtime/types.js").SerializedSQL | undefined;
38
38
  } | {
39
39
  primaryKey: true;
40
- optional?: false | undefined;
41
40
  default?: undefined;
41
+ optional?: false | undefined;
42
42
  })) & {
43
43
  references?: import("./types.js").NumberColumn;
44
44
  };
@@ -47,10 +47,10 @@ export declare function resolveDbConfig({ root, integrations, }: Pick<AstroConfi
47
47
  schema: ({
48
48
  unique: boolean;
49
49
  deprecated: boolean;
50
+ default?: string | import("../runtime/types.js").SerializedSQL | undefined;
50
51
  name?: string | undefined;
51
52
  label?: string | undefined;
52
53
  collection?: string | undefined;
53
- default?: string | import("../runtime/types.js").SerializedSQL | undefined;
54
54
  multiline?: boolean | undefined;
55
55
  enum?: [string, ...string[]] | undefined;
56
56
  } & ({
@@ -68,10 +68,10 @@ export declare function resolveDbConfig({ root, integrations, }: Pick<AstroConfi
68
68
  optional: boolean;
69
69
  unique: boolean;
70
70
  deprecated: boolean;
71
+ default?: string | import("../runtime/types.js").SerializedSQL | undefined;
71
72
  name?: string | undefined;
72
73
  label?: string | undefined;
73
74
  collection?: string | undefined;
74
- default?: string | import("../runtime/types.js").SerializedSQL | undefined;
75
75
  };
76
76
  } | {
77
77
  type: "json";
@@ -79,17 +79,17 @@ export declare function resolveDbConfig({ root, integrations, }: Pick<AstroConfi
79
79
  optional: boolean;
80
80
  unique: boolean;
81
81
  deprecated: boolean;
82
+ default?: unknown;
82
83
  name?: string | undefined;
83
84
  label?: string | undefined;
84
85
  collection?: string | undefined;
85
- default?: unknown;
86
86
  };
87
87
  }>;
88
88
  foreignKeys?: (Omit<{
89
89
  columns: import("./schemas.js").MaybeArray<string>;
90
- references: () => import("./schemas.js").MaybeArray<Omit<import("zod/v3").input<typeof import("./schemas.js").referenceableColumnSchema>, "references">>;
90
+ references: () => import("./schemas.js").MaybeArray<Omit<import("zod").input<typeof import("./schemas.js").referenceableColumnSchema>, "references">>;
91
91
  }, "references"> & {
92
- references: import("./schemas.js").MaybeArray<Omit<import("zod/v3").output<typeof import("./schemas.js").referenceableColumnSchema>, "references">>;
92
+ references: import("./schemas.js").MaybeArray<Omit<import("zod").output<typeof import("./schemas.js").referenceableColumnSchema>, "references">>;
93
93
  })[] | undefined;
94
94
  }>;
95
95
  };
@@ -19,8 +19,8 @@ export declare function getReferencesConfig(column: DBColumn): {
19
19
  default?: number | import("../runtime/types.js").SerializedSQL | undefined;
20
20
  } | {
21
21
  primaryKey: true;
22
- optional?: false | undefined;
23
22
  default?: undefined;
23
+ optional?: false | undefined;
24
24
  })) & {
25
25
  references?: NumberColumn;
26
26
  };
@@ -29,10 +29,10 @@ export declare function getReferencesConfig(column: DBColumn): {
29
29
  schema: ({
30
30
  unique: boolean;
31
31
  deprecated: boolean;
32
+ default?: string | import("../runtime/types.js").SerializedSQL | undefined;
32
33
  name?: string | undefined;
33
34
  label?: string | undefined;
34
35
  collection?: string | undefined;
35
- default?: string | import("../runtime/types.js").SerializedSQL | undefined;
36
36
  multiline?: boolean | undefined;
37
37
  enum?: [string, ...string[]] | undefined;
38
38
  } & ({