@astrojs/db 0.4.1 → 0.6.0

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.
Files changed (57) hide show
  1. package/dist/core/cli/commands/execute/index.d.ts +8 -0
  2. package/dist/core/cli/commands/execute/index.js +32 -0
  3. package/dist/core/cli/commands/link/index.d.ts +20 -8
  4. package/dist/core/cli/commands/link/index.js +191 -31
  5. package/dist/core/cli/commands/login/index.d.ts +4 -2
  6. package/dist/core/cli/commands/login/index.js +31 -22
  7. package/dist/core/cli/commands/logout/index.d.ts +1 -6
  8. package/dist/core/cli/commands/logout/index.js +1 -1
  9. package/dist/core/cli/commands/push/index.d.ts +4 -2
  10. package/dist/core/cli/commands/push/index.js +30 -170
  11. package/dist/core/cli/commands/shell/index.d.ts +4 -2
  12. package/dist/core/cli/commands/shell/index.js +3 -1
  13. package/dist/core/cli/commands/verify/index.d.ts +4 -2
  14. package/dist/core/cli/commands/verify/index.js +23 -37
  15. package/dist/core/cli/index.d.ts +1 -1
  16. package/dist/core/cli/index.js +26 -17
  17. package/dist/core/cli/migration-queries.d.ts +8 -13
  18. package/dist/core/cli/migration-queries.js +65 -121
  19. package/dist/core/consts.d.ts +2 -0
  20. package/dist/core/consts.js +4 -0
  21. package/dist/core/errors.d.ts +9 -7
  22. package/dist/core/errors.js +44 -43
  23. package/dist/core/integration/file-url.js +2 -5
  24. package/dist/core/integration/index.js +56 -112
  25. package/dist/core/integration/typegen.js +3 -13
  26. package/dist/core/integration/vite-plugin-db.d.ts +9 -5
  27. package/dist/core/integration/vite-plugin-db.js +66 -23
  28. package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +1 -1
  29. package/dist/core/load-file.d.ts +31 -0
  30. package/dist/core/load-file.js +98 -0
  31. package/dist/core/tokens.js +1 -1
  32. package/dist/core/types.d.ts +1148 -5306
  33. package/dist/core/types.js +19 -85
  34. package/dist/core/utils.d.ts +1 -0
  35. package/dist/core/utils.js +4 -0
  36. package/dist/index.d.ts +2 -3
  37. package/dist/index.js +3 -5
  38. package/dist/runtime/config.d.ts +147 -0
  39. package/dist/runtime/config.js +42 -0
  40. package/dist/runtime/db-client.d.ts +2 -9
  41. package/dist/runtime/db-client.js +8 -39
  42. package/dist/runtime/index.d.ts +5 -4
  43. package/dist/runtime/index.js +12 -10
  44. package/dist/{core → runtime}/queries.d.ts +20 -17
  45. package/dist/{core → runtime}/queries.js +67 -91
  46. package/dist/runtime/types.d.ts +3 -3
  47. package/dist/utils.d.ts +1 -0
  48. package/dist/utils.js +4 -0
  49. package/index.d.ts +5 -3
  50. package/package.json +20 -5
  51. package/config-augment.d.ts +0 -4
  52. package/dist/core/cli/commands/gen/index.d.ts +0 -6
  53. package/dist/core/cli/commands/gen/index.js +0 -39
  54. package/dist/core/cli/migrations.d.ts +0 -34
  55. package/dist/core/cli/migrations.js +0 -129
  56. package/dist/core/integration/load-astro-config.d.ts +0 -6
  57. package/dist/core/integration/load-astro-config.js +0 -79
@@ -1,127 +1,103 @@
1
- import {
2
- } from "../core/types.js";
3
- import { bold } from "kleur/colors";
4
- import { sql, getTableName } from "drizzle-orm";
1
+ import { LibsqlError } from "@libsql/client";
2
+ import { sql } from "drizzle-orm";
5
3
  import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
