@astrojs/db 0.0.0-10646-20240402132948

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.
Files changed (78) hide show
  1. package/LICENSE +59 -0
  2. package/README.md +38 -0
  3. package/dist/_internal/core/integration/error-map.d.ts +6 -0
  4. package/dist/_internal/core/schemas.d.ts +4034 -0
  5. package/dist/_internal/core/types.d.ts +59 -0
  6. package/dist/_internal/core/utils.d.ts +20 -0
  7. package/dist/_internal/runtime/config.d.ts +154 -0
  8. package/dist/_internal/runtime/types.d.ts +69 -0
  9. package/dist/core/cli/commands/execute/index.d.ts +8 -0
  10. package/dist/core/cli/commands/execute/index.js +66 -0
  11. package/dist/core/cli/commands/link/index.d.ts +20 -0
  12. package/dist/core/cli/commands/link/index.js +252 -0
  13. package/dist/core/cli/commands/login/index.d.ts +8 -0
  14. package/dist/core/cli/commands/login/index.js +55 -0
  15. package/dist/core/cli/commands/logout/index.d.ts +1 -0
  16. package/dist/core/cli/commands/logout/index.js +9 -0
  17. package/dist/core/cli/commands/push/index.d.ts +8 -0
  18. package/dist/core/cli/commands/push/index.js +93 -0
  19. package/dist/core/cli/commands/shell/index.d.ts +8 -0
  20. package/dist/core/cli/commands/shell/index.js +33 -0
  21. package/dist/core/cli/commands/verify/index.d.ts +8 -0
  22. package/dist/core/cli/commands/verify/index.js +46 -0
  23. package/dist/core/cli/index.d.ts +6 -0
  24. package/dist/core/cli/index.js +76 -0
  25. package/dist/core/cli/migration-queries.d.ts +23 -0
  26. package/dist/core/cli/migration-queries.js +386 -0
  27. package/dist/core/cli/print-help.d.ts +11 -0
  28. package/dist/core/cli/print-help.js +55 -0
  29. package/dist/core/consts.d.ts +8 -0
  30. package/dist/core/consts.js +21 -0
  31. package/dist/core/errors.d.ts +10 -0
  32. package/dist/core/errors.js +56 -0
  33. package/dist/core/integration/error-map.d.ts +6 -0
  34. package/dist/core/integration/error-map.js +79 -0
  35. package/dist/core/integration/file-url.d.ts +2 -0
  36. package/dist/core/integration/file-url.js +81 -0
  37. package/dist/core/integration/index.d.ts +2 -0
  38. package/dist/core/integration/index.js +160 -0
  39. package/dist/core/integration/typegen.d.ts +7 -0
  40. package/dist/core/integration/typegen.js +33 -0
  41. package/dist/core/integration/vite-plugin-db.d.ts +39 -0
  42. package/dist/core/integration/vite-plugin-db.js +134 -0
  43. package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +11 -0
  44. package/dist/core/integration/vite-plugin-inject-env-ts.js +53 -0
  45. package/dist/core/load-file.d.ts +253 -0
  46. package/dist/core/load-file.js +170 -0
  47. package/dist/core/schemas.d.ts +4034 -0
  48. package/dist/core/schemas.js +186 -0
  49. package/dist/core/tokens.d.ts +11 -0
  50. package/dist/core/tokens.js +181 -0
  51. package/dist/core/types.d.ts +59 -0
  52. package/dist/core/types.js +0 -0
  53. package/dist/core/utils.d.ts +20 -0
  54. package/dist/core/utils.js +32 -0
  55. package/dist/index.d.ts +4 -0
  56. package/dist/index.js +8 -0
  57. package/dist/runtime/config.js +111 -0
  58. package/dist/runtime/db-client.d.ts +6 -0
  59. package/dist/runtime/db-client.js +148 -0
  60. package/dist/runtime/drizzle.d.ts +1 -0
  61. package/dist/runtime/drizzle.js +48 -0
  62. package/dist/runtime/errors.d.ts +5 -0
  63. package/dist/runtime/errors.js +31 -0
  64. package/dist/runtime/index.d.ts +26 -0
  65. package/dist/runtime/index.js +131 -0
  66. package/dist/runtime/queries.d.ts +71 -0
  67. package/dist/runtime/queries.js +169 -0
  68. package/dist/runtime/seed-local.d.ts +10 -0
  69. package/dist/runtime/seed-local.js +55 -0
  70. package/dist/runtime/types.d.ts +69 -0
  71. package/dist/runtime/types.js +8 -0
  72. package/dist/runtime/utils.d.ts +8 -0
  73. package/dist/runtime/utils.js +17 -0
  74. package/dist/utils.d.ts +2 -0
  75. package/dist/utils.js +6 -0
  76. package/index.d.ts +3 -0
  77. package/package.json +95 -0
  78. package/virtual.d.ts +45 -0
