mirror of
https://github.com/withastro/astro.git
synced 2025-01-20 22:12:38 -05:00
feat: config design
This commit is contained in:
parent
915ed7ac0b
commit
bda07ec94e
3 changed files with 36 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
import type { SQLiteInsertValue } from 'drizzle-orm/sqlite-core';
|
import type { SQLiteInsertValue } from 'drizzle-orm/sqlite-core';
|
||||||
import type { SqliteDB, Table } from './internal.js';
|
import type { SqliteDB, Table } from './internal.js';
|
||||||
import type { MaybeArray, collectionSchema } from './types.js';
|
import type { DBCollection, MaybeArray, collectionSchema } from './types.js';
|
||||||
import {
|
import {
|
||||||
type BooleanField,
|
type BooleanField,
|
||||||
type DBFieldInput,
|
type DBFieldInput,
|
||||||
|
@ -9,15 +9,14 @@ import {
|
||||||
type NumberField,
|
type NumberField,
|
||||||
type TextField,
|
type TextField,
|
||||||
collectionsSchema,
|
collectionsSchema,
|
||||||
|
type indexSchema,
|
||||||
type MaybePromise,
|
type MaybePromise,
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
export type DBFieldsConfig = z.input<typeof collectionSchema>['fields'];
|
|
||||||
|
|
||||||
export type DBDataContext = {
|
export type DBDataContext = {
|
||||||
db: SqliteDB;
|
db: SqliteDB;
|
||||||
seed<TFields extends DBFieldsConfig>(
|
seed<TFields extends FieldsConfig>(
|
||||||
collection: ResolvedCollectionConfig<TFields>,
|
collection: ResolvedCollectionConfig<TFields>,
|
||||||
data: MaybeArray<
|
data: MaybeArray<
|
||||||
SQLiteInsertValue<
|
SQLiteInsertValue<
|
||||||
|
@ -25,7 +24,7 @@ export type DBDataContext = {
|
||||||
string,
|
string,
|
||||||
/** TODO: true type inference */ Record<
|
/** TODO: true type inference */ Record<
|
||||||
Extract<keyof TFields, string>,
|
Extract<keyof TFields, string>,
|
||||||
DBFieldsConfig[number]
|
FieldsConfig[number]
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
@ -51,26 +50,36 @@ export const astroConfigWithDbSchema = z.object({
|
||||||
db: dbConfigSchema.optional(),
|
db: dbConfigSchema.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
type CollectionMeta<TFields extends DBFieldsConfig> = {
|
export type FieldsConfig = z.input<typeof collectionSchema>['fields'];
|
||||||
|
|
||||||
|
type CollectionMeta<TFields extends FieldsConfig> = {
|
||||||
// Collection table 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.
|
||||||
table: Table<string, TFields>;
|
table: Table<string, TFields>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CollectionConfig<TFields extends DBFieldsConfig> = {
|
interface CollectionConfig<TFields extends FieldsConfig>
|
||||||
|
// use `extends` to ensure types line up with zod,
|
||||||
|
// only adding generics for type completions.
|
||||||
|
extends Pick<z.input<typeof collectionSchema>, 'fields' | 'indexes'> {
|
||||||
fields: TFields;
|
fields: TFields;
|
||||||
};
|
indexes?: Record<string, IndexConfig<TFields>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IndexConfig<TFields extends FieldsConfig> extends z.input<typeof indexSchema> {
|
||||||
|
on: MaybeArray<Extract<keyof TFields, string>>;
|
||||||
|
}
|
||||||
|
|
||||||
export type ResolvedCollectionConfig<
|
export type ResolvedCollectionConfig<
|
||||||
TFields extends DBFieldsConfig = DBFieldsConfig,
|
TFields extends FieldsConfig = FieldsConfig,
|
||||||
Writable extends boolean = boolean,
|
Writable extends boolean = boolean,
|
||||||
> = CollectionConfig<TFields> & {
|
> = CollectionConfig<TFields> & {
|
||||||
writable: Writable;
|
writable: Writable;
|
||||||
table: Table<string, TFields>;
|
table: Table<string, TFields>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function defineCollection<TFields extends DBFieldsConfig>(
|
export function defineCollection<TFields extends FieldsConfig>(
|
||||||
userConfig: CollectionConfig<TFields>
|
userConfig: CollectionConfig<TFields>
|
||||||
): ResolvedCollectionConfig<TFields, false> {
|
): ResolvedCollectionConfig<TFields, false> {
|
||||||
const meta: CollectionMeta<TFields> = { table: null! };
|
const meta: CollectionMeta<TFields> = { table: null! };
|
||||||
|
@ -88,7 +97,7 @@ export function defineCollection<TFields extends DBFieldsConfig>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineWritableCollection<TFields extends DBFieldsConfig>(
|
export function defineWritableCollection<TFields extends FieldsConfig>(
|
||||||
userConfig: CollectionConfig<TFields>
|
userConfig: CollectionConfig<TFields>
|
||||||
): ResolvedCollectionConfig<TFields, true> {
|
): ResolvedCollectionConfig<TFields, true> {
|
||||||
const meta: CollectionMeta<TFields> = { table: null! };
|
const meta: CollectionMeta<TFields> = { table: null! };
|
||||||
|
|
|
@ -52,18 +52,25 @@ const fieldSchema = z.union([
|
||||||
]);
|
]);
|
||||||
const fieldsSchema = z.record(fieldSchema);
|
const fieldsSchema = z.record(fieldSchema);
|
||||||
|
|
||||||
export const readableCollectionSchema = z.object({
|
export const indexSchema = z.object({
|
||||||
|
on: z.string().or(z.array(z.string())),
|
||||||
|
unique: z.boolean().optional(),
|
||||||
|
});
|
||||||
|
const indexesSchema = z.record(indexSchema);
|
||||||
|
|
||||||
|
const baseCollectionSchema = z.object({
|
||||||
fields: fieldsSchema,
|
fields: fieldsSchema,
|
||||||
writable: z.literal(false),
|
indexes: indexesSchema.optional(),
|
||||||
table: z.any(),
|
table: z.any(),
|
||||||
_setMeta: z.function().optional(),
|
_setMeta: z.function().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const writableCollectionSchema = z.object({
|
export const readableCollectionSchema = baseCollectionSchema.extend({
|
||||||
fields: fieldsSchema,
|
writable: z.literal(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const writableCollectionSchema = baseCollectionSchema.extend({
|
||||||
writable: z.literal(true),
|
writable: z.literal(true),
|
||||||
table: z.any(),
|
|
||||||
_setMeta: z.function().optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const collectionSchema = z.union([readableCollectionSchema, writableCollectionSchema]);
|
export const collectionSchema = z.union([readableCollectionSchema, writableCollectionSchema]);
|
||||||
|
|
|
@ -16,6 +16,9 @@ const Ingredient = defineCollection({
|
||||||
quantity: field.number(),
|
quantity: field.number(),
|
||||||
recipeId: field.text(),
|
recipeId: field.text(),
|
||||||
},
|
},
|
||||||
|
indexes: {
|
||||||
|
recipeIdx: { on: 'recipeId', unique: true },
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
|
Loading…
Add table
Reference in a new issue