6
- import { hasPrimaryKey } from "../runtime/index.js";
7
- import { isSerializedSQL } from "../runtime/types.js";
8
- import { SEED_EMPTY_ARRAY_ERROR, SEED_ERROR, SEED_WRITABLE_IN_PROD_ERROR } from "./errors.js";
4
+ import { bold } from "kleur/colors";
5
+ import {
6
+ FOREIGN_KEY_DNE_ERROR,
7
+ FOREIGN_KEY_REFERENCES_EMPTY_ERROR,
8
+ FOREIGN_KEY_REFERENCES_LENGTH_ERROR,
9
+ REFERENCE_DNE_ERROR,
10
+ SEED_ERROR
11
+ } from "../core/errors.js";
12
+ import { hasPrimaryKey } from "./index.js";
13
+ import { isSerializedSQL } from "./types.js";
9
14
  const sqlite = new SQLiteAsyncDialect();
10
- async function recreateTables({
11
- db,
12
- tables
13
- }) {
14
- const setupQueries = [];
15
- for (const [name, collection] of Object.entries(tables)) {
16
- const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${sqlite.escapeName(name)}`);
17
- const createQuery = sql.raw(getCreateTableQuery(name, collection));
18
- const indexQueries = getCreateIndexQueries(name, collection);
19
- setupQueries.push(dropQuery, createQuery, ...indexQueries.map((s) => sql.raw(s)));
20
- }
21
- for (const q of setupQueries) {
22
- await db.run(q);
23
- }
24
- }
25
- async function seedData({
15
+ const SEED_DEV_FILE_NAME = ["seed.ts", "seed.js", "seed.mjs", "seed.mts"];
16
+ async function seedLocal({
26
17
  db,
27
- data,
28
- logger,
29
- mode
18
+ tables,
19
+ // Glob all potential seed files to catch renames and deletions.
20
+ fileGlob
30
21
  }) {
31
- const dataFns = Array.isArray(data) ? data : [data];
32
- try {
33
- for (const dataFn of dataFns) {
34
- await dataFn({
35
- seed: async (config, values) => {
36
- seedErrorChecks(mode, config, values);
37
- try {
38
- await db.insert(config.table).values(values);
39
- } catch (e) {
40
- const msg = e instanceof Error ? e.message : String(e);
41
- throw new Error(SEED_ERROR(getTableName(config.table), msg));
42
- }
43
- },
44
- seedReturning: async (config, values) => {
45
- seedErrorChecks(mode, config, values);
46
- try {
47
- let result = db.insert(config.table).values(values).returning();
48
- if (!Array.isArray(values)) {
49
- result = result.get();
50
- }
51
- return result;
52
- } catch (e) {
53
- const msg = e instanceof Error ? e.message : String(e);
54
- throw new Error(SEED_ERROR(getTableName(config.table), msg));
55
- }
56
- },
57
- db,
58
- mode
22
+ await recreateTables({ db, tables });
23
+ for (const fileName of SEED_DEV_FILE_NAME) {
24
+ const key = Object.keys(fileGlob).find((f) => f.endsWith(fileName));
25
+ if (key) {
26
+ await fileGlob[key]().catch((e) => {
27
+ if (e instanceof LibsqlError) {
28
+ throw new Error(SEED_ERROR(e.message));
29
+ }
30
+ throw e;
59
31
  });
32
+ return;
60
33
  }
61
- } catch (e) {
62
- if (!(e instanceof Error))
63
- throw e;
64
- (logger ?? console).error(e.message);
65
34
  }
66
35
  }
67
- function seedErrorChecks(mode, { table, writable }, values) {
68
- const tableName = getTableName(table);
69
- if (writable && mode === "build" && process.env.ASTRO_DB_TEST_ENV !== "1") {
70
- throw new Error(SEED_WRITABLE_IN_PROD_ERROR(tableName));
71
- }
72
- if (Array.isArray(values) && values.length === 0) {
73
- throw new Error(SEED_EMPTY_ARRAY_ERROR(tableName));
36
+ async function recreateTables({ db, tables }) {
37
+ const setupQueries = [];
38
+ for (const [name, table] of Object.entries(tables)) {
39
+ const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${sqlite.escapeName(name)}`);
40
+ const createQuery = sql.raw(getCreateTableQuery(name, table));
41
+ const indexQueries = getCreateIndexQueries(name, table);
42
+ setupQueries.push(dropQuery, createQuery, ...indexQueries.map((s) => sql.raw(s)));
74
43
  }
