@astrojs/db 0.1.18 → 0.1.20
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/core/cli/commands/push/index.d.ts +6 -0
- package/dist/{cli → core/cli}/commands/push/index.js +43 -38
- package/dist/core/cli/commands/shell/index.d.ts +6 -0
- package/dist/{cli → core/cli}/commands/shell/index.js +4 -3
- package/dist/core/cli/commands/sync/index.d.ts +6 -0
- package/dist/{cli → core/cli}/commands/sync/index.js +2 -2
- package/dist/core/cli/commands/verify/index.d.ts +6 -0
- package/dist/{cli → core/cli}/commands/verify/index.js +1 -1
- package/dist/core/cli/index.d.ts +6 -0
- package/dist/core/cli/migration-queries.d.ts +18 -0
- package/dist/{cli/queries.js → core/cli/migration-queries.js} +68 -22
- package/dist/core/cli/migrations.d.ts +12 -0
- package/dist/core/consts.d.ts +6 -0
- package/dist/core/consts.js +17 -0
- package/dist/core/errors.d.ts +1 -0
- package/dist/core/errors.js +7 -0
- package/dist/core/integration/error-map.d.ts +6 -0
- package/dist/core/integration/file-url.d.ts +2 -0
- package/dist/core/integration/index.d.ts +2 -0
- package/dist/{integration.js → core/integration/index.js} +25 -19
- package/dist/core/integration/load-astro-config.d.ts +6 -0
- package/dist/core/integration/typegen.d.ts +5 -0
- package/dist/{typegen.js → core/integration/typegen.js} +4 -4
- package/dist/core/integration/vite-plugin-db.d.ts +20 -0
- package/dist/{vite-plugin-db.js → core/integration/vite-plugin-db.js} +9 -9
- package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +9 -0
- package/dist/{vite-plugin-inject-env-ts.js → core/integration/vite-plugin-inject-env-ts.js} +1 -1
- package/dist/core/queries.d.ts +19 -0
- package/dist/core/queries.js +151 -0
- package/dist/core/types.d.ts +2913 -0
- package/dist/{types.js → core/types.js} +66 -0
- package/dist/core/utils.d.ts +4 -0
- package/dist/core/utils.js +13 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.js +3 -3
- package/dist/runtime/db-client.d.ts +7 -0
- package/dist/runtime/db-client.js +90 -0
- package/dist/runtime/drizzle.d.ts +1 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.js +123 -0
- package/dist/runtime/types.d.ts +74 -0
- package/dist/runtime/types.js +0 -0
- package/package.json +17 -14
- package/dist/config.js +0 -72
- package/dist/consts.js +0 -21
- package/dist/errors.js +0 -15
- package/dist/internal.js +0 -308
- package/dist/utils-runtime.js +0 -52
- package/dist/utils.js +0 -39
- /package/dist/{cli → core/cli}/index.js +0 -0
- /package/dist/{migrations.js → core/cli/migrations.js} +0 -0
- /package/dist/{error-map.js → core/integration/error-map.js} +0 -0
- /package/dist/{file-url-integration.js → core/integration/file-url.js} +0 -0
- /package/dist/{load-astro-config.js → core/integration/load-astro-config.js} +0 -0
- /package/dist/{internal-drizzle.js → runtime/drizzle.js} +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { createClient } from "@libsql/client";
|
|
2
2
|
import deepDiff from "deep-diff";
|
|
3
|
-
import { eq, sql } from "drizzle-orm";
|
|
4
|
-
import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
|
|
5
|
-
import { appTokenError } from "../../../errors.js";
|
|
6
3
|
import { drizzle } from "drizzle-orm/sqlite-proxy";
|
|
4
|
+
import { appTokenError } from "../../../errors.js";
|
|
7
5
|
import {
|
|
8
6
|
createCurrentSnapshot,
|
|
9
7
|
createEmptySnapshot,
|
|
@@ -11,19 +9,11 @@ import {
|
|
|
11
9
|
initializeFromMigrations,
|
|
12
10
|
loadInitialSnapshot,
|
|
13
11
|
loadMigration
|
|
14
|
-
} from "
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
createRemoteDatabaseClient,
|
|
19
|
-
getAstroStudioEnv,
|
|
20
|
-
getRemoteDatabaseUrl,
|
|
21
|
-
migrationsTable
|
|
22
|
-
} from "../../../utils.js";
|
|
23
|
-
import { getMigrationQueries } from "../../queries.js";
|
|
24
|
-
import { setupDbTables } from "../../../internal.js";
|
|
12
|
+
} from "../../migrations.js";
|
|
13
|
+
import { getAstroStudioEnv, getRemoteDatabaseUrl } from "../../../utils.js";
|
|
14
|
+
import { getMigrationQueries } from "../../migration-queries.js";
|
|
15
|
+
import { setupDbTables } from "../../../queries.js";
|
|
25
16
|
const { diff } = deepDiff;
|
|
26
|
-
const sqliteDialect = new SQLiteAsyncDialect();
|
|
27
17
|
async function cmd({ config, flags }) {
|
|
28
18
|
const isSeedData = flags.seed;
|
|
29
19
|
const isDryRun = flags.dryRun;
|
|
@@ -45,20 +35,18 @@ async function cmd({ config, flags }) {
|
|
|
45
35
|
console.error(appTokenError);
|
|
46
36
|
process.exit(1);
|
|
47
37
|
}
|
|
48
|
-
const db = createRemoteDatabaseClient(appToken);
|
|
49
|
-
await db.run(
|
|
50
|
-
sql`CREATE TABLE IF NOT EXISTS ReservedAstroStudioMigrations ( name TEXT PRIMARY KEY )`
|
|
51
|
-
);
|
|
52
|
-
const allRemoteMigrations = await db.select().from(migrationsTable);
|
|
53
38
|
const allLocalMigrations = await getMigrations();
|
|
54
|
-
const missingMigrations =
|
|
55
|
-
|
|
39
|
+
const { data: missingMigrations } = await prepareMigrateQuery({
|
|
40
|
+
migrations: allLocalMigrations,
|
|
41
|
+
appToken
|
|
56
42
|
});
|
|
57
43
|
if (missingMigrations.length === 0) {
|
|
58
44
|
console.info("No migrations to push! Your database is up to date!");
|
|
59
|
-
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
if (missingMigrations.length > 0) {
|
|
60
48
|
console.log(`Pushing ${missingMigrations.length} migrations...`);
|
|
61
|
-
await pushSchema({ migrations: missingMigrations, appToken, isDryRun,
|
|
49
|
+
await pushSchema({ migrations: missingMigrations, appToken, isDryRun, currentSnapshot });
|
|
62
50
|
}
|
|
63
51
|
if (isSeedData) {
|
|
64
52
|
console.info("Pushing data...");
|
|
@@ -70,7 +58,6 @@ async function pushSchema({
|
|
|
70
58
|
migrations,
|
|
71
59
|
appToken,
|
|
72
60
|
isDryRun,
|
|
73
|
-
db,
|
|
74
61
|
currentSnapshot
|
|
75
62
|
}) {
|
|
76
63
|
const initialSnapshot = migrations.find((m) => m === "0000_snapshot.json");
|
|
@@ -80,13 +67,10 @@ async function pushSchema({
|
|
|
80
67
|
oldSnapshot: createEmptySnapshot(),
|
|
81
68
|
newSnapshot: await loadInitialSnapshot()
|
|
82
69
|
}) : [];
|
|
83
|
-
const
|
|
70
|
+
const queries = missingMigrationContents.reduce((acc, curr) => {
|
|
84
71
|
return [...acc, ...curr.db];
|
|
85
72
|
}, initialMigrationBatch);
|
|
86
|
-
|
|
87
|
-
await runBatchQuery({ queries, appToken, isDryRun });
|
|
88
|
-
await db.insert(migrationsTable).values(migrations.map((m) => ({ name: m })));
|
|
89
|
-
await db.update(adminTable).set({ collections: JSON.stringify(currentSnapshot) }).where(eq(adminTable.id, STUDIO_ADMIN_TABLE_ROW_ID));
|
|
73
|
+
await runMigrateQuery({ queries, migrations, snapshot: currentSnapshot, appToken, isDryRun });
|
|
90
74
|
}
|
|
91
75
|
async function pushData({
|
|
92
76
|
config,
|
|
@@ -131,21 +115,24 @@ async function pushData({
|
|
|
131
115
|
body: JSON.stringify(queries)
|
|
132
116
|
});
|
|
133
117
|
}
|
|
134
|
-
async function
|
|
135
|
-
queries
|
|
118
|
+
async function runMigrateQuery({
|
|
119
|
+
queries,
|
|
120
|
+
migrations,
|
|
121
|
+
snapshot,
|
|
136
122
|
appToken,
|
|
137
123
|
isDryRun
|
|
138
124
|
}) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
125
|
+
const requestBody = {
|
|
126
|
+
snapshot,
|
|
127
|
+
migrations,
|
|
128
|
+
sql: queries,
|
|
129
|
+
experimentalVersion: 1
|
|
130
|
+
};
|
|
144
131
|
if (isDryRun) {
|
|
145
132
|
console.info("[DRY RUN] Batch query:", JSON.stringify(requestBody, null, 2));
|
|
146
133
|
return new Response(null, { status: 200 });
|
|
147
134
|
}
|
|
148
|
-
const url = new URL("/db/
|
|
135
|
+
const url = new URL("/db/migrate/run", getRemoteDatabaseUrl());
|
|
149
136
|
return await fetch(url, {
|
|
150
137
|
method: "POST",
|
|
151
138
|
headers: new Headers({
|
|
@@ -154,6 +141,24 @@ async function runBatchQuery({
|
|
|
154
141
|
body: JSON.stringify(requestBody)
|
|
155
142
|
});
|
|
156
143
|
}
|
|
144
|
+
async function prepareMigrateQuery({
|
|
145
|
+
migrations,
|
|
146
|
+
appToken
|
|
147
|
+
}) {
|
|
148
|
+
const url = new URL("/db/migrate/prepare", getRemoteDatabaseUrl());
|
|
149
|
+
const requestBody = {
|
|
150
|
+
migrations,
|
|
151
|
+
experimentalVersion: 1
|
|
152
|
+
};
|
|
153
|
+
const result = await fetch(url, {
|
|
154
|
+
method: "POST",
|
|
155
|
+
headers: new Headers({
|
|
156
|
+
Authorization: `Bearer ${appToken}`
|
|
157
|
+
}),
|
|
158
|
+
body: JSON.stringify(requestBody)
|
|
159
|
+
});
|
|
160
|
+
return await result.json();
|
|
161
|
+
}
|
|
157
162
|
export {
|
|
158
163
|
cmd
|
|
159
164
|
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { sql } from "drizzle-orm";
|
|
2
2
|
import { appTokenError } from "../../../errors.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { getAstroStudioEnv, getRemoteDatabaseUrl } from "../../../utils.js";
|
|
4
|
+
import { createRemoteDatabaseClient } from "../../../../runtime/db-client.js";
|
|
5
|
+
async function cmd({ flags }) {
|
|
5
6
|
const query = flags.query;
|
|
6
7
|
const appToken = flags.token ?? getAstroStudioEnv().ASTRO_STUDIO_APP_TOKEN;
|
|
7
8
|
if (!appToken) {
|
|
8
9
|
console.error(appTokenError);
|
|
9
10
|
process.exit(1);
|
|
10
11
|
}
|
|
11
|
-
const db = createRemoteDatabaseClient(appToken);
|
|
12
|
+
const db = createRemoteDatabaseClient(appToken, getRemoteDatabaseUrl());
|
|
12
13
|
const result = await db.run(sql.raw(query));
|
|
13
14
|
console.log(result);
|
|
14
15
|
}
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
getMigrations,
|
|
6
6
|
initializeFromMigrations,
|
|
7
7
|
initializeMigrationsDirectory
|
|
8
|
-
} from "
|
|
9
|
-
import { getMigrationQueries } from "../../queries.js";
|
|
8
|
+
} from "../../migrations.js";
|
|
9
|
+
import { getMigrationQueries } from "../../migration-queries.js";
|
|
10
10
|
const { diff } = deepDiff;
|
|
11
11
|
async function cmd({ config }) {
|
|
12
12
|
const currentSnapshot = createCurrentSnapshot(config);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import deepDiff from "deep-diff";
|
|
2
|
-
import { getMigrations, initializeFromMigrations } from "
|
|
2
|
+
import { getMigrations, initializeFromMigrations } from "../../migrations.js";
|
|
3
3
|
const { diff } = deepDiff;
|
|
4
4
|
async function cmd({ config }) {
|
|
5
5
|
const currentSnapshot = JSON.parse(JSON.stringify(config.db?.collections ?? {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
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, }: {
|
|
8
|
+
oldSnapshot: DBSnapshot;
|
|
9
|
+
newSnapshot: DBSnapshot;
|
|
10
|
+
promptResponses?: PromptResponses;
|
|
11
|
+
}): Promise<string[]>;
|
|
12
|
+
export declare function getCollectionChangeQueries({ collectionName, oldCollection, newCollection, promptResponses, }: {
|
|
13
|
+
collectionName: string;
|
|
14
|
+
oldCollection: DBCollection;
|
|
15
|
+
newCollection: DBCollection;
|
|
16
|
+
promptResponses?: PromptResponses;
|
|
17
|
+
}): Promise<string[]>;
|
|
18
|
+
export {};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import * as color from "kleur/colors";
|
|
2
|
+
import deepDiff from "deep-diff";
|
|
2
3
|
import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
|
|
3
4
|
import { customAlphabet } from "nanoid";
|
|
4
5
|
import prompts from "prompts";
|
|
5
6
|
import {
|
|
7
|
+
getCreateIndexQueries,
|
|
6
8
|
getCreateTableQuery,
|
|
7
9
|
getModifiers,
|
|
8
10
|
hasDefault,
|
|
9
|
-
hasPrimaryKey,
|
|
10
11
|
schemaTypeToSqlType
|
|
11
|
-
} from "../
|
|
12
|
+
} from "../queries.js";
|
|
13
|
+
import { hasPrimaryKey } from "../../runtime/index.js";
|
|
12
14
|
const sqlite = new SQLiteAsyncDialect();
|
|
13
15
|
const genTempTableName = customAlphabet("abcdefghijklmnopqrstuvwxyz", 10);
|
|
14
16
|
async function getMigrationQueries({
|
|
@@ -36,6 +38,7 @@ async function getMigrationQueries({
|
|
|
36
38
|
}
|
|
37
39
|
for (const [collectionName, collection] of Object.entries(added)) {
|
|
38
40
|
queries.push(getCreateTableQuery(collectionName, collection));
|
|
41
|
+
queries.push(...getCreateIndexQueries(collectionName, collection));
|
|
39
42
|
}
|
|
40
43
|
for (const [collectionName] of Object.entries(dropped)) {
|
|
41
44
|
const dropQuery = `DROP TABLE ${sqlite.escapeName(collectionName)}`;
|
|
@@ -63,10 +66,14 @@ async function getCollectionChangeQueries({
|
|
|
63
66
|
}) {
|
|
64
67
|
const queries = [];
|
|
65
68
|
const updated = getUpdatedFields(oldCollection.fields, newCollection.fields);
|
|
66
|
-
let added =
|
|
67
|
-
let dropped =
|
|
69
|
+
let added = getAdded(oldCollection.fields, newCollection.fields);
|
|
70
|
+
let dropped = getDropped(oldCollection.fields, newCollection.fields);
|
|
68
71
|
if (isEmpty(updated) && isEmpty(added) && isEmpty(dropped)) {
|
|
69
|
-
return
|
|
72
|
+
return getChangeIndexQueries({
|
|
73
|
+
collectionName,
|
|
74
|
+
oldIndexes: oldCollection.indexes,
|
|
75
|
+
newIndexes: newCollection.indexes
|
|
76
|
+
});
|
|
70
77
|
}
|
|
71
78
|
if (!isEmpty(added) && !isEmpty(dropped)) {
|
|
72
79
|
const resolved = await resolveFieldRenames(
|
|
@@ -80,7 +87,14 @@ async function getCollectionChangeQueries({
|
|
|
80
87
|
queries.push(...getFieldRenameQueries(collectionName, resolved.renamed));
|
|
81
88
|
}
|
|
82
89
|
if (isEmpty(updated) && Object.values(dropped).every(canAlterTableDropColumn) && Object.values(added).every(canAlterTableAddColumn)) {
|
|
83
|
-
queries.push(
|
|
90
|
+
queries.push(
|
|
91
|
+
...getAlterTableQueries(collectionName, added, dropped),
|
|
92
|
+
...getChangeIndexQueries({
|
|
93
|
+
collectionName,
|
|
94
|
+
oldIndexes: oldCollection.indexes,
|
|
95
|
+
newIndexes: newCollection.indexes
|
|
96
|
+
})
|
|
97
|
+
);
|
|
84
98
|
return queries;
|
|
85
99
|
}
|
|
86
100
|
const dataLossCheck = canRecreateTableWithoutDataLoss(added, updated);
|
|
@@ -117,7 +131,7 @@ async function getCollectionChangeQueries({
|
|
|
117
131
|
allowDataLoss = !!res.allowDataLoss;
|
|
118
132
|
}
|
|
119
133
|
if (!allowDataLoss) {
|
|
120
|
-
console.
|
|
134
|
+
console.info("Exiting without changes \u{1F44B}");
|
|
121
135
|
process.exit(0);
|
|
122
136
|
}
|
|
123
137
|
}
|
|
@@ -127,13 +141,31 @@ async function getCollectionChangeQueries({
|
|
|
127
141
|
([, field]) => hasPrimaryKey(field.old) || hasPrimaryKey(field.new)
|
|
128
142
|
);
|
|
129
143
|
const recreateTableQueries = getRecreateTableQueries({
|
|
130
|
-
|
|
144
|
+
collectionName,
|
|
131
145
|
newCollection,
|
|
132
146
|
added,
|
|
133
147
|
hasDataLoss: dataLossCheck.dataLoss,
|
|
134
148
|
migrateHiddenPrimaryKey: !addedPrimaryKey && !droppedPrimaryKey && !updatedPrimaryKey
|
|
135
149
|
});
|
|
136
|
-
queries.push(...recreateTableQueries);
|
|
150
|
+
queries.push(...recreateTableQueries, ...getCreateIndexQueries(collectionName, newCollection));
|
|
151
|
+
return queries;
|
|
152
|
+
}
|
|
153
|
+
function getChangeIndexQueries({
|
|
154
|
+
collectionName,
|
|
155
|
+
oldIndexes = {},
|
|
156
|
+
newIndexes = {}
|
|
157
|
+
}) {
|
|
158
|
+
const added = getAdded(oldIndexes, newIndexes);
|
|
159
|
+
const dropped = getDropped(oldIndexes, newIndexes);
|
|
160
|
+
const updated = getUpdated(oldIndexes, newIndexes);
|
|
161
|
+
Object.assign(dropped, updated);
|
|
162
|
+
Object.assign(added, updated);
|
|
163
|
+
const queries = [];
|
|
164
|
+
for (const indexName of Object.keys(dropped)) {
|
|
165
|
+
const dropQuery = `DROP INDEX ${sqlite.escapeName(indexName)}`;
|
|
166
|
+
queries.push(dropQuery);
|
|
167
|
+
}
|
|
168
|
+
queries.push(...getCreateIndexQueries(collectionName, { indexes: added }));
|
|
137
169
|
return queries;
|
|
138
170
|
}
|
|
139
171
|
async function resolveFieldRenames(collectionName, mightAdd, mightDrop, renamePromptResponses) {
|
|
@@ -277,17 +309,20 @@ function getAlterTableQueries(unescapedCollectionName, added, dropped) {
|
|
|
277
309
|
return queries;
|
|
278
310
|
}
|
|
279
311
|
function getRecreateTableQueries({
|
|
280
|
-
|
|
312
|
+
collectionName: unescCollectionName,
|
|
281
313
|
newCollection,
|
|
282
314
|
added,
|
|
283
315
|
hasDataLoss,
|
|
284
316
|
migrateHiddenPrimaryKey
|
|
285
317
|
}) {
|
|
286
|
-
const unescTempName = `${
|
|
318
|
+
const unescTempName = `${unescCollectionName}_${genTempTableName()}`;
|
|
287
319
|
const tempName = sqlite.escapeName(unescTempName);
|
|
288
|
-
const collectionName = sqlite.escapeName(
|
|
320
|
+
const collectionName = sqlite.escapeName(unescCollectionName);
|
|
289
321
|
if (hasDataLoss) {
|
|
290
|
-
return [
|
|
322
|
+
return [
|
|
323
|
+
`DROP TABLE ${collectionName}`,
|
|
324
|
+
getCreateTableQuery(unescCollectionName, newCollection)
|
|
325
|
+
];
|
|
291
326
|
}
|
|
292
327
|
const newColumns = [...Object.keys(newCollection.fields)];
|
|
293
328
|
if (migrateHiddenPrimaryKey) {
|
|
@@ -330,7 +365,7 @@ function canRecreateTableWithoutDataLoss(added, updated) {
|
|
|
330
365
|
if (!a.optional && !hasDefault(a)) {
|
|
331
366
|
return { dataLoss: true, fieldName, reason: "added-required" };
|
|
332
367
|
}
|
|
333
|
-
if (a.unique) {
|
|
368
|
+
if (!a.optional && a.unique) {
|
|
334
369
|
return { dataLoss: true, fieldName, reason: "added-unique" };
|
|
335
370
|
}
|
|
336
371
|
}
|
|
@@ -341,22 +376,33 @@ function canRecreateTableWithoutDataLoss(added, updated) {
|
|
|
341
376
|
}
|
|
342
377
|
return { dataLoss: false };
|
|
343
378
|
}
|
|
344
|
-
function
|
|
379
|
+
function getAdded(oldObj, newObj) {
|
|
345
380
|
const added = {};
|
|
346
|
-
for (const [key,
|
|
347
|
-
if (!(key in
|
|
348
|
-
added[key] =
|
|
381
|
+
for (const [key, value] of Object.entries(newObj)) {
|
|
382
|
+
if (!(key in oldObj))
|
|
383
|
+
added[key] = value;
|
|
349
384
|
}
|
|
350
385
|
return added;
|
|
351
386
|
}
|
|
352
|
-
function
|
|
387
|
+
function getDropped(oldObj, newObj) {
|
|
353
388
|
const dropped = {};
|
|
354
|
-
for (const [key,
|
|
355
|
-
if (!(key in
|
|
356
|
-
dropped[key] =
|
|
389
|
+
for (const [key, value] of Object.entries(oldObj)) {
|
|
390
|
+
if (!(key in newObj))
|
|
391
|
+
dropped[key] = value;
|
|
357
392
|
}
|
|
358
393
|
return dropped;
|
|
359
394
|
}
|
|
395
|
+
function getUpdated(oldObj, newObj) {
|
|
396
|
+
const updated = {};
|
|
397
|
+
for (const [key, value] of Object.entries(newObj)) {
|
|
398
|
+
const oldValue = oldObj[key];
|
|
399
|
+
if (!oldValue)
|
|
400
|
+
continue;
|
|
401
|
+
if (deepDiff(oldValue, value))
|
|
402
|
+
updated[key] = value;
|
|
403
|
+
}
|
|
404
|
+
return updated;
|
|
405
|
+
}
|
|
360
406
|
function getUpdatedFields(oldFields, newFields) {
|
|
361
407
|
const updated = {};
|
|
362
408
|
for (const [key, newField] of Object.entries(newFields)) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DBSnapshot } from '../types.js';
|
|
2
|
+
import type { AstroConfig } from 'astro';
|
|
3
|
+
export declare function getMigrations(): Promise<string[]>;
|
|
4
|
+
export declare function loadMigration(migration: string): Promise<{
|
|
5
|
+
diff: any[];
|
|
6
|
+
db: string[];
|
|
7
|
+
}>;
|
|
8
|
+
export declare function loadInitialSnapshot(): Promise<DBSnapshot>;
|
|
9
|
+
export declare function initializeMigrationsDirectory(currentSnapshot: DBSnapshot): Promise<void>;
|
|
10
|
+
export declare function initializeFromMigrations(allMigrationFiles: string[]): Promise<DBSnapshot>;
|
|
11
|
+
export declare function createCurrentSnapshot(config: AstroConfig): DBSnapshot;
|
|
12
|
+
export declare function createEmptySnapshot(): DBSnapshot;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const PACKAGE_NAME: any;
|
|
2
|
+
export declare const RUNTIME_IMPORT: string;
|
|
3
|
+
export declare const RUNTIME_DRIZZLE_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";
|
|
@@ -0,0 +1,17 @@
|
|
|
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_DRIZZLE_IMPORT = JSON.stringify(`${PACKAGE_NAME}/runtime/drizzle`);
|
|
7
|
+
const DB_TYPES_FILE = "db-types.d.ts";
|
|
8
|
+
const VIRTUAL_MODULE_ID = "astro:db";
|
|
9
|
+
const DB_PATH = ".astro/content.db";
|
|
10
|
+
export {
|
|
11
|
+
DB_PATH,
|
|
12
|
+
DB_TYPES_FILE,
|
|
13
|
+
PACKAGE_NAME,
|
|
14
|
+
RUNTIME_DRIZZLE_IMPORT,
|
|
15
|
+
RUNTIME_IMPORT,
|
|
16
|
+
VIRTUAL_MODULE_ID
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const appTokenError: string;
|
|
@@ -3,16 +3,17 @@ import { vitePluginInjectEnvTs } from "./vite-plugin-inject-env-ts.js";
|
|
|
3
3
|
import { typegen } from "./typegen.js";
|
|
4
4
|
import { existsSync } from "fs";
|
|
5
5
|
import { mkdir, rm, writeFile } from "fs/promises";
|
|
6
|
-
import {
|
|
7
|
-
import { createLocalDatabaseClient
|
|
8
|
-
import { astroConfigWithDbSchema } from "
|
|
9
|
-
import { getAstroStudioEnv } from "
|
|
10
|
-
import { appTokenError } from "
|
|
6
|
+
import { DB_PATH } from "../consts.js";
|
|
7
|
+
import { createLocalDatabaseClient } from "../../runtime/db-client.js";
|
|
8
|
+
import { astroConfigWithDbSchema } from "../types.js";
|
|
9
|
+
import { getAstroStudioEnv } from "../utils.js";
|
|
10
|
+
import { appTokenError } from "../errors.js";
|
|
11
11
|
import { errorMap } from "./error-map.js";
|
|
12
12
|
import { dirname } from "path";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
14
|
import { bold } from "kleur/colors";
|
|
15
|
-
import { fileURLIntegration } from "./file-url
|
|
15
|
+
import { fileURLIntegration } from "./file-url.js";
|
|
16
|
+
import { setupDbTables } from "../queries.js";
|
|
16
17
|
function astroDBIntegration() {
|
|
17
18
|
return {
|
|
18
19
|
name: "astro:db",
|
|
@@ -41,10 +42,10 @@ function astroDBIntegration() {
|
|
|
41
42
|
connectToStudio: true,
|
|
42
43
|
collections,
|
|
43
44
|
appToken,
|
|
44
|
-
|
|
45
|
+
root: config.root
|
|
45
46
|
});
|
|
46
47
|
} else {
|
|
47
|
-
const dbUrl =
|
|
48
|
+
const dbUrl = new URL(DB_PATH, config.root);
|
|
48
49
|
if (existsSync(dbUrl)) {
|
|
49
50
|
await rm(dbUrl);
|
|
50
51
|
}
|
|
@@ -52,7 +53,7 @@ function astroDBIntegration() {
|
|
|
52
53
|
await writeFile(dbUrl, "");
|
|
53
54
|
const db = await createLocalDatabaseClient({
|
|
54
55
|
collections,
|
|
55
|
-
dbUrl: dbUrl.
|
|
56
|
+
dbUrl: dbUrl.toString(),
|
|
56
57
|
seeding: true
|
|
57
58
|
});
|
|
58
59
|
await setupDbTables({
|
|
@@ -65,23 +66,28 @@ function astroDBIntegration() {
|
|
|
65
66
|
logger.info("Collections set up \u{1F680}");
|
|
66
67
|
dbPlugin = vitePluginDb({
|
|
67
68
|
connectToStudio: false,
|
|
68
|
-
collections
|
|
69
|
+
collections,
|
|
70
|
+
root: config.root
|
|
69
71
|
});
|
|
70
72
|
}
|
|
71
73
|
updateConfig({
|
|
72
74
|
vite: {
|
|
73
75
|
assetsInclude: [DB_PATH],
|
|
74
|
-
plugins: [
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
plugins: [
|
|
77
|
+
dbPlugin,
|
|
78
|
+
vitePluginInjectEnvTs(config),
|
|
79
|
+
{
|
|
80
|
+
name: "my-plugin",
|
|
81
|
+
resolveId(id) {
|
|
82
|
+
if (id.endsWith("?server-path")) {
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
load(id) {
|
|
86
|
+
if (id.endsWith("?server-path")) {
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
|
-
|
|
90
|
+
]
|
|
85
91
|
}
|
|
86
92
|
});
|
|
87
93
|
await typegen({ collections, root: config.root });
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
-
import { DB_TYPES_FILE,
|
|
3
|
+
import { DB_TYPES_FILE, RUNTIME_DRIZZLE_IMPORT, RUNTIME_IMPORT } from "../consts.js";
|
|
4
4
|
async function typegen({ collections, root }) {
|
|
5
5
|
const content = `// This file is generated by \`studio sync\`
|
|
6
6
|
declare module 'astro:db' {
|
|
7
|
-
export const db: import(${
|
|
7
|
+
export const db: import(${RUNTIME_IMPORT}).SqliteDB;
|
|
8
8
|
export const dbUrl: string;
|
|
9
|
-
export * from ${
|
|
9
|
+
export * from ${RUNTIME_DRIZZLE_IMPORT};
|
|
10
10
|
|
|
11
11
|
${Object.entries(collections).map(([name, collection]) => generateTableType(name, collection)).join("\n")}
|
|
12
12
|
}
|
|
@@ -18,7 +18,7 @@ ${Object.entries(collections).map(([name, collection]) => generateTableType(name
|
|
|
18
18
|
await writeFile(new URL(DB_TYPES_FILE, dotAstroDir), content);
|
|
19
19
|
}
|
|
20
20
|
function generateTableType(name, collection) {
|
|
21
|
-
let tableType = ` export const ${name}: import(${
|
|
21
|
+
let tableType = ` export const ${name}: import(${RUNTIME_IMPORT}).Table<
|
|
22
22
|
${JSON.stringify(name)},
|
|
23
23
|
${JSON.stringify(
|
|
24
24
|
Object.fromEntries(
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DBCollections } from '../types.js';
|
|
2
|
+
import type { VitePlugin } from '../utils.js';
|
|
3
|
+
export declare function vitePluginDb(params: {
|
|
4
|
+
connectToStudio: false;
|
|
5
|
+
collections: DBCollections;
|
|
6
|
+
root: URL;
|
|
7
|
+
} | {
|
|
8
|
+
connectToStudio: true;
|
|
9
|
+
collections: DBCollections;
|
|
10
|
+
appToken: string;
|
|
11
|
+
root: URL;
|
|
12
|
+
}): VitePlugin;
|
|
13
|
+
export declare function getVirtualModContents({ collections, root }: {
|
|
14
|
+
collections: DBCollections;
|
|
15
|
+
root: URL;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare function getStudioVirtualModContents({ collections, appToken, }: {
|
|
18
|
+
collections: DBCollections;
|
|
19
|
+
appToken: string;
|
|
20
|
+
}): string;
|