@astrojs/db 0.1.2 → 0.1.3
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 +11 -15
- package/dist/internal.js +51 -20
- 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/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
|
@@ -17,6 +17,9 @@ import {
|
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
import { nanoid } from "nanoid";
|
|
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
|
}
|
|
@@ -55,8 +58,10 @@ async function createLocalDatabaseClient({
|
|
|
55
58
|
}
|
|
56
59
|
async function setupDbTables({
|
|
57
60
|
db,
|
|
61
|
+
data,
|
|
58
62
|
collections,
|
|
59
|
-
logger
|
|
63
|
+
logger,
|
|
64
|
+
mode
|
|
60
65
|
}) {
|
|
61
66
|
const setupQueries = [];
|
|
62
67
|
for (const [name, collection] of Object.entries(collections)) {
|
|
@@ -67,6 +72,15 @@ async function setupDbTables({
|
|
|
67
72
|
for (const q of setupQueries) {
|
|
68
73
|
await db.run(q);
|
|
69
74
|
}
|
|
75
|
+
if (data) {
|
|
76
|
+
const ormObjects = Object.fromEntries(
|
|
77
|
+
Object.entries(collections).map(([name, collection]) => {
|
|
78
|
+
const table = collectionToTable(name, collection, false);
|
|
79
|
+
return [name, table];
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
await data({ db, ...ormObjects, mode });
|
|
83
|
+
}
|
|
70
84
|
for (const [name, collection] of Object.entries(collections)) {
|
|
71
85
|
if (!isReadableCollection(collection) || !collection.data)
|
|
72
86
|
continue;
|
|
@@ -86,7 +100,13 @@ ${e}`
|
|
|
86
100
|
}
|
|
87
101
|
function getCreateTableQuery(collectionName, collection) {
|
|
88
102
|
let query = `CREATE TABLE ${sqlite.escapeName(collectionName)} (`;
|
|
89
|
-
const colQueries = [
|
|
103
|
+
const colQueries = [];
|
|
104
|
+
const colHasPrimaryKey = Object.entries(collection.fields).find(
|
|
105
|
+
([, field]) => hasPrimaryKey(field)
|
|
106
|
+
);
|
|
107
|
+
if (!colHasPrimaryKey) {
|
|
108
|
+
colQueries.push("_id INTEGER PRIMARY KEY");
|
|
109
|
+
}
|
|
90
110
|
for (const [columnName, column] of Object.entries(collection.fields)) {
|
|
91
111
|
const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
|
|
92
112
|
column.type
|
|
@@ -107,28 +127,37 @@ function schemaTypeToSqlType(type) {
|
|
|
107
127
|
return "integer";
|
|
108
128
|
}
|
|
109
129
|
}
|
|
110
|
-
function getModifiers(
|
|
130
|
+
function getModifiers(fieldName, field) {
|
|
111
131
|
let modifiers = "";
|
|
112
|
-
if (
|
|
132
|
+
if (hasPrimaryKey(field)) {
|
|
133
|
+
return " PRIMARY KEY";
|
|
134
|
+
}
|
|
135
|
+
if (!field.optional) {
|
|
113
136
|
modifiers += " NOT NULL";
|
|
114
137
|
}
|
|
115
|
-
if (
|
|
138
|
+
if (field.unique) {
|
|
116
139
|
modifiers += " UNIQUE";
|
|
117
140
|
}
|
|
118
|
-
if (hasDefault(
|
|
119
|
-
modifiers += ` DEFAULT ${getDefaultValueSql(
|
|
141
|
+
if (hasDefault(field)) {
|
|
142
|
+
modifiers += ` DEFAULT ${getDefaultValueSql(fieldName, field)}`;
|
|
120
143
|
}
|
|
121
144
|
return modifiers;
|
|
122
145
|
}
|
|
123
146
|
function hasDefault(field) {
|
|
124
|
-
|
|
147
|
+
if (field.default !== void 0) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (hasPrimaryKey(field) && field.type === "number") {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
125
154
|
}
|
|
126
155
|
function getDefaultValueSql(columnName, column) {
|
|
127
156
|
switch (column.type) {
|
|
128
157
|
case "boolean":
|
|
129
158
|
return column.default ? "TRUE" : "FALSE";
|
|
130
159
|
case "number":
|
|
131
|
-
return `${column.default}`;
|
|
160
|
+
return `${column.default || "AUTOINCREMENT"}`;
|
|
132
161
|
case "text":
|
|
133
162
|
return sqlite.escapeString(column.default);
|
|
134
163
|
case "date":
|
|
@@ -138,7 +167,7 @@ function getDefaultValueSql(columnName, column) {
|
|
|
138
167
|
try {
|
|
139
168
|
stringified = JSON.stringify(column.default);
|
|
140
169
|
} catch (e) {
|
|
141
|
-
console.
|
|
170
|
+
console.log(
|
|
142
171
|
`Invalid default value for column ${bold(
|
|
143
172
|
columnName
|
|
144
173
|
)}. Defaults must be valid JSON when using the \`json()\` type.`
|
|
@@ -149,9 +178,6 @@ function getDefaultValueSql(columnName, column) {
|
|
|
149
178
|
}
|
|
150
179
|
}
|
|
151
180
|
}
|
|
152
|
-
function generateId() {
|
|
153
|
-
return nanoid(12);
|
|
154
|
-
}
|
|
155
181
|
const dateType = customType({
|
|
156
182
|
dataType() {
|
|
157
183
|
return "text";
|
|
@@ -174,14 +200,11 @@ const jsonType = customType({
|
|
|
174
200
|
return JSON.parse(value);
|
|
175
201
|
}
|
|
176
202
|
});
|
|
177
|
-
const initialColumns = {
|
|
178
|
-
id: text("id").primaryKey().$default(() => generateId())
|
|
179
|
-
};
|
|
180
203
|
function collectionToTable(name, collection, isJsonSerializable = true) {
|
|
181
|
-
const columns = {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
204
|
+
const columns = {};
|
|
205
|
+
if (!Object.entries(collection.fields).some(([, field]) => hasPrimaryKey(field))) {
|
|
206
|
+
columns["_id"] = integer("_id").primaryKey();
|
|
207
|
+
}
|
|
185
208
|
for (const [fieldName, field] of Object.entries(collection.fields)) {
|
|
186
209
|
columns[fieldName] = columnMapper(fieldName, field, isJsonSerializable);
|
|
187
210
|
}
|
|
@@ -195,12 +218,16 @@ function columnMapper(fieldName, field, isJsonSerializable) {
|
|
|
195
218
|
c = text(fieldName);
|
|
196
219
|
if (field.default !== void 0)
|
|
197
220
|
c = c.default(field.default);
|
|
221
|
+
if (field.primaryKey === true)
|
|
222
|
+
c = c.primaryKey();
|
|
198
223
|
break;
|
|
199
224
|
}
|
|
200
225
|
case "number": {
|
|
201
226
|
c = integer(fieldName);
|
|
202
227
|
if (field.default !== void 0)
|
|
203
228
|
c = c.default(field.default);
|
|
229
|
+
if (field.primaryKey === true)
|
|
230
|
+
c = c.primaryKey({ autoIncrement: true });
|
|
204
231
|
break;
|
|
205
232
|
}
|
|
206
233
|
case "boolean": {
|
|
@@ -246,5 +273,9 @@ export {
|
|
|
246
273
|
createLocalDatabaseClient,
|
|
247
274
|
createRemoteDatabaseClient,
|
|
248
275
|
getCreateTableQuery,
|
|
276
|
+
getModifiers,
|
|
277
|
+
hasDefault,
|
|
278
|
+
hasPrimaryKey,
|
|
279
|
+
schemaTypeToSqlType,
|
|
249
280
|
setupDbTables
|
|
250
281
|
};
|
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
|
};
|