-
Notifications
You must be signed in to change notification settings - Fork 205
/
validation.ts
117 lines (95 loc) · 3.17 KB
/
validation.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
import * as semver from 'semver';
import parseSemver from 'parse-semver';
const nameRegex = /^[a-z0-9][a-z0-9\-]*$/i;
export function validatePublisher(publisher: string | undefined): string {
if (!publisher) {
throw new Error(
`Missing publisher name. Learn more: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#publishing-extensions`
);
}
if (!nameRegex.test(publisher)) {
throw new Error(
`Invalid publisher name '${publisher}'. Expected the identifier of a publisher, not its human-friendly name. Learn more: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#publishing-extensions`
);
}
return publisher;
}
export function validateExtensionName(name: string | undefined): string {
if (!name) {
throw new Error(`Missing extension name`);
}
if (!nameRegex.test(name)) {
throw new Error(`Invalid extension name '${name}'`);
}
return name;
}
export function validateVersion(version: string | undefined): string {
if (!version) {
throw new Error(`Missing extension version`);
}
if (!semver.valid(version)) {
throw new Error(`Invalid extension version '${version}'`);
}
return version;
}
export function validateEngineCompatibility(version: string | undefined): string {
if (!version) {
throw new Error(`Missing vscode engine compatibility version`);
}
if (!/^\*$|^(\^|>=)?((\d+)|x)\.((\d+)|x)\.((\d+)|x)(\-.*)?$/.test(version)) {
throw new Error(`Invalid vscode engine compatibility version '${version}'`);
}
return version;
}
/**
* User shouldn't use a newer version of @types/vscode than the one specified in engines.vscode
*
* NOTE: This is enforced at the major and minor level. Since we don't have control over the patch
* version (it's auto-incremented by DefinitelyTyped), we don't look at the patch version at all.
*/
export function validateVSCodeTypesCompatibility(engineVersion: string, typeVersion: string): void {
if (engineVersion === '*') {
return;
}
if (!typeVersion) {
throw new Error(`Missing @types/vscode version`);
}
let plainEngineVersion: string, plainTypeVersion: string;
try {
const engineSemver = parseSemver(`vscode@${engineVersion}`);
plainEngineVersion = engineSemver.version;
} catch (err) {
throw new Error('Failed to parse semver of engines.vscode');
}
try {
const typeSemver = parseSemver(`@types/vscode@${typeVersion}`);
plainTypeVersion = typeSemver.version;
} catch (err) {
throw new Error('Failed to parse semver of @types/vscode');
}
// For all `x`, use smallest version for comparison
plainEngineVersion = plainEngineVersion.replace(/x/g, '0');
const [typeMajor, typeMinor] = plainTypeVersion.split('.').map(x => {
try {
return parseInt(x);
} catch (err) {
return 0;
}
});
const [engineMajor, engineMinor] = plainEngineVersion.split('.').map(x => {
try {
return parseInt(x);
} catch (err) {
return 0;
}
});
const error = new Error(
`@types/vscode ${typeVersion} greater than engines.vscode ${engineVersion}. Either upgrade engines.vscode or use an older @types/vscode version`
);
if (typeMajor > engineMajor) {
throw error;
}
if (typeMajor === engineMajor && typeMinor > engineMinor) {
throw error;
}
}