@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.
- package/LICENSE +59 -0
- package/README.md +38 -0
- package/dist/_internal/core/integration/error-map.d.ts +6 -0
- package/dist/_internal/core/schemas.d.ts +4034 -0
- package/dist/_internal/core/types.d.ts +59 -0
- package/dist/_internal/core/utils.d.ts +20 -0
- package/dist/_internal/runtime/config.d.ts +154 -0
- package/dist/_internal/runtime/types.d.ts +69 -0
- package/dist/core/cli/commands/execute/index.d.ts +8 -0
- package/dist/core/cli/commands/execute/index.js +66 -0
- package/dist/core/cli/commands/link/index.d.ts +20 -0
- package/dist/core/cli/commands/link/index.js +252 -0
- package/dist/core/cli/commands/login/index.d.ts +8 -0
- package/dist/core/cli/commands/login/index.js +55 -0
- package/dist/core/cli/commands/logout/index.d.ts +1 -0
- package/dist/core/cli/commands/logout/index.js +9 -0
- package/dist/core/cli/commands/push/index.d.ts +8 -0
- package/dist/core/cli/commands/push/index.js +93 -0
- package/dist/core/cli/commands/shell/index.d.ts +8 -0
- package/dist/core/cli/commands/shell/index.js +33 -0
- package/dist/core/cli/commands/verify/index.d.ts +8 -0
- package/dist/core/cli/commands/verify/index.js +46 -0
- package/dist/core/cli/index.d.ts +6 -0
- package/dist/core/cli/index.js +76 -0
- package/dist/core/cli/migration-queries.d.ts +23 -0
- package/dist/core/cli/migration-queries.js +386 -0
- package/dist/core/cli/print-help.d.ts +11 -0
- package/dist/core/cli/print-help.js +55 -0
- package/dist/core/consts.d.ts +8 -0
- package/dist/core/consts.js +21 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.js +56 -0
- package/dist/core/integration/error-map.d.ts +6 -0
- package/dist/core/integration/error-map.js +79 -0
- package/dist/core/integration/file-url.d.ts +2 -0
- package/dist/core/integration/file-url.js +81 -0
- package/dist/core/integration/index.d.ts +2 -0
- package/dist/core/integration/index.js +160 -0
- package/dist/core/integration/typegen.d.ts +7 -0
- package/dist/core/integration/typegen.js +33 -0
- package/dist/core/integration/vite-plugin-db.d.ts +39 -0
- package/dist/core/integration/vite-plugin-db.js +134 -0
- package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +11 -0
- package/dist/core/integration/vite-plugin-inject-env-ts.js +53 -0
- package/dist/core/load-file.d.ts +253 -0
- package/dist/core/load-file.js +170 -0
- package/dist/core/schemas.d.ts +4034 -0
- package/dist/core/schemas.js +186 -0
- package/dist/core/tokens.d.ts +11 -0
- package/dist/core/tokens.js +181 -0
- package/dist/core/types.d.ts +59 -0
- package/dist/core/types.js +0 -0
- package/dist/core/utils.d.ts +20 -0
- package/dist/core/utils.js +32 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +8 -0
- package/dist/runtime/config.js +111 -0
- package/dist/runtime/db-client.d.ts +6 -0
- package/dist/runtime/db-client.js +148 -0
- package/dist/runtime/drizzle.d.ts +1 -0
- package/dist/runtime/drizzle.js +48 -0
- package/dist/runtime/errors.d.ts +5 -0
- package/dist/runtime/errors.js +31 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.js +131 -0
- package/dist/runtime/queries.d.ts +71 -0
- package/dist/runtime/queries.js +169 -0
- package/dist/runtime/seed-local.d.ts +10 -0
- package/dist/runtime/seed-local.js +55 -0
- package/dist/runtime/types.d.ts +69 -0
- package/dist/runtime/types.js +8 -0
- package/dist/runtime/utils.d.ts +8 -0
- package/dist/runtime/utils.js +17 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +6 -0
- package/index.d.ts +3 -0
- package/package.json +95 -0
- 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,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,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;
|