@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.
- package/dist/_internal/core/types.d.ts +0 -2
- package/dist/core/cli/migration-queries.d.ts +4 -4
- package/dist/core/cli/migration-queries.js +70 -77
- package/dist/core/cli/print-help.js +1 -1
- package/dist/core/integration/typegen.js +3 -3
- package/dist/core/integration/vite-plugin-db.js +5 -5
- package/dist/core/schemas.js +2 -2
- package/dist/core/types.d.ts +0 -2
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
38
|
-
const droppedTables =
|
|
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(
|
|
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 [
|
|
51
|
-
queries.push(getCreateTableQuery(
|
|
52
|
-
queries.push(...getCreateIndexQueries(
|
|
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 [
|
|
55
|
-
const dropQuery = `DROP TABLE ${sqlite.escapeName(
|
|
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 [
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
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(
|
|
63
|
-
const droppedColumns = getDropped(
|
|
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
|
-
`${
|
|
71
|
-
`${
|
|
68
|
+
`${tableName}.${Object.keys(addedColumns)[0]}`,
|
|
69
|
+
`${tableName}.${Object.keys(notDeprecatedDroppedColumns)[0]}`
|
|
72
70
|
)
|
|
73
71
|
);
|
|
74
72
|
}
|
|
75
|
-
const result = await
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
async function getTableChangeQueries({
|
|
84
|
+
tableName,
|
|
85
|
+
oldTable,
|
|
86
|
+
newTable
|
|
89
87
|
}) {
|
|
90
88
|
const queries = [];
|
|
91
89
|
const confirmations = [];
|
|
92
|
-
const updated = getUpdatedColumns(
|
|
93
|
-
const added = getAdded(
|
|
94
|
-
const dropped = getDropped(
|
|
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
|
-
|
|
102
|
-
oldIndexes:
|
|
103
|
-
newIndexes:
|
|
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(
|
|
106
|
+
...getAlterTableQueries(tableName, added, dropped),
|
|
111
107
|
...getChangeIndexQueries({
|
|
112
|
-
|
|
113
|
-
oldIndexes:
|
|
114
|
-
newIndexes:
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
139
|
-
|
|
134
|
+
tableName,
|
|
135
|
+
newTable,
|
|
140
136
|
added,
|
|
141
137
|
hasDataLoss: dataLossCheck.dataLoss,
|
|
142
138
|
migrateHiddenPrimaryKey: !primaryKeyExists && !droppedPrimaryKey
|
|
143
139
|
});
|
|
144
|
-
queries.push(...recreateTableQueries, ...getCreateIndexQueries(
|
|
140
|
+
queries.push(...recreateTableQueries, ...getCreateIndexQueries(tableName, newTable));
|
|
145
141
|
return { queries, confirmations };
|
|
146
142
|
}
|
|
147
143
|
function getChangeIndexQueries({
|
|
148
|
-
|
|
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(
|
|
158
|
+
queries.push(...getCreateIndexQueries(tableName, { indexes: added }));
|
|
163
159
|
return queries;
|
|
164
160
|
}
|
|
165
|
-
function
|
|
161
|
+
function getAddedTables(oldTables, newTables) {
|
|
166
162
|
const added = {};
|
|
167
|
-
for (const [key,
|
|
168
|
-
if (!(key in
|
|
169
|
-
added[key] =
|
|
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
|
|
169
|
+
function getDroppedTables(oldTables, newTables) {
|
|
174
170
|
const dropped = {};
|
|
175
|
-
for (const [key,
|
|
176
|
-
if (!(key in
|
|
177
|
-
dropped[key] =
|
|
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(
|
|
177
|
+
function getAlterTableQueries(unescTableName, added, dropped) {
|
|
182
178
|
const queries = [];
|
|
183
|
-
const
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
202
|
-
|
|
197
|
+
tableName: unescTableName,
|
|
198
|
+
newTable,
|
|
203
199
|
added,
|
|
204
200
|
hasDataLoss,
|
|
205
201
|
migrateHiddenPrimaryKey
|
|
206
202
|
}) {
|
|
207
|
-
const unescTempName = `${
|
|
203
|
+
const unescTempName = `${unescTableName}_${genTempTableName()}`;
|
|
208
204
|
const tempName = sqlite.escapeName(unescTempName);
|
|
209
|
-
const
|
|
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(
|
|
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,
|
|
223
|
-
`INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${
|
|
224
|
-
`DROP TABLE ${
|
|
225
|
-
`ALTER TABLE ${tempName} RENAME TO ${
|
|
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
|
|
358
|
-
const dropQuery =
|
|
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
|
};
|
|
@@ -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,
|
|
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,
|
|
22
|
-
const sanitizedColumnsList = Object.entries(
|
|
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
|
-
${
|
|
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
|
-
${
|
|
119
|
+
${getStringifiedTableExports(tables)}
|
|
120
120
|
`;
|
|
121
121
|
}
|
|
122
|
-
function
|
|
122
|
+
function getStringifiedTableExports(tables) {
|
|
123
123
|
return Object.entries(tables).map(
|
|
124
|
-
([name,
|
|
125
|
-
|
|
124
|
+
([name, table]) => `export const ${name} = asDrizzleTable(${JSON.stringify(name)}, ${JSON.stringify(
|
|
125
|
+
table
|
|
126
126
|
)}, false)`
|
|
127
127
|
).join("\n");
|
|
128
128
|
}
|
package/dist/core/schemas.js
CHANGED
|
@@ -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 `
|
|
18
|
+
// Defined when `defineDb()` is called to resolve `references`
|
|
19
19
|
name: z.string().optional(),
|
|
20
|
-
// TODO:
|
|
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({
|
package/dist/core/types.d.ts
CHANGED
|
@@ -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 {
|
|
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';
|