@astrojs/db 0.9.6 → 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.6"}`
30
+ `v${"0.9.7"}`
31
31
  )} ${headline}`
32
32
  );
33
33
  }
@@ -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)},
@@ -91,7 +91,7 @@ ${shouldSeed ? `await seedLocal({
91
91
 
92
92
  export * from ${RUNTIME_CONFIG_IMPORT};
93
93
 
94
- ${getStringifiedCollectionExports(tables)}`;
94
+ ${getStringifiedTableExports(tables)}`;
95
95
  }
96
96
  function getStudioVirtualModContents({
97
97
  tables,
@@ -116,13 +116,13 @@ export const db = await createRemoteDatabaseClient(${appTokenArg()}, ${dbUrlArg(
116
116
 
117
117
  export * from ${RUNTIME_CONFIG_IMPORT};
118
118
 
119
- ${getStringifiedCollectionExports(tables)}
119
+ ${getStringifiedTableExports(tables)}
120
120
  `;
121
121
  }
122
- function getStringifiedCollectionExports(tables) {
122
+ function getStringifiedTableExports(tables) {
123
123
  return Object.entries(tables).map(
124
- ([name, collection]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
125
- collection
124
+ ([name, table]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
125
+ table
126
126
  )}, false)`
127
127
  ).join("\n");
128
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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/db",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",