@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.
Files changed (55) hide show
  1. package/dist/core/cli/commands/push/index.d.ts +6 -0
  2. package/dist/{cli → core/cli}/commands/push/index.js +43 -38
  3. package/dist/core/cli/commands/shell/index.d.ts +6 -0
  4. package/dist/{cli → core/cli}/commands/shell/index.js +4 -3
  5. package/dist/core/cli/commands/sync/index.d.ts +6 -0
  6. package/dist/{cli → core/cli}/commands/sync/index.js +2 -2
  7. package/dist/core/cli/commands/verify/index.d.ts +6 -0
  8. package/dist/{cli → core/cli}/commands/verify/index.js +1 -1
  9. package/dist/core/cli/index.d.ts +6 -0
  10. package/dist/core/cli/migration-queries.d.ts +18 -0
  11. package/dist/{cli/queries.js → core/cli/migration-queries.js} +68 -22
  12. package/dist/core/cli/migrations.d.ts +12 -0
  13. package/dist/core/consts.d.ts +6 -0
  14. package/dist/core/consts.js +17 -0
  15. package/dist/core/errors.d.ts +1 -0
  16. package/dist/core/errors.js +7 -0
  17. package/dist/core/integration/error-map.d.ts +6 -0
  18. package/dist/core/integration/file-url.d.ts +2 -0
  19. package/dist/core/integration/index.d.ts +2 -0
  20. package/dist/{integration.js → core/integration/index.js} +25 -19
  21. package/dist/core/integration/load-astro-config.d.ts +6 -0
  22. package/dist/core/integration/typegen.d.ts +5 -0
  23. package/dist/{typegen.js → core/integration/typegen.js} +4 -4
  24. package/dist/core/integration/vite-plugin-db.d.ts +20 -0
  25. package/dist/{vite-plugin-db.js → core/integration/vite-plugin-db.js} +9 -9
  26. package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +9 -0
  27. package/dist/{vite-plugin-inject-env-ts.js → core/integration/vite-plugin-inject-env-ts.js} +1 -1
  28. package/dist/core/queries.d.ts +19 -0
  29. package/dist/core/queries.js +151 -0
  30. package/dist/core/types.d.ts +2913 -0
  31. package/dist/{types.js → core/types.js} +66 -0
  32. package/dist/core/utils.d.ts +4 -0
  33. package/dist/core/utils.js +13 -0
  34. package/dist/index.d.ts +4 -5
  35. package/dist/index.js +3 -3
  36. package/dist/runtime/db-client.d.ts +7 -0
  37. package/dist/runtime/db-client.js +90 -0
  38. package/dist/runtime/drizzle.d.ts +1 -0
  39. package/dist/runtime/index.d.ts +26 -0
  40. package/dist/runtime/index.js +123 -0
  41. package/dist/runtime/types.d.ts +74 -0
  42. package/dist/runtime/types.js +0 -0
  43. package/package.json +17 -14
  44. package/dist/config.js +0 -72
  45. package/dist/consts.js +0 -21
  46. package/dist/errors.js +0 -15
  47. package/dist/internal.js +0 -308
  48. package/dist/utils-runtime.js +0 -52
  49. package/dist/utils.js +0 -39
  50. /package/dist/{cli → core/cli}/index.js +0 -0
  51. /package/dist/{migrations.js → core/cli/migrations.js} +0 -0
  52. /package/dist/{error-map.js → core/integration/error-map.js} +0 -0
  53. /package/dist/{file-url-integration.js → core/integration/file-url.js} +0 -0
  54. /package/dist/{load-astro-config.js → core/integration/load-astro-config.js} +0 -0
  55. /package/dist/{internal-drizzle.js → runtime/drizzle.js} +0 -0
@@ -1,4 +1,5 @@
1
- import { DRIZZLE_MOD_IMPORT, INTERNAL_MOD_IMPORT, VIRTUAL_MODULE_ID, DB_PATH } from "./consts.js";
1
+ import { RUNTIME_IMPORT, VIRTUAL_MODULE_ID, DB_PATH, RUNTIME_DRIZZLE_IMPORT } from "../consts.js";
2
+ import { fileURLToPath } from "node:url";
2
3
  const resolvedVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
3
4
  function vitePluginDb(params) {
4
5
  return {
@@ -19,12 +20,11 @@ function vitePluginDb(params) {
19
20
  }
20
21
  };
21
22
  }
