From 9e8fb5c388747a3355c9f7bf560b90394b0d8b98 Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Thu, 11 Jan 2024 15:05:02 -0500 Subject: [PATCH] feat: data() fn with basic type safety --- packages/db/src/config.ts | 12 +++++++++--- packages/db/src/internal.ts | 20 ++++++++++++++++---- packages/db/src/types.ts | 11 +++++++++-- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/packages/db/src/config.ts b/packages/db/src/config.ts index 3e772dbe26..dc236c3ce5 100644 --- a/packages/db/src/config.ts +++ b/packages/db/src/config.ts @@ -20,9 +20,15 @@ export const astroConfigWithDBValidator = z.object({ db: adjustedConfigSchema.optional(), }); -export function defineCollection( - userConfig: z.input -): z.input { +type CollectionConfig['fields']> = { + fields: TFields; + // TODO: type inference based on field type. Just `any` for now. + data?: () => Array & { id?: string }>; +}; + +export function defineCollection['fields']>( + userConfig: CollectionConfig +): CollectionConfig { return userConfig; } diff --git a/packages/db/src/internal.ts b/packages/db/src/internal.ts index 654847e7e9..43460e70ad 100644 --- a/packages/db/src/internal.ts +++ b/packages/db/src/internal.ts @@ -83,6 +83,22 @@ export function getCreateTableQuery(collectionName: string, collection: DBCollec return query; } +export async function executeCollectionDataFn({ + db, + collectionName, + collection, +}: { + db: LibSQLDatabase; + collectionName: string; + collection: DBCollection; +}) { + const { data } = collection; + if (!data) return; + + const table = collectionToTable(collectionName, collection); + await db.insert(table).values(await data()); +} + function schemaTypeToSqlType(type: FieldType): 'text' | 'integer' { switch (type) { case 'date': @@ -124,10 +140,6 @@ function hasDefault(field: DBField): field is DBFieldWithDefault { return field.default !== undefined; } -function hasRuntimeDefault(field: DBField): field is DBFieldWithDefault { - return field.type === 'date' && field.default === 'now'; -} - function getDefaultValueSql(columnName: string, column: DBFieldWithDefault): string { switch (column.type) { case 'boolean': diff --git a/packages/db/src/types.ts b/packages/db/src/types.ts index 7aab9e1be3..77597623c6 100644 --- a/packages/db/src/types.ts +++ b/packages/db/src/types.ts @@ -52,6 +52,7 @@ const fieldsSchema = z.record(fieldSchema); export const collectionSchema = z.object({ fields: fieldsSchema, + data: z.function().returns(fieldsSchema).optional(), }); export const collectionsSchema = z.record(collectionSchema); @@ -74,8 +75,12 @@ export type FieldType = export type DBField = z.infer; export type DBFieldInput = DateFieldInput | BooleanField | NumberField | TextField | JsonField; export type DBFields = z.infer; -export type DBCollection = z.infer; -export type DBCollections = z.infer; +export type DBCollection = { + fields: TFields; + // TODO: better `insert` types + data?: () => MaybePromise>>; +}; +export type DBCollections = Record; export type AstroTable> = SQLiteTableWithColumns< T & { @@ -157,3 +162,5 @@ export type AstroId, 'tableName'>> = SQ baseColumn: never; } >; + +export type MaybePromise = T | Promise;