44
+ await db.batch([
45
+ db.run(sql`pragma defer_foreign_keys=true;`),
46
+ ...setupQueries.map((q) => db.run(q))
47
+ ]);
75
48
  }
76
- function getCreateTableQuery(collectionName, collection) {
77
- let query = `CREATE TABLE ${sqlite.escapeName(collectionName)} (`;
49
+ function getDropTableIfExistsQuery(tableName) {
50
+ return `DROP TABLE IF EXISTS ${sqlite.escapeName(tableName)}`;
51
+ }
52
+ function getCreateTableQuery(tableName, table) {
53
+ let query = `CREATE TABLE ${sqlite.escapeName(tableName)} (`;
78
54
  const colQueries = [];
79
- const colHasPrimaryKey = Object.entries(collection.columns).find(
55
+ const colHasPrimaryKey = Object.entries(table.columns).find(
80
56
  ([, column]) => hasPrimaryKey(column)
81
57
  );
82
58
  if (!colHasPrimaryKey) {
83
59
  colQueries.push("_id INTEGER PRIMARY KEY");
84
60
  }
85
- for (const [columnName, column] of Object.entries(collection.columns)) {
61
+ for (const [columnName, column] of Object.entries(table.columns)) {
86
62
  const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
87
63
  column.type
88
64
  )}${getModifiers(columnName, column)}`;
89
65
  colQueries.push(colQuery);
90
66
  }
91
- colQueries.push(...getCreateForeignKeyQueries(collectionName, collection));
67
+ colQueries.push(...getCreateForeignKeyQueries(tableName, table));
92
68
  query += colQueries.join(", ") + ")";
93
69
  return query;
94
70
  }
95
- function getCreateIndexQueries(collectionName, collection) {
71
+ function getCreateIndexQueries(tableName, table) {
96
72
  let queries = [];
97
- for (const [indexName, indexProps] of Object.entries(collection.indexes ?? {})) {
73
+ for (const [indexName, indexProps] of Object.entries(table.indexes ?? {})) {
98
74
  const onColNames = asArray(indexProps.on);
99
75
  const onCols = onColNames.map((colName) => sqlite.escapeName(colName));
100
76
  const unique = indexProps.unique ? "UNIQUE " : "";
101
77
  const indexQuery = `CREATE ${unique}INDEX ${sqlite.escapeName(
102
78
  indexName
103
- )} ON ${sqlite.escapeName(collectionName)} (${onCols.join(", ")})`;
79
+ )} ON ${sqlite.escapeName(tableName)} (${onCols.join(", ")})`;
104
80
  queries.push(indexQuery);
105
81
  }
106
82
  return queries;
107
83
  }
108
- function getCreateForeignKeyQueries(collectionName, collection) {
84
+ function getCreateForeignKeyQueries(tableName, table) {
109
85
  let queries = [];
110
- for (const foreignKey of collection.foreignKeys ?? []) {
86
+ for (const foreignKey of table.foreignKeys ?? []) {
111
87
  const columns = asArray(foreignKey.columns);
112
88
  const references = asArray(foreignKey.references);
113
89
  if (columns.length !== references.length) {
114
- throw new Error(
115
- `Foreign key on ${collectionName} is misconfigured. \`columns\` and \`references\` must be the same length.`
116
- );
90
+ throw new Error(FOREIGN_KEY_REFERENCES_LENGTH_ERROR(tableName));
91
+ }
92
+ const firstReference = references[0];
93
+ if (!firstReference) {
94
+ throw new Error(FOREIGN_KEY_REFERENCES_EMPTY_ERROR(tableName));
117
95
  }
118
- const referencedCollection = references[0]?.schema.collection;
119
- if (!referencedCollection) {
120
- throw new Error(
121
- `Foreign key on ${collectionName} is misconfigured. \`references\` cannot be empty.`
122
- );
96
+ const referencedTable = firstReference.schema.collection;
97
+ if (!referencedTable) {
98
+ throw new Error(FOREIGN_KEY_DNE_ERROR(tableName));
123
99
  }
124
- const query = `FOREIGN KEY (${columns.map((f) => sqlite.escapeName(f)).join(", ")}) REFERENCES ${sqlite.escapeName(referencedCollection)}(${references.map((r) => sqlite.escapeName(r.schema.name)).join(", ")})`;
100
+ const query = `FOREIGN KEY (${columns.map((f) => sqlite.escapeName(f)).join(", ")}) REFERENCES ${sqlite.escapeName(referencedTable)}(${references.map((r) => sqlite.escapeName(r.schema.name)).join(", ")})`;
125
101
  queries.push(query);
126
102
  }
127
103
  return queries;
@@ -156,13 +132,11 @@ function getModifiers(columnName, column) {
156
132
  }
157
133
  const references = getReferencesConfig(column);
158
134
  if (references) {
159
- const { collection, name } = references.schema;
160
- if (!collection || !name) {
161
- throw new Error(
162
- `Column ${collection}.${name} references a collection that does not exist. Did you apply the referenced collection to the \`tables\` object in your Astro config?`
163
- );
135
+ const { collection: tableName, name } = references.schema;
136
+ if (!tableName || !name) {
137
+ throw new Error(REFERENCE_DNE_ERROR(columnName));
164
138
  }
165
- modifiers += ` REFERENCES ${sqlite.escapeName(collection)} (${sqlite.escapeName(name)})`;
139
+ modifiers += ` REFERENCES ${sqlite.escapeName(tableName)} (${sqlite.escapeName(name)})`;
166
140
  }
167
141
  return modifiers;
168
142
  }
@@ -218,13 +192,15 @@ function getDefaultValueSql(columnName, column) {
218
192
  }
219
193
  }
220
194
  export {
195
+ SEED_DEV_FILE_NAME,
221
196
  getCreateForeignKeyQueries,
222
197
  getCreateIndexQueries,
223
198
  getCreateTableQuery,
199
+ getDropTableIfExistsQuery,
224
200
  getModifiers,
225
201
  getReferencesConfig,
226
202
  hasDefault,
227
203
  recreateTables,
228
204
  schemaTypeToSqlType,
229
- seedData
205
+ seedLocal
230
206
  };
@@ -1,6 +1,6 @@
1
- import type { ColumnDataType, ColumnBaseConfig } from 'drizzle-orm';
1
+ import type { ColumnBaseConfig, ColumnDataType } from 'drizzle-orm';
2
2
  import type { SQLiteColumn, SQLiteTableWithColumns } from 'drizzle-orm/sqlite-core';
3
- import type { DBColumn, ColumnsConfig } from '../core/types.js';
3
+ import type { ColumnsConfig, DBColumn, OutputColumnsConfig } from '../core/types.js';
4
4
  type GeneratedConfig<T extends ColumnDataType = ColumnDataType> = Pick<ColumnBaseConfig<T, string>, 'name' | 'tableName' | 'notNull' | 'hasDefault'>;
5
5
  export type AstroText<T extends GeneratedConfig<'string'>> = SQLiteColumn<T & {
6
6
  data: string;
@@ -43,7 +43,7 @@ export type AstroJson<T extends GeneratedConfig<'custom'>> = SQLiteColumn<T & {
43
43
  baseColumn: never;
44
44
  }>;
45
45
  export type Column<T extends DBColumn['type'], S extends GeneratedConfig> = T extends 'boolean' ? AstroBoolean<S> : T extends 'number' ? AstroNumber<S> : T extends 'text' ? AstroText<S> : T extends 'date' ? AstroDate<S> : T extends 'json' ? AstroJson<S> : never;
46
- export type Table<TTableName extends string, TColumns extends ColumnsConfig> = SQLiteTableWithColumns<{
46
+ export type Table<TTableName extends string, TColumns extends OutputColumnsConfig | ColumnsConfig> = SQLiteTableWithColumns<{
47
47
  name: TTableName;
48
48
  schema: undefined;
49
49
  dialect: 'sqlite';
@@ -0,0 +1 @@
1
+ export { asDrizzleTable } from './runtime/index.js';
package/dist/utils.js ADDED
@@ -0,0 +1,4 @@
1
+ import { asDrizzleTable } from "./runtime/index.js";
2
+ export {
3
+ asDrizzleTable
4
+ };
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- /// <reference types="./config-augment.d.ts" />
2
- export * from './dist/index.js';
3
- export { default } from './dist/index.js';
1
+ export { default, cli } from './dist/index.js';
2
+
3
+ declare module 'astro:db' {
4
+ export { defineTable, defineDB, column, sql, NOW, TRUE, FALSE } from './dist/index.js';
5
+ }
package/package.json CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "@astrojs/db",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "types": "./index.d.ts",
7
+ "types": "./dist/index.d.ts",
8
8
  "author": "withastro",
9
9
  "main": "./dist/index.js",
10
10
  "exports": {
11
11
  ".": {
12
- "types": "./index.d.ts",
12
+ "types": "./dist/index.d.ts",
13
13
  "import": "./dist/index.js"
14
14
  },
15
+ "./utils": {
16
+ "types": "./dist/utils.d.ts",
17
+ "import": "./dist/utils.js"
18
+ },
15
19
  "./runtime": {
16
20
  "types": "./dist/runtime/index.d.ts",
17
21
  "import": "./dist/runtime/index.js"
@@ -20,6 +24,10 @@
20
24
  "types": "./dist/runtime/drizzle.d.ts",
21
25
  "import": "./dist/runtime/drizzle.js"
22
26
  },
27
+ "./runtime/config": {
28
+ "types": "./dist/runtime/config.d.ts",
29
+ "import": "./dist/runtime/config.js"
30
+ },
23
31
  "./package.json": "./package.json"
24
32
  },
25
33
  "typesVersions": {
@@ -27,11 +35,17 @@
27
35
  ".": [
28
36
  "./index.d.ts"
29
37
  ],
38
+ "utils": [
39
+ "./dist/utils.d.ts"
40
+ ],
30
41
  "runtime": [
31
42
  "./dist/runtime/index.d.ts"
32
43
  ],
33
44
  "runtime/drizzle": [
34
45
  "./dist/runtime/drizzle.d.ts"
46
+ ],
47
+ "runtime/config": [
48
+ "./dist/runtime/config.d.ts"
35
49
  ]
36
50
  }
37
51
  },
@@ -46,6 +60,7 @@
46
60
  ],
47
61
  "dependencies": {
48
62
  "@libsql/client": "^0.4.3",
63
+ "async-listen": "^3.0.1",
49
64
  "deep-diff": "^1.0.2",
50
65
  "drizzle-orm": "^0.28.6",
51
66
  "kleur": "^4.1.5",
@@ -67,8 +82,8 @@
67
82
  "cheerio": "1.0.0-rc.12",
68
83
  "mocha": "^10.2.0",
69
84
  "typescript": "^5.2.2",
70
- "vite": "^4.4.11",
71
- "astro": "4.4.5",
85
+ "vite": "^5.1.4",
86
+ "astro": "4.4.10",
72
87
  "astro-scripts": "0.0.14"
73
88
  },
74
89
  "scripts": {
@@ -1,4 +0,0 @@
1
- declare namespace Config {
2
- type DBUserConfig = import('./dist/core/types.js').DBUserConfig;
3
- export interface Database extends DBUserConfig {}
4
- }
@@ -1,6 +0,0 @@
1
- import type { AstroConfig } from 'astro';
2
- import type { Arguments } from 'yargs-parser';
3
- export declare function cmd({ config }: {
4
- config: AstroConfig;
5
- flags: Arguments;
6
- }): Promise<void>;
@@ -1,39 +0,0 @@
1
- import { writeFile } from "node:fs/promises";
2
- import {
3
- MIGRATIONS_CREATED,
4
- MIGRATIONS_UP_TO_DATE,
5
- getMigrationStatus,
6
- initializeMigrationsDirectory
7
- } from "../../migrations.js";
8
- import { getMigrationQueries } from "../../migration-queries.js";
9
- import { bgRed, red, reset } from "kleur/colors";
10
- async function cmd({ config }) {
11
- const migration = await getMigrationStatus(config);
12
- if (migration.state === "no-migrations-found") {
13
- await initializeMigrationsDirectory(migration.currentSnapshot);
14
- console.log(MIGRATIONS_CREATED);
15
- return;
16
- } else if (migration.state === "up-to-date") {
17
- console.log(MIGRATIONS_UP_TO_DATE);
18
- return;
19
- }
20
- const { oldSnapshot, newSnapshot, newFilename, diff } = migration;
21
- const { queries: migrationQueries, confirmations } = await getMigrationQueries({
22
- oldSnapshot,
23
- newSnapshot
24
- });
25
- confirmations.map((message) => console.log(bgRed(" !!! ") + " " + red(message)));
26
- const migrationFileContent = {
27
- diff,
28
- db: migrationQueries,
29
- // TODO(fks): Encode the relevant data, instead of the raw message.
30
- // This will give `db push` more control over the formatting of the message.
31
- confirm: confirmations.map((c) => reset(c))
32
- };
33
- const migrationFileName = `./migrations/${newFilename}`;
34
- await writeFile(migrationFileName, JSON.stringify(migrationFileContent, void 0, 2));
35
- console.log(migrationFileName + " created!");
36
- }
37
- export {
38
- cmd
39
- };
@@ -1,34 +0,0 @@
1
- import deepDiff from 'deep-diff';
2
- import { type DBSnapshot } from '../types.js';
3
- import type { AstroConfig } from 'astro';
4
- export type MigrationStatus = {
5
- state: 'no-migrations-found';
6
- currentSnapshot: DBSnapshot;
7
- } | {
8
- state: 'ahead';
9
- oldSnapshot: DBSnapshot;
10
- newSnapshot: DBSnapshot;
11
- diff: deepDiff.Diff<DBSnapshot, DBSnapshot>[];
12
- newFilename: string;
13
- summary: string;
14
- newFileContent?: string;
15
- } | {
16
- state: 'up-to-date';
17
- currentSnapshot: DBSnapshot;
18
- };
19
- export declare function getMigrationStatus(config: AstroConfig): Promise<MigrationStatus>;
20
- export declare const MIGRATIONS_CREATED: string;
21
- export declare const MIGRATIONS_UP_TO_DATE: string;
22
- export declare const MIGRATIONS_NOT_INITIALIZED: string;
23
- export declare const MIGRATION_NEEDED: string;
24
- export declare function getMigrations(): Promise<string[]>;
25
- export declare function loadMigration(migration: string): Promise<{
26
- diff: any[];
27
- db: string[];
28
- confirm?: string[];
29
- }>;
30
- export declare function loadInitialSnapshot(): Promise<DBSnapshot>;
31
- export declare function initializeMigrationsDirectory(currentSnapshot: DBSnapshot): Promise<void>;
32
- export declare function initializeFromMigrations(allMigrationFiles: string[]): Promise<DBSnapshot>;
33
- export declare function createCurrentSnapshot(config: AstroConfig): DBSnapshot;
34
- export declare function createEmptySnapshot(): DBSnapshot;
@@ -1,129 +0,0 @@
1
- import deepDiff from "deep-diff";
2
- import { mkdir, readFile, readdir, writeFile } from "fs/promises";
3
- import { tablesSchema } from "../types.js";
4
- import { cyan, green, yellow } from "kleur/colors";
5
- const { applyChange, diff: generateDiff } = deepDiff;
6
- async function getMigrationStatus(config) {
7
- const currentSnapshot = createCurrentSnapshot(config);
8
- const allMigrationFiles = await getMigrations();
9
- if (allMigrationFiles.length === 0) {
10
- return {
11
- state: "no-migrations-found",
12
- currentSnapshot
13
- };
14
- }
15
- const previousSnapshot = await initializeFromMigrations(allMigrationFiles);
16
- const diff = generateDiff(previousSnapshot, currentSnapshot);
17
- if (diff) {
18
- const n = getNewMigrationNumber(allMigrationFiles);
19
- const newFilename = `${String(n + 1).padStart(4, "0")}_migration.json`;
20
- return {
21
- state: "ahead",
22
- oldSnapshot: previousSnapshot,
23
- newSnapshot: currentSnapshot,
24
- diff,
25
- newFilename,
26
- summary: generateDiffSummary(diff)
27
- };
28
- }
29
- return {
30
- state: "up-to-date",
31
- currentSnapshot
32
- };
33
- }
34
- const MIGRATIONS_CREATED = `${green(
35
- "\u25A0 Migrations initialized!"
36
- )}
37
-
38
- To execute your migrations, run
39
- ${cyan("astro db push")}`;
40
- const MIGRATIONS_UP_TO_DATE = `${green(
41
- "\u25A0 No migrations needed!"
42
- )}
43
-
44
- Your database is up to date.
45
- `;
46
- const MIGRATIONS_NOT_INITIALIZED = `${yellow(
47
- "\u25B6 No migrations found!"
48
- )}
49
-
50
- To scaffold your migrations folder, run
51
- ${cyan("astro db sync")}
52
- `;
53
- const MIGRATION_NEEDED = `${yellow(
54
- "\u25B6 Changes detected!"
55
- )}
56
-
57
- To create the necessary migration file, run
58
- ${cyan("astro db sync")}
59
- `;
60
- function generateDiffSummary(diff) {
61
- return JSON.stringify(diff, null, 2);
62
- }
63
- function getNewMigrationNumber(allMigrationFiles) {
64
- const len = allMigrationFiles.length - 1;
65
- return allMigrationFiles.reduce((acc, curr) => {
66
- const num = Number.parseInt(curr.split("_")[0] ?? len, 10);
67
- return num > acc ? num : acc;
68
- }, 0);
69
- }
70
- async function getMigrations() {
71
- const migrationFiles = await readdir("./migrations").catch((err) => {
72
- if (err.code === "ENOENT") {
73
- return [];
74
- }
75
- throw err;
76
- });
77
- return migrationFiles;
78
- }
79
- async function loadMigration(migration) {
80
- return JSON.parse(await readFile(`./migrations/${migration}`, "utf-8"));
81
- }
82
- async function loadInitialSnapshot() {
83
- const snapshot = JSON.parse(await readFile("./migrations/0000_snapshot.json", "utf-8"));
84
- if (snapshot.experimentalVersion === 1) {
85
- return snapshot;
86
- }
87
- if (!snapshot.schema) {
88
- return { experimentalVersion: 1, schema: snapshot };
89
- }
90
- throw new Error("Invalid snapshot format");
91
- }
92
- async function initializeMigrationsDirectory(currentSnapshot) {
93
- await mkdir("./migrations", { recursive: true });
94
- await writeFile("./migrations/0000_snapshot.json", JSON.stringify(currentSnapshot, void 0, 2));
95
- }
96
- async function initializeFromMigrations(allMigrationFiles) {
97
- const prevSnapshot = await loadInitialSnapshot();
98
- for (const migration of allMigrationFiles) {
99
- if (migration === "0000_snapshot.json")
100
- continue;
101
- const migrationContent = await loadMigration(migration);
102
- migrationContent.diff.forEach((change) => {
103
- applyChange(prevSnapshot, {}, change);
104
- });
105
- }
106
- return prevSnapshot;
107
- }
108
- function createCurrentSnapshot(config) {
109
- const tablesConfig = tablesSchema.parse(config.db?.tables ?? {});
110
- const schema = JSON.parse(JSON.stringify(tablesConfig));
111
- return { experimentalVersion: 1, schema };
112
- }
113
- function createEmptySnapshot() {
114
- return { experimentalVersion: 1, schema: {} };
115
- }
116
- export {
117
- MIGRATIONS_CREATED,
118
- MIGRATIONS_NOT_INITIALIZED,
119
- MIGRATIONS_UP_TO_DATE,
120
- MIGRATION_NEEDED,
121
- createCurrentSnapshot,
122
- createEmptySnapshot,
123
- getMigrationStatus,
124
- getMigrations,
125
- initializeFromMigrations,
126
- initializeMigrationsDirectory,
127
- loadInitialSnapshot,
128
- loadMigration
129
- };
@@ -1,6 +0,0 @@
1
- /**
2
- * Pulled from the mothership, Astro core ❤️
3
- *
4
- * @see https://github.com/withastro/astro/blob/main/packages/astro/src/core/config/config.ts#L121
5
- */
6
- export declare function loadAstroConfig(root: string): Promise<Record<string, unknown>>;
@@ -1,79 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { bold, red } from "kleur/colors";
5
- import { createServer } from "vite";
6
- async function loadAstroConfig(root) {
7
- const configPath = search(root);
8
- if (!configPath)
9
- return {};
10
- try {
11
- return await loadConfigWithVite(configPath);
12
- } catch (e) {
13
- console.error(`${bold(red("[astro]"))} Unable to load Astro config.
14
- `);
15
- throw e;
16
- }
17
- }
18
- function search(root) {
19
- const paths = [
20
- "astro.config.mjs",
21
- "astro.config.js",
22
- "astro.config.ts",
23
- "astro.config.mts",
24
- "astro.config.cjs",
25
- "astro.config.cts"
26
- ].map((p) => path.join(root, p));
27
- for (const file of paths) {
28
- if (fs.existsSync(file)) {
29
- return file;
30
- }
31
- }
32
- }
33
- async function loadConfigWithVite(configPath) {
34
- if (/\.[cm]?js$/.test(configPath)) {
35
- try {
36
- const config = await import(
37
- /* @vite-ignore */
38
- pathToFileURL(configPath).toString() + "?t=" + Date.now()
39
- );
40
- return config.default ?? {};
41
- } catch (e) {
42
- }
43
- }
44
- let server;
45
- try {
46
- server = await createViteServer();
47
- const mod = await server.ssrLoadModule(configPath, { fixStacktrace: true });
48
- return mod.default ?? {};
49
- } finally {
50
- if (server) {
51
- await server.close();
52
- }
53
- }
54
- }
55
- async function createViteServer() {
56
- const viteServer = await createServer({
57
- server: { middlewareMode: true, hmr: false, watch: { ignored: ["**"] } },
58
- optimizeDeps: { disabled: true },
59
- clearScreen: false,
60
- appType: "custom",
61
- ssr: {
62
- // NOTE: Vite doesn't externalize linked packages by default. During testing locally,
63
- // these dependencies trip up Vite's dev SSR transform. Awaiting upstream feature:
64
- // https://github.com/vitejs/vite/pull/10939
65
- external: [
66
- "@astrojs/tailwind",
67
- "@astrojs/mdx",
68
- "@astrojs/react",
69
- "@astrojs/preact",
70
- "@astrojs/sitemap",
71
- "@astrojs/markdoc"
72
- ]
73
- }
74
- });
75
- return viteServer;
76
- }
77
- export {
78
- loadAstroConfig
79
- };