Skip to content

Commit

Permalink
chore: type regression
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Jan 22, 2025
1 parent c514bfc commit 1de94c4
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 60 deletions.
1 change: 1 addition & 0 deletions packages/schema/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './plugins'
export * from './safeSchema'
export * from './schema'
export * from './tags'
export * from './util'
34 changes: 17 additions & 17 deletions packages/schema/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ type TitleTemplateResolver = string | ((title?: string) => string | null)

export type Title = MaybeFunction<number | string | Falsey> | ResolvableValues<({ textContent: string } & SchemaAugmentations['title'])>
export type TitleTemplate = TitleTemplateResolver | null | ({ textContent: TitleTemplateResolver } & SchemaAugmentations['titleTemplate'])
export type Base<E extends EntryAugmentation = Record<string, any>> = Partial<Merge<SchemaAugmentations['base'], ResolvableValues<_Base>>> & DefinedValueOrEmptyObject<E>
export type Link<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<LinkBase & DataKeys> & MaybeEventFnHandlers<HttpEventAttributes> & SchemaAugmentations['link'] & DefinedValueOrEmptyObject<E>
export type Meta<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<BaseMeta & DataKeys> & SchemaAugmentations['meta'] & DefinedValueOrEmptyObject<E>
export type Style<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<_Style & DataKeys> & SchemaAugmentations['style'] & DefinedValueOrEmptyObject<E>
export type Script<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<ScriptBase & DataKeys> & MaybeEventFnHandlers<HttpEventAttributes> & SchemaAugmentations['script'] & DefinedValueOrEmptyObject<E>
export type Noscript<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<_Noscript & DataKeys> & SchemaAugmentations['noscript'] & DefinedValueOrEmptyObject<E>
export type HtmlAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<HtmlAttr & DataKeys> & SchemaAugmentations['htmlAttrs'] & DefinedValueOrEmptyObject<E>
export type BodyAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<BodyAttr & DataKeys> & MaybeEventFnHandlers<BodyEvents> & SchemaAugmentations['bodyAttrs'] & DefinedValueOrEmptyObject<E>
export type Base<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<_Base & SchemaAugmentations['base']> & DefinedValueOrEmptyObject<E>
export type Link<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<LinkBase & DataKeys & SchemaAugmentations['link']> & MaybeEventFnHandlers<HttpEventAttributes> & DefinedValueOrEmptyObject<E>
export type Meta<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<BaseMeta & DataKeys & SchemaAugmentations['meta']> & DefinedValueOrEmptyObject<E>
export type Style<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<_Style & DataKeys & SchemaAugmentations['style']> & DefinedValueOrEmptyObject<E>
export type Script<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<ScriptBase & DataKeys & SchemaAugmentations['script'] > & MaybeEventFnHandlers<HttpEventAttributes> & DefinedValueOrEmptyObject<E>
export type Noscript<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<_Noscript & DataKeys & SchemaAugmentations['noscript']> & DefinedValueOrEmptyObject<E>
export type HtmlAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<HtmlAttr & DataKeys & SchemaAugmentations['htmlAttrs']> & DefinedValueOrEmptyObject<E>
export type BodyAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableValues<BodyAttr & DataKeys & SchemaAugmentations['bodyAttrs']> & MaybeEventFnHandlers<BodyEvents> & DefinedValueOrEmptyObject<E>

export type ResolvedTitle = ({ textContent: string } & ResolvedSchemaAugmentations['title'])
export type ResolvedTitleTemplate = TitleTemplateResolver | null | ({ textContent: TitleTemplateResolver } & ResolvedSchemaAugmentations['titleTemplate'])
Expand Down Expand Up @@ -172,15 +172,15 @@ export interface Head<E extends MergeHead = SchemaAugmentations> extends HeadUti
}

