Skip to content

Commit 7b85ff2

Browse files
authored
feat(ts): update types for v2 (#338)
* 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
1 parent 111c769 commit 7b85ff2

File tree

7 files changed

+487
-424
lines changed

7 files changed

+487
-424
lines changed

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
"files": [
3636
"lib",
3737
"es",
38-
"types/index.d.ts",
39-
"types/vue.d.ts"
38+
"types/*.d.ts"
4039
],
4140
"main": "lib/vue-meta.common.js",
4241
"web": "lib/vue-meta.js",
@@ -57,7 +56,8 @@
5756
"test": "yarn test:unit && yarn test:e2e-ssr && yarn test:e2e-browser",
5857
"test:e2e-ssr": "jest test/e2e/ssr",
5958
"test:e2e-browser": "jest test/e2e/browser",
60-
"test:unit": "jest test/unit"
59+
"test:unit": "jest test/unit",
60+
"test:types": "tsc -p types/test"
6161
},
6262
"dependencies": {
6363
"deepmerge": "^3.2.0"
@@ -113,6 +113,7 @@
113113
"selenium-webdriver": "^4.0.0-alpha.1",
114114
"standard-version": "^5.0.2",
115115
"tib": "^0.4.0",
116+
"typescript": "^3.4.1",
116117
"vue": "^2.6.10",
117118
"vue-jest": "^3.0.4",
118119
"vue-loader": "^15.7.0",

types/index.d.ts

+9-49
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,11 @@
1-
import './vue';
2-
import { PluginFunction } from 'vue/types/plugin';
1+
import './vue'
2+
import { VueMeta } from './vue-meta'
33

4-
/**
5-
* Installation function
6-
*
7-
* @param {Vue} Vue - the Vue constructor.
8-
* @param {{
9-
* keyName: string, // the component option name that vue-meta looks for meta info on.
10-
* attribute: string, // the attribute name vue-meta adds to the tags it observes
11-
* ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
12-
* tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
13-
* }} options
14-
*/
15-
declare const Meta: PluginFunction<{
16-
keyName: string, // the component option name that vue-meta looks for meta info on.
17-
attribute: string, // the attribute name vue-meta adds to the tags it observes
18-
ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
19-
tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
20-
}>;
4+
export default VueMeta
215

22-
export default Meta;
23-
24-
export interface MetaInfo {
25-
title?: string
26-
titleTemplate?: string | ((titleChunk: string) => string)
27-
htmlAttrs?: { [key: string]: string }
28-
bodyAttrs?: { [key: string]: string }
29-
base?: { target: string, href: string }
30-
31-
meta?: {
32-
vmid?: string,
33-
charset?: string,
34-
content?: string,
35-
'http-equiv'?: 'content-security-policy' | 'refresh',
36-
name?: string,
37-
[key: string]: any
38-
}[]
39-
40-
link?: { rel: string, href: string, [key: string]: any }[]
41-
style?: { cssText: string, type: string, [key: string]: any }[]
42-
script?: { innerHTML?: string, src?: string, type: string, [key: string]: any }[]
43-
noscript?: { innerHTML: string, [key: string]: any }[]
44-
45-
__dangerouslyDisableSanitizers?: string[]
46-
__dangerouslyDisableSanitizersByTagID?: string[]
47-
48-
changed?: <T extends object>(newInfo: T, addedTags: HTMLElement[], removedTags: HTMLElement[]) => void
49-
afterNavigation?: <T extends object>(vm: Vue, newInfo: T) => void
50-
refreshOnceOnNavigation?: boolean
51-
}
6+
export {
7+
VueMetaOptions,
8+
VueMetaPlugin,
9+
MetaInfo,
10+
MetaInfoSSR
11+
} from './vue-meta'

types/test/index.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import Vue, { ComponentOptions } from 'vue'
2+
import VueMeta, { VueMetaPlugin, VueMetaOptions, MetaInfo, MetaInfoSSR } from '../index'
3+
4+
Vue.use(VueMeta, {
5+
keyName: 'head'
6+
} as VueMetaOptions)
7+
8+
const FooMetaInfo: MetaInfo = {
9+
title: 'title',
10+
titleTemplate: '%s - Home',
11+
bodyAttrs: { class: 'a' }
12+
}
13+
14+
const BarMetaInfo: MetaInfo = {
15+
title: 'title',
16+
titleTemplate: c => `${c} - Home`,
17+
bodyAttrs: { class: ['a', 'b'] },
18+
__dangerouslyDisableSanitizers: ['script'],
19+
__dangerouslyDisableSanitizersByTagID: {
20+
ldjson: ['innerHTML']
21+
},
22+
script: [{
23+
src: '', crossorigin: '', async: true
24+
}],
25+
meta: [
26+
{ charset: 'utf-8' },
27+
{
28+
'property': 'og:title',
29+
'content': 'Test title',
30+
'template': chunk => `${chunk} - My page`, //or as string template: '%s - My page',
31+
'vmid': 'og:title'
32+
}
33+
],
34+
changed(newdata: MetaInfo, newTags: HTMLElement[], oldTags: HTMLElement[]) {
35+
},
36+
afterNavigation(data: MetaInfo) {
37+
}
38+
}
39+
40+
const Foo: ComponentOptions<Vue> = {
41+
metaInfo: FooMetaInfo
42+
}
43+
44+
const Bar: ComponentOptions<Vue> = {
45+
metaInfo() {
46+
return BarMetaInfo
47+
}
48+
}
49+
50+
const app: Vue = new Vue(Foo)
51+
const $meta: VueMetaPlugin = app.$meta()
52+
53+
// getOptions
54+
const options: VueMetaOptions = $meta.getOptions()
55+
56+
// client side refresh
57+
const { metaInfo: metaData1 }: { metaInfo: MetaInfo } = $meta.refresh()
58+
59+
// server side injection
60+
const metaDataSSR: MetaInfoSSR = $meta.inject()
61+
if (metaDataSSR.script) {
62+
metaDataSSR.script.text()
63+
metaDataSSR.script.text({ body: true })
64+
}
65+
66+
// pausing & resuming
67+
let resume
68+
resume = $meta.pause()
69+
const ret: void = resume()
70+
resume = $meta.pause(true)
71+
const { metaInfo: metaData2 }: { metaInfo: MetaInfo } = resume()
72+
const { metaInfo: metaData3 }: { metaInfo: MetaInfo } = $meta.resume(true)

types/tsconfig.json renamed to types/test/tsconfig.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
"target": "es5",
44
"module": "es2015",
55
"moduleResolution": "node",
6+
"strict": true,
7+
"noEmit": true,
68
"lib": [
79
"es5",
810
"dom",
911
"es2015.promise"
10-
],
11-
"strict": true,
12-
"noEmit": true
12+
]
1313
},
1414
"include": [
15-
"*.d.ts"
15+
"*.ts",
16+
"../*.d.ts"
1617
]
1718
}

