Skip to content

Commit

Permalink
improve resolved metadata types
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi committed Jan 24, 2023
1 parent 8181bc3 commit 436a42d
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 26 deletions.
9 changes: 4 additions & 5 deletions packages/next/src/lib/metadata/generate/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { ResolvedMetadata } from '../types/metadata-interface'
import type { Icon, IconDescriptor } from '../types/metadata-types'

import React from 'react'
import { resolveAsArrayOrUndefined } from './utils'

const resolveUrl = (url: string | URL) =>
typeof url === 'string' ? url : url.toString()
Expand Down Expand Up @@ -30,10 +29,10 @@ export function ResolvedIconsMetadata({
}) {
if (!icons) return null

const shortcutList = resolveAsArrayOrUndefined(icons.shortcut)
const iconList = resolveAsArrayOrUndefined(icons.icon)
const appleList = resolveAsArrayOrUndefined(icons.apple)
const otherList = resolveAsArrayOrUndefined(icons.other)
const shortcutList = icons.shortcut
const iconList = icons.icon
const appleList = icons.apple
const otherList = icons.other

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/lib/metadata/generate/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function resolveAsArrayOrUndefined<T = any>(
value: T | T[] | undefined
value: T | T[] | undefined | null
): undefined | T[] {
if (typeof value === 'undefined' || value === null) {
return undefined
Expand Down
2 changes: 2 additions & 0 deletions packages/next/src/lib/metadata/metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ResolvedIconsMetadata } from './generate/icons'

// Generate the actual React elements from the resolved metadata.
export async function Metadata({ metadata }: { metadata: any }) {
if (!metadata) return null

const resolved: ResolvedMetadata = await resolveMetadata(metadata)
return (
<>
Expand Down
43 changes: 33 additions & 10 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ import type {
} from './types/metadata-interface'
import type { Viewport } from './types/extra-types'
import type { ResolvedTwitterMetadata } from './types/twitter-types'
import type { AbsoluteTemplateString } from './types/metadata-types'
import type {
AbsoluteTemplateString,
Icon,
IconDescriptor,
Icons,
IconURL,
ResolvedIcons,
} from './types/metadata-types'
import { createDefaultMetadata } from './default-metadata'
import { resolveOpenGraph } from './resolve-opengraph'
import { mergeTitle } from './resolve-title'
import { resolveAsArrayOrUndefined } from './generate/utils'

const viewPortKeys = {
width: 'width',
Expand Down Expand Up @@ -68,17 +76,32 @@ function resolveViewport(
return resolved
}

function isUrlIcon(icon: any): icon is string | URL {
return typeof icon === 'string' || icon instanceof URL
}

function resolveIcon(icon: Icon): IconDescriptor {
if (isUrlIcon(icon)) return { url: icon }
else if (Array.isArray(icon)) return icon
return icon
}

const IconKeys = ['icon', 'shortcut', 'apple', 'other'] as (keyof Icons)[]

function resolveIcons(icons: Metadata['icons']): ResolvedMetadata['icons'] {
let resolved: ResolvedMetadata['icons'] = null
if (icons == null) {
resolved = null
if (!icons) {
return null
}

const resolved: ResolvedMetadata['icons'] = {}
if (Array.isArray(icons)) {
resolved.icon = icons.map(resolveIcon).filter(Boolean)
} else if (isUrlIcon(icons)) {
resolved.icon = [resolveIcon(icons)]
} else {
if (Array.isArray(icons) || typeof icons === 'string') {
resolved = {
icon: icons,
}
} else {
resolved = icons
for (const key of IconKeys) {
const values = resolveAsArrayOrUndefined(icons[key])
if (values) resolved[key] = values.map(resolveIcon)
}
}
return resolved
Expand Down
6 changes: 4 additions & 2 deletions packages/next/src/lib/metadata/types/metadata-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import type {
ColorSchemeEnum,
Icon,
Icons,
IconURL,
ReferrerEnum,
ResolvedIcons,
Robots,
TemplateString,
Verification,
Expand Down Expand Up @@ -56,7 +58,7 @@ export interface Metadata {

// Defaults to rel="icon" but the Icons type can be used
// to get more specific about rel types
icons?: null | Array<Icon> | Icons
icons?: null | IconURL | Array<Icon> | Icons

openGraph?: null | OpenGraph

Expand Down Expand Up @@ -145,7 +147,7 @@ export interface ResolvedMetadata {

// Defaults to rel="icon" but the Icons type can be used
// to get more specific about rel types
icons: null | Icons
icons: null | ResolvedIcons

openGraph: null | ResolvedOpenGraph

Expand Down
24 changes: 16 additions & 8 deletions packages/next/src/lib/metadata/types/metadata-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export type Robots = {
googleBot?: string | Robots
}

export type Icon = string | IconDescriptor | URL
export type IconURL = string | URL
export type Icon = IconURL | IconDescriptor
export type IconDescriptor = {
url: string | URL
type?: string
Expand All @@ -74,20 +75,27 @@ export type IconDescriptor = {
}
export type Icons = {
// rel="icon"
icon?: Icon | Array<Icon>
icon?: Icon | Icon[]
// rel="shortcut icon"
shortcut?: Icon | Array<Icon>
shortcut?: Icon | Icon[]
// rel="apple-touch-icon"
apple?: Icon | Array<Icon>
apple?: Icon | Icon[]
// rel inferred from descriptor, defaults to "icon"
other?: IconDescriptor | Array<IconDescriptor>
other?: IconDescriptor | IconDescriptor[]
}

export type Verification = {
google?: null | string | number | Array<string | number>
yahoo?: null | string | number | Array<string | number>
google?: null | string | number | (string | number)[]
yahoo?: null | string | number | (string | number)[]
// if you ad-hoc additional verification
other?: {
[name: string]: string | number | Array<string | number>
[name: string]: string | number | (string | number)[]
}
}

export type ResolvedIcons = {
icon?: IconDescriptor[]
shortcut?: IconDescriptor[]
apple?: IconDescriptor[]
other?: IconDescriptor[]
}

0 comments on commit 436a42d

Please sign in to comment.