22
- function getVirtualModContents({
23
- collections
24
- }) {
23
+ function getVirtualModContents({ collections, root }) {
24
+ const dbUrl = new URL(DB_PATH, root);
25
25
  return `
26
- import { collectionToTable, createLocalDatabaseClient } from ${INTERNAL_MOD_IMPORT};
27
- import dbUrl from './.astro/content.db?fileurl';
26
+ import { collectionToTable, createLocalDatabaseClient } from ${RUNTIME_IMPORT};
27
+ import dbUrl from '${fileURLToPath(dbUrl)}?fileurl';
28
28
 
29
29
  const params = ${JSON.stringify({
30
30
  collections,
@@ -34,7 +34,7 @@ params.dbUrl = dbUrl;
34
34
 
35
35
  export const db = await createLocalDatabaseClient(params);
36
36
 
37
- export * from ${DRIZZLE_MOD_IMPORT};
37
+ export * from ${RUNTIME_DRIZZLE_IMPORT};
38
38
 
39
39
  ${getStringifiedCollectionExports(collections)}
40
40
  `;
@@ -44,12 +44,12 @@ function getStudioVirtualModContents({
44
44
  appToken
45
45
  }) {
46
46
  return `
47
- import {collectionToTable, createRemoteDatabaseClient} from ${INTERNAL_MOD_IMPORT};
47
+ import {collectionToTable, createRemoteDatabaseClient} from ${RUNTIME_IMPORT};
48
48
 
49
49
  export const db = await createRemoteDatabaseClient(${JSON.stringify(
50
50
  appToken
51
51
  )}, import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL);
52
- export * from ${DRIZZLE_MOD_IMPORT};
52
+ export * from ${RUNTIME_DRIZZLE_IMPORT};
53
53
 
54
54
  ${getStringifiedCollectionExports(collections)}
55
55
  `;
@@ -0,0 +1,9 @@
1
+ import type { VitePlugin } from '../utils.js';
2
+ export declare function vitePluginInjectEnvTs({ srcDir, root }: {
3
+ srcDir: URL;
4
+ root: URL;
5
+ }): VitePlugin;
6
+ export declare function setUpEnvTs({ srcDir, root }: {
7
+ srcDir: URL;
8
+ root: URL;
9
+ }): Promise<void>;
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { bold, cyan } from "kleur/colors";
6
6
  import { normalizePath } from "vite";
7
- import { DB_TYPES_FILE } from "./consts.js";
7
+ import { DB_TYPES_FILE } from "../consts.js";
8
8
  function vitePluginInjectEnvTs({ srcDir, root }) {
9
9
  return {
10
10
  name: "db-inject-env-ts",
@@ -0,0 +1,19 @@
1
+ import type { SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy';
2
+ import { type BooleanField, type DBCollection, type DBCollections, type DBField, type DateField, type FieldType, type JsonField, type NumberField, type TextField } from '../core/types.js';
3
+ import type { AstroIntegrationLogger } from 'astro';
4
+ import type { DBUserConfig } from '../core/types.js';
5
+ export declare function setupDbTables({ db, data, collections, logger, mode, }: {
6
+ db: SqliteRemoteDatabase;
7
+ data?: DBUserConfig['data'];
8
+ collections: DBCollections;
9
+ logger?: AstroIntegrationLogger;
10
+ mode: 'dev' | 'build';
11
+ }): Promise<void>;
12
+ export declare function getCreateTableQuery(collectionName: string, collection: DBCollection): string;
13
+ export declare function getCreateIndexQueries(collectionName: string, collection: Pick<DBCollection, 'indexes'>): string[];
14
+ export declare function schemaTypeToSqlType(type: FieldType): 'text' | 'integer';
15
+ export declare function getModifiers(fieldName: string, field: DBField): string;
16
+ type WithDefaultDefined<T extends DBField> = T & Required<Pick<T, 'default'>>;
17
+ type DBFieldWithDefault = WithDefaultDefined<TextField> | WithDefaultDefined<DateField> | WithDefaultDefined<NumberField> | WithDefaultDefined<BooleanField> | WithDefaultDefined<JsonField>;
18
+ export declare function hasDefault(field: DBField): field is DBFieldWithDefault;
19
+ export {};
@@ -0,0 +1,151 @@
1
+ import {
2
+ } from "../core/types.js";
3
+ import { bold } from "kleur/colors";
4
+ import { sql } from "drizzle-orm";
5
+ import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
6
+ import { collectionToTable, hasPrimaryKey } from "../runtime/index.js";
7
+ const sqlite = new SQLiteAsyncDialect();
8
+ async function setupDbTables({
9
+ db,
10
+ data,
11
+ collections,
12
+ logger,
13
+ mode
14
+ }) {
15
+ const setupQueries = [];
16
+ for (const [name, collection] of Object.entries(collections)) {
17
+ const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${name}`);
18
+ const createQuery = sql.raw(getCreateTableQuery(name, collection));
19
+ const indexQueries = getCreateIndexQueries(name, collection);
20
+ setupQueries.push(dropQuery, createQuery, ...indexQueries.map((s) => sql.raw(s)));
21
+ }
22
+ for (const q of setupQueries) {
23
+ await db.run(q);
24
+ }
25
+ if (data) {
26
+ for (const [name, collection] of Object.entries(collections)) {
27
+ const table = collectionToTable(name, collection);
28
+ collection._setMeta?.({ table });
29
+ }
30
+ try {
31
+ await data({
32
+ async seed({ table }, values) {
33
+ const result = Array.isArray(values) ? (
34
+ // TODO: fix values typing once we can infer fields type correctly
35
+ await db.insert(table).values(values).returning()
36
+ ) : await db.insert(table).values(values).returning().get();
37
+ return result;
38
+ },
39
+ db,
40
+ mode
41
+ });
42
+ } catch (e) {
43
+ (logger ?? console).error(
44
+ `Failed to seed data. Did you update to match recent schema changes? Full error:
45
+
46
+ ${e}`
47
+ );
48
+ }
49
+ }
50
+ }
51
+ function getCreateTableQuery(collectionName, collection) {
52
+ let query = `CREATE TABLE ${sqlite.escapeName(collectionName)} (`;
53
+ const colQueries = [];
54
+ const colHasPrimaryKey = Object.entries(collection.fields).find(
55
+ ([, field]) => hasPrimaryKey(field)
56
+ );
57
+ if (!colHasPrimaryKey) {
58
+ colQueries.push("_id INTEGER PRIMARY KEY");
59
+ }
60
+ for (const [columnName, column] of Object.entries(collection.fields)) {
61
+ const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
62
+ column.type
63
+ )}${getModifiers(columnName, column)}`;
64
+ colQueries.push(colQuery);
65
+ }
66
+ query += colQueries.join(", ") + ")";
67
+ return query;
68
+ }
69
+ function getCreateIndexQueries(collectionName, collection) {
70
+ let queries = [];
71
+ for (const [indexName, indexProps] of Object.entries(collection.indexes ?? {})) {
72
+ const onColNames = Array.isArray(indexProps.on) ? indexProps.on : [indexProps.on];
73
+ const onCols = onColNames.map((colName) => sqlite.escapeName(colName));
74
+ const unique = indexProps.unique ? "UNIQUE " : "";
75
+ const indexQuery = `CREATE ${unique}INDEX ${sqlite.escapeName(
76
+ indexName
77
+ )} ON ${sqlite.escapeName(collectionName)} (${onCols.join(", ")})`;
78
+ queries.push(indexQuery);
79
+ }
80
+ return queries;
81
+ }
82
+ function schemaTypeToSqlType(type) {
83
+ switch (type) {
84
+ case "date":
85
+ case "text":
86
+ case "json":
87
+ return "text";
88
+ case "number":
89
+ case "boolean":
90
+ return "integer";
91
+ }
92
+ }
93
+ function getModifiers(fieldName, field) {
94
+ let modifiers = "";
95
+ if (hasPrimaryKey(field)) {
96
+ return " PRIMARY KEY";
97
+ }
98
+ if (!field.optional) {
99
+ modifiers += " NOT NULL";
100
+ }
101
+ if (field.unique) {
102
+ modifiers += " UNIQUE";
103
+ }
104
+ if (hasDefault(field)) {
105
+ modifiers += ` DEFAULT ${getDefaultValueSql(fieldName, field)}`;
106
+ }
107
+ return modifiers;
108
+ }
109
+ function hasDefault(field) {
110
+ if (field.default !== void 0) {
111
+ return true;
112
+ }
113
+ if (hasPrimaryKey(field) && field.type === "number") {
114
+ return true;
115
+ }
116
+ return false;
117
+ }
118
+ function getDefaultValueSql(columnName, column) {
119
+ switch (column.type) {
120
+ case "boolean":
121
+ return column.default ? "TRUE" : "FALSE";
122
+ case "number":
123
+ return `${column.default || "AUTOINCREMENT"}`;
124
+ case "text":
125
+ return sqlite.escapeString(column.default);
126
+ case "date":
127
+ return column.default === "now" ? "CURRENT_TIMESTAMP" : sqlite.escapeString(column.default);
128
+ case "json": {
129
+ let stringified = "";
130
+ try {
131
+ stringified = JSON.stringify(column.default);
132
+ } catch (e) {
133
+ console.log(
134
+ `Invalid default value for column ${bold(
135
+ columnName
136
+ )}. Defaults must be valid JSON when using the \`json()\` type.`
137
+ );
138
+ process.exit(0);
139
+ }
140
+ return sqlite.escapeString(stringified);
141
+ }
142
+ }
143
+ }
144
+ export {
145
+ getCreateIndexQueries,
146
+ getCreateTableQuery,
147
+ getModifiers,
148
+ hasDefault,
149
+ schemaTypeToSqlType,
150
+ setupDbTables
151
+ };