ovsx 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/lib/check-license.d.ts.map +1 -1
- package/lib/check-license.js +5 -4
- package/lib/check-license.js.map +1 -1
- package/lib/create-namespace.d.ts.map +1 -1
- package/lib/create-namespace.js +3 -1
- package/lib/create-namespace.js.map +1 -1
- package/lib/get.js +5 -5
- package/lib/get.js.map +1 -1
- package/lib/http.d.ts +32 -0
- package/lib/http.d.ts.map +1 -0
- package/lib/http.js +170 -0
- package/lib/http.js.map +1 -0
- package/lib/index.d.ts +0 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -3
- package/lib/index.js.map +1 -1
- package/lib/main.js +50 -61
- package/lib/main.js.map +1 -1
- package/lib/oidc.d.ts.map +1 -1
- package/lib/oidc.js +5 -47
- package/lib/oidc.js.map +1 -1
- package/lib/pat.d.ts +6 -1
- package/lib/pat.d.ts.map +1 -1
- package/lib/pat.js +16 -7
- package/lib/pat.js.map +1 -1
- package/lib/publish.d.ts +6 -0
- package/lib/publish.d.ts.map +1 -1
- package/lib/publish.js +147 -40
- package/lib/publish.js.map +1 -1
- package/lib/registry.d.ts +50 -12
- package/lib/registry.d.ts.map +1 -1
- package/lib/registry.js +131 -126
- package/lib/registry.js.map +1 -1
- package/lib/trusted-publishing-options.d.ts +5 -0
- package/lib/trusted-publishing-options.d.ts.map +1 -1
- package/lib/trusted-publishing.js +28 -4
- package/lib/trusted-publishing.js.map +1 -1
- package/lib/unpublish.d.ts.map +1 -1
- package/lib/unpublish.js +5 -8
- package/lib/unpublish.js.map +1 -1
- package/lib/util.d.ts +19 -15
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +51 -71
- package/lib/util.js.map +1 -1
- package/lib/verify-pat.d.ts.map +1 -1
- package/lib/verify-pat.js +3 -1
- package/lib/verify-pat.js.map +1 -1
- package/lib/verify.js +2 -2
- package/lib/verify.js.map +1 -1
- package/lib/zip.d.ts.map +1 -1
- package/lib/zip.js +2 -10
- package/lib/zip.js.map +1 -1
- package/package.json +19 -14
- package/src/check-license.ts +5 -4
- package/src/create-namespace.ts +3 -1
- package/src/get.ts +6 -6
- package/src/http.ts +176 -0
- package/src/index.ts +0 -3
- package/src/main.ts +54 -63
- package/src/oidc.ts +5 -47
- package/src/pat.ts +22 -9
- package/src/publish.ts +187 -44
- package/src/registry.ts +153 -126
- package/src/trusted-publishing-options.ts +5 -0
- package/src/trusted-publishing.ts +33 -5
- package/src/unpublish.ts +4 -7
- package/src/util.ts +47 -73
- package/src/verify-pat.ts +3 -1
- package/src/verify.ts +3 -3
- package/src/zip.ts +2 -12
- package/lib/version.d.ts +0 -2
- package/lib/version.d.ts.map +0 -1
- package/lib/version.js +0 -5
- package/lib/version.js.map +0 -1
- package/src/version.ts +0 -1
package/src/util.ts
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
* SPDX-License-Identifier: EPL-2.0
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
|
|
11
|
+
import * as crypto from 'crypto';
|
|
11
12
|
import * as fs from 'fs';
|
|
13
|
+
import * as os from 'os';
|
|
12
14
|
import * as path from 'path';
|
|
13
|
-
import * as tmp from 'tmp';
|
|
14
15
|
import * as http from 'http';
|
|
16
|
+
import { InvalidArgumentError } from 'commander';
|
|
15
17
|
import { RegistryOptions } from './registry-options';
|
|
16
18
|
import { TrustedPublishingOptions } from './trusted-publishing-options';
|
|
17
19
|
|
|
18
|
-
export { promisify } from 'util';
|
|
19
|
-
|
|
20
20
|
export function addEnvOptions(options: RegistryOptions): void {
|
|
21
21
|
options.registryUrl ??= process.env.OVSX_REGISTRY_URL;
|
|
22
22
|
options.pat ??= process.env.OVSX_PAT;
|
|
@@ -29,6 +29,7 @@ export function addTrustedPublishingEnvOptions(options: TrustedPublishingOptions
|
|
|
29
29
|
options.trustedPublishing ??= parseBooleanEnv(process.env.OVSX_TRUSTED_PUBLISHING);
|
|
30
30
|
options.idToken ??= process.env.OVSX_ID_TOKEN;
|
|
31
31
|
options.oidcAudience ??= process.env.OVSX_OIDC_AUDIENCE;
|
|
32
|
+
options.registrationCode ??= process.env.OVSX_REGISTRATION_CODE;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/** How long a request may make no progress before it is abandoned; see RegistryOptions.timeout. */
|
|
@@ -67,7 +68,8 @@ function parseBooleanEnv(value?: string): boolean | undefined {
|
|
|
67
68
|
export function parseNonNegativeInt(value: string): number {
|
|
68
69
|
const parsed = Number(value);
|
|
69
70
|
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
70
|
-
|
|
71
|
+
// Commander prints only this error type as a usage message; anything else escapes as a stack trace.
|
|
72
|
+
throw new InvalidArgumentError(`Expected a non-negative whole number, got '${value}'.`);
|
|
71
73
|
}
|
|
72
74
|
return parsed;
|
|
73
75
|
}
|
|
@@ -76,36 +78,39 @@ export function matchExtensionId(id: string): RegExpExecArray | null {
|
|
|
76
78
|
return /^([\w-]+)(?:\.|\/)([\w-]+)$/.exec(id);
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Levenshtein distance between `a` and `b`: the minimum number of single-character insertions,
|
|
83
|
+
* deletions or substitutions needed to turn one into the other. Used to suggest the closest known
|
|
84
|
+
* command for a typo.
|
|
85
|
+
*/
|
|
86
|
+
export function levenshtein(a: string, b: string): number {
|
|
87
|
+
if (a === b) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
// The distance is symmetric, so keep the shorter string in `b` to bound the row size.
|
|
91
|
+
if (b.length > a.length) {
|
|
92
|
+
[a, b] = [b, a];
|
|
93
|
+
}
|
|
94
|
+
// A single row of the edit distance matrix, seeded with the distance between the empty prefix
|
|
95
|
+
// of `a` and every prefix of `b`.
|
|
96
|
+
const row = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
97
|
+
for (let i = 1; i <= a.length; i++) {
|
|
98
|
+
let diagonal = row[0];
|
|
99
|
+
row[0] = i;
|
|
100
|
+
for (let j = 1; j <= b.length; j++) {
|
|
101
|
+
const above = row[j];
|
|
102
|
+
row[j] = Math.min(row[j - 1] + 1, above + 1, diagonal + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
103
|
+
diagonal = above;
|
|
96
104
|
}
|
|
97
|
-
}
|
|
105
|
+
}
|
|
106
|
+
return row[b.length];
|
|
98
107
|
}
|
|
99
108
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
else
|
|
106
|
-
resolve(name);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
+
/**
|
|
110
|
+
* Returns a random, not-yet-created file path ending in `postfix`, directly in the OS temp directory.
|
|
111
|
+
*/
|
|
112
|
+
export function getTempFilePath(postfix = ''): string {
|
|
113
|
+
return path.join(os.tmpdir(), `ovsx-${crypto.randomUUID()}${postfix}`);
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
export function rejectError(err: any) {
|
|
@@ -135,9 +140,9 @@ export function handleError(debug?: boolean, additionalMessage?: string, exit: b
|
|
|
135
140
|
}
|
|
136
141
|
|
|
137
142
|
/**
|
|
138
|
-
* Formats a byte count for display, e.g. `1536` -> `1
|
|
139
|
-
* `FileUtils.byteCountToDisplaySize` formatting so client- and
|
|
140
|
-
* the same way.
|
|
143
|
+
* Formats a byte count for display, rounding down, e.g. `1536` -> `1 KB` and `1048577` -> `1 MB`.
|
|
144
|
+
* Mirrors the registry's own `FileUtils.byteCountToDisplaySize` formatting so client- and
|
|
145
|
+
* server-side size limit messages read the same way.
|
|
141
146
|
*/
|
|
142
147
|
export function formatBytes(bytes: number): string {
|
|
143
148
|
const units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
|
|
@@ -167,10 +172,12 @@ export function withStatus(error: Error, status?: number): StatusError {
|
|
|
167
172
|
/**
|
|
168
173
|
* A URL in the form it can safely be printed: no user info and no query string.
|
|
169
174
|
*
|
|
170
|
-
*
|
|
171
|
-
* `
|
|
172
|
-
*
|
|
173
|
-
*
|
|
175
|
+
* The personal access token travels in a header now, but `createNamespace`, `verifyPat`, `publish`
|
|
176
|
+
* and `delete` still carry it in the query string too when talking to a registry too old to resolve
|
|
177
|
+
* it from the header (see `Registry.tokenQuery`, #1344). An error message goes straight to stderr
|
|
178
|
+
* and from there into CI logs, and the query carries nothing an error needs - so it stays dropped
|
|
179
|
+
* whole rather than filtered key by key, a filter having to be kept in step with every parameter
|
|
180
|
+
* anyone ever adds.
|
|
174
181
|
*/
|
|
175
182
|
export function redactUrl(url: URL | string): string {
|
|
176
183
|
try {
|
|
@@ -189,24 +196,8 @@ export function statusError(response: http.IncomingMessage): StatusError {
|
|
|
189
196
|
return withStatus(new Error(message), response.statusCode);
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
export function readFile(name: string, packagePath?: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {
|
|
193
|
-
return new Promise((resolve, reject) => {
|
|
194
|
-
fs.readFile(
|
|
195
|
-
path.join(packagePath ?? process.cwd(), name),
|
|
196
|
-
{ encoding },
|
|
197
|
-
(err: NodeJS.ErrnoException | null, content: string) => {
|
|
198
|
-
if (err) {
|
|
199
|
-
reject(err);
|
|
200
|
-
} else {
|
|
201
|
-
resolve(content);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
);
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
199
|
export async function readManifest(packagePath?: string): Promise<Manifest> {
|
|
209
|
-
const content = await readFile('package.json',
|
|
200
|
+
const content = await fs.promises.readFile(path.join(packagePath ?? process.cwd(), 'package.json'), 'utf-8');
|
|
210
201
|
return JSON.parse(content);
|
|
211
202
|
}
|
|
212
203
|
|
|
@@ -222,26 +213,9 @@ export function validateManifest(manifest: Manifest): void {
|
|
|
222
213
|
}
|
|
223
214
|
}
|
|
224
215
|
|
|
225
|
-
export function writeFile(name: string, content: string, packagePath?: string, encoding: BufferEncoding = 'utf-8'): Promise<void> {
|
|
226
|
-
return new Promise((resolve, reject) => {
|
|
227
|
-
fs.writeFile(
|
|
228
|
-
path.join(packagePath ?? process.cwd(), name),
|
|
229
|
-
content,
|
|
230
|
-
{ encoding },
|
|
231
|
-
(err: NodeJS.ErrnoException | null) => {
|
|
232
|
-
if (err) {
|
|
233
|
-
reject(err);
|
|
234
|
-
} else {
|
|
235
|
-
resolve();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
);
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
216
|
export function writeManifest(manifest: Manifest, packagePath?: string): Promise<void> {
|
|
243
217
|
const content = JSON.stringify(manifest, null, 4);
|
|
244
|
-
return writeFile('package.json', content,
|
|
218
|
+
return fs.promises.writeFile(path.join(packagePath ?? process.cwd(), 'package.json'), content, 'utf-8');
|
|
245
219
|
}
|
|
246
220
|
|
|
247
221
|
export interface Manifest {
|
package/src/verify-pat.ts
CHANGED
|
@@ -33,6 +33,8 @@ export async function verifyPat(options: VerifyPatOptions): Promise<void> {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
const { pat, save } = await getPAT(options.namespace, options, false);
|
|
37
|
+
options.pat = pat;
|
|
37
38
|
await doVerifyPat(options);
|
|
39
|
+
await save();
|
|
38
40
|
}
|
package/src/verify.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import * as crypto from 'crypto';
|
|
15
15
|
import * as fs from 'fs';
|
|
16
16
|
import { Registry, Extension } from './registry';
|
|
17
|
-
import { addEnvOptions,
|
|
17
|
+
import { addEnvOptions, getTempFilePath } from './util';
|
|
18
18
|
import { readVSIXPackage, readZip } from './zip';
|
|
19
19
|
import { VerifyOptions } from './verify-options';
|
|
20
20
|
|
|
@@ -82,7 +82,7 @@ async function resolveVersion(registry: Registry, extension: Extension, version:
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
async function downloadSignature(registry: Registry, url: string): Promise<Buffer> {
|
|
85
|
-
const sigzipPath =
|
|
85
|
+
const sigzipPath = getTempFilePath('.sigzip');
|
|
86
86
|
try {
|
|
87
87
|
await registry.download(sigzipPath, new URL(url));
|
|
88
88
|
const entries = await readZip(sigzipPath, name => name === SIGNATURE_ENTRY);
|
|
@@ -97,7 +97,7 @@ async function downloadSignature(registry: Registry, url: string): Promise<Buffe
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
async function downloadPublicKey(registry: Registry, url: string): Promise<string> {
|
|
100
|
-
const publicKeyPath =
|
|
100
|
+
const publicKeyPath = getTempFilePath('.pem');
|
|
101
101
|
try {
|
|
102
102
|
await registry.download(publicKeyPath, new URL(url));
|
|
103
103
|
return await fs.promises.readFile(publicKeyPath, 'utf-8');
|
package/src/zip.ts
CHANGED
|
@@ -9,19 +9,10 @@
|
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
import * as crypto from 'crypto';
|
|
11
11
|
import * as yauzl from 'yauzl-promise';
|
|
12
|
-
import {
|
|
12
|
+
import { buffer } from 'stream/consumers';
|
|
13
13
|
import { pipeline } from 'stream/promises';
|
|
14
14
|
import { Manifest } from './util';
|
|
15
15
|
|
|
16
|
-
async function bufferStream(stream: Readable): Promise<Buffer> {
|
|
17
|
-
return await new Promise((resolve, reject) => {
|
|
18
|
-
const buffers: Buffer[] = [];
|
|
19
|
-
stream.on('data', buffer => buffers.push(buffer));
|
|
20
|
-
stream.once('error', reject);
|
|
21
|
-
stream.once('end', () => resolve(Buffer.concat(buffers)));
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
16
|
export async function readZip(packagePath: string, filter: (name: string) => boolean): Promise<Map<string, Buffer>> {
|
|
26
17
|
const result = new Map<string, Buffer>();
|
|
27
18
|
const zipfile = await yauzl.open(packagePath);
|
|
@@ -30,8 +21,7 @@ export async function readZip(packagePath: string, filter: (name: string) => boo
|
|
|
30
21
|
const name = entry.filename.toLowerCase();
|
|
31
22
|
if (filter(name)) {
|
|
32
23
|
const stream = await zipfile.openReadStream(entry);
|
|
33
|
-
|
|
34
|
-
result.set(name, buffer);
|
|
24
|
+
result.set(name, await buffer(stream));
|
|
35
25
|
}
|
|
36
26
|
}
|
|
37
27
|
} finally {
|
package/lib/version.d.ts
DELETED
package/lib/version.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/lib/version.js
DELETED
package/lib/version.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG,OAAO,CAAC"}
|
package/src/version.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const LIB_VERSION = "1.2.0";
|