ovsx 1.2.0 → 1.3.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 +2 -0
- package/lib/check-license.d.ts.map +1 -1
- package/lib/check-license.js +3 -2
- package/lib/check-license.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/main.js +44 -41
- 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/publish.d.ts.map +1 -1
- package/lib/publish.js +100 -32
- package/lib/publish.js.map +1 -1
- package/lib/registry.d.ts +49 -11
- package/lib/registry.d.ts.map +1 -1
- package/lib/registry.js +115 -124
- package/lib/registry.js.map +1 -1
- package/lib/util.d.ts +16 -12
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +44 -67
- package/lib/util.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 +14 -11
- package/src/check-license.ts +4 -3
- package/src/get.ts +6 -6
- package/src/http.ts +176 -0
- package/src/main.ts +48 -43
- package/src/oidc.ts +5 -47
- package/src/publish.ts +136 -34
- package/src/registry.ts +132 -124
- package/src/util.ts +40 -69
- 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/lib/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";AAAA;;;;;;;;kFAQkF;;;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/lib/verify.js
CHANGED
|
@@ -70,7 +70,7 @@ async function resolveVersion(registry, extension, version) {
|
|
|
70
70
|
return registry.getJson(new URL(versionUrl));
|
|
71
71
|
}
|
|
72
72
|
async function downloadSignature(registry, url) {
|
|
73
|
-
const sigzipPath =
|
|
73
|
+
const sigzipPath = (0, util_1.getTempFilePath)('.sigzip');
|
|
74
74
|
try {
|
|
75
75
|
await registry.download(sigzipPath, new URL(url));
|
|
76
76
|
const entries = await (0, zip_1.readZip)(sigzipPath, name => name === SIGNATURE_ENTRY);
|
|
@@ -85,7 +85,7 @@ async function downloadSignature(registry, url) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
async function downloadPublicKey(registry, url) {
|
|
88
|
-
const publicKeyPath =
|
|
88
|
+
const publicKeyPath = (0, util_1.getTempFilePath)('.pem');
|
|
89
89
|
try {
|
|
90
90
|
await registry.download(publicKeyPath, new URL(url));
|
|
91
91
|
return await fs.promises.readFile(publicKeyPath, 'utf-8');
|
package/lib/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;+EAW+E;;AAiB/E,wBAsCC;AArDD,iCAAiC;AACjC,yBAAyB;AACzB,yCAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/lib/zip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zip.d.ts","sourceRoot":"","sources":["../src/zip.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"zip.d.ts","sourceRoot":"","sources":["../src/zip.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,wBAAsB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgBlH;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBzF;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAQ5E"}
|
package/lib/zip.js
CHANGED
|
@@ -14,15 +14,8 @@ exports.readVSIXPackage = readVSIXPackage;
|
|
|
14
14
|
********************************************************************************/
|
|
15
15
|
const crypto = require("crypto");
|
|
16
16
|
const yauzl = require("yauzl-promise");
|
|
17
|
+
const consumers_1 = require("stream/consumers");
|
|
17
18
|
const promises_1 = require("stream/promises");
|
|
18
|
-
async function bufferStream(stream) {
|
|
19
|
-
return await new Promise((resolve, reject) => {
|
|
20
|
-
const buffers = [];
|
|
21
|
-
stream.on('data', buffer => buffers.push(buffer));
|
|
22
|
-
stream.once('error', reject);
|
|
23
|
-
stream.once('end', () => resolve(Buffer.concat(buffers)));
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
19
|
async function readZip(packagePath, filter) {
|
|
27
20
|
const result = new Map();
|
|
28
21
|
const zipfile = await yauzl.open(packagePath);
|
|
@@ -31,8 +24,7 @@ async function readZip(packagePath, filter) {
|
|
|
31
24
|
const name = entry.filename.toLowerCase();
|
|
32
25
|
if (filter(name)) {
|
|
33
26
|
const stream = await zipfile.openReadStream(entry);
|
|
34
|
-
|
|
35
|
-
result.set(name, buffer);
|
|
27
|
+
result.set(name, await (0, consumers_1.buffer)(stream));
|
|
36
28
|
}
|
|
37
29
|
}
|
|
38
30
|
}
|
package/lib/zip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zip.js","sourceRoot":"","sources":["../src/zip.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"zip.js","sourceRoot":"","sources":["../src/zip.ts"],"names":[],"mappings":";;AAeA,0BAgBC;AAUD,8CAkBC;AAED,0CAQC;AArED;;;;;;;;kFAQkF;AAClF,iCAAiC;AACjC,uCAAuC;AACvC,gDAA0C;AAC1C,8CAA2C;AAGpC,KAAK,UAAU,OAAO,CAAC,WAAmB,EAAE,MAAiC;IACnF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBACnD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAA,kBAAM,EAAC,MAAM,CAAC,CAAC,CAAC;YACxC,CAAC;QACF,CAAC;IACF,CAAC;YAAS,CAAC;QACV,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,SAAS;YACV,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,IAAA,mBAAQ,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,CAAC;IACF,CAAC;YAAS,CAAC;QACV,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,WAAmB;IACxD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzF,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAa,CAAC;AAC7D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ovsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Command line interface for Eclipse Open VSX",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
"name": "Miro Spönemann",
|
|
22
22
|
"email": "miro.spoenemann@typefox.io",
|
|
23
23
|
"url": "https://www.typefox.io"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "Thomas Neidhart",
|
|
27
|
+
"email": "thomas.neidhart@eclipse-foundation.org"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "Jordi Gómez Hidalgo",
|
|
31
|
+
"email": "jordi.gomez@eclipse-foundation.org"
|
|
24
32
|
}
|
|
25
33
|
],
|
|
26
34
|
"files": [
|
|
@@ -35,25 +43,20 @@
|
|
|
35
43
|
},
|
|
36
44
|
"dependencies": {
|
|
37
45
|
"@inquirer/prompts": "^7.10.1",
|
|
38
|
-
"@vscode/vsce": "^
|
|
39
|
-
"commander": "^
|
|
46
|
+
"@vscode/vsce": "^4.0.0",
|
|
47
|
+
"commander": "^14.0.3",
|
|
40
48
|
"cross-keychain": "^1.1.0",
|
|
41
|
-
"follow-redirects": "^1.16.0",
|
|
42
49
|
"is-ci": "^2.0.0",
|
|
43
|
-
"leven": "^3.1.0",
|
|
44
50
|
"semver": "^7.6.0",
|
|
45
|
-
"tmp": "^0.2.3",
|
|
46
51
|
"yauzl-promise": "^4.0.0"
|
|
47
52
|
},
|
|
48
53
|
"devDependencies": {
|
|
49
54
|
"@eslint/eslintrc": "^3.2.0",
|
|
50
55
|
"@eslint/js": "^9.15.0",
|
|
51
56
|
"@stylistic/eslint-plugin": "^2.11.0",
|
|
52
|
-
"@types/follow-redirects": "^1.13.1",
|
|
53
57
|
"@types/is-ci": "^2.0.0",
|
|
54
58
|
"@types/node": "^22.0.0",
|
|
55
59
|
"@types/semver": "^7.5.8",
|
|
56
|
-
"@types/tmp": "^0.2.2",
|
|
57
60
|
"@types/yauzl-promise": "^4",
|
|
58
61
|
"@types/yazl": "^3.3.1",
|
|
59
62
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
@@ -62,17 +65,17 @@
|
|
|
62
65
|
"limiter": "^2.1.0",
|
|
63
66
|
"rimraf": "^6.0.1",
|
|
64
67
|
"typescript": "^5.6.3",
|
|
65
|
-
"
|
|
68
|
+
"vite": "^8.3.2",
|
|
69
|
+
"vitest": "^5.0.3",
|
|
66
70
|
"yazl": "^3.3.1"
|
|
67
71
|
},
|
|
68
72
|
"scripts": {
|
|
69
73
|
"clean": "rimraf lib",
|
|
70
|
-
"prebuild": "node -p \"'export const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
|
|
71
74
|
"build": "tsc -p ./tsconfig.json && yarn run lint",
|
|
72
75
|
"watch": "tsc -w -p ./tsconfig.json",
|
|
73
76
|
"test": "vitest run",
|
|
74
77
|
"lint": "eslint -c ./configs/eslintrc.mjs src test",
|
|
75
|
-
"prepare": "yarn run clean && yarn run
|
|
78
|
+
"prepare": "yarn run clean && yarn run build",
|
|
76
79
|
"publish:next": "yarn npm publish --tag next",
|
|
77
80
|
"publish:latest": "yarn npm publish --tag latest",
|
|
78
81
|
"load-extensions": "node scripts/load-test-extensions.js"
|
package/src/check-license.ts
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
|
|
11
11
|
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
12
13
|
import * as isCI from 'is-ci';
|
|
13
14
|
import { input, select } from '@inquirer/prompts';
|
|
14
15
|
import {
|
|
15
|
-
readManifest, writeManifest, Manifest,
|
|
16
|
+
readManifest, writeManifest, Manifest, validateManifest
|
|
16
17
|
} from './util';
|
|
17
18
|
|
|
18
19
|
async function addLicense(packagePath: string, manifest: Manifest): Promise<void> {
|
|
@@ -87,14 +88,14 @@ async function useMITLicense(manifest: Manifest, packagePath?: string) {
|
|
|
87
88
|
manifest.license = 'MIT';
|
|
88
89
|
await writeManifest(manifest, packagePath);
|
|
89
90
|
const license = MIT_LICENSE_TEXT.replace('<YEAR> <COPYRIGHT HOLDER>', copyright);
|
|
90
|
-
await writeFile('LICENSE', license,
|
|
91
|
+
await fs.promises.writeFile(path.join(packagePath ?? process.cwd(), 'LICENSE'), license, 'utf-8');
|
|
91
92
|
console.log('LICENSE file has been written. Please commit it to the source repository.');
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
const LICENSE_FILE_NAMES = ['license.md', 'license', 'license.txt', 'licence.md', 'licence', 'licence.txt'];
|
|
95
96
|
|
|
96
97
|
async function hasLicenseFile(packagePath?: string): Promise<boolean> {
|
|
97
|
-
const fileNames = await
|
|
98
|
+
const fileNames = await fs.promises.readdir(packagePath ?? '.');
|
|
98
99
|
for (const fileName of fileNames) {
|
|
99
100
|
for (const licFileName of LICENSE_FILE_NAMES) {
|
|
100
101
|
if (fileName.toLowerCase() === licFileName) {
|
package/src/get.ts
CHANGED
|
@@ -12,7 +12,7 @@ import * as fs from 'fs';
|
|
|
12
12
|
import * as path from 'path';
|
|
13
13
|
import * as semver from 'semver';
|
|
14
14
|
import { Registry, Extension } from "./registry";
|
|
15
|
-
import {
|
|
15
|
+
import { matchExtensionId, addEnvOptions, rejectError } from './util';
|
|
16
16
|
import { GetOptions } from './get-options';
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -70,15 +70,15 @@ async function printMetadata(registry: Registry, extension: Extension, output?:
|
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
let filePath: string | undefined;
|
|
73
|
-
const stats =
|
|
73
|
+
const stats = fs.statSync(output, { throwIfNoEntry: false });
|
|
74
74
|
if (stats?.isDirectory() || !stats && output.endsWith(path.sep)) {
|
|
75
75
|
const fileName = `${extension.namespace}.${extension.name}-${extension.version}.json`;
|
|
76
76
|
filePath = path.resolve(process.cwd(), output, fileName);
|
|
77
77
|
} else {
|
|
78
78
|
filePath = path.resolve(process.cwd(), output);
|
|
79
79
|
}
|
|
80
|
-
await
|
|
81
|
-
await
|
|
80
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
81
|
+
await fs.promises.writeFile(filePath, metadata);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
async function download(registry: Registry, extension: Extension, output?: string): Promise<void> {
|
|
@@ -90,7 +90,7 @@ async function download(registry: Registry, extension: Extension, output?: strin
|
|
|
90
90
|
const fileName = decodeURIComponent(downloadUrl.substring(fileNameIndex + 1));
|
|
91
91
|
let filePath: string | undefined;
|
|
92
92
|
if (output) {
|
|
93
|
-
const stats =
|
|
93
|
+
const stats = fs.statSync(output, { throwIfNoEntry: false });
|
|
94
94
|
if (stats?.isDirectory() || !stats && output.endsWith(path.sep)) {
|
|
95
95
|
filePath = path.resolve(process.cwd(), output, fileName);
|
|
96
96
|
} else {
|
|
@@ -99,7 +99,7 @@ async function download(registry: Registry, extension: Extension, output?: strin
|
|
|
99
99
|
} else {
|
|
100
100
|
filePath = path.resolve(process.cwd(), fileName);
|
|
101
101
|
}
|
|
102
|
-
await
|
|
102
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
103
103
|
const target = extension.targetPlatform !== 'universal' ? '@' + extension.targetPlatform : '';
|
|
104
104
|
console.log(`Downloading ${extension.namespace}.${extension.name}-${extension.version}${target} to ${filePath}`);
|
|
105
105
|
await registry.download(filePath, new URL(downloadUrl));
|
package/src/http.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* Copyright (c) 2026 Contributors to the Eclipse Foundation.
|
|
3
|
+
*
|
|
4
|
+
* See the NOTICE file(s) distributed with this work for additional
|
|
5
|
+
* information regarding copyright ownership.
|
|
6
|
+
*
|
|
7
|
+
* This program and the accompanying materials are made available under the
|
|
8
|
+
* terms of the Eclipse Public License 2.0 which is available at
|
|
9
|
+
* https://www.eclipse.org/legal/epl-2.0.
|
|
10
|
+
*
|
|
11
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
12
|
+
*****************************************************************************/
|
|
13
|
+
|
|
14
|
+
import * as http from 'http';
|
|
15
|
+
import * as https from 'https';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import { redactUrl, statusError, withStatus } from './util';
|
|
18
|
+
|
|
19
|
+
// Hop limit the fetch standard uses.
|
|
20
|
+
const MAX_REDIRECTS = 20;
|
|
21
|
+
|
|
22
|
+
// Dropped on a redirect to another origin; X-OpenVSX-Token carries the PAT just like Authorization.
|
|
23
|
+
const CREDENTIAL_HEADERS = /^(?:authorization|cookie|proxy-authorization|x-openvsx-token)$/i;
|
|
24
|
+
|
|
25
|
+
export type RequestBody = () => string | Buffer | Uint8Array | fs.ReadStream;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Sends a request and follows redirects to `onResponse`'s final response, reporting any failure
|
|
29
|
+
* to `fail`. A GET follows every redirect; a request with a body follows only 307/308, sending
|
|
30
|
+
* the body again, because 301/302/303 turn it into a GET without one. Credentials are dropped
|
|
31
|
+
* once a redirect leaves the origin. Only the headers in `options` are sent, so a caller that
|
|
32
|
+
* passes none carries no credentials.
|
|
33
|
+
*/
|
|
34
|
+
export function send(
|
|
35
|
+
url: URL,
|
|
36
|
+
options: http.RequestOptions,
|
|
37
|
+
body: RequestBody | undefined,
|
|
38
|
+
onResponse: (response: http.IncomingMessage) => void,
|
|
39
|
+
fail: (err: Error) => void,
|
|
40
|
+
hops = 0
|
|
41
|
+
): void {
|
|
42
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
43
|
+
const request = protocol.request(url, options, response => {
|
|
44
|
+
const status = response.statusCode ?? 0;
|
|
45
|
+
const location = response.headers.location;
|
|
46
|
+
if (status < 300 || status > 399 || !location) {
|
|
47
|
+
onResponse(response);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
response.resume();
|
|
51
|
+
|
|
52
|
+
let next: URL;
|
|
53
|
+
try {
|
|
54
|
+
next = new URL(location, url);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
fail(err as Error);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (hops >= MAX_REDIRECTS) {
|
|
60
|
+
fail(new Error(`The request to ${redactUrl(url)} was redirected more than ${MAX_REDIRECTS} times.`));
|
|
61
|
+
} else if (next.protocol !== 'https:' && next.protocol !== 'http:') {
|
|
62
|
+
fail(new Error(`The request to ${redactUrl(url)} was redirected to unsupported URL ${redactUrl(next)}.`));
|
|
63
|
+
} else if (body && status !== 307 && status !== 308) {
|
|
64
|
+
fail(withStatus(new Error(`The ${options.method} request to ${redactUrl(url)} was redirected to ${redactUrl(next)} `
|
|
65
|
+
+ `with status ${status}, which drops the request body. Use the redirect target as the registry URL.`), status));
|
|
66
|
+
} else {
|
|
67
|
+
// The server may answer before reading the body: abandon this hop so its stream
|
|
68
|
+
// releases the file and a late reset on its socket can't fail the next hop.
|
|
69
|
+
request.removeListener('error', fail);
|
|
70
|
+
request.on('error', () => { /* abandoned */ });
|
|
71
|
+
if (content instanceof fs.ReadStream) {
|
|
72
|
+
content.unpipe(request);
|
|
73
|
+
content.destroy();
|
|
74
|
+
}
|
|
75
|
+
request.destroy();
|
|
76
|
+
const headers = next.origin === url.origin ? options.headers : withoutCredentials(options.headers as http.OutgoingHttpHeaders);
|
|
77
|
+
send(next, { ...options, headers }, body, onResponse, fail, hops + 1);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
request.on('error', fail);
|
|
81
|
+
failOnTimeout(request, url, options.timeout, fail);
|
|
82
|
+
|
|
83
|
+
const content = body?.();
|
|
84
|
+
if (content instanceof fs.ReadStream) {
|
|
85
|
+
content.on('error', (err: Error) => {
|
|
86
|
+
request.destroy();
|
|
87
|
+
fail(err);
|
|
88
|
+
});
|
|
89
|
+
request.on('error', () => content.close());
|
|
90
|
+
content.on('open', () => content.pipe(request));
|
|
91
|
+
} else {
|
|
92
|
+
request.end(content);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Sends a GET with only the given headers and resolves with the parsed JSON response. */
|
|
97
|
+
export function getJson<T>(url: URL, headers: http.OutgoingHttpHeaders, timeout: number): Promise<T> {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
send(url, { method: 'GET', headers, timeout }, undefined, jsonResponse<T>(resolve, reject), reject);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Reads a response as JSON. A non-2xx status rejects with the `message` or `error` of a JSON
|
|
105
|
+
* error body when there is one, and with the status otherwise. An HTML page rejects with an
|
|
106
|
+
* Error rather than its markup, since it usually means the URL points at a website, not an API.
|
|
107
|
+
*/
|
|
108
|
+
export function jsonResponse<T>(resolve: (value: T) => void, reject: (reason: any) => void): (res: http.IncomingMessage) => void {
|
|
109
|
+
return response => {
|
|
110
|
+
response.setEncoding('utf-8');
|
|
111
|
+
let json = '';
|
|
112
|
+
// A connection lost after the headers have arrived ends the response without 'end' ever
|
|
113
|
+
// firing, so without this the promise is never settled and the command waits on a body
|
|
114
|
+
// that is not coming. The configured timeout would eventually rescue it, but rejecting
|
|
115
|
+
// here reports what actually happened instead of thirty seconds of silence.
|
|
116
|
+
response.on('error', reject);
|
|
117
|
+
response.on('data', chunk => json += chunk);
|
|
118
|
+
response.on('end', () => {
|
|
119
|
+
if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode > 299)) {
|
|
120
|
+
if (json.trimStart().startsWith('{')) {
|
|
121
|
+
try {
|
|
122
|
+
const parsed = JSON.parse(json) as { message?: string; error?: string };
|
|
123
|
+
const message = parsed.message || parsed.error;
|
|
124
|
+
if (message) {
|
|
125
|
+
// keep the status: the message alone cannot say whether retrying is worth it
|
|
126
|
+
reject(withStatus(new Error(message), response.statusCode));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
// Ignore the error and reject with response status
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
reject(statusError(response));
|
|
134
|
+
} else if (isHtml(response, json)) {
|
|
135
|
+
reject(withStatus(new Error(`The server responded with status ${response.statusCode} and an HTML page instead of JSON.`),
|
|
136
|
+
response.statusCode));
|
|
137
|
+
} else {
|
|
138
|
+
try {
|
|
139
|
+
resolve(JSON.parse(json));
|
|
140
|
+
} catch (err) {
|
|
141
|
+
reject(err);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Node's `timeout` option only raises an event - the request stays open, which is why a server
|
|
150
|
+
* that accepts a connection and then says nothing used to hold a command open indefinitely.
|
|
151
|
+
* Destroying the request with an error routes through the error handling each caller already
|
|
152
|
+
* has, so a stalled request rejects the way any other failure does. With a timeout of zero the
|
|
153
|
+
* event never fires and this does nothing.
|
|
154
|
+
*/
|
|
155
|
+
function failOnTimeout(request: http.ClientRequest, url: URL, timeout: number | undefined, fail: (err: Error) => void): void {
|
|
156
|
+
request.on('timeout', () => {
|
|
157
|
+
// Reported before the request is torn down, rather than by destroying it with the error.
|
|
158
|
+
// Destroying raises errors of its own - ECONNRESET on the response, a premature close
|
|
159
|
+
// from pipeline - and node guarantees no order between those and the request's own. In
|
|
160
|
+
// practice the request's arrives first, so this is belt and braces rather than the thing
|
|
161
|
+
// that stops the wrong error being reported; that is the caller claiming the failure
|
|
162
|
+
// before it does any asynchronous cleanup.
|
|
163
|
+
fail(new Error(`No response from ${redactUrl(url)} for ${timeout} ms.`));
|
|
164
|
+
request.destroy();
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// The body check covers servers that send HTML without a text/html Content-Type.
|
|
169
|
+
function isHtml(response: http.IncomingMessage, body: string): boolean {
|
|
170
|
+
const contentType = response.headers['content-type']?.split(';')[0].trim().toLowerCase();
|
|
171
|
+
return contentType === 'text/html' || /^\s*<(?:!doctype\s+html|html)[\s>]/i.test(body);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function withoutCredentials(headers: http.OutgoingHttpHeaders = {}): http.OutgoingHttpHeaders {
|
|
175
|
+
return Object.fromEntries(Object.entries(headers).filter(([name]) => !CREDENTIAL_HEADERS.test(name)));
|
|
176
|
+
}
|