types/vue-meta.d.ts

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import './vue'
2+
import Vue, { ComponentOptions, PluginFunction } from 'vue'
3+
4+
type Component = ComponentOptions<Vue> | typeof Vue
5+
type elements = HTMLElement[]
6+
7+
export interface VueMetaOptions {
8+
keyName: string, // the component option name that vue-meta looks for meta info on.
9+
attribute: string, // the attribute name vue-meta adds to the tags it observes
10+
ssrAttribute: string, // the attribute name that lets vue-meta know that meta info has already been server-rendered
11+
tagIDKeyName: string // the property name that vue-meta uses to determine whether to overwrite or append a tag
12+
refreshOnceOnNavigation: boolean
13+
}
14+
15+
export declare class VueMeta {
16+
static version: string
17+
static install(vue: typeof Vue, options?: VueMetaOptions): PluginFunction<never>
18+
static hasMetaInfo(vm: Component): boolean
19+
}
20+
21+
interface Refreshed {
22+
vm: Component,
23+
metaInfo: MetaInfo,
24+
tags: {
25+
addedTags: elements
26+
removedTags: elements
27+
}
28+
}
29+
30+
export interface VueMetaPlugin {
31+
getOptions(): VueMetaOptions
32+
refresh(): Refreshed
33+
inject(): MetaInfoSSR
34+
pause(refresh: true): () => Refreshed
35+
pause(refresh?: boolean): () => void
36+
resume(refresh: true): Refreshed
37+
resume(refresh?: boolean): void
38+
}
39+
40+
export interface AttributeProperty {
41+
[key: string]: string | string[]
42+
}
43+
44+
export interface MetaDataProperty {
45+
vmid?: string,
46+
[key: string]: any
47+
}
48+
49+
export interface MetaPropertyCharset extends MetaDataProperty {
50+
charset: string,
51+
}
52+
53+
export interface MetaPropertyEquiv extends MetaDataProperty {
54+
httpEquiv: string,
55+
name: string,
56+
template?: (chunk: string) => string
57+
}
58+
59+
export interface MetaPropertyName extends MetaDataProperty {
60+
name: string,
61+
content: string,
62+
template?: (chunk: string) => string
63+
}
64+
65+
// non-w3c interface
66+
export interface MetaPropertyProperty extends MetaDataProperty {
67+
property: string,
68+
content: string,
69+
template?: (chunk: string) => string
70+
}
71+
72+
export interface LinkProperty extends MetaDataProperty {
73+
rel: string,
74+
crossOrigin?: string | null,
75+
href?: string,
76+
hreflang?: string,
77+
media?: string,
78+
nonce?: string,
79+
referrerPolicy?: string,
80+
rev?: string,
81+
type?: string,
82+
}
83+
84+
export interface StyleProperty extends MetaDataProperty {
85+
cssText: string,
86+
media?: string,
87+
nonce?: string,
88+
type?: string,
89+
}
90+
91+
export interface ScriptPropertyBase extends MetaDataProperty {
92+
type?: string,
93+
charset?: string,
94+
body?: boolean,
95+
async?: boolean,
96+
defer?: boolean,
97+
crossOrigin?: string,
98+
nonce?: string
99+
}
100+
101+
export interface ScriptPropertyText extends ScriptPropertyBase {
102+
innerHTML: string,
103+
}
104+
105+
export interface ScriptPropertySrc extends ScriptPropertyBase {
106+
src: string,
107+
}
108+
109+
export interface NoScriptProperty extends MetaDataProperty {
110+
innerHTML: string,
111+
}
112+
113+
export interface MetaInfo {
114+
title?: string
115+
titleTemplate?: string | ((titleChunk: string) => string)
116+
117+
htmlAttrs?: AttributeProperty
118+
headAttrs?: AttributeProperty
119+
bodyAttrs?: AttributeProperty
120+
121+
base?: {
122+
target: string,
123+
href: string
124+
}
125+
126+
meta?: (MetaPropertyCharset | MetaPropertyEquiv | MetaPropertyName | MetaPropertyProperty)[]
127+
link?: LinkProperty[]
128+
style?: StyleProperty[]
129+
script?: (ScriptPropertyText | ScriptPropertySrc)[]
130+
noscript?: NoScriptProperty[]
131+
132+
__dangerouslyDisableSanitizers?: string[]
133+
__dangerouslyDisableSanitizersByTagID?: {
134+
[key: string]: string[]
135+
}
136+
137+
changed?: <T extends MetaInfo>(newInfo: T, addedTags: elements, removedTags: elements) => void
138+
afterNavigation?: <T extends MetaInfo>(newInfo: T) => void
139+
}
140+
141+
export type MetaInfoComputed = () => MetaInfo
142+
143+
interface ToText {
144+
text(): string
145+
}
146+
147+
interface ToBodyTextOption {
148+
body: boolean
149+
}
150+
interface ToBodyText {
151+
text(options?: ToBodyTextOption): string
152+
}
153+
154+
export interface MetaInfoSSR {
155+
title?: ToText
156+
htmlAttrs?: ToText
157+
headAttrs?: ToText
158+
bodyAttrs?: ToText
159+
base?: ToText
160+
meta?: ToText
161+
link?: ToText
162+
style?: ToText
163+
script?: ToBodyText
164+
noscript?: ToBodyText
165+
}

types/vue.d.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
* Augment the typings of Vue.js
33
*/
44

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

8-
declare module "vue/types/options" {
9-
interface ComponentOptions<V extends Vue> {
10-
metaInfo?: MetaInfo | (() => MetaInfo)
8+
declare module 'vue/types/vue' {
9+
interface Vue {
10+
$meta(): VueMetaPlugin
1111
}
1212
}
1313

14-
declare module "vue/types/vue" {
15-
interface Vue {
16-
$meta(): MetaInfo
14+
declare module 'vue/types/options' {
15+
interface ComponentOptions<V extends Vue> {
16+
metaInfo?: MetaInfo | MetaInfoComputed
1717
}
1818
}

0 commit comments

Comments
 (0)