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 {
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<TFields extends z.input<typeof collectionSchema>['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<string, TFields>;
};
type CollectionConfig<
@ -57,26 +58,26 @@ type CollectionConfig<
};
export type ResolvedCollectionConfig<
TFields extends z.input<typeof collectionSchema>['fields'] = z.input<
typeof collectionSchema
>['fields'],
TFields extends z.input<typeof collectionSchema>['fields'],
Writable extends boolean = boolean,
> = CollectionConfig<TFields, Writable> & {
writable: Writable;
_: CollectionMeta;
table: Table<string, TFields>;
};
export function defineCollection<TFields extends z.input<typeof collectionSchema>['fields']>(
userConfig: CollectionConfig<TFields, false>
): ResolvedCollectionConfig<TFields, false> {
const _ = {};
function _setMeta(values: CollectionMeta) {
Object.assign(_, values);
const meta: CollectionMeta<TFields> = { table: null! };
function _setMeta(values: CollectionMeta<TFields>) {
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<TFields extends z.input<typeof collectionSchema
export function defineWritableCollection<
TFields extends z.input<typeof collectionSchema>['fields'],
>(userConfig: CollectionConfig<TFields, true>): ResolvedCollectionConfig<TFields, true> {
const _ = {};
function _setMeta(values: CollectionMeta) {
Object.assign(_, values);
const meta: CollectionMeta<TFields> = {
table: null!,
};
function _setMeta(values: CollectionMeta<TFields>) {
Object.assign(meta, values);
}
return {
...userConfig,
writable: true,
_,
table: meta.table,
// @ts-expect-error private field
_setMeta,
};

View file

@ -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,

View file

@ -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<T extends ColumnDataType = ColumnDataType> = Pick<
'name' | 'tableName' | 'notNull' | 'hasDefault'
>;
type DbFieldsConfig = z.input<typeof collectionSchema>['fields'];
export type DbDataContext = {
db: SqliteDB;
seed<TFields extends z.input<typeof collectionSchema>['fields']>(
collection: ResolvedCollectionConfig,
seed<TFields extends DbFieldsConfig>(
collection: ResolvedCollectionConfig<TFields>,
data: MaybeArray<
SQLiteInsertValue<
Table<
string,
/** TODO: true type inference */ Record<Extract<keyof TFields, string>, DBField>
/** TODO: true type inference */ Record<
Extract<keyof TFields, string>,
DbFieldsConfig[number]
>
>
>
>