export interface ResolvedHead<E extends MergeHead = ResolvedSchemaAugmentations> extends HeadUtils {
title: ResolvedTitle
base: ResolvedBase<E['base']>
link: ResolvedLink<E['link']>[]
meta: ResolvedMeta<E['meta']>[]
style: (ResolvedStyle<E['style']> | string)[]
script: (ResolvedScript<E['script']> | string)[]
noscript: (ResolvedNoscript<E['noscript']> | string)[]
htmlAttrs: ResolvedHtmlAttributes<E['htmlAttrs']>
bodyAttrs: ResolvedBodyAttributes<E['bodyAttrs']>
title?: ResolvedTitle
base?: ResolvedBase<E['base']>
link?: ResolvedLink<E['link']>[]
meta?: ResolvedMeta<E['meta']>[]
style?: (ResolvedStyle<E['style']> | string)[]
script?: (ResolvedScript<E['script']> | string)[]
noscript?: (ResolvedNoscript<E['noscript']> | string)[]
htmlAttrs?: ResolvedHtmlAttributes<E['htmlAttrs']>
bodyAttrs?: ResolvedBodyAttributes<E['bodyAttrs']>
}

export type UseSeoMetaInput = MetaFlatInput & { title?: Title, titleTemplate?: TitleTemplate }
Expand Down
4 changes: 2 additions & 2 deletions packages/scripts/src/vue/useScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
SchemaAugmentations,
ScriptBase,
} from '@unhead/schema'
import type { MaybeComputedRefEntriesOnly, VueHeadClient } from '@unhead/vue'
import type { ResolvableProperties, VueHeadClient } from '@unhead/vue'
import type { ComponentInternalInstance, Ref, WatchHandle } from 'vue'
import type { UseScriptOptions as BaseUseScriptOptions, ScriptInstance, UseFunctionType, UseScriptStatus } from '../types'
import { injectHead } from '@unhead/vue'
Expand All @@ -15,7 +15,7 @@ export interface VueScriptInstance<T extends Record<symbol | string, any>> exten
status: Ref<UseScriptStatus>
}

