Skip to content

Commit

Permalink
feat(ts): update types for v2 (#338)
Browse files Browse the repository at this point in the history
* chore: update types for v2

* fix: script.type shouldnt be required

fix: define meta.http-equiv as string, too many options to list

* chore: improve types

* chore: update typescript dependency

* chore: remove unnecessary gitignore

* chore: add metainfocomputed type

* chore: use camelcase for type

* chore: add interfaces for metaInfo properties

* chore: add missing body boolen for script types

* chore: include all type files on build

* chore: remove unused import
  • Loading branch information
pimlie authored Apr 3, 2019
1 parent 111c769 commit 7b85ff2
Show file tree
Hide file tree
Showing 7 changed files with 487 additions and 424 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
"files": [
"lib",
"es",
"types/index.d.ts",
"types/vue.d.ts"
"types/*.d.ts"
],
"main": "lib/vue-meta.common.js",
"web": "lib/vue-meta.js",
Expand All @@ -57,7 +56,8 @@
"test": "yarn test:unit && yarn test:e2e-ssr && yarn test:e2e-browser",
"test:e2e-ssr": "jest test/e2e/ssr",
"test:e2e-browser": "jest test/e2e/browser",
"test:unit": "jest test/unit"
"test:unit": "jest test/unit",
"test:types": "tsc -p types/test"
},
"dependencies": {
"deepmerge": "^3.2.0"
Expand Down Expand Up @@ -113,6 +113,7 @@
"selenium-webdriver": "^4.0.0-alpha.1",
"standard-version": "^5.0.2",
"tib": "^0.4.0",
"typescript": "^3.4.1",
"vue": "^2.6.10",
"vue-jest": "^3.0.4",
"vue-loader": "^15.7.0",
Expand Down
58 changes: 9 additions & 49 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
import './vue';
import { PluginFunction } from 'vue/types/plugin';
import './vue'
import { VueMeta } from './vue-meta'

/**
* Installation function
*
* @param {Vue} Vue - the Vue constructor.
* @param {{
* keyName: string, // the component option name that vue-meta looks for meta info on.
* attribute: string, // the attribute name vue-meta adds to the tags it observes
* ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
* tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
* }} options
*/
declare const Meta: PluginFunction<{
keyName: string, // the component option name that vue-meta looks for meta info on.
attribute: string, // the attribute name vue-meta adds to the tags it observes
ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
}>;
export default VueMeta

export default Meta;

export interface MetaInfo {
title?: string
titleTemplate?: string | ((titleChunk: string) => string)
htmlAttrs?: { [key: string]: string }
bodyAttrs?: { [key: string]: string }
base?: { target: string, href: string }

meta?: {
vmid?: string,
charset?: string,
content?: string,
'http-equiv'?: 'content-security-policy' | 'refresh',
name?: string,
[key: string]: any
}[]

link?: { rel: string, href: string, [key: string]: any }[]
style?: { cssText: string, type: string, [key: string]: any }[]
script?: { innerHTML?: string, src?: string, type: string, [key: string]: any }[]
noscript?: { innerHTML: string, [key: string]: any }[]

__dangerouslyDisableSanitizers?: string[]
__dangerouslyDisableSanitizersByTagID?: string[]

changed?: <T extends object>(newInfo: T, addedTags: HTMLElement[], removedTags: HTMLElement[]) => void
afterNavigation?: <T extends object>(vm: Vue, newInfo: T) => void
refreshOnceOnNavigation?: boolean
}
export {
VueMetaOptions,
VueMetaPlugin,
MetaInfo,
MetaInfoSSR
} from './vue-meta'
72 changes: 72 additions & 0 deletions types/test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import Vue, { ComponentOptions } from 'vue'
import VueMeta, { VueMetaPlugin, VueMetaOptions, MetaInfo, MetaInfoSSR } from '../index'

Vue.use(VueMeta, {
keyName: 'head'
} as VueMetaOptions)

const FooMetaInfo: MetaInfo = {
title: 'title',
titleTemplate: '%s - Home',
bodyAttrs: { class: 'a' }
}

const BarMetaInfo: MetaInfo = {
title: 'title',
titleTemplate: c => `${c} - Home`,
bodyAttrs: { class: ['a', 'b'] },
__dangerouslyDisableSanitizers: ['script'],
__dangerouslyDisableSanitizersByTagID: {
ldjson: ['innerHTML']
},
script: [{
src: '', crossorigin: '', async: true
}],
meta: [
{ charset: 'utf-8' },
{
'property': 'og:title',
'content': 'Test title',
'template': chunk => `${chunk} - My page`, //or as string template: '%s - My page',
'vmid': 'og:title'
}
],
changed(newdata: MetaInfo, newTags: HTMLElement[], oldTags: HTMLElement[]) {
},
afterNavigation(data: MetaInfo) {
}
}

const Foo: ComponentOptions<Vue> = {
metaInfo: FooMetaInfo
}

const Bar: ComponentOptions<Vue> = {
metaInfo() {
return BarMetaInfo
}
}

const app: Vue = new Vue(Foo)
const $meta: VueMetaPlugin = app.$meta()

// getOptions
const options: VueMetaOptions = $meta.getOptions()

// client side refresh
const { metaInfo: metaData1 }: { metaInfo: MetaInfo } = $meta.refresh()

// server side injection
const metaDataSSR: MetaInfoSSR = $meta.inject()
if (metaDataSSR.script) {
metaDataSSR.script.text()
metaDataSSR.script.text({ body: true })
}

// pausing & resuming
let resume
resume = $meta.pause()
const ret: void = resume()
resume = $meta.pause(true)
const { metaInfo: metaData2 }: { metaInfo: MetaInfo } = resume()
const { metaInfo: metaData3 }: { metaInfo: MetaInfo } = $meta.resume(true)
9 changes: 5 additions & 4 deletions types/tsconfig.json → types/test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"strict": true,
"noEmit": true,
"lib": [
"es5",
"dom",
"es2015.promise"
],
"strict": true,
"noEmit": true
]
},
"include": [
"*.d.ts"
"*.ts",
"../*.d.ts"
]
}
165 changes: 165 additions & 0 deletions types/vue-meta.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import './vue'
import Vue, { ComponentOptions, PluginFunction } from 'vue'

