@astrojs/db 0.2.2 → 0.3.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.
Files changed (39) hide show
  1. package/config-augment.d.ts +1 -1
  2. package/dist/core/cli/commands/link/index.d.ts +8 -0
  3. package/dist/core/cli/commands/link/index.js +64 -0
  4. package/dist/core/cli/commands/login/index.d.ts +6 -0
  5. package/dist/core/cli/commands/login/index.js +46 -0
  6. package/dist/core/cli/commands/logout/index.d.ts +6 -0
  7. package/dist/core/cli/commands/logout/index.js +9 -0
  8. package/dist/core/cli/commands/push/index.js +71 -43
  9. package/dist/core/cli/commands/shell/index.js +5 -8
  10. package/dist/core/cli/commands/sync/index.js +22 -29
  11. package/dist/core/cli/commands/verify/index.d.ts +1 -1
  12. package/dist/core/cli/commands/verify/index.js +20 -16
  13. package/dist/core/cli/index.js +29 -8
  14. package/dist/core/cli/migration-queries.d.ts +19 -11
  15. package/dist/core/cli/migration-queries.js +124 -161
  16. package/dist/core/cli/migrations.d.ts +22 -1
  17. package/dist/core/cli/migrations.js +66 -2
  18. package/dist/core/errors.d.ts +5 -1
  19. package/dist/core/errors.js +35 -5
  20. package/dist/core/integration/index.js +32 -17
  21. package/dist/core/integration/typegen.js +2 -2
  22. package/dist/core/integration/vite-plugin-db.d.ts +1 -1
  23. package/dist/core/integration/vite-plugin-db.js +6 -4
  24. package/dist/core/queries.d.ts +57 -1
  25. package/dist/core/queries.js +70 -23
  26. package/dist/core/tokens.d.ts +11 -0
  27. package/dist/core/tokens.js +131 -0
  28. package/dist/core/types.d.ts +7049 -1903
  29. package/dist/core/types.js +133 -60
  30. package/dist/core/utils.d.ts +1 -0
  31. package/dist/core/utils.js +6 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.js +8 -2
  34. package/dist/runtime/db-client.js +1 -1
  35. package/dist/runtime/index.d.ts +5 -1
  36. package/dist/runtime/index.js +36 -21
  37. package/dist/runtime/types.d.ts +13 -3
  38. package/dist/runtime/types.js +8 -0
  39. package/package.json +5 -3
@@ -1,4 +1,4 @@
1
1
  declare namespace Config {
2
- type DBUserConfig = import('./dist/config.js').DBUserConfig;
2
+ type DBUserConfig = import('./dist/core/types.js').DBUserConfig;
3
3
  export interface Database extends DBUserConfig {}
4
4
  }
