@astrojs/db 0.3.5 → 0.4.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 (61) hide show
  1. package/dist/core/cli/commands/link/index.js +7 -3
  2. package/dist/core/cli/commands/push/index.js +3 -3
  3. package/dist/core/cli/migration-queries.d.ts +4 -4
  4. package/dist/core/cli/migration-queries.js +73 -73
  5. package/dist/core/cli/migrations.js +15 -7
  6. package/dist/core/errors.js +7 -3
  7. package/dist/core/integration/file-url.js +2 -1
  8. package/dist/core/integration/index.js +106 -57
  9. package/dist/core/integration/typegen.d.ts +3 -3
  10. package/dist/core/integration/typegen.js +8 -8
  11. package/dist/core/integration/vite-plugin-db.d.ts +14 -9
  12. package/dist/core/integration/vite-plugin-db.js +15 -12
  13. package/dist/core/integration/vite-plugin-inject-env-ts.d.ts +4 -2
  14. package/dist/core/integration/vite-plugin-inject-env-ts.js +8 -4
  15. package/dist/core/queries.d.ts +12 -12
  16. package/dist/core/queries.js +49 -46
  17. package/dist/core/types.d.ts +232 -231
  18. package/dist/core/types.js +56 -55
  19. package/dist/core/utils.js +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +4 -4
  22. package/dist/runtime/db-client.d.ts +9 -4
  23. package/dist/runtime/db-client.js +11 -7
  24. package/dist/runtime/index.d.ts +7 -7
  25. package/dist/runtime/index.js +27 -29
  26. package/dist/runtime/types.d.ts +7 -7
  27. package/package.json +3 -5
  28. package/components/Renderer.astro +0 -14
  29. package/components/astro-env.d.ts +0 -1
  30. package/components/index.ts +0 -2
  31. package/components/tsconfig.json +0 -7
  32. package/dist/cli/commands/push/index.d.ts +0 -6
  33. package/dist/cli/commands/shell/index.d.ts +0 -6
  34. package/dist/cli/commands/sync/index.d.ts +0 -6
  35. package/dist/cli/commands/verify/index.d.ts +0 -6
  36. package/dist/cli/index.d.ts +0 -6
  37. package/dist/cli/queries.d.ts +0 -18
  38. package/dist/cli/seed.d.ts +0 -6
  39. package/dist/cli/sync/admin.d.ts +0 -33
  40. package/dist/cli/sync/index.d.ts +0 -1
  41. package/dist/cli/sync/migrate.d.ts +0 -1
  42. package/dist/cli/sync/queries.d.ts +0 -19
  43. package/dist/cli/sync/remote-db.d.ts +0 -1
  44. package/dist/config.d.ts +0 -1374
  45. package/dist/consts.d.ts +0 -7
  46. package/dist/core/cli/commands/sync/index.d.ts +0 -6
  47. package/dist/error-map.d.ts +0 -6
  48. package/dist/errors.d.ts +0 -3
  49. package/dist/file-url-integration.d.ts +0 -2
  50. package/dist/integration.d.ts +0 -2
  51. package/dist/internal-drizzle.d.ts +0 -1
  52. package/dist/internal.d.ts +0 -47
  53. package/dist/load-astro-config.d.ts +0 -6
  54. package/dist/migrations.d.ts +0 -12
  55. package/dist/root.d.ts +0 -3
  56. package/dist/typegen.d.ts +0 -5
  57. package/dist/types.d.ts +0 -1604
  58. package/dist/utils-runtime.d.ts +0 -1
  59. package/dist/utils.d.ts +0 -59
  60. package/dist/vite-plugin-db.d.ts +0 -19
  61. package/dist/vite-plugin-inject-env-ts.d.ts +0 -9
@@ -1,14 +1,14 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { mkdir, writeFile } from "node:fs/promises";
3
3
  import { DB_TYPES_FILE, RUNTIME_DRIZZLE_IMPORT, RUNTIME_IMPORT } from "../consts.js";