export type UseScriptInput = string | (MaybeComputedRefEntriesOnly<Omit<ScriptBase & DataKeys & SchemaAugmentations['script'], 'src'>> & { src: string })
export type UseScriptInput = string | (ResolvableProperties<Omit<ScriptBase & DataKeys & SchemaAugmentations['script'], 'src'>> & { src: string })
export interface UseScriptOptions<T extends Record<symbol | string, any> = Record<string, any>> extends Omit<HeadEntryOptions, 'head'>, Pick<BaseUseScriptOptions<T>, 'use' | 'eventContext' | 'beforeInit'> {
/**
* The trigger to load the script:
Expand Down
31 changes: 31 additions & 0 deletions packages/unhead/test/unit/types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useHead } from '../../src/composables'
import { createHead } from '../../src/server'

describe('types', () => {
it('types useHead', () => {
const unhead = createHead()
useHead(unhead, {
htmlAttrs: {
lang: () => false,
},
base: { href: '/base' },
link: () => [],
meta: [
{ key: 'key', name: 'description', content: 'some description ' },
() => ({ key: 'key', name: 'description', content: 'some description ' }),
],
script: [
() => 'test',
{
innerHTML: () => 'foo',
},
],
style: () => [
() => 'foo',
],
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} - Site Title` : 'Site Title'
},
})
})
})
4 changes: 2 additions & 2 deletions packages/vue/src/legacy/useScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
SchemaAugmentations,
ScriptBase,
} from '@unhead/schema'
import type { MaybeComputedRefEntriesOnly, UseHeadOptions } from '@unhead/vue'
import type { ResolvableProperties, UseHeadOptions } from '@unhead/vue'
import type { UseScriptOptions as BaseUseScriptOptions, ScriptInstance, UseFunctionType, UseScriptStatus } from 'unhead/legacy'
import type { ComponentInternalInstance, Ref, WatchHandle } from 'vue'
import { useScript as _useScript } from 'unhead/legacy'
Expand All @@ -19,7 +19,7 @@ export interface VueScriptInstance<T extends Record<symbol | string, any>> exten
status: Ref<UseScriptStatus>
}

export type UseScriptInput = string | (MaybeComputedRefEntriesOnly<Omit<ScriptBase & DataKeys & SchemaAugmentations['script'], 'src'>> & { src: string })
export type UseScriptInput = string | (ResolvableProperties<Omit<ScriptBase & DataKeys & SchemaAugmentations['script'], 'src'>> & { src: string })
export interface UseScriptOptions<T extends Record<symbol | string, any> = Record<string, any>> extends Omit<HeadEntryOptions, 'head'>, Pick<BaseUseScriptOptions<T>, 'use' | 'eventContext' | 'beforeInit'> {
/**
* The trigger to load the script:
Expand Down
14 changes: 7 additions & 7 deletions packages/vue/src/types/safeSchema.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { SafeBodyAttr, SafeHtmlAttr, SafeLink, SafeMeta, SafeNoscript, SafeScript } from '@unhead/schema'
import type { ReactiveHead } from './schema'
import type { MaybeComputedRef, MaybeComputedRefEntries } from './util'
import type { MaybeComputedRef, ResolvableArray } from './util'

export interface HeadSafe extends Pick<ReactiveHead, 'title' | 'titleTemplate' | 'templateParams'> {
meta?: MaybeComputedRefEntries<SafeMeta>[]
link?: MaybeComputedRefEntries<SafeLink>[]
noscript?: MaybeComputedRefEntries<SafeNoscript>[]
script?: MaybeComputedRefEntries<SafeScript>[]
htmlAttrs?: MaybeComputedRefEntries<SafeHtmlAttr>
bodyAttrs?: MaybeComputedRefEntries<SafeBodyAttr>
meta?: ResolvableArray<SafeMeta>[]
link?: ResolvableArray<SafeLink>[]
noscript?: ResolvableArray<SafeNoscript>[]
script?: ResolvableArray<SafeScript>[]
htmlAttrs?: ResolvableArray<SafeHtmlAttr>
bodyAttrs?: ResolvableArray<SafeBodyAttr>
}

export type UseHeadSafeInput = MaybeComputedRef<HeadSafe>
59 changes: 41 additions & 18 deletions packages/vue/src/types/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import type { Base as _Base, Link as _Link, Meta as _Meta, Noscript as _Noscript, Script as _Script, Style as _Style, Title as _Title, TitleTemplate as _TitleTemplate, BaseBodyAttr, BaseHtmlAttr, BodyEvents, DataKeys, DefinedValueOrEmptyObject, EntryAugmentation, HeadEntryOptions, MaybeArray, MaybeEventFnHandlers, MergeHead, MetaFlatInput, SchemaAugmentations, Unhead } from '@unhead/schema'
import type {
Base as _Base,
Noscript as _Noscript,
Style as _Style,
TitleTemplate as _TitleTemplate,
BaseBodyAttr,
BaseHtmlAttr,
BaseMeta,
BodyEvents,
DataKeys,
DefinedValueOrEmptyObject,
EntryAugmentation,
Falsey,
HeadEntryOptions,
MaybeArray,
MaybeEventFnHandlers,
MaybeFunction,
MergeHead,
MetaFlatInput,
ResolvableValues,
SchemaAugmentations,
Unhead,
} from '@unhead/schema'
import type { Plugin, Ref } from 'vue'
import type { MaybeComputedRef, MaybeComputedRefEntries, MaybeComputedRefEntriesOnly } from './util'
import type { HttpEventAttributes, LinkBase, ScriptBase } from 'zhead'
import type { MaybeComputedRef, ResolvableArray, ResolvableProperties } from './util'

export interface HtmlAttr extends Omit<BaseHtmlAttr, 'class'> {
/**
Expand All @@ -26,16 +49,16 @@ export interface BodyAttr extends Omit<BaseBodyAttr, 'class' | 'style'> {
style?: MaybeArray<MaybeComputedRef<string>> | Record<string, MaybeComputedRef<string | boolean>>
}

export type Title = MaybeComputedRef<_Title>
export type Title = MaybeFunction<number | string | Falsey> | ResolvableValues<({ textContent: string } & SchemaAugmentations['title'])>
export type TitleTemplate = _TitleTemplate | Ref<_TitleTemplate> | ((title?: string) => _TitleTemplate)
export type Base<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRef<MaybeComputedRefEntries<_Base<E>>>
export type Link<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRefEntries<_Link<E>>
export type Meta<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRefEntries<_Meta<E>>
export type Style<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRefEntries<_Style<E>>
export type Script<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRefEntries<_Script<E>>
export type Noscript<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRefEntries<_Noscript<E>>
export type HtmlAttributes<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRef<MaybeComputedRefEntries<HtmlAttr & DataKeys & SchemaAugmentations['htmlAttrs'] & DefinedValueOrEmptyObject<E>>>
export type BodyAttributes<E extends EntryAugmentation = Record<string, any>> = MaybeComputedRef<MaybeComputedRefEntries<BodyAttr & DataKeys & SchemaAugmentations['bodyAttrs'] & DefinedValueOrEmptyObject<E>> & MaybeEventFnHandlers<BodyEvents>>
export type Base<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<_Base & SchemaAugmentations['base']> & DefinedValueOrEmptyObject<E>
export type Link<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<LinkBase & DataKeys & SchemaAugmentations['link']> & MaybeEventFnHandlers<HttpEventAttributes> & DefinedValueOrEmptyObject<E>
export type Meta<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<BaseMeta & DataKeys & SchemaAugmentations['meta']> & DefinedValueOrEmptyObject<E>
export type Style<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<_Style & DataKeys & SchemaAugmentations['style']> & DefinedValueOrEmptyObject<E>
export type Script<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<ScriptBase & DataKeys & SchemaAugmentations['script'] > & MaybeEventFnHandlers<HttpEventAttributes> & DefinedValueOrEmptyObject<E>
export type Noscript<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<_Noscript & DataKeys & SchemaAugmentations['noscript']> & DefinedValueOrEmptyObject<E>
export type HtmlAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<HtmlAttr & DataKeys & SchemaAugmentations['htmlAttrs']> & DefinedValueOrEmptyObject<E>
export type BodyAttributes<E extends EntryAugmentation = Record<string, any>> = ResolvableProperties<BodyAttr & DataKeys & SchemaAugmentations['bodyAttrs']> & MaybeEventFnHandlers<BodyEvents> & DefinedValueOrEmptyObject<E>

export interface ReactiveHead<E extends MergeHead = MergeHead> {
/**
Expand All @@ -52,7 +75,7 @@ export interface ReactiveHead<E extends MergeHead = MergeHead> {
/**
* Variables used to substitute in the title and meta content.
*/
templateParams?: MaybeComputedRefEntries<{ separator?: '|' | '-' | '·' | string } & Record<string, null | string | MaybeComputedRefEntries<Record<string, null | string>>>>
templateParams?: ResolvableArray<{ separator?: '|' | '-' | '·' | string } & Record<string, null | string | ResolvableArray<Record<string, null | string>>>>
/**
* The `<base>` HTML element specifies the base URL to use for all relative URLs in a document.
* There can be only one <base> element in a document.
Expand All @@ -67,33 +90,33 @@ export interface ReactiveHead<E extends MergeHead = MergeHead> {
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as
*/
link?: MaybeComputedRef<Link<E['link']>[]>
link?: ResolvableArray<Link<E['link']>>
/**
* The `<meta>` element represents metadata that cannot be expressed in other HTML elements, like `<link>` or `<script>`.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
*/
meta?: MaybeComputedRef<Meta<E['meta']>[]>
meta?: ResolvableArray<Meta<E['meta']>>
/**
* The `<style>` HTML element contains style information for a document, or part of a document.
* It contains CSS, which is applied to the contents of the document containing the `<style>` element.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style
*/
style?: MaybeComputedRef<(Style<E['style']> | string)[]>
style?: ResolvableArray<(Style<E['style']> | string)>
/**
* The `<script>` HTML element is used to embed executable code or data; this is typically used to embed or refer to JavaScript code.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
*/
script?: MaybeComputedRef<(Script<E['script']> | string)[]>
script?: ResolvableArray<(Script<E['script']> | string)>
/**
* The `<noscript>` HTML element defines a section of HTML to be inserted if a script type on the page is unsupported
* or if scripting is currently turned off in the browser.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript
*/
noscript?: MaybeComputedRef<(Noscript<E['noscript']> | string)[]>
noscript?: ResolvableArray<(Noscript<E['noscript']> | string)>
/**
* Attributes for the `<html>` HTML element.
*
Expand All @@ -110,5 +133,5 @@ export interface ReactiveHead<E extends MergeHead = MergeHead> {

export type UseHeadOptions = Omit<HeadEntryOptions, 'head'> & { head?: VueHeadClient<any> }
export type UseHeadInput<T extends MergeHead = Record<string, any>> = MaybeComputedRef<ReactiveHead<T>>
export type UseSeoMetaInput = MaybeComputedRefEntriesOnly<MetaFlatInput> & { title?: ReactiveHead['title'], titleTemplate?: ReactiveHead['titleTemplate'] }
export type UseSeoMetaInput = ResolvableProperties<MetaFlatInput> & { title?: ReactiveHead['title'], titleTemplate?: ReactiveHead['titleTemplate'] }
export type VueHeadClient<T extends MergeHead> = Unhead<MaybeComputedRef<ReactiveHead<T>>> & Plugin
19 changes: 5 additions & 14 deletions packages/vue/src/types/util.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import type { Falsey } from '@unhead/schema'
import type { ComputedRef, Ref } from 'vue'

// copied from @vueuse/shared
export type MaybeReadonlyRef<T> = ComputedRef<T>
export type MaybeComputedRef<T> = T | MaybeReadonlyRef<T> | Ref<T>
export type MaybeComputedRefOrFalsy<T> = T | MaybeReadonlyRef<T> | Ref<T>
export type MaybeComputedRef<T> = T | (() => T) | ComputedRef<T> | Ref<T>

/**
* @deprecated Use MaybeComputedRefOrFalsy
*/
export type MaybeComputedRefOrPromise<T> = MaybeComputedRefOrFalsy<T>
export type ResolvableArray<T> = MaybeComputedRef<MaybeComputedRef<T>[]>

export type MaybeComputedRefEntries<T> = MaybeComputedRef<T> | {
[key in keyof T]?: MaybeComputedRefOrFalsy<T[key]>
}

export type MaybeComputedRefEntriesOnly<T> = {
[key in keyof T]?: MaybeComputedRefOrFalsy<T[key]>
export type ResolvableProperties<T> = {
[key in keyof T]?: MaybeComputedRef<T[key] | Falsey>
}
44 changes: 44 additions & 0 deletions packages/vue/test/unit/types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { createHead } from '@unhead/vue/client'
import { computed } from 'vue'
import { useHead } from '../../src/composables'

describe('types', () => {
it('types useHead', () => {
const head = createHead()
useHead({
htmlAttrs: {
lang: () => false,
class: {
foo: () => false,
something: computed(() => true),
},
},
base: { href: () => '/base' },
link: () => [],
meta: [
{ key: 'key', name: 'description', content: 'some description ' },
() => ({ key: 'key', name: 'description', content: 'some description ' }),
],
script: [
() => 'test',
{
innerHTML: () => 'foo',
},
],
style: () => [
() => 'foo',
],
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} - Site Title` : 'Site Title'
},
}, {
head,
})

useHead(() => ({
title: 'foo',
}), {
head,
})
})
})

0 comments on commit 1de94c4

Please sign in to comment.