@@ -0,0 +1,8 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ export declare function cmd({ flags }: {
4
+ config: AstroConfig;
5
+ flags: Arguments;
6
+ }): Promise<void>;
7
+ export declare function promptProjectName(defaultName?: string): Promise<string>;
8
+ export declare function promptWorkspaceName(defaultName?: string): Promise<string>;
@@ -0,0 +1,64 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import prompts from "prompts";
3
+ import { PROJECT_ID_FILE, getSessionIdFromFile } from "../../../tokens.js";
4
+ import { getAstroStudioUrl } from "../../../utils.js";
5
+ import { MISSING_SESSION_ID_ERROR } from "../../../errors.js";
6
+ async function cmd({ flags }) {
7
+ const linkUrl = new URL(getAstroStudioUrl() + "/auth/cli/link");
8
+ const sessionToken = await getSessionIdFromFile();
9
+ if (!sessionToken) {
10
+ console.error(MISSING_SESSION_ID_ERROR);
11
+ process.exit(1);
12
+ }
13
+ let body = { id: flags._[4] };
14
+ if (!body.id) {
15
+ const workspaceIdName = await promptWorkspaceName();
16
+ const projectIdName = await promptProjectName();
17
+ body = { projectIdName, workspaceIdName };
18
+ }
19
+ const response = await fetch(linkUrl, {
20
+ method: "POST",
21
+ headers: {
22
+ Authorization: `Bearer ${await getSessionIdFromFile()}`,
23
+ "Content-Type": "application/json"
24
+ },
25
+ body: JSON.stringify(body)
26
+ });
27
+ if (!response.ok) {
28
+ console.error(`Failed to link project: ${response.status} ${response.statusText}`);
29
+ process.exit(1);
30
+ }
31
+ const { data } = await response.json();
32
+ await mkdir(new URL(".", PROJECT_ID_FILE), { recursive: true });
33
+ await writeFile(PROJECT_ID_FILE, `${data.id}`);
34
+ console.info("Project linked.");
35
+ }
36
+ async function promptProjectName(defaultName) {
37
+ const { projectName } = await prompts({
38
+ type: "text",
39
+ name: "projectName",
40
+ message: "Project ID",
41
+ initial: defaultName
42
+ });
43
+ if (typeof projectName !== "string") {
44
+ process.exit(0);
45
+ }
46
+ return projectName;
47
+ }
48
+ async function promptWorkspaceName(defaultName) {
49
+ const { workspaceName } = await prompts({
50
+ type: "text",
51
+ name: "workspaceName",
52
+ message: "Workspace ID",
53
+ initial: defaultName
54
+ });
55
+ if (typeof workspaceName !== "string") {
56
+ process.exit(0);
57
+ }
58
+ return workspaceName;
59
+ }
60
+ export {
61
+ cmd,
62
+ promptProjectName,
63
+ promptWorkspaceName
64
+ };
@@ -0,0 +1,6 @@
1
+ import type { AstroConfig } from 'astro';
2
+ import type { Arguments } from 'yargs-parser';
3
+ export declare function cmd({ flags }: {
4
+ config: AstroConfig;
5
+ flags: Arguments;
6
+ }): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { cyan } from "kleur/colors";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { createServer } from "node:http";
4
+ import ora from "ora";
5
+ import { getAstroStudioUrl } from "../../../utils.js";
6
+ import open from "open";
7
+ import { SESSION_LOGIN_FILE } from "../../../tokens.js";
8
+ function serveAndResolveSession() {
9
+ let resolve, reject;
10
+ const sessionPromise = new Promise((_resolve, _reject) => {
11
+ resolve = _resolve;
12
+ reject = _reject;
13
+ });
14
+ const server = createServer((req, res) => {
15
+ res.writeHead(200);
16
+ res.end();
17
+ const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
18
+ const session = url.searchParams.get("session");
19
+ if (!session) {
20
+ reject();
21
+ } else {
22
+ resolve(session);
23
+ }
24
+ }).listen(5710, "localhost");
25
+ return sessionPromise.finally(() => {
26
+ server.closeAllConnections();
27
+ server.close();
28
+ });
29
+ }
30
+ async function cmd({ flags }) {
31
+ let session = flags.session;
32
+ const loginUrl = getAstroStudioUrl() + "/auth/cli";
33
+ if (!session) {
34
+ console.log(`Opening ${cyan(loginUrl)} in your browser...`);
35
+ console.log(`If something goes wrong, copy-and-paste the URL into your browser.`);
36
+ open(loginUrl);
37
+ const spinner = ora("Waiting for confirmation...");
38
+ session = await serveAndResolveSession();
39
+ spinner.succeed("Successfully logged in!");
40
+ }
41
+ await mkdir(new URL(".", SESSION_LOGIN_FILE), { recursive: true });
42
+ await writeFile(SESSION_LOGIN_FILE, `${session}`);
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 cmd({}: {
4
+ config: AstroConfig;
5
+ flags: Arguments;
6
+ }): 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
+ };
@@ -1,57 +1,68 @@
1
1
  import { createClient } from "@libsql/client";
2
- import deepDiff from "deep-diff";
3
2
  import { drizzle } from "drizzle-orm/sqlite-proxy";
4
- import { appTokenError } from "../../../errors.js";
3
+ import { red } from "kleur/colors";
4
+ import prompts from "prompts";
5
+ import { setupDbTables } from "../../../queries.js";
6
+ import { getManagedAppTokenOrExit } from "../../../tokens.js";
7
+ import { collectionsSchema } from "../../../types.js";
8
+ import { getRemoteDatabaseUrl } from "../../../utils.js";
9
+ import { getMigrationQueries } from "../../migration-queries.js";
5
10
  import {
6
- createCurrentSnapshot,
7
11
  createEmptySnapshot,
8
12
  getMigrations,
9
- initializeFromMigrations,
13
+ getMigrationStatus,
10
14
  loadInitialSnapshot,
11
- loadMigration
15
+ loadMigration,
16
+ MIGRATION_NEEDED,
17
+ MIGRATIONS_NOT_INITIALIZED,
18
+ MIGRATIONS_UP_TO_DATE
12
19
  } from "../../migrations.js";
