-
Notifications
You must be signed in to change notification settings - Fork 213
/
Copy pathoxide.ts
155 lines (129 loc) · 3.3 KB
/
oxide.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { lte } from '@tailwindcss/language-service/src/util/semver'
// This covers the Oxide API from v4.0.0-alpha.1 to v4.0.0-alpha.18
declare namespace OxideV1 {
interface GlobEntry {
base: string
glob: string
}
interface ScanOptions {
base: string
globs?: boolean
}
interface ScanResult {
files: Array<string>
globs: Array<GlobEntry>
}
}
// This covers the Oxide API from v4.0.0-alpha.19
declare namespace OxideV2 {
interface GlobEntry {
base: string
pattern: string
}
interface ScanOptions {
base: string
sources: Array<GlobEntry>
}
interface ScanResult {
files: Array<string>
globs: Array<GlobEntry>
}
}
// This covers the Oxide API from v4.0.0-alpha.20+
declare namespace OxideV3 {
interface GlobEntry {
base: string
pattern: string
}
interface ScannerOptions {
detectSources?: { base: string }
sources: Array<GlobEntry>
}
interface ScannerConstructor {
new (options: ScannerOptions): Scanner
}
interface Scanner {
files: Array<string>
globs: Array<GlobEntry>
}
}
interface Oxide {
scanDir?(options: OxideV1.ScanOptions): OxideV1.ScanResult
scanDir?(options: OxideV2.ScanOptions): OxideV2.ScanResult
Scanner?: OxideV3.ScannerConstructor
}
async function loadOxideAtPath(id: string): Promise<Oxide | null> {
let oxide = await import(id)
// This is a much older, unsupported version of Oxide before v4.0.0-alpha.1
if (!oxide.scanDir && !oxide.Scanner) return null
return oxide
}
interface GlobEntry {
base: string
pattern: string
}
interface ScanOptions {
oxidePath: string
oxideVersion: string
basePath: string
sources: Array<GlobEntry>
}
interface ScanResult {
files: Array<string>
globs: Array<GlobEntry>
}
/**
* This is a helper function that leverages the Oxide API to scan a directory
* and a set of sources and turn them into files and globs.
*
* Because the Oxide API has changed over time this function presents a unified
* interface that works with all versions of the Oxide API but the results may
* be different depending on the version of Oxide that is being used.
*
* For example, the `sources` option is ignored before v4.0.0-alpha.19.
*/
export async function scan(options: ScanOptions): Promise<ScanResult | null> {
let oxide = await loadOxideAtPath(options.oxidePath)
if (!oxide) return null
// V1
if (lte(options.oxideVersion, '4.0.0-alpha.18')) {
let result = oxide.scanDir?.({
base: options.basePath,
globs: true,
})
return {
files: result.files,
globs: result.globs.map((g) => ({ base: g.base, pattern: g.glob })),
}
}
// V2
if (lte(options.oxideVersion, '4.0.0-alpha.19')) {
let result = oxide.scanDir({
base: options.basePath,
sources: options.sources,
})
return {
files: result.files,
globs: result.globs,
}
}
// V3
if (lte(options.oxideVersion, '4.0.0-alpha.30')) {
let scanner = new oxide.Scanner({
detectSources: { base: options.basePath },
sources: options.sources,
})
return {
files: scanner.files,
globs: scanner.globs,
}
}
// V4
let scanner = new oxide.Scanner({
sources: [{ base: options.basePath, pattern: '**/*' }, ...options.sources],
})
return {
files: scanner.files,
globs: scanner.globs,
}
}