diff --git a/packages/db/src/config.ts b/packages/db/src/config.ts index 5246e80f17..4f497c748a 100644 --- a/packages/db/src/config.ts +++ b/packages/db/src/config.ts @@ -1,3 +1,5 @@ +import type { Table } from './internal.js'; +import type { collectionSchema } from './types.js'; import { type BooleanField, type DBFieldInput, @@ -5,7 +7,6 @@ import { type JsonField, type NumberField, type TextField, - type collectionSchema, collectionsSchema, type MaybePromise, type DbDataContext, @@ -30,11 +31,11 @@ export const astroConfigWithDbSchema = z.object({ db: dbConfigSchema.optional(), }); -type CollectionMeta = { - // Collection name is set later when running the data() function. +type CollectionMeta['fields']> = { + // Collection table is set later when running the data() function. // Collection config is assigned to an object key, // so the collection itself does not know the table name. - name?: string; + table: Table; }; type CollectionConfig< @@ -57,26 +58,26 @@ type CollectionConfig< }; export type ResolvedCollectionConfig< - TFields extends z.input['fields'] = z.input< - typeof collectionSchema - >['fields'], + TFields extends z.input['fields'], Writable extends boolean = boolean, > = CollectionConfig & { writable: Writable; - _: CollectionMeta; + table: Table; }; export function defineCollection['fields']>( userConfig: CollectionConfig ): ResolvedCollectionConfig { - const _ = {}; - function _setMeta(values: CollectionMeta) { - Object.assign(_, values); + const meta: CollectionMeta = { table: null! }; + function _setMeta(values: CollectionMeta) { + Object.assign(meta, values); } return { ...userConfig, writable: false, - _, + get table() { + return meta.table; + }, // @ts-expect-error private field _setMeta, }; @@ -85,14 +86,16 @@ export function defineCollection['fields'], >(userConfig: CollectionConfig): ResolvedCollectionConfig { - const _ = {}; - function _setMeta(values: CollectionMeta) { - Object.assign(_, values); + const meta: CollectionMeta = { + table: null!, + }; + function _setMeta(values: CollectionMeta) { + Object.assign(meta, values); } return { ...userConfig, writable: true, - _, + table: meta.table, // @ts-expect-error private field _setMeta, }; diff --git a/packages/db/src/internal.ts b/packages/db/src/internal.ts index 25022dd825..5bc170d48c 100644 --- a/packages/db/src/internal.ts +++ b/packages/db/src/internal.ts @@ -10,7 +10,6 @@ import { type JsonField, type NumberField, type TextField, - collectionSchema, } from './types.js'; import { type LibSQLDatabase, drizzle } from 'drizzle-orm/libsql'; import { bold } from 'kleur/colors'; @@ -69,7 +68,6 @@ export async function createLocalDatabaseClient({ const { insert: drizzleInsert, update: drizzleUpdate, delete: drizzleDelete } = db; return Object.assign(db, { insert(Table: SQLiteTable) { - //console.log('Table info...', Table._); checkIfModificationIsAllowed(collections, Table); return drizzleInsert.call(this, Table); }, @@ -108,21 +106,23 @@ export async function setupDbTables({ } if (data) { for (const [name, collection] of Object.entries(collections)) { - (collection as any)._setMeta?.({ name }); + const table = collectionToTable(name, collection); + collection._setMeta?.({ table }); } try { await data({ - async seed(collection, values) { - const collectionName = collection._.name; - if (!collectionName) { - throw new Error( - `Failed to set collection data. Did you call set() outside of the data() function?` - ); - } - const table = collectionToTable(collectionName, collectionSchema.parse(collection)); + async seed({ table }, values) { const result = Array.isArray(values) - ? await db.insert(table).values(values).returning() - : await db.insert(table).values(values).returning().get(); + ? // TODO: fix values typing once we can infer fields type correctly + await db + .insert(table) + .values(values as any) + .returning() + : await db + .insert(table) + .values(values as any) + .returning() + .get(); return result; }, db, diff --git a/packages/db/src/types.ts b/packages/db/src/types.ts index 17adb75715..2288bb34a6 100644 --- a/packages/db/src/types.ts +++ b/packages/db/src/types.ts @@ -61,14 +61,14 @@ const fieldsSchema = z.record(fieldSchema); export const readableCollectionSchema = z.object({ fields: fieldsSchema, writable: z.literal(false), - _: z.object({ name: z.string().optional() }).optional(), + table: z.any(), _setMeta: z.function().optional(), }); export const writableCollectionSchema = z.object({ fields: fieldsSchema, writable: z.literal(true), - _: z.object({ name: z.string().optional() }).optional(), + table: z.any(), _setMeta: z.function().optional(), }); @@ -113,15 +113,20 @@ type GeneratedConfig = Pick< 'name' | 'tableName' | 'notNull' | 'hasDefault' >; +type DbFieldsConfig = z.input['fields']; + export type DbDataContext = { db: SqliteDB; - seed['fields']>( - collection: ResolvedCollectionConfig, + seed( + collection: ResolvedCollectionConfig, data: MaybeArray< SQLiteInsertValue< Table< string, - /** TODO: true type inference */ Record, DBField> + /** TODO: true type inference */ Record< + Extract, + DbFieldsConfig[number] + > > > >