@astrojs/db 0.0.0-db-export-bug-20240307130354

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 (63) hide show
  1. package/LICENSE +59 -0
  2. package/README.md +38 -0
  3. package/dist/core/cli/commands/execute/index.d.ts +8 -0
  4. package/dist/core/cli/commands/execute/index.js +32 -0
  5. package/dist/core/cli/commands/link/index.d.ts +20 -0
  6. package/dist/core/cli/commands/link/index.js +238 -0
  7. package/dist/core/cli/commands/login/index.d.ts +8 -0
  8. package/dist/core/cli/commands/login/index.js +55 -0
  9. package/dist/core/cli/commands/logout/index.d.ts +1 -0
  10. package/dist/core/cli/commands/logout/index.js +9 -0
  11. package/dist/core/cli/commands/push/index.d.ts +8 -0
  12. package/dist/core/cli/commands/push/index.js +77 -0
  13. package/dist/core/cli/commands/shell/index.d.ts +8 -0
  14. package/dist/core/cli/commands/shell/index.js +17 -0
  15. package/dist/core/cli/commands/verify/index.d.ts +8 -0
  16. package/dist/core/cli/commands/verify/index.js +46 -0
  17. package/dist/core/cli/index.d.ts +6 -0
  18. package/dist/core/cli/index.js +77 -0
  19. package/dist/core/cli/migration-queries.d.ts +22 -0
  20. package/dist/core/cli/migration-queries.js +366 -0
  21. package/dist/core/consts.d.ts +7 -0
  22. package/dist/core/consts.js +19 -0
  23. package/dist/core/errors.d.ts +11 -0
  24. package/dist/core/errors.js +65 -0
  25. package/dist/core/integration/error-map.d.ts +6 -0
  26. package/dist/core/integration/error-map.js +79 -0
  27. package/dist/core/integration/file-url.d.ts +2 -0
  28. package/dist/core/integration/file-url.js +81 -0
  29. package/dist/core/integration/index.d.ts +2 -0
  30. package/dist/core/integration/index.js +112 -0
  31. package/dist/core/integration/typegen.d.ts +5 -0
  32. package/dist/core/integration/typegen.js +31 -0
  33. package/dist/core/integration/vite-plugin-db.d.ts +29 -0
  34. package/dist/core/integration/vite-plugin-db.js +111 -0
  35. package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +11 -0
  36. package/dist/core/integration/vite-plugin-inject-env-ts.js +53 -0
  37. package/dist/core/load-file.d.ts +31 -0
  38. package/dist/core/load-file.js +98 -0
  39. package/dist/core/tokens.d.ts +11 -0
  40. package/dist/core/tokens.js +131 -0
  41. package/dist/core/types.d.ts +3901 -0
  42. package/dist/core/types.js +143 -0
  43. package/dist/core/utils.d.ts +6 -0
  44. package/dist/core/utils.js +22 -0
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.js +6 -0
  47. package/dist/runtime/config.d.ts +148 -0
  48. package/dist/runtime/config.js +87 -0
  49. package/dist/runtime/db-client.d.ts +5 -0
  50. package/dist/runtime/db-client.js +64 -0
  51. package/dist/runtime/drizzle.d.ts +1 -0
  52. package/dist/runtime/drizzle.js +48 -0
  53. package/dist/runtime/index.d.ts +31 -0
  54. package/dist/runtime/index.js +126 -0
  55. package/dist/runtime/queries.d.ts +81 -0
  56. package/dist/runtime/queries.js +206 -0
  57. package/dist/runtime/types.d.ts +69 -0
  58. package/dist/runtime/types.js +8 -0
  59. package/dist/utils.d.ts +1 -0
  60. package/dist/utils.js +4 -0
  61. package/index.d.ts +3 -0
  62. package/package.json +90 -0
  63. package/virtual.d.ts +9 -0