4
- async function typegen({ collections, root }) {
4
+ async function typegen({ tables, root }) {
5
5
  const content = `// This file is generated by \`studio sync\`
6
6
  declare module 'astro:db' {
7
7
  export const db: import(${RUNTIME_IMPORT}).SqliteDB;
8
8
  export const dbUrl: string;
9
9
  export * from ${RUNTIME_DRIZZLE_IMPORT};
10
10
 
11
- ${Object.entries(collections).map(([name, collection]) => generateTableType(name, collection)).join("\n")}
11
+ ${Object.entries(tables).map(([name, collection]) => generateTableType(name, collection)).join("\n")}
12
12
  }
13
13
  `;
14
14
  const dotAstroDir = new URL(".astro/", root);
@@ -22,13 +22,13 @@ function generateTableType(name, collection) {
22
22
  ${JSON.stringify(name)},
23
23
  ${JSON.stringify(
24
24
  Object.fromEntries(
25
- Object.entries(collection.fields).map(([fieldName, field]) => [
26
- fieldName,
25
+ Object.entries(collection.columns).map(([columnName, column]) => [
26
+ columnName,
27
27
  {
28
- // Only select fields Drizzle needs for inference
29
- type: field.type,
30
- optional: field.schema.optional,
31
- default: field.schema.default
28
+ // Only select columns Drizzle needs for inference
29
+ type: column.type,
30
+ optional: column.schema.optional,
31
+ default: column.schema.default
32
32
  }
33
33
  ])
34
34
  )
@@ -1,20 +1,25 @@
1
- import type { DBCollections } from '../types.js';
1
+ import type { DBTables } from '../types.js';
2
2
  import type { VitePlugin } from '../utils.js';
3
- export declare function vitePluginDb(params: {
3
+ type LateSchema = {
4
+ tables: () => DBTables;
5
+ };
6
+ type VitePluginDBParams = {
4
7
  connectToStudio: false;
5
- collections: DBCollections;
8
+ schemas: LateSchema;
6
9
  root: URL;
7
10
  } | {
8
11
  connectToStudio: true;
9
- collections: DBCollections;
12
+ schemas: LateSchema;
10
13
  appToken: string;
11
14
  root: URL;
12
- }): VitePlugin;
13
- export declare function getVirtualModContents({ collections, root, }: {
14
- collections: DBCollections;
15
+ };
16
+ export declare function vitePluginDb(params: VitePluginDBParams): VitePlugin;
17
+ export declare function getVirtualModContents({ tables, root }: {
18
+ tables: DBTables;
15
19
  root: URL;
16
20
  }): string;
17
- export declare function getStudioVirtualModContents({ collections, appToken, }: {
18
- collections: DBCollections;
21
+ export declare function getStudioVirtualModContents({ tables, appToken, }: {
22
+ tables: DBTables;
19
23
  appToken: string;
20
24
  }): string;
25
+ export {};
@@ -13,23 +13,26 @@ function vitePluginDb(params) {
13
13
  if (id !== resolvedVirtualModuleId)
14
14
  return;
15
15
  if (params.connectToStudio) {
16
- return getStudioVirtualModContents(params);
16
+ return getStudioVirtualModContents({
17
+ appToken: params.appToken,
18
+ tables: params.schemas.tables()
19
+ });
17
20
  }
18
- return getVirtualModContents(params);
21
+ return getVirtualModContents({
22
+ root: params.root,
23
+ tables: params.schemas.tables()
24
+ });
19
25
  }
20
26
  };
21
27
  }
22
- function getVirtualModContents({
23
- collections,
24
- root
25
- }) {
28
+ function getVirtualModContents({ tables, root }) {
26
29
  const dbUrl = new URL(DB_PATH, root);
27
30
  return `
28
31
  import { collectionToTable, createLocalDatabaseClient } from ${RUNTIME_IMPORT};
29
32
  import dbUrl from ${JSON.stringify(`${dbUrl}?fileurl`)};
30
33
 
31
34
  const params = ${JSON.stringify({
32
- collections,
35
+ tables,
33
36
  seeding: false
34
37
  })};
35
38
  params.dbUrl = dbUrl;
@@ -38,11 +41,11 @@ export const db = await createLocalDatabaseClient(params);
38
41
 
39
42
  export * from ${RUNTIME_DRIZZLE_IMPORT};
40
43
 
41
- ${getStringifiedCollectionExports(collections)}
44
+ ${getStringifiedCollectionExports(tables)}
42
45
  `;
43
46
  }
44
47
  function getStudioVirtualModContents({
45
- collections,
48
+ tables,
46
49
  appToken
47
50
  }) {
48
51
  return `
@@ -53,11 +56,11 @@ export const db = await createRemoteDatabaseClient(${JSON.stringify(
53
56
  )}, import.meta.env.ASTRO_STUDIO_REMOTE_DB_URL);
54
57
  export * from ${RUNTIME_DRIZZLE_IMPORT};
55
58
 
56
- ${getStringifiedCollectionExports(collections)}
59
+ ${getStringifiedCollectionExports(tables)}
57
60
  `;
58
61
  }
59
- function getStringifiedCollectionExports(collections) {
60
- return Object.entries(collections).map(
62
+ function getStringifiedCollectionExports(tables) {
63
+ return Object.entries(tables).map(
61
64
  ([name, collection]) => `export const ${name} = collectionToTable(${JSON.stringify(name)}, ${JSON.stringify(
62
65
  collection
63
66
  )}, false)`
@@ -1,9 +1,11 @@
1
1
  import type { VitePlugin } from '../utils.js';
2
+ import type { AstroIntegrationLogger } from 'astro';
2
3
  export declare function vitePluginInjectEnvTs({ srcDir, root }: {
3
4
  srcDir: URL;
4
5
  root: URL;
5
- }): VitePlugin;
6
- export declare function setUpEnvTs({ srcDir, root }: {
6
+ }, logger: AstroIntegrationLogger): VitePlugin;
7
+ export declare function setUpEnvTs({ srcDir, root, logger, }: {
7
8
  srcDir: URL;
8
9
  root: URL;
10
+ logger: AstroIntegrationLogger;
9
11
  }): Promise<void>;
@@ -5,16 +5,20 @@ import { fileURLToPath } from "node:url";
5
5
  import { bold, cyan } from "kleur/colors";
6
6
  import { normalizePath } from "vite";
7
7
  import { DB_TYPES_FILE } from "../consts.js";
8
- function vitePluginInjectEnvTs({ srcDir, root }) {
8
+ function vitePluginInjectEnvTs({ srcDir, root }, logger) {
9
9
  return {
10
10
  name: "db-inject-env-ts",
11
11
  enforce: "post",
12
12
  async config() {
13
- await setUpEnvTs({ srcDir, root });
13
+ await setUpEnvTs({ srcDir, root, logger });
14
14
  }
15
15
  };
16
16
  }
17
- async function setUpEnvTs({ srcDir, root }) {
17
+ async function setUpEnvTs({
18
+ srcDir,
19
+ root,
20
+ logger
21
+ }) {
18
22
  const envTsPath = getEnvTsPath({ srcDir });
19
23
  const envTsPathRelativetoRoot = normalizePath(
20
24
  path.relative(fileURLToPath(root), fileURLToPath(envTsPath))
@@ -29,7 +33,7 @@ async function setUpEnvTs({ srcDir, root }) {
29
33
  typesEnvContents = `${dbTypeReference}
30
34
  ${typesEnvContents}`;
31
35
  await writeFile(envTsPath, typesEnvContents, "utf-8");
32
- console.info(`${cyan(bold("[astro:db]"))} Added ${bold(envTsPathRelativetoRoot)} types`);
36
+ logger.info(`${cyan(bold("[astro:db]"))} Added ${bold(envTsPathRelativetoRoot)} types`);
33
37
  }
34
38
  }
35
39
  }
@@ -1,10 +1,10 @@
1
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';
2
+ import { type BooleanColumn, type DBTable, type DBTables, type DBColumn, type DateColumn, type ColumnType, type JsonColumn, type NumberColumn, type TextColumn } from '../core/types.js';
3
3
  import type { AstroIntegrationLogger } from 'astro';
4
4
  import type { DBUserConfig } from '../core/types.js';
5
- export declare function recreateTables({ db, collections, }: {
5
+ export declare function recreateTables({ db, tables, }: {
6
6
  db: SqliteRemoteDatabase;
7
- collections: DBCollections;
7
+ tables: DBTables;
8
8
  }): Promise<void>;
9
9
  export declare function seedData({ db, data, logger, mode, }: {
10
10
  db: SqliteRemoteDatabase;
@@ -12,12 +12,12 @@ export declare function seedData({ db, data, logger, mode, }: {
12
12
  logger?: AstroIntegrationLogger;
13
13
  mode: 'dev' | 'build';
14
14
  }): Promise<void>;
15
- export declare function getCreateTableQuery(collectionName: string, collection: DBCollection): string;
16
- export declare function getCreateIndexQueries(collectionName: string, collection: Pick<DBCollection, 'indexes'>): string[];
17
- export declare function getCreateForeignKeyQueries(collectionName: string, collection: DBCollection): string[];
18
- export declare function schemaTypeToSqlType(type: FieldType): 'text' | 'integer';
19
- export declare function getModifiers(fieldName: string, field: DBField): string;
20
- export declare function getReferencesConfig(field: DBField): {
15
+ export declare function getCreateTableQuery(collectionName: string, collection: DBTable): string;
16
+ export declare function getCreateIndexQueries(collectionName: string, collection: Pick<DBTable, 'indexes'>): string[];
17
+ export declare function getCreateForeignKeyQueries(collectionName: string, collection: DBTable): string[];
18
+ export declare function schemaTypeToSqlType(type: ColumnType): 'text' | 'integer';
19
+ export declare function getModifiers(columnName: string, column: DBColumn): string;
20
+ export declare function getReferencesConfig(column: DBColumn): {
21
21
  type: "number";
22
22
  schema: ({
23
23
  unique: boolean;
@@ -70,9 +70,9 @@ export declare function getReferencesConfig(field: DBField): {
70
70
  references?: any | undefined;
71
71
  });
72
72
  } | undefined;
73
- type WithDefaultDefined<T extends DBField> = T & {
73
+ type WithDefaultDefined<T extends DBColumn> = T & {
74
74
  schema: Required<Pick<T['schema'], 'default'>>;
75
75
  };
76
- type DBFieldWithDefault = WithDefaultDefined<TextField> | WithDefaultDefined<DateField> | WithDefaultDefined<NumberField> | WithDefaultDefined<BooleanField> | WithDefaultDefined<JsonField>;
77
- export declare function hasDefault(field: DBField): field is DBFieldWithDefault;
76
+ type DBColumnWithDefault = WithDefaultDefined<TextColumn> | WithDefaultDefined<DateColumn> | WithDefaultDefined<NumberColumn> | WithDefaultDefined<BooleanColumn> | WithDefaultDefined<JsonColumn>;
77
+ export declare function hasDefault(column: DBColumn): column is DBColumnWithDefault;
78
78
  export {};
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  } from "../core/types.js";
3
- import { bold, red } from "kleur/colors";
3
+ import { bold } from "kleur/colors";
4
4
  import { sql, getTableName } from "drizzle-orm";
5
5
  import { SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
6
6
  import { hasPrimaryKey } from "../runtime/index.js";
@@ -9,10 +9,10 @@ import { SEED_WRITABLE_IN_PROD_ERROR } from "./errors.js";
9
9
  const sqlite = new SQLiteAsyncDialect();
10
10
  async function recreateTables({
11
11
  db,
12
- collections
12
+ tables
13
13
  }) {
14
14
  const setupQueries = [];
15
- for (const [name, collection] of Object.entries(collections)) {
15
+ for (const [name, collection] of Object.entries(tables)) {
16
16
  const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${sqlite.escapeName(name)}`);
17
17
  const createQuery = sql.raw(getCreateTableQuery(name, collection));
18
18
  const indexQueries = getCreateIndexQueries(name, collection);
@@ -29,28 +29,31 @@ async function seedData({
29
29
  mode
30
30
  }) {
31
31
  try {
32
- await data({
33
- seed: async ({ table, writable }, values) => {
34
- if (writable && mode === "build" && process.env.ASTRO_DB_TEST_ENV !== "1") {
35
- (logger ?? console).error(SEED_WRITABLE_IN_PROD_ERROR(getTableName(table)));
36
- process.exit(1);
37
- }
38
- await db.insert(table).values(values);
39
- },
40
- seedReturning: async ({ table, writable }, values) => {
41
- if (writable && mode === "build" && process.env.ASTRO_DB_TEST_ENV !== "1") {
42
- (logger ?? console).error(SEED_WRITABLE_IN_PROD_ERROR(getTableName(table)));
43
- process.exit(1);
44
- }
45
- let result = db.insert(table).values(values).returning();
46
- if (!Array.isArray(values)) {
47
- result = result.get();
48
- }
49
- return result;
50
- },
51
- db,
52
- mode
53
- });
32
+ const dataFns = Array.isArray(data) ? data : [data];
33
+ for (const dataFn of dataFns) {
34
+ await dataFn({
35
+ seed: async ({ table, writable }, values) => {
36
+ if (writable && mode === "build" && process.env.ASTRO_DB_TEST_ENV !== "1") {
37
+ (logger ?? console).error(SEED_WRITABLE_IN_PROD_ERROR(getTableName(table)));
38
+ process.exit(1);
39
+ }
40
+ await db.insert(table).values(values);
41
+ },
42
+ seedReturning: async ({ table, writable }, values) => {
43
+ if (writable && mode === "build" && process.env.ASTRO_DB_TEST_ENV !== "1") {
44
+ (logger ?? console).error(SEED_WRITABLE_IN_PROD_ERROR(getTableName(table)));
45
+ process.exit(1);
46
+ }
47
+ let result = db.insert(table).values(values).returning();
48
+ if (!Array.isArray(values)) {
49
+ result = result.get();
50
+ }
51
+ return result;
52
+ },
53
+ db,
54
+ mode
55
+ });
56
+ }
54
57
  } catch (error) {
55
58
  (logger ?? console).error(
56
59
  `Failed to seed data. Did you update to match recent schema changes?`
@@ -61,13 +64,13 @@ async function seedData({
61
64
  function getCreateTableQuery(collectionName, collection) {
62
65
  let query = `CREATE TABLE ${sqlite.escapeName(collectionName)} (`;
63
66
  const colQueries = [];
64
- const colHasPrimaryKey = Object.entries(collection.fields).find(
65
- ([, field]) => hasPrimaryKey(field)
67
+ const colHasPrimaryKey = Object.entries(collection.columns).find(
68
+ ([, column]) => hasPrimaryKey(column)
66
69
  );
67
70
  if (!colHasPrimaryKey) {
68
71
  colQueries.push("_id INTEGER PRIMARY KEY");
69
72
  }
70
- for (const [columnName, column] of Object.entries(collection.fields)) {
73
+ for (const [columnName, column] of Object.entries(collection.columns)) {
71
74
  const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
72
75
  column.type
73
76
  )}${getModifiers(columnName, column)}`;
@@ -93,11 +96,11 @@ function getCreateIndexQueries(collectionName, collection) {
93
96
  function getCreateForeignKeyQueries(collectionName, collection) {
94
97
  let queries = [];
95
98
  for (const foreignKey of collection.foreignKeys ?? []) {
96
- const fields = asArray(foreignKey.fields);
99
+ const columns = asArray(foreignKey.columns);
97
100
  const references = asArray(foreignKey.references);
98
- if (fields.length !== references.length) {
101
+ if (columns.length !== references.length) {
99
102
  throw new Error(
100
- `Foreign key on ${collectionName} is misconfigured. \`fields\` and \`references\` must be the same length.`
103
+ `Foreign key on ${collectionName} is misconfigured. \`columns\` and \`references\` must be the same length.`
101
104
  );
102
105
  }
103
106
  const referencedCollection = references[0]?.schema.collection;
@@ -106,7 +109,7 @@ function getCreateForeignKeyQueries(collectionName, collection) {
106
109
  `Foreign key on ${collectionName} is misconfigured. \`references\` cannot be empty.`
107
110
  );
108
111
  }
109
- const query = `FOREIGN KEY (${fields.map((f) => sqlite.escapeName(f)).join(", ")}) REFERENCES ${sqlite.escapeName(referencedCollection)}(${references.map((r) => sqlite.escapeName(r.schema.name)).join(", ")})`;
112
+ const query = `FOREIGN KEY (${columns.map((f) => sqlite.escapeName(f)).join(", ")}) REFERENCES ${sqlite.escapeName(referencedCollection)}(${references.map((r) => sqlite.escapeName(r.schema.name)).join(", ")})`;
110
113
  queries.push(query);
111
114
  }
112
115
  return queries;
@@ -125,43 +128,43 @@ function schemaTypeToSqlType(type) {
125
128
  return "integer";
126
129
  }
127
130
  }
128
- function getModifiers(fieldName, field) {
131
+ function getModifiers(columnName, column) {
129
132
  let modifiers = "";
130
- if (hasPrimaryKey(field)) {
133
+ if (hasPrimaryKey(column)) {
131
134
  return " PRIMARY KEY";
132
135
  }
133
- if (!field.schema.optional) {
136
+ if (!column.schema.optional) {
134
137
  modifiers += " NOT NULL";
135
138
  }
136
- if (field.schema.unique) {
139
+ if (column.schema.unique) {
137
140
  modifiers += " UNIQUE";
138
141
  }
139
- if (hasDefault(field)) {
140
- modifiers += ` DEFAULT ${getDefaultValueSql(fieldName, field)}`;
142
+ if (hasDefault(column)) {
143
+ modifiers += ` DEFAULT ${getDefaultValueSql(columnName, column)}`;
141
144
  }
142
- const references = getReferencesConfig(field);
145
+ const references = getReferencesConfig(column);
143
146
  if (references) {
144
147
  const { collection, name } = references.schema;
145
148
  if (!collection || !name) {
146
149
  throw new Error(
147
- `Field ${collection}.${name} references a collection that does not exist. Did you apply the referenced collection to the \`collections\` object in your Astro config?`
150
+ `Column ${collection}.${name} references a collection that does not exist. Did you apply the referenced collection to the \`tables\` object in your Astro config?`
148
151
  );
149
152
  }
150
153
  modifiers += ` REFERENCES ${sqlite.escapeName(collection)} (${sqlite.escapeName(name)})`;
151
154
  }
152
155
  return modifiers;
153
156
  }
154
- function getReferencesConfig(field) {
155
- const canHaveReferences = field.type === "number" || field.type === "text";
157
+ function getReferencesConfig(column) {
158
+ const canHaveReferences = column.type === "number" || column.type === "text";
156
159
  if (!canHaveReferences)
157
160
  return void 0;
158
- return field.schema.references;
161
+ return column.schema.references;
159
162
  }
160
- function hasDefault(field) {
161
- if (field.schema.default !== void 0) {
163
+ function hasDefault(column) {
164
+ if (column.schema.default !== void 0) {
162
165
  return true;
163
166
  }
164
- if (hasPrimaryKey(field) && field.type === "number") {
167
+ if (hasPrimaryKey(column) && column.type === "number") {
165
168
  return true;
166
169
  }
167
170
  return false;