type Component = ComponentOptions<Vue> | typeof Vue
type elements = HTMLElement[]

export interface VueMetaOptions {
keyName: string, // the component option name that vue-meta looks for meta info on.
attribute: string, // the attribute name vue-meta adds to the tags it observes
ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
refreshOnceOnNavigation: boolean
}

export declare class VueMeta {
static version: string
static install(vue: typeof Vue, options?: VueMetaOptions): PluginFunction<never>
static hasMetaInfo(vm: Component): boolean
}

interface Refreshed {
vm: Component,
metaInfo: MetaInfo,
tags: {
addedTags: elements
removedTags: elements
}
}

export interface VueMetaPlugin {
getOptions(): VueMetaOptions
refresh(): Refreshed
inject(): MetaInfoSSR
pause(refresh: true): () => Refreshed
pause(refresh?: boolean): () => void
resume(refresh: true): Refreshed
resume(refresh?: boolean): void
}

export interface AttributeProperty {
[key: string]: string | string[]
}

export interface MetaDataProperty {
vmid?: string,
[key: string]: any
}

export interface MetaPropertyCharset extends MetaDataProperty {
charset: string,
}

export interface MetaPropertyEquiv extends MetaDataProperty {
httpEquiv: string,
name: string,
template?: (chunk: string) => string
}

export interface MetaPropertyName extends MetaDataProperty {
name: string,
content: string,
template?: (chunk: string) => string
}

// non-w3c interface
export interface MetaPropertyProperty extends MetaDataProperty {
property: string,
content: string,
template?: (chunk: string) => string
}

export interface LinkProperty extends MetaDataProperty {
rel: string,
crossOrigin?: string | null,
href?: string,
hreflang?: string,
media?: string,
nonce?: string,
referrerPolicy?: string,
rev?: string,
type?: string,
}

export interface StyleProperty extends MetaDataProperty {
cssText: string,
media?: string,
nonce?: string,
type?: string,
}

export interface ScriptPropertyBase extends MetaDataProperty {
type?: string,
charset?: string,
body?: boolean,
async?: boolean,
defer?: boolean,
crossOrigin?: string,
nonce?: string
}

export interface ScriptPropertyText extends ScriptPropertyBase {
innerHTML: string,
}

export interface ScriptPropertySrc extends ScriptPropertyBase {
src: string,
}

export interface NoScriptProperty extends MetaDataProperty {
innerHTML: string,
}

export interface MetaInfo {
title?: string
titleTemplate?: string | ((titleChunk: string) => string)

htmlAttrs?: AttributeProperty
headAttrs?: AttributeProperty
bodyAttrs?: AttributeProperty

base?: {
target: string,
href: string
}

meta?: (MetaPropertyCharset | MetaPropertyEquiv | MetaPropertyName | MetaPropertyProperty)[]
link?: LinkProperty[]
style?: StyleProperty[]
script?: (ScriptPropertyText | ScriptPropertySrc)[]
noscript?: NoScriptProperty[]

__dangerouslyDisableSanitizers?: string[]
__dangerouslyDisableSanitizersByTagID?: {
[key: string]: string[]
}

changed?: <T extends MetaInfo>(newInfo: T, addedTags: elements, removedTags: elements) => void
afterNavigation?: <T extends MetaInfo>(newInfo: T) => void
}

export type MetaInfoComputed = () => MetaInfo

interface ToText {
text(): string
}

interface ToBodyTextOption {
body: boolean
}
interface ToBodyText {
text(options?: ToBodyTextOption): string
}

export interface MetaInfoSSR {
title?: ToText
htmlAttrs?: ToText
headAttrs?: ToText
bodyAttrs?: ToText
base?: ToText
meta?: ToText
link?: ToText
style?: ToText
script?: ToBodyText
noscript?: ToBodyText
}
16 changes: 8 additions & 8 deletions types/vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
* Augment the typings of Vue.js
*/

import Vue, { ComponentOptions } from "vue";
import { MetaInfo } from './index';
import Vue, { ComponentOptions } from 'vue'
import { MetaInfo, MetaInfoComputed, VueMetaPlugin } from './vue-meta'

declare module "vue/types/options" {
interface ComponentOptions<V extends Vue> {
metaInfo?: MetaInfo | (() => MetaInfo)
declare module 'vue/types/vue' {
interface Vue {
$meta(): VueMetaPlugin
}
}

declare module "vue/types/vue" {
interface Vue {
$meta(): MetaInfo
declare module 'vue/types/options' {
interface ComponentOptions<V extends Vue> {
metaInfo?: MetaInfo | MetaInfoComputed
}
}
Loading

0 comments on commit 7b85ff2

Please sign in to comment.