@@ -0,0 +1,77 @@
1
+ import { loadDbConfigFile } from "../load-file.js";
2
+ import { dbConfigSchema } from "../types.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 { mod } = await loadDbConfigFile(astroConfig.root);
10
+ const dbConfig = dbConfigSchema.parse(mod?.default ?? {});
11
+ switch (command) {
12
+ case "shell": {
13
+ const { cmd } = await import("./commands/shell/index.js");
14
+ return await cmd({ astroConfig, dbConfig, flags });
15
+ }
16
+ case "gen": {
17
+ console.log('"astro db gen" is no longer needed! Visit the docs for more information.');
18
+ return;
19
+ }
20
+ case "sync": {
21
+ console.log('"astro db sync" is no longer needed! Visit the docs for more information.');
22
+ return;
23
+ }
24
+ case "push": {
25
+ const { cmd } = await import("./commands/push/index.js");
26
+ return await cmd({ astroConfig, dbConfig, flags });
27
+ }
28
+ case "verify": {
29
+ const { cmd } = await import("./commands/verify/index.js");
30
+ return await cmd({ astroConfig, dbConfig, flags });
31
+ }
32
+ case "execute": {
33
+ const { cmd } = await import("./commands/execute/index.js");
34
+ return await cmd({ astroConfig, dbConfig, flags });
35
+ }
36
+ case "login": {
37
+ const { cmd } = await import("./commands/login/index.js");
38
+ return await cmd({ astroConfig, dbConfig, flags });
39
+ }
40
+ case "logout": {
41
+ const { cmd } = await import("./commands/logout/index.js");
42
+ return await cmd();
43
+ }
44
+ case "link": {
45
+ const { cmd } = await import("./commands/link/index.js");
46
+ return await cmd();
47
+ }
48
+ default: {
49
+ if (command == null) {
50
+ console.error(`No command provided.
51
+
52
+ ${showHelp()}`);
53
+ } else {
54
+ console.error(`Unknown command: ${command}
55
+
56
+ ${showHelp()}`);
57
+ }
58
+ return;
59
+ }
60
+ }
61
+ function showHelp() {
62
+ return `astro db <command>
63
+
64
+ Usage:
65
+
66
+ astro login Authenticate your machine with Astro Studio
67
+ astro logout End your authenticated session with Astro Studio
68
+ astro link Link this directory to an Astro Studio project
69
+
70
+ astro db gen Creates snapshot based on your schema
71
+ astro db push Pushes schema updates to Astro Studio
72
+ astro db verify Tests schema updates /w Astro Studio (good for CI)`;
73
+ }
74
+ }
75
+ export {
76
+ cli
77
+ };
@@ -0,0 +1,22 @@
1
+ import { type DBConfig, type DBSnapshot, type DBTable } from '../types.js';
2
+ export declare function getMigrationQueries({ oldSnapshot, newSnapshot, }: {
3
+ oldSnapshot: DBSnapshot;
4
+ newSnapshot: DBSnapshot;
5
+ }): Promise<{
6
+ queries: string[];
7
+ confirmations: string[];
8
+ }>;
9
+ export declare function getCollectionChangeQueries({ collectionName, oldCollection, newCollection, }: {
10
+ collectionName: string;
11
+ oldCollection: DBTable;
12
+ newCollection: DBTable;
13
+ }): Promise<{
14
+ queries: string[];
15
+ confirmations: string[];
16
+ }>;
17
+ export declare function getProductionCurrentSnapshot({ appToken, }: {
18
+ appToken: string;
19
+ }): Promise<DBSnapshot>;
20
+ export declare function createCurrentSnapshot({ tables }: DBConfig): DBSnapshot;
21
+ export declare function createEmptySnapshot(): DBSnapshot;
22
+ export declare function formatDataLossMessage(confirmations: string[], isColor?: boolean): string;
@@ -0,0 +1,366 @@
1
+ import deepDiff from "deep-diff";
2
+ import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
3
+ import * as color from "kleur/colors";
4
+ import { customAlphabet } from "nanoid";
5
+ import stripAnsi from "strip-ansi";
6
+ import { hasPrimaryKey } from "../../runtime/index.js";
7
+ import {
8
+ getCreateIndexQueries,
9
+ getCreateTableQuery,
10
+ getDropTableIfExistsQuery,
11
+ getModifiers,
12
+ getReferencesConfig,
13
+ hasDefault,
14
+ schemaTypeToSqlType
15
+ } from "../../runtime/queries.js";
16
+ import { isSerializedSQL } from "../../runtime/types.js";
17
+ import { RENAME_COLUMN_ERROR, RENAME_TABLE_ERROR } from "../errors.js";
18
+ import {
19
+ columnSchema
20
+ } from "../types.js";
21
+ import { getRemoteDatabaseUrl } from "../utils.js";
22
+ const sqlite = new SQLiteAsyncDialect();
23
+ const genTempTableName = customAlphabet("abcdefghijklmnopqrstuvwxyz", 10);
24
+ async function getMigrationQueries({
25
+ oldSnapshot,
26
+ newSnapshot
27
+ }) {
28
+ const queries = [];
29
+ const confirmations = [];
30
+ const addedCollections = getAddedCollections(oldSnapshot, newSnapshot);
31
+ const droppedTables = getDroppedCollections(oldSnapshot, newSnapshot);
32
+ const notDeprecatedDroppedTables = Object.fromEntries(
33
+ Object.entries(droppedTables).filter(([, table]) => !table.deprecated)
34
+ );
35
+ if (!isEmpty(addedCollections) && !isEmpty(notDeprecatedDroppedTables)) {
36
+ throw new Error(
37
+ RENAME_TABLE_ERROR(
38
+ Object.keys(addedCollections)[0],
39
+ Object.keys(notDeprecatedDroppedTables)[0]
40
+ )
41
+ );
42
+ }
43
+ for (const [collectionName, collection] of Object.entries(addedCollections)) {
44
+ queries.push(getDropTableIfExistsQuery(collectionName));
45
+ queries.push(getCreateTableQuery(collectionName, collection));
46
+ queries.push(...getCreateIndexQueries(collectionName, collection));
47
+ }
48
+ for (const [collectionName] of Object.entries(droppedTables)) {
49
+ const dropQuery = `DROP TABLE ${sqlite.escapeName(collectionName)}`;
50
+ queries.push(dropQuery);
51
+ }
52
+ for (const [collectionName, newCollection] of Object.entries(newSnapshot.schema)) {
53
+ const oldCollection = oldSnapshot.schema[collectionName];
54
+ if (!oldCollection)
55
+ continue;
56
+ const addedColumns = getAdded(oldCollection.columns, newCollection.columns);
57
+ const droppedColumns = getDropped(oldCollection.columns, newCollection.columns);
58
+ const notDeprecatedDroppedColumns = Object.fromEntries(
59
+ Object.entries(droppedColumns).filter(([key, col]) => !col.schema.deprecated)
60
+ );
61
+ if (!isEmpty(addedColumns) && !isEmpty(notDeprecatedDroppedColumns)) {
62
+ throw new Error(
63
+ RENAME_COLUMN_ERROR(
64
+ `${collectionName}.${Object.keys(addedColumns)[0]}`,
65
+ `${collectionName}.${Object.keys(notDeprecatedDroppedColumns)[0]}`
66
+ )
67
+ );
68
+ }
69
+ const result = await getCollectionChangeQueries({
70
+ collectionName,
71
+ oldCollection,
72
+ newCollection
73
+ });
74
+ queries.push(...result.queries);
75
+ confirmations.push(...result.confirmations);
76
+ }
77
+ return { queries, confirmations };
78
+ }
79
+ async function getCollectionChangeQueries({
80
+ collectionName,
81
+ oldCollection,
82
+ newCollection
83
+ }) {
84
+ const queries = [];
85
+ const confirmations = [];
86
+ const updated = getUpdatedColumns(oldCollection.columns, newCollection.columns);
87
+ const added = getAdded(oldCollection.columns, newCollection.columns);
88
+ const dropped = getDropped(oldCollection.columns, newCollection.columns);
89
+ const hasForeignKeyChanges = Boolean(
90
+ deepDiff(oldCollection.foreignKeys, newCollection.foreignKeys)
91
+ );
92
+ if (!hasForeignKeyChanges && isEmpty(updated) && isEmpty(added) && isEmpty(dropped)) {
93
+ return {
94
+ queries: getChangeIndexQueries({
95
+ collectionName,
96
+ oldIndexes: oldCollection.indexes,
97
+ newIndexes: newCollection.indexes
98
+ }),
99
+ confirmations
100
+ };
101
+ }
102
+ if (!hasForeignKeyChanges && isEmpty(updated) && Object.values(dropped).every(canAlterTableDropColumn) && Object.values(added).every(canAlterTableAddColumn)) {
103
+ queries.push(
104
+ ...getAlterTableQueries(collectionName, added, dropped),
105
+ ...getChangeIndexQueries({
106
+ collectionName,
107
+ oldIndexes: oldCollection.indexes,
108
+ newIndexes: newCollection.indexes
109
+ })
110
+ );
111
+ return { queries, confirmations };
112
+ }
113
+ const dataLossCheck = canRecreateTableWithoutDataLoss(added, updated);
114
+ if (dataLossCheck.dataLoss) {
115
+ const { reason, columnName } = dataLossCheck;
116
+ const reasonMsgs = {
117
+ "added-required": `You added new required column '${color.bold(
118
+ collectionName + "." + columnName
119
+ )}' with no default value.
120
+ This cannot be executed on an existing table.`,
121
+ "updated-type": `Updating existing column ${color.bold(
122
+ collectionName + "." + columnName
123
+ )} to a new type that cannot be handled automatically.`
124
+ };
125
+ confirmations.push(reasonMsgs[reason]);
126
+ }
127
+ const primaryKeyExists = Object.entries(newCollection.columns).find(
128
+ ([, column]) => hasPrimaryKey(column)
129
+ );
130
+ const droppedPrimaryKey = Object.entries(dropped).find(([, column]) => hasPrimaryKey(column));
131
+ const recreateTableQueries = getRecreateTableQueries({
132
+ collectionName,
133
+ newCollection,
134
+ added,
135
+ hasDataLoss: dataLossCheck.dataLoss,
136
+ migrateHiddenPrimaryKey: !primaryKeyExists && !droppedPrimaryKey
137
+ });
138
+ queries.push(...recreateTableQueries, ...getCreateIndexQueries(collectionName, newCollection));
139
+ return { queries, confirmations };
140
+ }
141
+ function getChangeIndexQueries({
142
+ collectionName,
143
+ oldIndexes = {},
144
+ newIndexes = {}
145
+ }) {
146
+ const added = getAdded(oldIndexes, newIndexes);
147
+ const dropped = getDropped(oldIndexes, newIndexes);
148
+ const updated = getUpdated(oldIndexes, newIndexes);
149
+ Object.assign(dropped, updated);
150
+ Object.assign(added, updated);
151
+ const queries = [];
152
+ for (const indexName of Object.keys(dropped)) {
153
+ const dropQuery = `DROP INDEX ${sqlite.escapeName(indexName)}`;
154
+ queries.push(dropQuery);
155
+ }
156
+ queries.push(...getCreateIndexQueries(collectionName, { indexes: added }));
157
+ return queries;
158
+ }
159
+ function getAddedCollections(oldCollections, newCollections) {
160
+ const added = {};
161
+ for (const [key, newCollection] of Object.entries(newCollections.schema)) {
162
+ if (!(key in oldCollections.schema))
163
+ added[key] = newCollection;
164
+ }
165
+ return added;
166
+ }
167
+ function getDroppedCollections(oldCollections, newCollections) {
168
+ const dropped = {};
169
+ for (const [key, oldCollection] of Object.entries(oldCollections.schema)) {
170
+ if (!(key in newCollections.schema))
171
+ dropped[key] = oldCollection;
172
+ }
173
+ return dropped;
174
+ }
175
+ function getAlterTableQueries(unescapedCollectionName, added, dropped) {
176
+ const queries = [];
177
+ const collectionName = sqlite.escapeName(unescapedCollectionName);
178
+ for (const [unescColumnName, column] of Object.entries(added)) {
179
+ const columnName = sqlite.escapeName(unescColumnName);
180
+ const type = schemaTypeToSqlType(column.type);
181
+ const q = `ALTER TABLE ${collectionName} ADD COLUMN ${columnName} ${type}${getModifiers(
182
+ columnName,
183
+ column
184
+ )}`;
185
+ queries.push(q);
186
+ }
187
+ for (const unescColumnName of Object.keys(dropped)) {
188
+ const columnName = sqlite.escapeName(unescColumnName);
189
+ const q = `ALTER TABLE ${collectionName} DROP COLUMN ${columnName}`;
190
+ queries.push(q);
191
+ }
192
+ return queries;
193
+ }
194
+ function getRecreateTableQueries({
195
+ collectionName: unescCollectionName,
196
+ newCollection,
197
+ added,
198
+ hasDataLoss,
199
+ migrateHiddenPrimaryKey
200
+ }) {
201
+ const unescTempName = `${unescCollectionName}_${genTempTableName()}`;
202
+ const tempName = sqlite.escapeName(unescTempName);
203
+ const collectionName = sqlite.escapeName(unescCollectionName);
204
+ if (hasDataLoss) {
205
+ return [
206
+ `DROP TABLE ${collectionName}`,
207
+ getCreateTableQuery(unescCollectionName, newCollection)
208
+ ];
209
+ }
210
+ const newColumns = [...Object.keys(newCollection.columns)];
211
+ if (migrateHiddenPrimaryKey) {
212
+ newColumns.unshift("_id");
213
+ }
214
+ const escapedColumns = newColumns.filter((i) => !(i in added)).map((c) => sqlite.escapeName(c)).join(", ");
215
+ return [
216
+ getCreateTableQuery(unescTempName, newCollection),
217
+ `INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${collectionName}`,
218
+ `DROP TABLE ${collectionName}`,
219
+ `ALTER TABLE ${tempName} RENAME TO ${collectionName}`
220
+ ];
221
+ }
222
+ function isEmpty(obj) {
223
+ return Object.keys(obj).length === 0;
224
+ }
225
+ function canAlterTableAddColumn(column) {
226
+ if (column.schema.unique)
227
+ return false;
228
+ if (hasRuntimeDefault(column))
229
+ return false;
230
+ if (!column.schema.optional && !hasDefault(column))
231
+ return false;
232
+ if (hasPrimaryKey(column))
233
+ return false;
234
+ if (getReferencesConfig(column))
235
+ return false;
236
+ return true;
237
+ }
238
+ function canAlterTableDropColumn(column) {
239
+ if (column.schema.unique)
240
+ return false;
241
+ if (hasPrimaryKey(column))
242
+ return false;
243
+ return true;
244
+ }
245
+ function canRecreateTableWithoutDataLoss(added, updated) {
246
+ for (const [columnName, a] of Object.entries(added)) {
247
+ if (hasPrimaryKey(a) && a.type !== "number" && !hasDefault(a)) {
248
+ return { dataLoss: true, columnName, reason: "added-required" };
249
+ }
250
+ if (!a.schema.optional && !hasDefault(a)) {
251
+ return { dataLoss: true, columnName, reason: "added-required" };
252
+ }
253
+ }
254
+ for (const [columnName, u] of Object.entries(updated)) {
255
+ if (u.old.type !== u.new.type && !canChangeTypeWithoutQuery(u.old, u.new)) {
256
+ return { dataLoss: true, columnName, reason: "updated-type" };
257
+ }
258
+ }
259
+ return { dataLoss: false };
260
+ }
261
+ function getAdded(oldObj, newObj) {
262
+ const added = {};
263
+ for (const [key, value] of Object.entries(newObj)) {
264
+ if (!(key in oldObj))
265
+ added[key] = value;
266
+ }
267
+ return added;
268
+ }
269
+ function getDropped(oldObj, newObj) {
270
+ const dropped = {};
271
+ for (const [key, value] of Object.entries(oldObj)) {
272
+ if (!(key in newObj))
273
+ dropped[key] = value;
274
+ }
275
+ return dropped;
276
+ }
277
+ function getUpdated(oldObj, newObj) {
278
+ const updated = {};
279
+ for (const [key, value] of Object.entries(newObj)) {
280
+ const oldValue = oldObj[key];
281
+ if (!oldValue)
282
+ continue;
283
+ if (deepDiff(oldValue, value))
284
+ updated[key] = value;
285
+ }
286
+ return updated;
287
+ }
288
+ function getUpdatedColumns(oldColumns, newColumns) {
289
+ const updated = {};
290
+ for (const [key, newColumn] of Object.entries(newColumns)) {
291
+ let oldColumn = oldColumns[key];
292
+ if (!oldColumn)
293
+ continue;
294
+ if (oldColumn.type !== newColumn.type && canChangeTypeWithoutQuery(oldColumn, newColumn)) {
295
+ const asNewColumn = columnSchema.safeParse({
296
+ type: newColumn.type,
297
+ schema: oldColumn.schema
298
+ });
299
+ if (asNewColumn.success) {
300
+ oldColumn = asNewColumn.data;
301
+ }
302
+ }
303
+ const diff = deepDiff(oldColumn, newColumn);
304
+ if (diff) {
305
+ updated[key] = { old: oldColumn, new: newColumn };
306
+ }
307
+ }
308
+ return updated;
309
+ }
310
+ const typeChangesWithoutQuery = [
311
+ { from: "boolean", to: "number" },
312
+ { from: "date", to: "text" },
313
+ { from: "json", to: "text" }
314
+ ];
315
+ function canChangeTypeWithoutQuery(oldColumn, newColumn) {
316
+ return typeChangesWithoutQuery.some(
317
+ ({ from, to }) => oldColumn.type === from && newColumn.type === to
318
+ );
319
+ }
320
+ function hasRuntimeDefault(column) {
321
+ return !!(column.schema.default && isSerializedSQL(column.schema.default));
322
+ }
323
+ async function getProductionCurrentSnapshot({
324
+ appToken
325
+ }) {
326
+ const url = new URL("/db/schema", getRemoteDatabaseUrl());
327
+ const response = await fetch(url, {
328
+ method: "POST",
329
+ headers: new Headers({
330
+ Authorization: `Bearer ${appToken}`
331
+ })
332
+ });
333
+ const result = await response.json();
334
+ return result.data;
335
+ }
336
+ function createCurrentSnapshot({ tables = {} }) {
337
+ const schema = JSON.parse(JSON.stringify(tables));
338
+ return { experimentalVersion: 1, schema };
339
+ }
340
+ function createEmptySnapshot() {
341
+ return { experimentalVersion: 1, schema: {} };
342
+ }
343
+ function formatDataLossMessage(confirmations, isColor = true) {
344
+ const messages = [];
345
+ messages.push(color.red("\u2716 We found some schema changes that cannot be handled automatically:"));
346
+ messages.push(``);
347
+ messages.push(...confirmations.map((m, i) => color.red(` (${i + 1}) `) + m));
348
+ messages.push(``);
349
+ messages.push(`To resolve, revert these changes or update your schema, and re-run the command.`);
350
+ messages.push(
351
+ `You may also run 'astro db push --force-reset' to ignore all warnings and force-push your local database schema to production instead. All data will be lost and the database will be reset.`
352
+ );
353
+ let finalMessage = messages.join("\n");
354
+ if (!isColor) {
355
+ finalMessage = stripAnsi(finalMessage);
356
+ }
357
+ return finalMessage;
358
+ }
359
+ export {
360
+ createCurrentSnapshot,
361
+ createEmptySnapshot,
362
+ formatDataLossMessage,
363
+ getCollectionChangeQueries,
364
+ getMigrationQueries,
365
+ getProductionCurrentSnapshot
366
+ };
@@ -0,0 +1,7 @@
1
+ export declare const PACKAGE_NAME: any;
2
+ export declare const RUNTIME_IMPORT: string;
3
+ export declare const RUNTIME_CONFIG_IMPORT: string;
4
+ export declare const DB_TYPES_FILE = "db-types.d.ts";
5
+ export declare const VIRTUAL_MODULE_ID = "astro:db";
6
+ export declare const DB_PATH = ".astro/content.db";
7
+ export declare const CONFIG_FILE_NAMES: string[];
@@ -0,0 +1,19 @@
1
+ import { readFileSync } from "node:fs";
2
+ const PACKAGE_NAME = JSON.parse(
3
+ readFileSync(new URL("../../package.json", import.meta.url), "utf8")
4
+ ).name;
5
+ const RUNTIME_IMPORT = JSON.stringify(`${PACKAGE_NAME}/runtime`);
6
+ const RUNTIME_CONFIG_IMPORT = JSON.stringify(`${PACKAGE_NAME}/runtime/config`);
7
+ const DB_TYPES_FILE = "db-types.d.ts";
8
+ const VIRTUAL_MODULE_ID = "astro:db";
9
+ const DB_PATH = ".astro/content.db";
10
+ const CONFIG_FILE_NAMES = ["config.ts", "config.js", "config.mts", "config.mjs"];
11
+ export {
12
+ CONFIG_FILE_NAMES,
13
+ DB_PATH,
14
+ DB_TYPES_FILE,
15
+ PACKAGE_NAME,
16
+ RUNTIME_CONFIG_IMPORT,
17
+ RUNTIME_IMPORT,
18
+ VIRTUAL_MODULE_ID
19
+ };
@@ -0,0 +1,11 @@
1
+ export declare const MISSING_SESSION_ID_ERROR: string;
2
+ export declare const MISSING_PROJECT_ID_ERROR: string;
3
+ export declare const MISSING_EXECUTE_PATH_ERROR: string;
4
+ export declare const RENAME_TABLE_ERROR: (oldTable: string, newTable: string) => string;
5
+ export declare const RENAME_COLUMN_ERROR: (oldSelector: string, newSelector: string) => string;
6
+ export declare const FILE_NOT_FOUND_ERROR: (path: string) => string;
7
+ export declare const SEED_ERROR: (error: string) => string;
8
+ export declare const REFERENCE_DNE_ERROR: (columnName: string) => string;
9
+ export declare const FOREIGN_KEY_DNE_ERROR: (tableName: string) => string;
10
+ export declare const FOREIGN_KEY_REFERENCES_LENGTH_ERROR: (tableName: string) => string;
11
+ export declare const FOREIGN_KEY_REFERENCES_EMPTY_ERROR: (tableName: string) => string;
@@ -0,0 +1,65 @@
1
+ import { bold, cyan, green, red, yellow } from "kleur/colors";
2
+ const MISSING_SESSION_ID_ERROR = `${red("\u25B6 Login required!")}
3
+
4
+ To authenticate with Astro Studio, run
5
+ ${cyan("astro db login")}
6
+ `;
7
+ const MISSING_PROJECT_ID_ERROR = `${red("\u25B6 Directory not linked.")}
8
+
9
+ To link this directory to an Astro Studio project, run
10
+ ${cyan("astro db link")}
11
+ `;
12
+ const MISSING_EXECUTE_PATH_ERROR = `${red(
13
+ "\u25B6 No file path provided."
14
+ )} Provide a path by running ${cyan("astro db execute <path>")}
15
+ `;
16
+ const RENAME_TABLE_ERROR = (oldTable, newTable) => {
17
+ return red("\u25B6 Potential table rename detected: " + oldTable + ", " + newTable) + `
18
+ You cannot add and remove tables in the same schema update batch.
19
+ To resolve, add a 'deprecated: true' flag to '${oldTable}' instead.`;
20
+ };
21
+ const RENAME_COLUMN_ERROR = (oldSelector, newSelector) => {
22
+ return red("\u25B6 Potential column rename detected: " + oldSelector + ", " + newSelector) + `
23
+ You cannot add and remove columns in the same table.
24
+ To resolve, add a 'deprecated: true' flag to '${oldSelector}' instead.`;
25
+ };
26
+ const FILE_NOT_FOUND_ERROR = (path) => `${red("\u25B6 File not found:")} ${bold(path)}
27
+ `;
28
+ const SEED_ERROR = (error) => {
29
+ return `${red(`Error while seeding database:`)}
30
+
31
+ ${error}`;
32
+ };
33
+ const REFERENCE_DNE_ERROR = (columnName) => {
34
+ return `Column ${bold(
35
+ columnName
36
+ )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
37
+ };
38
+ const FOREIGN_KEY_DNE_ERROR = (tableName) => {
39
+ return `Table ${bold(
40
+ tableName
41
+ )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
42
+ };
43
+ const FOREIGN_KEY_REFERENCES_LENGTH_ERROR = (tableName) => {
44
+ return `Foreign key on ${bold(
45
+ tableName
46
+ )} is misconfigured. \`columns\` and \`references\` must be the same length.`;
47
+ };
48
+ const FOREIGN_KEY_REFERENCES_EMPTY_ERROR = (tableName) => {
49
+ return `Foreign key on ${bold(
50
+ tableName
51
+ )} is misconfigured. \`references\` array cannot be empty.`;
52
+ };
53
+ export {
54
+ FILE_NOT_FOUND_ERROR,
55
+ FOREIGN_KEY_DNE_ERROR,
56
+ FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
57
+ FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
58
+ MISSING_EXECUTE_PATH_ERROR,
59
+ MISSING_PROJECT_ID_ERROR,
60
+ MISSING_SESSION_ID_ERROR,
61
+ REFERENCE_DNE_ERROR,
62
+ RENAME_COLUMN_ERROR,
63
+ RENAME_TABLE_ERROR,
64
+ SEED_ERROR
65
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This is a modified version of Astro's error map. source:
3
+ * https://github.com/withastro/astro/blob/main/packages/astro/src/content/error-map.ts
4
+ */
5
+ import type { z } from 'astro/zod';
6
+ export declare const errorMap: z.ZodErrorMap;
@@ -0,0 +1,79 @@
1
+ const errorMap = (baseError, ctx) => {
2
+ const baseErrorPath = flattenErrorPath(baseError.path);
3
+ if (baseError.code === "invalid_union") {
4
+ const typeOrLiteralErrByPath = /* @__PURE__ */ new Map();
5
+ for (const unionError of baseError.unionErrors.flatMap((e) => e.errors)) {
6
+ if (unionError.code === "invalid_type" || unionError.code === "invalid_literal") {
7
+ const flattenedErrorPath = flattenErrorPath(unionError.path);
8
+ const typeOrLiteralErr = typeOrLiteralErrByPath.get(flattenedErrorPath);
9
+ if (typeOrLiteralErr) {
10
+ typeOrLiteralErr.expected.push(unionError.expected);
11
+ } else {
12
+ typeOrLiteralErrByPath.set(flattenedErrorPath, {
13
+ code: unionError.code,
14
+ received: unionError.received,
15
+ expected: [unionError.expected]
16
+ });
17
+ }
18
+ }
19
+ }
20
+ const messages = [
21
+ prefix(
22
+ baseErrorPath,
23
+ typeOrLiteralErrByPath.size ? "Did not match union:" : "Did not match union."
24
+ )
25
+ ];
26
+ return {
27
+ message: messages.concat(
28
+ [...typeOrLiteralErrByPath.entries()].filter(([, error]) => error.expected.length === baseError.unionErrors.length).map(
29
+ ([key, error]) => (
30
+ // Avoid printing the key again if it's a base error
31
+ key === baseErrorPath ? `> ${getTypeOrLiteralMsg(error)}` : `> ${prefix(key, getTypeOrLiteralMsg(error))}`
32
+ )
33
+ )
34
+ ).join("\n")
35
+ };
36
+ }
37
+ if (baseError.code === "invalid_literal" || baseError.code === "invalid_type") {
38
+ return {
39
+ message: prefix(
40
+ baseErrorPath,
41
+ getTypeOrLiteralMsg({
42
+ code: baseError.code,
43
+ received: baseError.received,
44
+ expected: [baseError.expected]
45
+ })
46
+ )
47
+ };
48
+ } else if (baseError.message) {
49
+ return { message: prefix(baseErrorPath, baseError.message) };
50
+ } else {
51
+ return { message: prefix(baseErrorPath, ctx.defaultError) };
52
+ }
53
+ };
54
+ const getTypeOrLiteralMsg = (error) => {
55
+ if (error.received === "undefined")
56
+ return "Required";
57
+ const expectedDeduped = new Set(error.expected);
58
+ switch (error.code) {
59
+ case "invalid_type":
60
+ return `Expected type \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
61
+ error.received
62
+ )}`;
63
+ case "invalid_literal":
64
+ return `Expected \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
65
+ error.received
66
+ )}`;
67
+ }
68
+ };
69
+ const prefix = (key, msg) => key.length ? `**${key}**: ${msg}` : msg;
70
+ const unionExpectedVals = (expectedVals) => [...expectedVals].map((expectedVal, idx) => {
71
+ if (idx === 0)
72
+ return JSON.stringify(expectedVal);
73
+ const sep = " | ";
74
+ return `${sep}${JSON.stringify(expectedVal)}`;
75
+ }).join("");
76
+ const flattenErrorPath = (errorPath) => errorPath.join(".");
77
+ export {
78
+ errorMap
79
+ };
@@ -0,0 +1,2 @@
1
+ import type { AstroIntegration } from 'astro';
2
+ export declare function fileURLIntegration(): AstroIntegration;