@@ -0,0 +1,55 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { createServer as _createServer } from "node:http";
3
+ import { listen } from "async-listen";
4
+ import { cyan } from "kleur/colors";
5
+ import open from "open";
6
+ import ora from "ora";
7
+ import { SESSION_LOGIN_FILE } from "../../../tokens.js";
8
+ import { getAstroStudioUrl } from "../../../utils.js";
9
+ async function createServer() {
10
+ let resolve, reject;
11
+ const server = _createServer((req, res) => {
12
+ const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
13
+ const sessionParam = url.searchParams.get("session");
14
+ res.statusCode = 302;
15
+ if (!sessionParam) {
16
+ res.setHeader("location", getAstroStudioUrl() + "/auth/cli/error");
17
+ reject(new Error("Failed to log in"));
18
+ } else {
19
+ res.setHeader("location", getAstroStudioUrl() + "/auth/cli/success");
20
+ resolve(sessionParam);
21
+ }
22
+ res.end();
23
+ });
24
+ const { port } = await listen(server, 0, "127.0.0.1");
25
+ const serverUrl = `http://localhost:${port}`;
26
+ const sessionPromise = new Promise((_resolve, _reject) => {
27
+ resolve = _resolve;
28
+ reject = _reject;
29
+ }).finally(() => {
30
+ server.closeAllConnections();
31
+ server.close();
32
+ });
33
+ return { url: serverUrl, promise: sessionPromise };
34
+ }
35
+ async function cmd({
36
+ flags
37
+ }) {
38
+ let session = flags.session;
39
+ if (!session) {
40
+ const { url, promise } = await createServer();
41
+ const loginUrl = getAstroStudioUrl() + "/auth/cli/login?returnTo=" + encodeURIComponent(url);
42
+ console.log(`Opening the following URL in your browser...`);
43
+ console.log(cyan(loginUrl));
44
+ console.log(`If something goes wrong, copy-and-paste the URL into your browser.`);
45
+ open(loginUrl);
46
+ const spinner = ora("Waiting for confirmation...");
47
+ session = await promise;
48
+ spinner.succeed("Successfully logged in!");
49
+ }
50
+ await mkdir(new URL(".", SESSION_LOGIN_FILE), { recursive: true });
51
+ await writeFile(SESSION_LOGIN_FILE, `${session}`);
52
+ }
53
+ export {
54
+ cmd
55
+ };
@@ -0,0 +1 @@
1
+ export declare function cmd(): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { unlink } from "node:fs/promises";
2
+ import { SESSION_LOGIN_FILE } from "../../../tokens.js";
3
+ async function cmd() {
4
+ await unlink(SESSION_LOGIN_FILE);
5
+ console.log("Successfully logged out of Astro Studio.");
6
+ }
7
+ export {
8
+ cmd
9
+ };
@@ -0,0 +1,8 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ import { type DBConfig } from '../../../types.js';
4
+ export declare function cmd({ dbConfig, flags, }: {
5
+ astroConfig: AstroConfig;
6
+ dbConfig: DBConfig;
7
+ flags: Arguments;
8
+ }): Promise<void>;
@@ -0,0 +1,93 @@
1
+ import { safeFetch } from "../../../../runtime/utils.js";
2
+ import { MIGRATION_VERSION } from "../../../consts.js";
3
+ import { getManagedAppTokenOrExit } from "../../../tokens.js";
4
+ import {} from "../../../types.js";
5
+ import { getRemoteDatabaseUrl } from "../../../utils.js";
6
+ import {
7
+ createCurrentSnapshot,
8
+ createEmptySnapshot,
9
+ formatDataLossMessage,
10
+ getMigrationQueries,
11
+ getProductionCurrentSnapshot
12
+ } from "../../migration-queries.js";
13
+ async function cmd({
14
+ dbConfig,
15
+ flags
16
+ }) {
17
+ const isDryRun = flags.dryRun;
18
+ const isForceReset = flags.forceReset;
19
+ const appToken = await getManagedAppTokenOrExit(flags.token);
20
+ const productionSnapshot = await getProductionCurrentSnapshot({ appToken: appToken.token });
21
+ const currentSnapshot = createCurrentSnapshot(dbConfig);
22
+ const isFromScratch = !productionSnapshot;
23
+ const { queries: migrationQueries, confirmations } = await getMigrationQueries({
24
+ oldSnapshot: isFromScratch ? createEmptySnapshot() : productionSnapshot,
25
+ newSnapshot: currentSnapshot,
26
+ reset: isForceReset
27
+ });
28
+ if (migrationQueries.length === 0) {
29
+ console.log("Database schema is up to date.");
30
+ } else {
31
+ console.log(`Database schema is out of date.`);
32
+ }
33
+ if (isForceReset) {
34
+ console.log(`Force-pushing to the database. All existing data will be erased.`);
35
+ } else if (confirmations.length > 0) {
36
+ console.log("\n" + formatDataLossMessage(confirmations) + "\n");
37
+ throw new Error("Exiting.");
38
+ }
39
+ if (isDryRun) {
40
+ console.log("Statements:", JSON.stringify(migrationQueries, void 0, 2));
41
+ } else {
42
+ console.log(`Pushing database schema updates...`);
43
+ await pushSchema({
44
+ statements: migrationQueries,
45
+ appToken: appToken.token,
46
+ isDryRun,
47
+ currentSnapshot
48
+ });
49
+ }
50
+ await appToken.destroy();
51
+ console.info("Push complete!");
52
+ }
53
+ async function pushSchema({
54
+ statements,
55
+ appToken,
56
+ isDryRun,
57
+ currentSnapshot
58
+ }) {
59
+ const requestBody = {
60
+ snapshot: currentSnapshot,
61
+ sql: statements,
62
+ version: MIGRATION_VERSION
63
+ };
64
+ if (isDryRun) {
65
+ console.info("[DRY RUN] Batch query:", JSON.stringify(requestBody, null, 2));
66
+ return new Response(null, { status: 200 });
67
+ }
68
+ const url = new URL("/db/push", getRemoteDatabaseUrl());
69
+ const response = await safeFetch(
70
+ url,
71
+ {
72
+ method: "POST",
73
+ headers: new Headers({
74
+ Authorization: `Bearer ${appToken}`
75
+ }),
76
+ body: JSON.stringify(requestBody)
77
+ },
78
+ async (res) => {
79
+ console.error(`${url.toString()} failed: ${res.status} ${res.statusText}`);
80
+ console.error(await res.text());
81
+ throw new Error(`/db/push fetch failed: ${res.status} ${res.statusText}`);
82
+ }
83
+ );
84
+ const result = await response.json();
85
+ if (!result.success) {
86
+ console.error(`${url.toString()} unsuccessful`);
87
+ console.error(await response.text());
88
+ throw new Error(`/db/push fetch unsuccessful`);
89
+ }
90
+ }
91
+ export {
92
+ cmd
93
+ };
@@ -0,0 +1,8 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ import type { DBConfigInput } from '../../../types.js';
4
+ export declare function cmd({ flags, astroConfig, }: {
5
+ dbConfig: DBConfigInput;
6
+ astroConfig: AstroConfig;
7
+ flags: Arguments;
8
+ }): Promise<void>;
@@ -0,0 +1,33 @@
1
+ import { sql } from "drizzle-orm";
2
+ import {
3
+ createLocalDatabaseClient,
4
+ createRemoteDatabaseClient
5
+ } from "../../../../runtime/db-client.js";
6
+ import { DB_PATH } from "../../../consts.js";
7
+ import { SHELL_QUERY_MISSING_ERROR } from "../../../errors.js";
8
+ import { getManagedAppTokenOrExit } from "../../../tokens.js";
9
+ import { getRemoteDatabaseUrl } from "../../../utils.js";
10
+ async function cmd({
11
+ flags,
12
+ astroConfig
13
+ }) {
14
+ const query = flags.query;
15
+ if (!query) {
16
+ console.error(SHELL_QUERY_MISSING_ERROR);
17
+ process.exit(1);
18
+ }
19
+ if (flags.remote) {
20
+ const appToken = await getManagedAppTokenOrExit(flags.token);
21
+ const db = createRemoteDatabaseClient(appToken.token, getRemoteDatabaseUrl());
22
+ const result = await db.run(sql.raw(query));
23
+ await appToken.destroy();
24
+ console.log(result);
25
+ } else {
26
+ const db = createLocalDatabaseClient({ dbUrl: new URL(DB_PATH, astroConfig.root).href });
27
+ const result = await db.run(sql.raw(query));
28
+ console.log(result);
29
+ }
30
+ }
31
+ export {
32
+ cmd
33
+ };
@@ -0,0 +1,8 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ import type { DBConfig } from '../../../types.js';
4
+ export declare function cmd({ dbConfig, flags, }: {
5
+ astroConfig: AstroConfig;
6
+ dbConfig: DBConfig;
7
+ flags: Arguments;
8
+ }): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { getManagedAppTokenOrExit } from "../../../tokens.js";
2
+ import {
3
+ createCurrentSnapshot,
4
+ createEmptySnapshot,
5
+ formatDataLossMessage,
6
+ getMigrationQueries,
7
+ getProductionCurrentSnapshot
8
+ } from "../../migration-queries.js";
9
+ async function cmd({
10
+ dbConfig,
11
+ flags
12
+ }) {
13
+ const isJson = flags.json;
14
+ const appToken = await getManagedAppTokenOrExit(flags.token);
15
+ const productionSnapshot = await getProductionCurrentSnapshot({ appToken: appToken.token });
16
+ const currentSnapshot = createCurrentSnapshot(dbConfig);
17
+ const { queries: migrationQueries, confirmations } = await getMigrationQueries({
18
+ oldSnapshot: productionSnapshot || createEmptySnapshot(),
19
+ newSnapshot: currentSnapshot
20
+ });
21
+ const result = { exitCode: 0, message: "", code: "", data: void 0 };
22
+ if (migrationQueries.length === 0) {
23
+ result.code = "MATCH";
24
+ result.message = `Database schema is up to date.`;
25
+ } else {
26
+ result.code = "NO_MATCH";
27
+ result.message = `Database schema is out of date.
28
+ Run 'astro db push' to push up your latest changes.`;
29
+ }
30
+ if (confirmations.length > 0) {
31
+ result.code = "DATA_LOSS";
32
+ result.exitCode = 1;
33
+ result.data = confirmations;
34
+ result.message = formatDataLossMessage(confirmations, !isJson);
35
+ }
36
+ if (isJson) {
37
+ console.log(JSON.stringify(result));
38
+ } else {
39
+ console.log(result.message);
40
+ }
41
+ await appToken.destroy();
42
+ process.exit(result.exitCode);
43
+ }
44
+ export {
45
+ cmd
46
+ };
@@ -0,0 +1,6 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ export declare function cli({ flags, config: astroConfig, }: {
4
+ flags: Arguments;
5
+ config: AstroConfig;
6
+ }): Promise<void>;
@@ -0,0 +1,76 @@
1
+ import { resolveDbConfig } from "../load-file.js";
2
+ import { printHelp } from "./print-help.js";
3
+ async function cli({
4
+ flags,
5
+ config: astroConfig
6
+ }) {
7
+ const args = flags._;
8
+ const command = args[2] === "db" ? args[3] : args[2];
9
+ const { dbConfig } = await resolveDbConfig(astroConfig);
10
+ switch (command) {
11
+ case "shell": {
12
+ const { cmd } = await import("./commands/shell/index.js");
13
+ return await cmd({ astroConfig, dbConfig, flags });
14
+ }
15
+ case "gen": {
16
+ console.log('"astro db gen" is no longer needed! Visit the docs for more information.');
17
+ return;
18
+ }
19
+ case "sync": {
20
+ console.log('"astro db sync" is no longer needed! Visit the docs for more information.');
21
+ return;
22
+ }
23
+ case "push": {
24
+ const { cmd } = await import("./commands/push/index.js");
25
+ return await cmd({ astroConfig, dbConfig, flags });
26
+ }
27
+ case "verify": {
28
+ const { cmd } = await import("./commands/verify/index.js");
29
+ return await cmd({ astroConfig, dbConfig, flags });
30
+ }
31
+ case "execute": {
32
+ const { cmd } = await import("./commands/execute/index.js");
33
+ return await cmd({ astroConfig, dbConfig, flags });
34
+ }
35
+ case "login": {
36
+ const { cmd } = await import("./commands/login/index.js");
37
+ return await cmd({ astroConfig, dbConfig, flags });
38
+ }
39
+ case "logout": {
40
+ const { cmd } = await import("./commands/logout/index.js");
41
+ return await cmd();
42
+ }
43
+ case "link": {
44
+ const { cmd } = await import("./commands/link/index.js");
45
+ return await cmd();
46
+ }
47
+ default: {
48
+ if (command != null) {
49
+ console.error(`Unknown command: ${command}`);
50
+ }
51
+ printHelp({
52
+ commandName: "astro db",
53
+ usage: "[command] [...flags]",
54
+ headline: " ",
55
+ tables: {
56
+ Commands: [
57
+ ["push", "Push table schema updates to Astro Studio."],
58
+ ["verify", "Test schema updates /w Astro Studio (good for CI)."],
59
+ [
60
+ "astro db execute <file-path>",
61
+ "Execute a ts/js file using astro:db. Use --remote to connect to Studio."
62
+ ],
63
+ [
64
+ "astro db shell --query <sql-string>",
65
+ "Execute a SQL string. Use --remote to connect to Studio."
66
+ ]
67
+ ]
68
+ }
69
+ });
70
+ return;
71
+ }
72
+ }
73
+ }
74
+ export {
75
+ cli
76
+ };
@@ -0,0 +1,23 @@
1
+ import { type DBConfig, type DBSnapshot, type ResolvedDBTable } from '../types.js';
2
+ export declare function getMigrationQueries({ oldSnapshot, newSnapshot, reset, }: {
3
+ oldSnapshot: DBSnapshot;
4
+ newSnapshot: DBSnapshot;
5
+ reset?: boolean;
6
+ }): Promise<{
7
+ queries: string[];
8
+ confirmations: string[];
9
+ }>;
10
+ export declare function getTableChangeQueries({ tableName, oldTable, newTable, }: {
11
+ tableName: string;
12
+ oldTable: ResolvedDBTable;
13
+ newTable: ResolvedDBTable;
14
+ }): Promise<{
15
+ queries: string[];
16
+ confirmations: string[];
17
+ }>;
18
+ export declare function getProductionCurrentSnapshot({ appToken, }: {
19
+ appToken: string;
20
+ }): Promise<DBSnapshot | undefined>;
21
+ export declare function createCurrentSnapshot({ tables }: DBConfig): DBSnapshot;
22
+ export declare function createEmptySnapshot(): DBSnapshot;
23
+ export declare function formatDataLossMessage(confirmations: string[], isColor?: boolean): string;