Skip to content

Commit

Permalink
feat(astro): improve astro:content types (#9906)
Browse files Browse the repository at this point in the history
* feat: improve �stro:content types

* fix: do not change tsconfig

* "astro/zod" -> "zod"

* `CollectionConfig` parameter extends `BaseSchema`

* fix: update import to zod

* feat: add fallbacks for every export

* Update .changeset/young-bulldogs-tickle.md

---------

Co-authored-by: lilnasy <[email protected]>
Co-authored-by: Nate Moore <[email protected]>
  • Loading branch information
3 people authored Feb 5, 2024
1 parent 5eb0597 commit 3c0876c
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 49 deletions.
5 changes: 5 additions & 0 deletions .changeset/young-bulldogs-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": patch
---

Improves the types for the `astro:content` module by making low fidelity types available before running `astro sync`
4 changes: 4 additions & 0 deletions packages/astro/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ declare module 'astro:components' {
export * from 'astro/components';
}

declare module 'astro:content' {
export * from 'astro/virtual-modules/content.js'
}

type MD = import('./dist/@types/astro.js').MarkdownInstance<Record<string, any>>;
interface ExportedMarkdownModuleEntities {
frontmatter: MD['frontmatter'];
Expand Down
49 changes: 0 additions & 49 deletions packages/astro/content-types.template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ declare module 'astro:content' {
}

declare module 'astro:content' {
export { z } from 'astro/zod';

type Flatten<T> = T extends { [K: string]: infer U } ? U : never;

export type CollectionKey = keyof AnyEntryMap;
Expand All @@ -19,53 +17,6 @@ declare module 'astro:content' {
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;

// This needs to be in sync with ImageMetadata
export type ImageFunction = () => import('astro/zod').ZodObject<{
src: import('astro/zod').ZodString;
width: import('astro/zod').ZodNumber;
height: import('astro/zod').ZodNumber;
format: import('astro/zod').ZodUnion<
[
import('astro/zod').ZodLiteral<'png'>,
import('astro/zod').ZodLiteral<'jpg'>,
import('astro/zod').ZodLiteral<'jpeg'>,
import('astro/zod').ZodLiteral<'tiff'>,
import('astro/zod').ZodLiteral<'webp'>,
import('astro/zod').ZodLiteral<'gif'>,
import('astro/zod').ZodLiteral<'svg'>,
import('astro/zod').ZodLiteral<'avif'>,
]
>;
}>;

type BaseSchemaWithoutEffects =
| import('astro/zod').AnyZodObject
| import('astro/zod').ZodUnion<[BaseSchemaWithoutEffects, ...BaseSchemaWithoutEffects[]]>
| import('astro/zod').ZodDiscriminatedUnion<string, import('astro/zod').AnyZodObject[]>
| import('astro/zod').ZodIntersection<BaseSchemaWithoutEffects, BaseSchemaWithoutEffects>;

type BaseSchema =
| BaseSchemaWithoutEffects
| import('astro/zod').ZodEffects<BaseSchemaWithoutEffects>;

export type SchemaContext = { image: ImageFunction };

type DataCollectionConfig<S extends BaseSchema> = {
type: 'data';
schema?: S | ((context: SchemaContext) => S);
};

type ContentCollectionConfig<S extends BaseSchema> = {
type?: 'content';
schema?: S | ((context: SchemaContext) => S);
};

type CollectionConfig<S> = ContentCollectionConfig<S> | DataCollectionConfig<S>;

export function defineCollection<S extends BaseSchema>(
input: CollectionConfig<S>
): CollectionConfig<S>;

type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
Expand Down
75 changes: 75 additions & 0 deletions packages/astro/src/virtual-modules/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { defineCollection as _defineCollection } from '../content/runtime.js';
import { z } from 'zod';

export { z };

// This needs to be in sync with ImageMetadata
export type ImageFunction = () => z.ZodObject<{
src: z.ZodString;
width: z.ZodNumber;
height: z.ZodNumber;
format: z.ZodUnion<
[
z.ZodLiteral<'png'>,
z.ZodLiteral<'jpg'>,
z.ZodLiteral<'jpeg'>,
z.ZodLiteral<'tiff'>,
z.ZodLiteral<'webp'>,
z.ZodLiteral<'gif'>,
z.ZodLiteral<'svg'>,
z.ZodLiteral<'avif'>,
]
>;
}>;

type BaseSchemaWithoutEffects =
| z.AnyZodObject
| z.ZodUnion<[BaseSchemaWithoutEffects, ...BaseSchemaWithoutEffects[]]>
| z.ZodDiscriminatedUnion<string, z.AnyZodObject[]>
| z.ZodIntersection<BaseSchemaWithoutEffects, BaseSchemaWithoutEffects>;

type BaseSchema = BaseSchemaWithoutEffects | z.ZodEffects<BaseSchemaWithoutEffects>;

export type SchemaContext = { image: ImageFunction };

type DataCollectionConfig<S extends BaseSchema> = {
type: 'data';
schema?: S | ((context: SchemaContext) => S);
};

type ContentCollectionConfig<S extends BaseSchema> = {
type?: 'content';
schema?: S | ((context: SchemaContext) => S);
};

type CollectionConfig<S extends BaseSchema> = ContentCollectionConfig<S> | DataCollectionConfig<S>;

export function defineCollection<S extends BaseSchema>(
input: CollectionConfig<S>
): CollectionConfig<S> {
return _defineCollection(input);
}

const noop: (...args: any[]) => any = () => {};
/** Run `astro sync` to generate high fidelity types */
export const getEntryBySlug = noop;
/** Run `astro sync` to generate high fidelity types */
export const getDataEntryById = noop;
/** Run `astro sync` to generate high fidelity types */
export const getCollection = noop;
/** Run `astro sync` to generate high fidelity types */
export const getEntry = noop;
/** Run `astro sync` to generate high fidelity types */
export const getEntries = noop;
/** Run `astro sync` to generate high fidelity types */
export const reference = noop;
/** Run `astro sync` to generate high fidelity types */
export type CollectionKey = any;
/** Run `astro sync` to generate high fidelity types */
export type CollectionEntry<C> = any;
/** Run `astro sync` to generate high fidelity types */
export type ContentCollectionKey = any;
/** Run `astro sync` to generate high fidelity types */
export type DataCollectionKey = any;
/** Run `astro sync` to generate high fidelity types */
export type ContentConfig = any;

0 comments on commit 3c0876c

Please sign in to comment.