13
- import { getAstroStudioEnv, getRemoteDatabaseUrl } from "../../../utils.js";
14
- import { getMigrationQueries } from "../../migration-queries.js";
15
- import { setupDbTables } from "../../../queries.js";
16
- const { diff } = deepDiff;
20
+ import { MISSING_SESSION_ID_ERROR } from "../../../errors.js";
17
21
  async function cmd({ config, flags }) {
18
- const isSeedData = flags.seed;
19
22
  const isDryRun = flags.dryRun;
20
- const appToken = flags.token ?? getAstroStudioEnv().ASTRO_STUDIO_APP_TOKEN;
21
- const currentSnapshot = createCurrentSnapshot(config);
22
- const allMigrationFiles = await getMigrations();
23
- if (allMigrationFiles.length === 0) {
24
- console.log("Project not yet initialized!");
23
+ const appToken = await getManagedAppTokenOrExit(flags.token);
24
+ const migration = await getMigrationStatus(config);
25
+ if (migration.state === "no-migrations-found") {
26
+ console.log(MIGRATIONS_NOT_INITIALIZED);
25
27
  process.exit(1);
26
- }
27
- const prevSnapshot = await initializeFromMigrations(allMigrationFiles);
28
- const calculatedDiff = diff(prevSnapshot, currentSnapshot);
29
- if (calculatedDiff) {
30
- console.log("Changes detected!");
31
- console.log(calculatedDiff);
28
+ } else if (migration.state === "ahead") {
29
+ console.log(MIGRATION_NEEDED);
32
30
  process.exit(1);
33
31
  }
34
- if (!appToken) {
35
- console.error(appTokenError);
32
+ const allLocalMigrations = await getMigrations();
33
+ let missingMigrations = [];
34
+ try {
35
+ const { data } = await prepareMigrateQuery({
36
+ migrations: allLocalMigrations,
37
+ appToken: appToken.token
38
+ });
39
+ missingMigrations = data;
40
+ } catch (error) {
41
+ if (error instanceof Error) {
42
+ if (error.message.startsWith("{")) {
43
+ const { error: { code } = { code: "" } } = JSON.parse(error.message);
44
+ if (code === "TOKEN_UNAUTHORIZED") {
45
+ console.error(MISSING_SESSION_ID_ERROR);
46
+ }
47
+ }
48
+ }
49
+ console.error(error);
36
50
  process.exit(1);
37
51
  }
38
- const allLocalMigrations = await getMigrations();
39
- const { data: missingMigrations } = await prepareMigrateQuery({
40
- migrations: allLocalMigrations,
41
- appToken
42
- });
43
52
  if (missingMigrations.length === 0) {
44
- console.info("No migrations to push! Your database is up to date!");
45
- process.exit(0);
46
- }
47
- if (missingMigrations.length > 0) {
53
+ console.log(MIGRATIONS_UP_TO_DATE);
54
+ } else {
48
55
  console.log(`Pushing ${missingMigrations.length} migrations...`);
49
- await pushSchema({ migrations: missingMigrations, appToken, isDryRun, currentSnapshot });
50
- }
51
- if (isSeedData) {
52
- console.info("Pushing data...");
53
- await pushData({ config, appToken, isDryRun });
56
+ await pushSchema({
57
+ migrations: missingMigrations,
58
+ appToken: appToken.token,
59
+ isDryRun,
60
+ currentSnapshot: migration.currentSnapshot
61
+ });
54
62
  }
63
+ console.info("Pushing data...");
64
+ await pushData({ config, appToken: appToken.token, isDryRun });
65
+ await appToken.destroy();
55
66
  console.info("Push complete!");
56
67
  }
57
68
  async function pushSchema({
@@ -63,10 +74,26 @@ async function pushSchema({
63
74
  const initialSnapshot = migrations.find((m) => m === "0000_snapshot.json");
64
75
  const filteredMigrations = migrations.filter((m) => m !== "0000_snapshot.json");
65
76
  const missingMigrationContents = await Promise.all(filteredMigrations.map(loadMigration));
66
- const initialMigrationBatch = initialSnapshot ? await getMigrationQueries({
77
+ const initialMigrationBatch = initialSnapshot ? (await getMigrationQueries({
67
78
  oldSnapshot: createEmptySnapshot(),
68
79
  newSnapshot: await loadInitialSnapshot()
69
- }) : [];
80
+ })).queries : [];
81
+ const confirmations = missingMigrationContents.reduce((acc, curr) => {
82
+ return [...acc, ...curr.confirm || []];
83
+ }, []);
84
+ if (confirmations.length > 0) {
85
+ const response = await prompts([
86
+ ...confirmations.map((message, index) => ({
87
+ type: "confirm",
88
+ name: String(index),
89
+ message: red("Warning: ") + message + "\nContinue?",
90
+ initial: true
91
+ }))
92
+ ]);
93
+ if (Object.values(response).length === 0 || Object.values(response).some((value) => value === false)) {
94
+ process.exit(1);
95
+ }
96
+ }
70
97
  const queries = missingMigrationContents.reduce((acc, curr) => {
71
98
  return [...acc, ...curr.db];
72
99
  }, initialMigrationBatch);
@@ -98,7 +125,7 @@ async function pushData({
98
125
  await setupDbTables({
99
126
  db,
100
127
  mode: "build",
101
- collections: config.db.collections ?? {},
128
+ collections: collectionsSchema.parse(config.db.collections ?? {}),
102
129
  data: config.db.data
103
130
  });
104
131
  }
@@ -116,12 +143,13 @@ async function pushData({
116
143
  });
117
144
  }
118
145
  async function runMigrateQuery({
119
- queries,
146
+ queries: baseQueries,
120
147
  migrations,
121
148
  snapshot,
122
149
  appToken,
123
150
  isDryRun
124
151
  }) {
152
+ const queries = ["pragma defer_foreign_keys=true;", ...baseQueries];
125
153
  const requestBody = {
126
154
  snapshot,
127
155
  migrations,
@@ -132,7 +160,7 @@ async function runMigrateQuery({
132
160
  console.info("[DRY RUN] Batch query:", JSON.stringify(requestBody, null, 2));
133
161
  return new Response(null, { status: 200 });
134
162
  }
135
- const url = new URL("/db/migrate/run", getRemoteDatabaseUrl());
163
+ const url = new URL("/migrations/run", getRemoteDatabaseUrl());
136
164
  return await fetch(url, {
137
165
  method: "POST",
138
166
  headers: new Headers({
@@ -145,7 +173,7 @@ async function prepareMigrateQuery({
145
173
  migrations,
146
174
  appToken
147
175
  }) {
148
- const url = new URL("/db/migrate/prepare", getRemoteDatabaseUrl());
176
+ const url = new URL("/migrations/prepare", getRemoteDatabaseUrl());
149
177
  const requestBody = {
150
178
  migrations,
151
179
  experimentalVersion: 1
@@ -1,16 +1,13 @@
1
1
  import { sql } from "drizzle-orm";
2
- import { appTokenError } from "../../../errors.js";
3
- import { getAstroStudioEnv, getRemoteDatabaseUrl } from "../../../utils.js";
4
2
  import { createRemoteDatabaseClient } from "../../../../runtime/db-client.js";
3
+ import { getManagedAppTokenOrExit } from "../../../tokens.js";
4
+ import { getRemoteDatabaseUrl } from "../../../utils.js";
5
5
  async function cmd({ flags }) {
6
6
  const query = flags.query;
7
- const appToken = flags.token ?? getAstroStudioEnv().ASTRO_STUDIO_APP_TOKEN;
8
- if (!appToken) {
9
- console.error(appTokenError);
10
- process.exit(1);
11
- }
12
- const db = createRemoteDatabaseClient(appToken, getRemoteDatabaseUrl());
7
+ const appToken = await getManagedAppTokenOrExit(flags.token);
8
+ const db = createRemoteDatabaseClient(appToken.token, getRemoteDatabaseUrl());
13
9
  const result = await db.run(sql.raw(query));
10
+ await appToken.destroy();
14
11
  console.log(result);
15
12
  }
16
13
  export {
@@ -1,43 +1,36 @@
1
- import deepDiff from "deep-diff";
2
- import { writeFile } from "fs/promises";
1
+ import { writeFile } from "node:fs/promises";
3
2
  import {
4
- createCurrentSnapshot,
5
- getMigrations,
6
- initializeFromMigrations,
3
+ MIGRATIONS_CREATED,
4
+ MIGRATIONS_UP_TO_DATE,
5
+ getMigrationStatus,
7
6
  initializeMigrationsDirectory
8
7
  } from "../../migrations.js";
9
8
  import { getMigrationQueries } from "../../migration-queries.js";
10
- const { diff } = deepDiff;
9
+ import { bgRed, red, reset } from "kleur/colors";
11
10
  async function cmd({ config }) {
12
- const currentSnapshot = createCurrentSnapshot(config);
13
- const allMigrationFiles = await getMigrations();
14
- if (allMigrationFiles.length === 0) {
15
- await initializeMigrationsDirectory(currentSnapshot);
16
- console.log("Project initialized!");
11
+ const migration = await getMigrationStatus(config);
12
+ if (migration.state === "no-migrations-found") {
13
+ await initializeMigrationsDirectory(migration.currentSnapshot);
14
+ console.log(MIGRATIONS_CREATED);
17
15
  return;
18
- }
19
- const prevSnapshot = await initializeFromMigrations(allMigrationFiles);
20
- const calculatedDiff = diff(prevSnapshot, currentSnapshot);
21
- if (!calculatedDiff) {
22
- console.log("No changes detected!");
16
+ } else if (migration.state === "up-to-date") {
17
+ console.log(MIGRATIONS_UP_TO_DATE);
23
18
  return;
24
19
  }
25
- const migrationQueries = await getMigrationQueries({
26
- oldSnapshot: prevSnapshot,
27
- newSnapshot: currentSnapshot
20
+ const { oldSnapshot, newSnapshot, newFilename, diff } = migration;
21
+ const { queries: migrationQueries, confirmations } = await getMigrationQueries({
22
+ oldSnapshot,
23
+ newSnapshot
28
24
  });
29
- const largestNumber = allMigrationFiles.reduce((acc, curr) => {
30
- const num = parseInt(curr.split("_")[0]);
31
- return num > acc ? num : acc;
32
- }, 0);
25
+ confirmations.map((message) => console.log(bgRed(" !!! ") + " " + red(message)));
33
26
  const migrationFileContent = {
34
- diff: calculatedDiff,
35
- db: migrationQueries
27
+ diff,
28
+ db: migrationQueries,
29
+ // TODO(fks): Encode the relevant data, instead of the raw message.
30
+ // This will give `db push` more control over the formatting of the message.
31
+ confirm: confirmations.map((c) => reset(c))
36
32
  };
37
- const migrationFileName = `./migrations/${String(largestNumber + 1).padStart(
38
- 4,
39
- "0"
40
- )}_migration.json`;
33
+ const migrationFileName = `./migrations/${newFilename}`;
41
34
  await writeFile(migrationFileName, JSON.stringify(migrationFileContent, void 0, 2));
42
35
  console.log(migrationFileName + " created!");
43
36
  }
@@ -1,6 +1,6 @@
1
1
  import type { AstroConfig } from 'astro';
2
2
  import type { Arguments } from 'yargs-parser';
3
- export declare function cmd({ config }: {
3
+ export declare function cmd({ config, flags }: {
4
4
  config: AstroConfig;
5
5
  flags: Arguments;
6
6
  }): Promise<void>;
@@ -1,21 +1,25 @@
1
- import deepDiff from "deep-diff";
2
- import { getMigrations, initializeFromMigrations } from "../../migrations.js";
3
- const { diff } = deepDiff;
4
- async function cmd({ config }) {
5
- const currentSnapshot = JSON.parse(JSON.stringify(config.db?.collections ?? {}));
6
- const allMigrationFiles = await getMigrations();
7
- if (allMigrationFiles.length === 0) {
8
- console.log("Project not yet initialized!");
9
- process.exit(1);
1
+ import { getMigrationStatus, MIGRATION_NEEDED, MIGRATIONS_NOT_INITIALIZED, MIGRATIONS_UP_TO_DATE } from "../../migrations.js";
2
+ async function cmd({ config, flags }) {
3
+ const status = await getMigrationStatus(config);
4
+ const { state } = status;
5
+ if (flags.json) {
6
+ console.log(JSON.stringify(status));
7
+ process.exit(state === "up-to-date" ? 0 : 1);
10
8
  }
11
- const prevSnapshot = await initializeFromMigrations(allMigrationFiles);
12
- const calculatedDiff = diff(prevSnapshot, currentSnapshot);
13
- if (calculatedDiff) {
14
- console.log("Changes detected!");
15
- process.exit(1);
9
+ switch (state) {
10
+ case "no-migrations-found": {
11
+ console.log(MIGRATIONS_NOT_INITIALIZED);
12
+ process.exit(1);
13
+ }
14
+ case "ahead": {
15
+ console.log(MIGRATION_NEEDED);
16
+ process.exit(1);
17
+ }
18
+ case "up-to-date": {
19
+ console.log(MIGRATIONS_UP_TO_DATE);
20
+ return;
21
+ }
16
22
  }
17
- console.log("No changes detected.");
18
- return;
19
23
  }
20
24
  export {
21
25
  cmd
@@ -1,21 +1,38 @@
1
+ import { STUDIO_CONFIG_MISSING_CLI_ERROR } from "../errors.js";
1
2
  async function cli({ flags, config }) {
2
3
  const command = flags._[3];
4
+ if (!config.db?.studio) {
5
+ console.log(STUDIO_CONFIG_MISSING_CLI_ERROR);
6
+ process.exit(1);
7
+ }
3
8
  switch (command) {
4
9
  case "shell": {
5
- const { cmd: shellCommand } = await import("./commands/shell/index.js");
6
- return await shellCommand({ config, flags });
10
+ const { cmd } = await import("./commands/shell/index.js");
11
+ return await cmd({ config, flags });
7
12
  }
8
13
  case "sync": {
9
- const { cmd: syncCommand } = await import("./commands/sync/index.js");
10
- return await syncCommand({ config, flags });
14
+ const { cmd } = await import("./commands/sync/index.js");
15
+ return await cmd({ config, flags });
11
16
  }
12
17
  case "push": {
13
- const { cmd: pushCommand } = await import("./commands/push/index.js");
14
- return await pushCommand({ config, flags });
18
+ const { cmd } = await import("./commands/push/index.js");
19
+ return await cmd({ config, flags });
15
20
  }
16
21
  case "verify": {
17
- const { cmd: verifyCommand } = await import("./commands/verify/index.js");
18
- return await verifyCommand({ config, flags });
22
+ const { cmd } = await import("./commands/verify/index.js");
23
+ return await cmd({ config, flags });
24
+ }
25
+ case "login": {
26
+ const { cmd } = await import("./commands/login/index.js");
27
+ return await cmd({ config, flags });
28
+ }
29
+ case "logout": {
30
+ const { cmd } = await import("./commands/logout/index.js");
31
+ return await cmd({ config, flags });
32
+ }
33
+ case "link": {
34
+ const { cmd } = await import("./commands/link/index.js");
35
+ return await cmd({ config, flags });
19
36
  }
20
37
  default: {
21
38
  if (command == null) {
@@ -35,6 +52,10 @@ ${showHelp()}`);
35
52
 
36
53
  Usage:
37
54
 
55
+ astro db login Authenticate your machine with Astro Studio
56
+ astro db logout End your authenticated session with Astro Studio
57
+ astro db link Link this directory to an Astro Studio project
58
+
38
59
  astro db sync Creates snapshot based on your schema
39
60
  astro db push Pushes migrations to Astro Studio
40
61
  astro db verify Verifies migrations have been pushed and errors if not`;
@@ -1,18 +1,26 @@
1
1
  import type { DBCollection, DBSnapshot } from '../types.js';
2
- interface PromptResponses {
3
- allowDataLoss: boolean;
4
- fieldRenames: Record<string, string | false>;
5
- collectionRenames: Record<string, string | false>;
6
- }
7
- export declare function getMigrationQueries({ oldSnapshot, newSnapshot, promptResponses, }: {
2
+ /** Dependency injected for unit testing */
3
+ type AmbiguityResponses = {
4
+ collectionRenames: Record<string, string>;
5
+ fieldRenames: {
6
+ [collectionName: string]: Record<string, string>;
7
+ };
8
+ };
9
+ export declare function getMigrationQueries({ oldSnapshot, newSnapshot, ambiguityResponses, }: {
8
10
  oldSnapshot: DBSnapshot;
9
11
  newSnapshot: DBSnapshot;
10
- promptResponses?: PromptResponses;
11
- }): Promise<string[]>;
12
- export declare function getCollectionChangeQueries({ collectionName, oldCollection, newCollection, promptResponses, }: {
12
+ ambiguityResponses?: AmbiguityResponses;
13
+ }): Promise<{
14
+ queries: string[];
15
+ confirmations: string[];
16
+ }>;
17
+ export declare function getCollectionChangeQueries({ collectionName, oldCollection, newCollection, ambiguityResponses, }: {
13
18
  collectionName: string;
14
19
  oldCollection: DBCollection;
15
20
  newCollection: DBCollection;
16
- promptResponses?: PromptResponses;
17
- }): Promise<string[]>;
21
+ ambiguityResponses?: AmbiguityResponses;
22
+ }): Promise<{
23
+ queries: string[];
24
+ confirmations: string[];
25
+ }>;
18
26
  export {};