@astrojs/db 0.1.2 → 0.1.4
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/cli/commands/push/index.js +11 -11
- package/dist/cli/commands/shell/index.d.ts +6 -0
- package/dist/cli/commands/shell/index.js +17 -0
- package/dist/cli/commands/sync/index.js +4 -3
- package/dist/cli/commands/verify/index.js +2 -5
- package/dist/cli/index.js +4 -0
- package/dist/cli/queries.d.ts +4 -5
- package/dist/cli/queries.js +66 -113
- package/dist/config.d.ts +72 -0
- package/dist/config.js +3 -1
- package/dist/integration.js +7 -1
- package/dist/internal.d.ts +12 -16
- package/dist/internal.js +52 -22
- package/dist/migrations.d.ts +7 -4
- package/dist/migrations.js +17 -1
- package/dist/typegen.js +16 -33
- package/dist/types.d.ts +106 -6
- package/dist/types.js +4 -2
- package/dist/utils-runtime.d.ts +1 -0
- package/dist/utils-runtime.js +52 -0
- package/dist/utils.js +3 -48
- package/dist/vite-plugin-db.js +1 -3
- package/package.json +2 -2
- package/dist/cli/sync/index.js +0 -0
- package/dist/cli/sync/migrate.js +0 -0
package/dist/internal.js
CHANGED
|
@@ -15,8 +15,11 @@ import {
|
|
|
15
15
|
text
|
|
16
16
|
} from "drizzle-orm/sqlite-core";
|
|
17
17
|
import { z } from "zod";
|
|
18
|
-
import {
|
|
18
|
+
import { createRemoteDatabaseClient } from "./utils-runtime.js";
|
|
19
19
|
const sqlite = new SQLiteAsyncDialect();
|
|
20
|
+
function hasPrimaryKey(field) {
|
|
21
|
+
return "primaryKey" in field && !!field.primaryKey;
|
|
22
|
+
}
|
|
20
23
|
function isReadableCollection(collection) {
|
|
21
24
|
return !collection.writable;
|
|
22
25
|
}
|
|
@@ -27,7 +30,6 @@ function checkIfModificationIsAllowed(collections, Table) {
|
|
|
27
30
|
throw new Error(`The [${tableName}] collection is read-only.`);
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
|
-
import { createRemoteDatabaseClient } from "./utils.js";
|
|
31
33
|
async function createLocalDatabaseClient({
|
|
32
34
|
collections,
|
|
33
35
|
dbUrl,
|
|
@@ -55,8 +57,10 @@ async function createLocalDatabaseClient({
|
|
|
55
57
|
}
|
|
56
58
|
async function setupDbTables({
|
|
57
59
|
db,
|
|
60
|
+
data,
|
|
58
61
|
collections,
|
|
59
|
-
logger
|
|
62
|
+
logger,
|
|
63
|
+
mode
|
|
60
64
|
}) {
|
|
61
65
|
const setupQueries = [];
|
|
62
66
|
for (const [name, collection] of Object.entries(collections)) {
|
|
@@ -67,6 +71,15 @@ async function setupDbTables({
|
|
|
67
71
|
for (const q of setupQueries) {
|
|
68
72
|
await db.run(q);
|
|
69
73
|
}
|
|
74
|
+
if (data) {
|
|
75
|
+
const ormObjects = Object.fromEntries(
|
|
76
|
+
Object.entries(collections).map(([name, collection]) => {
|
|
77
|
+
const table = collectionToTable(name, collection, false);
|
|
78
|
+
return [name, table];
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
await data({ db, ...ormObjects, mode });
|
|
82
|
+
}
|
|
70
83
|
for (const [name, collection] of Object.entries(collections)) {
|
|
71
84
|
if (!isReadableCollection(collection) || !collection.data)
|
|
72
85
|
continue;
|
|
@@ -86,7 +99,13 @@ ${e}`
|
|
|
86
99
|
}
|
|
87
100
|
function getCreateTableQuery(collectionName, collection) {
|
|
88
101
|
let query = `CREATE TABLE ${sqlite.escapeName(collectionName)} (`;
|
|
89
|
-
const colQueries = [
|
|
102
|
+
const colQueries = [];
|
|
103
|
+
const colHasPrimaryKey = Object.entries(collection.fields).find(
|
|
104
|
+
([, field]) => hasPrimaryKey(field)
|
|
105
|
+
);
|
|
106
|
+
if (!colHasPrimaryKey) {
|
|
107
|
+
colQueries.push("_id INTEGER PRIMARY KEY");
|
|
108
|
+
}
|
|
90
109
|
for (const [columnName, column] of Object.entries(collection.fields)) {
|
|
91
110
|
const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
|
|
92
111
|
column.type
|
|
@@ -107,28 +126,37 @@ function schemaTypeToSqlType(type) {
|
|
|
107
126
|
return "integer";
|
|
108
127
|
}
|
|
109
128
|
}
|
|
110
|
-
function getModifiers(
|
|
129
|
+
function getModifiers(fieldName, field) {
|
|
111
130
|
let modifiers = "";
|
|
112
|
-
if (
|
|
131
|
+
if (hasPrimaryKey(field)) {
|
|
132
|
+
return " PRIMARY KEY";
|
|
133
|
+
}
|
|
134
|
+
if (!field.optional) {
|
|
113
135
|
modifiers += " NOT NULL";
|
|
114
136
|
}
|
|
115
|
-
if (
|
|
137
|
+
if (field.unique) {
|
|
116
138
|
modifiers += " UNIQUE";
|
|
117
139
|
}
|
|
118
|
-
if (hasDefault(
|
|
119
|
-
modifiers += ` DEFAULT ${getDefaultValueSql(
|
|
140
|
+
if (hasDefault(field)) {
|
|
141
|
+
modifiers += ` DEFAULT ${getDefaultValueSql(fieldName, field)}`;
|
|
120
142
|
}
|
|
121
143
|
return modifiers;
|
|
122
144
|
}
|
|
123
145
|
function hasDefault(field) {
|
|
124
|
-
|
|
146
|
+
if (field.default !== void 0) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
if (hasPrimaryKey(field) && field.type === "number") {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
125
153
|
}
|
|
126
154
|
function getDefaultValueSql(columnName, column) {
|
|
127
155
|
switch (column.type) {
|
|
128
156
|
case "boolean":
|
|
129
157
|
return column.default ? "TRUE" : "FALSE";
|
|
130
158
|
case "number":
|
|
131
|
-
return `${column.default}`;
|
|
159
|
+
return `${column.default || "AUTOINCREMENT"}`;
|
|
132
160
|
case "text":
|
|
133
161
|
return sqlite.escapeString(column.default);
|
|
134
162
|
case "date":
|
|
@@ -138,7 +166,7 @@ function getDefaultValueSql(columnName, column) {
|
|
|
138
166
|
try {
|
|
139
167
|
stringified = JSON.stringify(column.default);
|
|
140
168
|
} catch (e) {
|
|
141
|
-
console.
|
|
169
|
+
console.log(
|
|
142
170
|
`Invalid default value for column ${bold(
|
|
143
171
|
columnName
|
|
144
172
|
)}. Defaults must be valid JSON when using the \`json()\` type.`
|
|
@@ -149,9 +177,6 @@ function getDefaultValueSql(columnName, column) {
|
|
|
149
177
|
}
|
|
150
178
|
}
|
|
151
179
|
}
|
|
152
|
-
function generateId() {
|
|
153
|
-
return nanoid(12);
|
|
154
|
-
}
|
|
155
180
|
const dateType = customType({
|
|
156
181
|
dataType() {
|
|
157
182
|
return "text";
|
|
@@ -174,14 +199,11 @@ const jsonType = customType({
|
|
|
174
199
|
return JSON.parse(value);
|
|
175
200
|
}
|
|
176
201
|
});
|
|
177
|
-
const initialColumns = {
|
|
178
|
-
id: text("id").primaryKey().$default(() => generateId())
|
|
179
|
-
};
|
|
180
202
|
function collectionToTable(name, collection, isJsonSerializable = true) {
|
|
181
|
-
const columns = {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
203
|
+
const columns = {};
|
|
204
|
+
if (!Object.entries(collection.fields).some(([, field]) => hasPrimaryKey(field))) {
|
|
205
|
+
columns["_id"] = integer("_id").primaryKey();
|
|
206
|
+
}
|
|
185
207
|
for (const [fieldName, field] of Object.entries(collection.fields)) {
|
|
186
208
|
columns[fieldName] = columnMapper(fieldName, field, isJsonSerializable);
|
|
187
209
|
}
|
|
@@ -195,12 +217,16 @@ function columnMapper(fieldName, field, isJsonSerializable) {
|
|
|
195
217
|
c = text(fieldName);
|
|
196
218
|
if (field.default !== void 0)
|
|
197
219
|
c = c.default(field.default);
|
|
220
|
+
if (field.primaryKey === true)
|
|
221
|
+
c = c.primaryKey();
|
|
198
222
|
break;
|
|
199
223
|
}
|
|
200
224
|
case "number": {
|
|
201
225
|
c = integer(fieldName);
|
|
202
226
|
if (field.default !== void 0)
|
|
203
227
|
c = c.default(field.default);
|
|
228
|
+
if (field.primaryKey === true)
|
|
229
|
+
c = c.primaryKey({ autoIncrement: true });
|
|
204
230
|
break;
|
|
205
231
|
}
|
|
206
232
|
case "boolean": {
|
|
@@ -246,5 +272,9 @@ export {
|
|
|
246
272
|
createLocalDatabaseClient,
|
|
247
273
|
createRemoteDatabaseClient,
|
|
248
274
|
getCreateTableQuery,
|
|
275
|
+
getModifiers,
|
|
276
|
+
hasDefault,
|
|
277
|
+
hasPrimaryKey,
|
|
278
|
+
schemaTypeToSqlType,
|
|
249
279
|
setupDbTables
|
|
250
280
|
};
|
package/dist/migrations.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DBSnapshot } from './types.js';
|
|
2
|
+
import type { AstroConfig } from 'astro';
|
|
2
3
|
export declare function getMigrations(): Promise<string[]>;
|
|
3
4
|
export declare function loadMigration(migration: string): Promise<{
|
|
4
5
|
diff: any[];
|
|
5
6
|
db: string[];
|
|
6
7
|
}>;
|
|
7
|
-
export declare function loadInitialSnapshot(): Promise<
|
|
8
|
-
export declare function initializeMigrationsDirectory(currentSnapshot:
|
|
9
|
-
export declare function initializeFromMigrations(allMigrationFiles: string[]): Promise<
|
|
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;
|
package/dist/migrations.js
CHANGED
|
@@ -14,7 +14,14 @@ async function loadMigration(migration) {
|
|
|
14
14
|
return JSON.parse(await readFile(`./migrations/${migration}`, "utf-8"));
|
|
15
15
|
}
|
|
16
16
|
async function loadInitialSnapshot() {
|
|
17
|
-
|
|
17
|
+
const snapshot = JSON.parse(await readFile("./migrations/0000_snapshot.json", "utf-8"));
|
|
18
|
+
if (snapshot.experimentalVersion === 1) {
|
|
19
|
+
return snapshot;
|
|
20
|
+
}
|
|
21
|
+
if (!snapshot.schema) {
|
|
22
|
+
return { experimentalVersion: 1, schema: snapshot };
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Invalid snapshot format");
|
|
18
25
|
}
|
|
19
26
|
async function initializeMigrationsDirectory(currentSnapshot) {
|
|
20
27
|
await mkdir("./migrations", { recursive: true });
|
|
@@ -32,7 +39,16 @@ async function initializeFromMigrations(allMigrationFiles) {
|
|
|
32
39
|
}
|
|
33
40
|
return prevSnapshot;
|
|
34
41
|
}
|
|
42
|
+
function createCurrentSnapshot(config) {
|
|
43
|
+
const schema = JSON.parse(JSON.stringify(config.db?.collections ?? {}));
|
|
44
|
+
return { experimentalVersion: 1, schema };
|
|
45
|
+
}
|
|
46
|
+
function createEmptySnapshot() {
|
|
47
|
+
return { experimentalVersion: 1, schema: {} };
|
|
48
|
+
}
|
|
35
49
|
export {
|
|
50
|
+
createCurrentSnapshot,
|
|
51
|
+
createEmptySnapshot,
|
|
36
52
|
getMigrations,
|
|
37
53
|
initializeFromMigrations,
|
|
38
54
|
initializeMigrationsDirectory,
|
package/dist/typegen.js
CHANGED
|
@@ -17,41 +17,24 @@ ${Object.entries(collections).map(([name, collection]) => generateTableType(name
|
|
|
17
17
|
await writeFile(new URL(DB_TYPES_FILE, dotAstroDir), content);
|
|
18
18
|
}
|
|
19
19
|
function generateTableType(name, collection) {
|
|
20
|
-
let tableType = ` export const ${name}: import(${INTERNAL_MOD_IMPORT}).
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
tableType += `
|
|
37
|
-
};
|
|
38
|
-
}>;`;
|
|
20
|
+
let tableType = ` export const ${name}: import(${INTERNAL_MOD_IMPORT}).Table<
|
|
21
|
+
${JSON.stringify(name)},
|
|
22
|
+
${JSON.stringify(
|
|
23
|
+
Object.fromEntries(
|
|
24
|
+
Object.entries(collection.fields).map(([fieldName, field]) => [
|
|
25
|
+
fieldName,
|
|
26
|
+
{
|
|
27
|
+
// Only select fields Drizzle needs for inference
|
|
28
|
+
type: field.type,
|
|
29
|
+
optional: field.optional,
|
|
30
|
+
default: field.default
|
|
31
|
+
}
|
|
32
|
+
])
|
|
33
|
+
)
|
|
34
|
+
)}
|
|
35
|
+
>;`;
|
|
39
36
|
return tableType;
|
|
40
37
|
}
|
|
41
|
-
function schemaTypeToDrizzleInterface(type) {
|
|
42
|
-
switch (type) {
|
|
43
|
-
case "text":
|
|
44
|
-
return "AstroText";
|
|
45
|
-
case "number":
|
|
46
|
-
return "AstroNumber";
|
|
47
|
-
case "boolean":
|
|
48
|
-
return "AstroBoolean";
|
|
49
|
-
case "date":
|
|
50
|
-
return "AstroDate";
|
|
51
|
-
case "json":
|
|
52
|
-
return "AstroJson";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
38
|
export {
|
|
56
39
|
typegen
|
|
57
40
|
};
|