forked from vuejs/rollup-plugin-vue
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutils.ts
125 lines (96 loc) · 2.95 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import {
SFCDescriptor,
SFCBlock,
SFCCustomBlock
} from '@vue/component-compiler-utils'
import { createFilter } from 'rollup-pluginutils'
import * as queryString from 'querystring'
import * as path from 'path'
const GET_QUERY = /\.vue(\.[a-z]+?)?\?(.+)$/i
const PARAM_NAME = 'rollup-plugin-vue'
export interface VuePartRequest {
filename: string
meta: VuePartRequestMeta
}
export interface VuePartRequestMeta {
type: 'template' | 'script' | 'styles' | 'customBlocks'
lang: string
index?: number
}
export interface VuePartRequestCreator {
(filename: string, lang: string, type: string, index?: number): string
defaultLang: {
[key: string]: string
}
}
export function createVueFilter(
include: string | string[] = ['*.vue', '**/*.vue'],
exclude: string | string[] = []
): (file: string) => boolean {
const filter = createFilter(include, exclude)
return id => filter(id)
}
export function getVueMetaFromQuery(id: string): VuePartRequestMeta | null {
const match = GET_QUERY.exec(id)
if (match) {
const query = queryString.parse(match[2])
if (PARAM_NAME in query) {
const data: string = (Array.isArray(query[PARAM_NAME])
? query[PARAM_NAME][0]
: query[PARAM_NAME]) as string
const [type, index, lang] = data.split('.')
return (lang
? { type, lang, index: parseInt(index) } // styles.0.css
: { type, lang: index }) as VuePartRequestMeta // script.js
}
}
return null
}
export function isVuePartRequest(id: string): boolean {
return getVueMetaFromQuery(id) !== null
}
export const createVuePartRequest: VuePartRequestCreator = ((
filename: string,
lang: string | undefined,
type: string,
index?: number
): string => {
lang = lang || createVuePartRequest.defaultLang[type]
const match = GET_QUERY.exec(filename)
const query = match ? queryString.parse(match[2]) : {}
query[PARAM_NAME] = [type, index, lang]
.filter(it => it !== undefined)
.join('.')
return `${path.basename(filename)}?${queryString.stringify(query)}`
}) as VuePartRequestCreator
createVuePartRequest.defaultLang = {
template: 'html',
styles: 'css',
script: 'js'
}
export function parseVuePartRequest(id: string): VuePartRequest | undefined {
if (!id.includes('.vue')) return
const filename = id.substr(0, id.lastIndexOf('.vue') + 4)
const params = getVueMetaFromQuery(id)
if (params === null) return
return {
filename,
meta: params
}
}
export function resolveVuePart(
descriptors: Map<string, SFCDescriptor>,
{ filename, meta }: VuePartRequest
): SFCBlock | SFCCustomBlock {
const descriptor = descriptors.get(filename)
if (!descriptor) throw Error('File not processed yet, ' + filename)
const blocks = descriptor[meta.type]
const block = Array.isArray(blocks) ? blocks[meta.index as number] : blocks
if (!block)
throw Error(
`Requested (type=${meta.type} & index=${
meta.index
}) block not found in ${filename}`
)
return block
}