0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-03 22:57:08 -05:00

feat: expose Model.table

This commit is contained in:
bholmesdev 2024-01-26 16:47:33 -05:00
parent 500effd3fc
commit 87230f6982
3 changed files with 42 additions and 34 deletions

View file

@ -1,3 +1,5 @@
import type { Table } from './internal.js';
import type { collectionSchema } from './types.js';
import { import {
type BooleanField, type BooleanField,
type DBFieldInput, type DBFieldInput,
@ -5,7 +7,6 @@ import {
type JsonField, type JsonField,
type NumberField, type NumberField,
type TextField, type TextField,
type collectionSchema,
collectionsSchema, collectionsSchema,
type MaybePromise, type MaybePromise,
type DbDataContext, type DbDataContext,
@ -30,11 +31,11 @@ export const astroConfigWithDbSchema = z.object({
db: dbConfigSchema.optional(), db: dbConfigSchema.optional(),
}); });
type CollectionMeta = { type CollectionMeta<TFields extends z.input<typeof collectionSchema>['fields']> = {
// Collection name is set later when running the data() function. // Collection table is set later when running the data() function.
// Collection config is assigned to an object key, // Collection config is assigned to an object key,
// so the collection itself does not know the table name. // so the collection itself does not know the table name.
name?: string; table: Table<string, TFields>;
}; };
type CollectionConfig< type CollectionConfig<
@ -57,26 +58,26 @@ type CollectionConfig<
}; };
export type ResolvedCollectionConfig< export type ResolvedCollectionConfig<
TFields extends z.input<typeof collectionSchema>['fields'] = z.input< TFields extends z.input<typeof collectionSchema>['fields'],
typeof collectionSchema
>['fields'],
Writable extends boolean = boolean, Writable extends boolean = boolean,
> = CollectionConfig<TFields, Writable> & { > = CollectionConfig<TFields, Writable> & {
writable: Writable; writable: Writable;
_: CollectionMeta; table: Table<string, TFields>;
}; };
export function defineCollection<TFields extends z.input<typeof collectionSchema>['fields']>( export function defineCollection<TFields extends z.input<typeof collectionSchema>['fields']>(
userConfig: CollectionConfig<TFields, false> userConfig: CollectionConfig<TFields, false>
): ResolvedCollectionConfig<TFields, false> { ): ResolvedCollectionConfig<TFields, false> {
const _ = {}; const meta: CollectionMeta<TFields> = { table: null! };
function _setMeta(values: CollectionMeta) { function _setMeta(values: CollectionMeta<TFields>) {
Object.assign(_, values); Object.assign(meta, values);
} }
return { return {
...userConfig, ...userConfig,
writable: false, writable: false,
_, get table() {
return meta.table;
},
// @ts-expect-error private field // @ts-expect-error private field
_setMeta, _setMeta,
}; };
@ -85,14 +86,16 @@ export function defineCollection<TFields extends z.input<typeof collectionSchema
export function defineWritableCollection< export function defineWritableCollection<
TFields extends z.input<typeof collectionSchema>['fields'], TFields extends z.input<typeof collectionSchema>['fields'],
>(userConfig: CollectionConfig<TFields, true>): ResolvedCollectionConfig<TFields, true> { >(userConfig: CollectionConfig<TFields, true>): ResolvedCollectionConfig<TFields, true> {
const _ = {}; const meta: CollectionMeta<TFields> = {
function _setMeta(values: CollectionMeta) { table: null!,
Object.assign(_, values); };
function _setMeta(values: CollectionMeta<TFields>) {
Object.assign(meta, values);
} }
return { return {
...userConfig, ...userConfig,
writable: true, writable: true,
_, table: meta.table,
// @ts-expect-error private field // @ts-expect-error private field
_setMeta, _setMeta,
}; };

View file

@ -10,7 +10,6 @@ import {
type JsonField, type JsonField,
type NumberField, type NumberField,
type TextField, type TextField,
collectionSchema,
} from './types.js'; } from './types.js';
import { type LibSQLDatabase, drizzle } from 'drizzle-orm/libsql'; import { type LibSQLDatabase, drizzle } from 'drizzle-orm/libsql';
import { bold } from 'kleur/colors'; import { bold } from 'kleur/colors';
@ -69,7 +68,6 @@ export async function createLocalDatabaseClient({
const { insert: drizzleInsert, update: drizzleUpdate, delete: drizzleDelete } = db; const { insert: drizzleInsert, update: drizzleUpdate, delete: drizzleDelete } = db;
return Object.assign(db, { return Object.assign(db, {
insert(Table: SQLiteTable) { insert(Table: SQLiteTable) {
//console.log('Table info...', Table._);
checkIfModificationIsAllowed(collections, Table); checkIfModificationIsAllowed(collections, Table);
return drizzleInsert.call(this, Table); return drizzleInsert.call(this, Table);
}, },
@ -108,21 +106,23 @@ export async function setupDbTables({
} }
if (data) { if (data) {
for (const [name, collection] of Object.entries(collections)) { for (const [name, collection] of Object.entries(collections)) {
(collection as any)._setMeta?.({ name }); const table = collectionToTable(name, collection);
collection._setMeta?.({ table });
} }
try { try {
await data({ await data({
async seed(collection, values) { async seed({ table }, 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));
const result = Array.isArray(values) const result = Array.isArray(values)
? await db.insert(table).values(values).returning() ? // TODO: fix values typing once we can infer fields type correctly
: await db.insert(table).values(values).returning().get(); await db
.insert(table)
.values(values as any)
.returning()
: await db
.insert(table)
.values(values as any)
.returning()
.get();
return result; return result;
}, },
db, db,

View file

@ -61,14 +61,14 @@ const fieldsSchema = z.record(fieldSchema);
export const readableCollectionSchema = z.object({ export const readableCollectionSchema = z.object({
fields: fieldsSchema, fields: fieldsSchema,
writable: z.literal(false), writable: z.literal(false),
_: z.object({ name: z.string().optional() }).optional(), table: z.any(),
_setMeta: z.function().optional(), _setMeta: z.function().optional(),
}); });
export const writableCollectionSchema = z.object({ export const writableCollectionSchema = z.object({
fields: fieldsSchema, fields: fieldsSchema,
writable: z.literal(true), writable: z.literal(true),
_: z.object({ name: z.string().optional() }).optional(), table: z.any(),
_setMeta: z.function().optional(), _setMeta: z.function().optional(),
}); });
@ -113,15 +113,20 @@ type GeneratedConfig<T extends ColumnDataType = ColumnDataType> = Pick<
'name' | 'tableName' | 'notNull' | 'hasDefault' 'name' | 'tableName' | 'notNull' | 'hasDefault'
>; >;
type DbFieldsConfig = z.input<typeof collectionSchema>['fields'];
export type DbDataContext = { export type DbDataContext = {
db: SqliteDB; db: SqliteDB;
seed<TFields extends z.input<typeof collectionSchema>['fields']>( seed<TFields extends DbFieldsConfig>(
collection: ResolvedCollectionConfig, collection: ResolvedCollectionConfig<TFields>,
data: MaybeArray< data: MaybeArray<
SQLiteInsertValue< SQLiteInsertValue<
Table< Table<
string, string,
/** TODO: true type inference */ Record<Extract<keyof TFields, string>, DBField> /** TODO: true type inference */ Record<
Extract<keyof TFields, string>,
DbFieldsConfig[number]
>
> >
> >
> >