@astrojs/db 0.9.5 → 0.9.7

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.
@@ -38,8 +38,6 @@ export interface TableConfig<TColumns extends ColumnsConfig = ColumnsConfig> ext
38
38
  interface IndexConfig<TColumns extends ColumnsConfig> extends z.input<typeof indexSchema> {
39
39
  on: MaybeArray<Extract<keyof TColumns, string>>;
40
40
  }
41
- /** @deprecated Use `TableConfig` instead */
42
- export type ResolvedCollectionConfig<TColumns extends ColumnsConfig = ColumnsConfig> = TableConfig<TColumns>;
43
41
  export type NumberColumnOpts = z.input<typeof numberColumnOptsSchema>;
44
42
  export type TextColumnOpts = z.input<typeof textColumnOptsSchema>;
45
43
  export type AstroDbIntegration = AstroIntegration & {
@@ -7,10 +7,10 @@ export declare function getMigrationQueries({ oldSnapshot, newSnapshot, reset, }
7
7
  queries: string[];
8
8
  confirmations: string[];
9
9
  }>;
10
- export declare function getCollectionChangeQueries({ collectionName, oldCollection, newCollection, }: {
11
- collectionName: string;
12
- oldCollection: DBTable;
13
- newCollection: DBTable;
10
+ export declare function getTableChangeQueries({ tableName, oldTable, newTable, }: {
11
+ tableName: string;
12
+ oldTable: DBTable;
13
+ newTable: DBTable;
14
14
  }): Promise<{
15
15
  queries: string[];
16
16
  confirmations: string[];
@@ -7,6 +7,7 @@ import { hasPrimaryKey } from "../../runtime/index.js";
7
7
  import {
8
8
  getCreateIndexQueries,
9
9
  getCreateTableQuery,
10
+ getDropTableIfExistsQuery,
10
11
  getModifiers,
11
12
  getReferencesConfig,
12
13
  hasDefault,
@@ -34,84 +35,79 @@ async function getMigrationQueries({
34
35
  oldSnapshot = createEmptySnapshot();
35
36
  queries.push(...getDropTableQueriesForSnapshot(currentSnapshot));
36
37
  }
37
- const addedCollections = getAddedCollections(oldSnapshot, newSnapshot);
38
- const droppedTables = getDroppedCollections(oldSnapshot, newSnapshot);
38
+ const addedTables = getAddedTables(oldSnapshot, newSnapshot);
39
+ const droppedTables = getDroppedTables(oldSnapshot, newSnapshot);
39
40
  const notDeprecatedDroppedTables = Object.fromEntries(
40
41
  Object.entries(droppedTables).filter(([, table]) => !table.deprecated)
41
42
  );
42
- if (!isEmpty(addedCollections) && !isEmpty(notDeprecatedDroppedTables)) {
43
+ if (!isEmpty(addedTables) && !isEmpty(notDeprecatedDroppedTables)) {
43
44
  throw new Error(
44
- RENAME_TABLE_ERROR(
45
- Object.keys(addedCollections)[0],
46
- Object.keys(notDeprecatedDroppedTables)[0]
47
- )
45
+ RENAME_TABLE_ERROR(Object.keys(addedTables)[0], Object.keys(notDeprecatedDroppedTables)[0])
48
46
  );
49
47
  }
50
- for (const [collectionName, collection] of Object.entries(addedCollections)) {
51
- queries.push(getCreateTableQuery(collectionName, collection));
52
- queries.push(...getCreateIndexQueries(collectionName, collection));
48
+ for (const [tableName, table] of Object.entries(addedTables)) {
49
+ queries.push(getCreateTableQuery(tableName, table));
50
+ queries.push(...getCreateIndexQueries(tableName, table));
53
51
  }
54
- for (const [collectionName] of Object.entries(droppedTables)) {
55
- const dropQuery = `DROP TABLE ${sqlite.escapeName(collectionName)}`;
52
+ for (const [tableName] of Object.entries(droppedTables)) {
53
+ const dropQuery = `DROP TABLE ${sqlite.escapeName(tableName)}`;
56
54
  queries.push(dropQuery);
57
55
  }
58
- for (const [collectionName, newCollection] of Object.entries(newSnapshot.schema)) {
59
- const oldCollection = oldSnapshot.schema[collectionName];
60
- if (!oldCollection)
56
+ for (const [tableName, newTable] of Object.entries(newSnapshot.schema)) {
57
+ const oldTable = oldSnapshot.schema[tableName];
58
+ if (!oldTable)
61
59
  continue;
62
- const addedColumns = getAdded(oldCollection.columns, newCollection.columns);
63
- const droppedColumns = getDropped(oldCollection.columns, newCollection.columns);
60
+ const addedColumns = getAdded(oldTable.columns, newTable.columns);
61
+ const droppedColumns = getDropped(oldTable.columns, newTable.columns);
64
62
  const notDeprecatedDroppedColumns = Object.fromEntries(
65
63
  Object.entries(droppedColumns).filter(([, col]) => !col.schema.deprecated)
66
64
  );
67
65
  if (!isEmpty(addedColumns) && !isEmpty(notDeprecatedDroppedColumns)) {
68
66
  throw new Error(
69
67
  RENAME_COLUMN_ERROR(
70
- `${collectionName}.${Object.keys(addedColumns)[0]}`,
71
- `${collectionName}.${Object.keys(notDeprecatedDroppedColumns)[0]}`
68
+ `${tableName}.${Object.keys(addedColumns)[0]}`,
69
+ `${tableName}.${Object.keys(notDeprecatedDroppedColumns)[0]}`
72
70
  )
73
71
  );
74
72
  }
75
- const result = await getCollectionChangeQueries({
76
- collectionName,
77
- oldCollection,
78
- newCollection
73
+ const result = await getTableChangeQueries({
74
+ tableName,
75
+ oldTable,
76
+ newTable
79
77
  });
80
78
  queries.push(...result.queries);
81
79
  confirmations.push(...result.confirmations);
82
80
  }
83
81
  return { queries, confirmations };
84
82
  }
85
- async function getCollectionChangeQueries({
86
- collectionName,
87
- oldCollection,
88
- newCollection
83
+ async function getTableChangeQueries({
84
+ tableName,
85
+ oldTable,
86
+ newTable
89
87
  }) {
90
88
  const queries = [];
91
89
  const confirmations = [];
92
- const updated = getUpdatedColumns(oldCollection.columns, newCollection.columns);
93
- const added = getAdded(oldCollection.columns, newCollection.columns);
94
- const dropped = getDropped(oldCollection.columns, newCollection.columns);
95
- const hasForeignKeyChanges = Boolean(
96
- deepDiff(oldCollection.foreignKeys, newCollection.foreignKeys)
97
- );
90
+ const updated = getUpdatedColumns(oldTable.columns, newTable.columns);
91
+ const added = getAdded(oldTable.columns, newTable.columns);
92
+ const dropped = getDropped(oldTable.columns, newTable.columns);
93
+ const hasForeignKeyChanges = Boolean(deepDiff(oldTable.foreignKeys, newTable.foreignKeys));
98
94
  if (!hasForeignKeyChanges && isEmpty(updated) && isEmpty(added) && isEmpty(dropped)) {
99
95
  return {
100
96
  queries: getChangeIndexQueries({
101
- collectionName,
102
- oldIndexes: oldCollection.indexes,
103
- newIndexes: newCollection.indexes
97
+ tableName,
98
+ oldIndexes: oldTable.indexes,
99
+ newIndexes: newTable.indexes
104
100
  }),
105
101
  confirmations
106
102
  };
107
103
  }
108
104
  if (!hasForeignKeyChanges && isEmpty(updated) && Object.values(dropped).every(canAlterTableDropColumn) && Object.values(added).every(canAlterTableAddColumn)) {
109
105
  queries.push(
110
- ...getAlterTableQueries(collectionName, added, dropped),
106
+ ...getAlterTableQueries(tableName, added, dropped),
111
107
  ...getChangeIndexQueries({
112
- collectionName,
113
- oldIndexes: oldCollection.indexes,
114
- newIndexes: newCollection.indexes
108
+ tableName,
109
+ oldIndexes: oldTable.indexes,
110
+ newIndexes: newTable.indexes
115
111
  })
116
112
  );
117
113
  return { queries, confirmations };
@@ -121,31 +117,31 @@ async function getCollectionChangeQueries({
121
117
  const { reason, columnName } = dataLossCheck;
122
118
  const reasonMsgs = {
123
119
  "added-required": `You added new required column '${color.bold(
124
- collectionName + "." + columnName
120
+ tableName + "." + columnName
125
121
  )}' with no default value.
126
122
  This cannot be executed on an existing table.`,
127
123
  "updated-type": `Updating existing column ${color.bold(
128
- collectionName + "." + columnName
124
+ tableName + "." + columnName
129
125
  )} to a new type that cannot be handled automatically.`
130
126
  };
131
127
  confirmations.push(reasonMsgs[reason]);
132
128
  }
133
- const primaryKeyExists = Object.entries(newCollection.columns).find(
129
+ const primaryKeyExists = Object.entries(newTable.columns).find(
134
130
  ([, column]) => hasPrimaryKey(column)
135
131
  );
136
132
  const droppedPrimaryKey = Object.entries(dropped).find(([, column]) => hasPrimaryKey(column));
137
133
  const recreateTableQueries = getRecreateTableQueries({
138
- collectionName,
139
- newCollection,
134
+ tableName,
135
+ newTable,
140
136
  added,
141
137
  hasDataLoss: dataLossCheck.dataLoss,
142
138
  migrateHiddenPrimaryKey: !primaryKeyExists && !droppedPrimaryKey
143
139
  });
144
- queries.push(...recreateTableQueries, ...getCreateIndexQueries(collectionName, newCollection));
140
+ queries.push(...recreateTableQueries, ...getCreateIndexQueries(tableName, newTable));
145
141
  return { queries, confirmations };
146
142
  }
147
143
  function getChangeIndexQueries({
148
- collectionName,
144
+ tableName,
149
145
  oldIndexes = {},
150
146
  newIndexes = {}
151
147
  }) {
@@ -159,32 +155,32 @@ function getChangeIndexQueries({
159
155
  const dropQuery = `DROP INDEX ${sqlite.escapeName(indexName)}`;
160
156
  queries.push(dropQuery);
161
157
  }
162
- queries.push(...getCreateIndexQueries(collectionName, { indexes: added }));
158
+ queries.push(...getCreateIndexQueries(tableName, { indexes: added }));
163
159
  return queries;
164
160
  }
165
- function getAddedCollections(oldCollections, newCollections) {
161
+ function getAddedTables(oldTables, newTables) {
166
162
  const added = {};
167
- for (const [key, newCollection] of Object.entries(newCollections.schema)) {
168
- if (!(key in oldCollections.schema))
169
- added[key] = newCollection;
163
+ for (const [key, newTable] of Object.entries(newTables.schema)) {
164
+ if (!(key in oldTables.schema))
165
+ added[key] = newTable;
170
166
  }
171
167
  return added;
172
168
  }
173
- function getDroppedCollections(oldCollections, newCollections) {
169
+ function getDroppedTables(oldTables, newTables) {
174
170
  const dropped = {};
175
- for (const [key, oldCollection] of Object.entries(oldCollections.schema)) {
176
- if (!(key in newCollections.schema))
177
- dropped[key] = oldCollection;
171
+ for (const [key, oldTable] of Object.entries(oldTables.schema)) {
172
+ if (!(key in newTables.schema))
173
+ dropped[key] = oldTable;
178
174
  }
179
175
  return dropped;
180
176
  }
181
- function getAlterTableQueries(unescapedCollectionName, added, dropped) {
177
+ function getAlterTableQueries(unescTableName, added, dropped) {
182
178
  const queries = [];
183
- const collectionName = sqlite.escapeName(unescapedCollectionName);
179
+ const tableName = sqlite.escapeName(unescTableName);
184
180
  for (const [unescColumnName, column] of Object.entries(added)) {
185
181
  const columnName = sqlite.escapeName(unescColumnName);
186
182
  const type = schemaTypeToSqlType(column.type);
187
- const q = `ALTER TABLE ${collectionName} ADD COLUMN ${columnName} ${type}${getModifiers(
183
+ const q = `ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${type}${getModifiers(
188
184
  columnName,
189
185
  column
190
186
  )}`;
@@ -192,37 +188,34 @@ function getAlterTableQueries(unescapedCollectionName, added, dropped) {
192
188
  }
193
189
  for (const unescColumnName of Object.keys(dropped)) {
194
190
  const columnName = sqlite.escapeName(unescColumnName);
195
- const q = `ALTER TABLE ${collectionName} DROP COLUMN ${columnName}`;
191
+ const q = `ALTER TABLE ${tableName} DROP COLUMN ${columnName}`;
196
192
  queries.push(q);
197
193
  }
198
194
  return queries;
199
195
  }
200
196
  function getRecreateTableQueries({
201
- collectionName: unescCollectionName,
202
- newCollection,
197
+ tableName: unescTableName,
198
+ newTable,
203
199
  added,
204
200
  hasDataLoss,
205
201
  migrateHiddenPrimaryKey
206
202
  }) {
207
- const unescTempName = `${unescCollectionName}_${genTempTableName()}`;
203
+ const unescTempName = `${unescTableName}_${genTempTableName()}`;
208
204
  const tempName = sqlite.escapeName(unescTempName);
209
- const collectionName = sqlite.escapeName(unescCollectionName);
205
+ const tableName = sqlite.escapeName(unescTableName);
210
206
  if (hasDataLoss) {
211
- return [
212
- `DROP TABLE ${collectionName}`,
213
- getCreateTableQuery(unescCollectionName, newCollection)
214
- ];
207
+ return [`DROP TABLE ${tableName}`, getCreateTableQuery(unescTableName, newTable)];
215
208
  }
216
- const newColumns = [...Object.keys(newCollection.columns)];
209
+ const newColumns = [...Object.keys(newTable.columns)];
217
210
  if (migrateHiddenPrimaryKey) {
218
211
  newColumns.unshift("_id");
219
212
  }
220
213
  const escapedColumns = newColumns.filter((i) => !(i in added)).map((c) => sqlite.escapeName(c)).join(", ");
221
214
  return [
222
- getCreateTableQuery(unescTempName, newCollection),
223
- `INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${collectionName}`,
224
- `DROP TABLE ${collectionName}`,
225
- `ALTER TABLE ${tempName} RENAME TO ${collectionName}`
215
+ getCreateTableQuery(unescTempName, newTable),
216
+ `INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${tableName}`,
217
+ `DROP TABLE ${tableName}`,
218
+ `ALTER TABLE ${tempName} RENAME TO ${tableName}`
226
219
  ];
227
220
  }
228
221
  function isEmpty(obj) {
@@ -354,8 +347,8 @@ async function getProductionCurrentSnapshot({
354
347
  }
355
348
  function getDropTableQueriesForSnapshot(snapshot) {
356
349
  const queries = [];
357
- for (const collectionName of Object.keys(snapshot.schema)) {
358
- const dropQuery = `DROP TABLE ${sqlite.escapeName(collectionName)}`;
350
+ for (const tableName of Object.keys(snapshot.schema)) {
351
+ const dropQuery = getDropTableIfExistsQuery(tableName);
359
352
  queries.unshift(dropQuery);
360
353
  }
361
354
  return queries;
@@ -387,7 +380,7 @@ export {
387
380
  createCurrentSnapshot,
388
381
  createEmptySnapshot,
389
382
  formatDataLossMessage,
390
- getCollectionChangeQueries,
391
383
  getMigrationQueries,
392
- getProductionCurrentSnapshot
384
+ getProductionCurrentSnapshot,
385
+ getTableChangeQueries
393
386
  };
@@ -27,7 +27,7 @@ function printHelp({
27
27
  message.push(
28
28
  linebreak(),
29
29
  ` ${bgGreen(black(` ${commandName} `))} ${green(
30
- `v${"0.9.5"}`
30
+ `v${"0.9.7"}`
31
31
  )} ${headline}`
32
32
  );
33
33
  }
@@ -5,12 +5,6 @@ export declare const RENAME_TABLE_ERROR: (oldTable: string, newTable: string) =>
5
5
  export declare const RENAME_COLUMN_ERROR: (oldSelector: string, newSelector: string) => string;
6
6
  export declare const FILE_NOT_FOUND_ERROR: (path: string) => string;
7
7
  export declare const SHELL_QUERY_MISSING_ERROR: string;
8
- export declare const SEED_ERROR: (error: string) => string;
9
8
  export declare const EXEC_ERROR: (error: string) => string;
10
- export declare const SEED_DEFAULT_EXPORT_ERROR: (fileName: string) => string;
11
9
  export declare const EXEC_DEFAULT_EXPORT_ERROR: (fileName: string) => string;
12
- export declare const REFERENCE_DNE_ERROR: (columnName: string) => string;
13
- export declare const FOREIGN_KEY_DNE_ERROR: (tableName: string) => string;
14
- export declare const FOREIGN_KEY_REFERENCES_LENGTH_ERROR: (tableName: string) => string;
15
- export declare const FOREIGN_KEY_REFERENCES_EMPTY_ERROR: (tableName: string) => string;
16
10
  export declare const INTEGRATION_TABLE_CONFLICT_ERROR: (integrationName: string, tableName: string, isUserConflict: boolean) => string;
@@ -29,42 +29,14 @@ const SHELL_QUERY_MISSING_ERROR = `${red(
29
29
  "\u25B6 Please provide a query to execute using the --query flag."
30
30
  )}
31
31
  `;
32
- const SEED_ERROR = (error) => {
33
- return `${red(`Error while seeding database:`)}
34
-
35
- ${error}`;
36
- };
37
32
  const EXEC_ERROR = (error) => {
38
33
  return `${red(`Error while executing file:`)}
39
34
 
40
35
  ${error}`;
41
36
  };
42
- const SEED_DEFAULT_EXPORT_ERROR = (fileName) => {
43
- return SEED_ERROR(`Missing default function export in ${bold(fileName)}`);
44
- };
45
37
  const EXEC_DEFAULT_EXPORT_ERROR = (fileName) => {
46
38
  return EXEC_ERROR(`Missing default function export in ${bold(fileName)}`);
47
39
  };
48
- const REFERENCE_DNE_ERROR = (columnName) => {
49
- return `Column ${bold(
50
- columnName
51
- )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
52
- };
53
- const FOREIGN_KEY_DNE_ERROR = (tableName) => {
54
- return `Table ${bold(
55
- tableName
56
- )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
57
- };
58
- const FOREIGN_KEY_REFERENCES_LENGTH_ERROR = (tableName) => {
59
- return `Foreign key on ${bold(
60
- tableName
61
- )} is misconfigured. \`columns\` and \`references\` must be the same length.`;
62
- };
63
- const FOREIGN_KEY_REFERENCES_EMPTY_ERROR = (tableName) => {
64
- return `Foreign key on ${bold(
65
- tableName
66
- )} is misconfigured. \`references\` array cannot be empty.`;
67
- };
68
40
  const INTEGRATION_TABLE_CONFLICT_ERROR = (integrationName, tableName, isUserConflict) => {
69
41
  return red("\u25B6 Conflicting table name in integration " + bold(integrationName)) + isUserConflict ? `
70
42
  A user-defined table named ${bold(tableName)} already exists` : `
@@ -74,17 +46,11 @@ export {
74
46
  EXEC_DEFAULT_EXPORT_ERROR,
75
47
  EXEC_ERROR,
76
48
  FILE_NOT_FOUND_ERROR,
77
- FOREIGN_KEY_DNE_ERROR,
78
- FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
79
- FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
80
49
  INTEGRATION_TABLE_CONFLICT_ERROR,
81
50
  MISSING_EXECUTE_PATH_ERROR,
82
51
  MISSING_PROJECT_ID_ERROR,
83
52
  MISSING_SESSION_ID_ERROR,
84
- REFERENCE_DNE_ERROR,
85
53
  RENAME_COLUMN_ERROR,
86
54
  RENAME_TABLE_ERROR,
87
- SEED_DEFAULT_EXPORT_ERROR,
88
- SEED_ERROR,
89
55
  SHELL_QUERY_MISSING_ERROR
90
56
  };
@@ -1,8 +1,10 @@
1
1
  import { existsSync } from "fs";
2
2
  import { dirname } from "path";
3
3
  import { fileURLToPath } from "url";
4
+ import { AstroError } from "astro/errors";
4
5
  import { mkdir, writeFile } from "fs/promises";
5
6
  import { blue, yellow } from "kleur/colors";
7
+ import { loadEnv } from "vite";
6
8
  import parseArgs from "yargs-parser";
7
9
  import { CONFIG_FILE_NAMES, DB_PATH } from "../consts.js";
8
10
  import { resolveDbConfig } from "../load-file.js";
@@ -28,12 +30,14 @@ function astroDBIntegration() {
28
30
  }
29
31
  };
30
32
  let command;
33
+ let output = "server";
31
34
  return {
32
35
  name: "astro:db",
33
36
  hooks: {
34
37
  "astro:config:setup": async ({ updateConfig, config, command: _command, logger }) => {
35
38
  command = _command;
36
39
  root = config.root;
40
+ output = config.output;
37
41
  if (command === "preview")
38
42
  return;
39
43
  let dbPlugin = void 0;
@@ -98,6 +102,11 @@ function astroDBIntegration() {
98
102
  });
99
103
  },
100
104
  "astro:build:start": async ({ logger }) => {
105
+ if (!connectToStudio && !databaseFileEnvDefined() && (output === "server" || output === "hybrid")) {
106
+ const message = `Attempting to build without the --remote flag or the ASTRO_DATABASE_FILE environment variable defined. You probably want to pass --remote to astro build.`;
107
+ const hint = "Learn more connecting to Studio: https://docs.astro.build/en/guides/astro-db/#connect-to-astro-studio";
108
+ throw new AstroError(message, hint);
109
+ }
101
110
  logger.info("database: " + (connectToStudio ? yellow("remote") : blue("local database.")));
102
111
  },
103
112
  "astro:build:done": async ({}) => {
@@ -106,6 +115,10 @@ function astroDBIntegration() {
106
115
  }
107
116
  };
108
117
  }
118
+ function databaseFileEnvDefined() {
119
+ const env = loadEnv("", process.cwd());
120
+ return env.ASTRO_DATABASE_FILE != null || process.env.ASTRO_DATABASE_FILE != null;
121
+ }
109
122
  function integration() {
110
123
  return [astroDBIntegration(), fileURLIntegration()];
111
124
  }
@@ -9,7 +9,7 @@ async function typegen(astroConfig) {
9
9
  async function typegenInternal({ tables, root }) {
10
10
  const content = `// This file is generated by Astro DB
11
11
  declare module 'astro:db' {
12
- ${Object.entries(tables).map(([name, collection]) => generateTableType(name, collection)).join("\n")}
12
+ ${Object.entries(tables).map(([name, table]) => generateTableType(name, table)).join("\n")}
13
13
  }
14
14
  `;
15
15
  const dotAstroDir = new URL(".astro/", root);
@@ -18,8 +18,8 @@ ${Object.entries(tables).map(([name, collection]) => generateTableType(name, col
18
18
  }
19
19
  await writeFile(new URL(DB_TYPES_FILE, dotAstroDir), content);
20
20
  }
21
- function generateTableType(name, collection) {
22
- const sanitizedColumnsList = Object.entries(collection.columns).filter(([, val]) => !val.schema.deprecated);
21
+ function generateTableType(name, table) {
22
+ const sanitizedColumnsList = Object.entries(table.columns).filter(([, val]) => !val.schema.deprecated);
23
23
  const sanitizedColumns = Object.fromEntries(sanitizedColumnsList);
24
24
  let tableType = ` export const ${name}: import(${RUNTIME_IMPORT}).Table<
25
25
  ${JSON.stringify(name)},
@@ -78,7 +78,8 @@ import { asDrizzleTable, createLocalDatabaseClient } from ${RUNTIME_IMPORT};
78
78
  ${shouldSeed ? `import { seedLocal } from ${RUNTIME_IMPORT};` : ""}
79
79
  ${shouldSeed ? integrationSeedImportStatements.join("\n") : ""}
80
80
 
81
- const dbUrl = ${JSON.stringify(dbUrl)};
81
+ const dbUrl = import.meta.env.ASTRO_DATABASE_FILE ?? ${JSON.stringify(dbUrl)};
82
+
82
83
  export const db = createLocalDatabaseClient({ dbUrl });
83
84
 
84
85
  ${shouldSeed ? `await seedLocal({
@@ -90,7 +91,7 @@ ${shouldSeed ? `await seedLocal({
90
91
 
91
92
  export * from ${RUNTIME_CONFIG_IMPORT};
92
93
 
93
- ${getStringifiedCollectionExports(tables)}`;
94
+ ${getStringifiedTableExports(tables)}`;
94
95
  }
95
96
  function getStudioVirtualModContents({
96
97
  tables,
@@ -115,13 +116,13 @@ export const db = await createRemoteDatabaseClient(${appTokenArg()}, ${dbUrlArg(
115
116
 
116
117
  export * from ${RUNTIME_CONFIG_IMPORT};
117
118
 
118
- ${getStringifiedCollectionExports(tables)}
119
+ ${getStringifiedTableExports(tables)}
119
120
  `;
120
121
  }
121
- function getStringifiedCollectionExports(tables) {
122
+ function getStringifiedTableExports(tables) {
122
123
  return Object.entries(tables).map(
123
- ([name, collection]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
124
- collection
124
+ ([name, table]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
125
+ table
125
126
  )}, false)`
126
127
  ).join("\n");
127
128
  }
@@ -15,9 +15,9 @@ const baseColumnSchema = z.object({
15
15
  optional: z.boolean().optional().default(false),
16
16
  unique: z.boolean().optional().default(false),
17
17
  deprecated: z.boolean().optional().default(false),
18
- // Defined when `defineReadableTable()` is called
18
+ // Defined when `defineDb()` is called to resolve `references`
19
19
  name: z.string().optional(),
20
- // TODO: rename to `tableName`. Breaking schema change
20
+ // TODO: Update to `table`. Will need migration file version change
21
21
  collection: z.string().optional()
22
22
  });
23
23
  const booleanColumnSchema = z.object({
@@ -38,8 +38,6 @@ export interface TableConfig<TColumns extends ColumnsConfig = ColumnsConfig> ext
38
38
  interface IndexConfig<TColumns extends ColumnsConfig> extends z.input<typeof indexSchema> {
39
39
  on: MaybeArray<Extract<keyof TColumns, string>>;
40
40
  }
41
- /** @deprecated Use `TableConfig` instead */
42
- export type ResolvedCollectionConfig<TColumns extends ColumnsConfig = ColumnsConfig> = TableConfig<TColumns>;
43
41
  export type NumberColumnOpts = z.input<typeof numberColumnOptsSchema>;
44
42
  export type TextColumnOpts = z.input<typeof textColumnOptsSchema>;
45
43
  export type AstroDbIntegration = AstroIntegration & {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { ResolvedCollectionConfig, TableConfig } from './core/types.js';
1
+ export type { TableConfig } from './core/types.js';
2
2
  export { cli } from './core/cli/index.js';
3
3
  export { integration as default } from './core/integration/index.js';
4
4
  export { typegen } from './core/integration/typegen.js';
@@ -0,0 +1,6 @@
1
+ export declare const FOREIGN_KEY_DNE_ERROR: (tableName: string) => string;
2
+ export declare const FOREIGN_KEY_REFERENCES_LENGTH_ERROR: (tableName: string) => string;
3
+ export declare const FOREIGN_KEY_REFERENCES_EMPTY_ERROR: (tableName: string) => string;
4
+ export declare const REFERENCE_DNE_ERROR: (columnName: string) => string;
5
+ export declare const SEED_ERROR: (error: string) => string;
6
+ export declare const SEED_DEFAULT_EXPORT_ERROR: (fileName: string) => string;
@@ -0,0 +1,37 @@
1
+ import { bold, red } from "kleur/colors";
2
+ const FOREIGN_KEY_DNE_ERROR = (tableName) => {
3
+ return `Table ${bold(
4
+ tableName
5
+ )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
6
+ };
7
+ const FOREIGN_KEY_REFERENCES_LENGTH_ERROR = (tableName) => {
8
+ return `Foreign key on ${bold(
9
+ tableName
10
+ )} is misconfigured. \`columns\` and \`references\` must be the same length.`;
11
+ };
12
+ const FOREIGN_KEY_REFERENCES_EMPTY_ERROR = (tableName) => {
13
+ return `Foreign key on ${bold(
14
+ tableName
15
+ )} is misconfigured. \`references\` array cannot be empty.`;
16
+ };
17
+ const REFERENCE_DNE_ERROR = (columnName) => {
18
+ return `Column ${bold(
19
+ columnName
20
+ )} references a table that does not exist. Did you apply the referenced table to the \`tables\` object in your db config?`;
21
+ };
22
+ const SEED_ERROR = (error) => {
23
+ return `${red(`Error while seeding database:`)}
24
+
25
+ ${error}`;
26
+ };
27
+ const SEED_DEFAULT_EXPORT_ERROR = (fileName) => {
28
+ return SEED_ERROR(`Missing default function export in ${bold(fileName)}`);
29
+ };
30
+ export {
31
+ FOREIGN_KEY_DNE_ERROR,
32
+ FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
33
+ FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
34
+ REFERENCE_DNE_ERROR,
35
+ SEED_DEFAULT_EXPORT_ERROR,
36
+ SEED_ERROR
37
+ };
@@ -6,7 +6,7 @@ import {
6
6
  FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
7
7
  FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
8
8
  REFERENCE_DNE_ERROR
9
- } from "../core/errors.js";
9
+ } from "./errors.js";
10
10
  import { hasPrimaryKey } from "./index.js";
11
11
  import { isSerializedSQL } from "./types.js";
12
12
  const sqlite = new SQLiteAsyncDialect();
@@ -1,8 +1,8 @@
1
1
  import { LibsqlError } from "@libsql/client";
2
2
  import { sql } from "drizzle-orm";
3
3
  import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
4
- import { SEED_DEFAULT_EXPORT_ERROR, SEED_ERROR } from "../core/errors.js";
5
4
  import {} from "../core/types.js";
5
+ import { SEED_DEFAULT_EXPORT_ERROR, SEED_ERROR } from "./errors.js";
6
6
  import { getCreateIndexQueries, getCreateTableQuery } from "./queries.js";
7
7
  const sqlite = new SQLiteAsyncDialect();
8
8
  async function seedLocal({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/db",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",