chore(deps): drop `node-fetch` dependency (#3217)

Co-authored-by: Luca Greco <11484+rpl@users.noreply.github.com>
This commit is contained in:
Federico Brigante 2024-08-24 01:29:12 +07:00 коммит произвёл GitHub
Родитель 19694d20a9
Коммит b438d60c7e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 66 добавлений и 135 удалений

127
package-lock.json сгенерированный
Просмотреть файл

@ -23,7 +23,6 @@
"jose": "5.6.3",
"jszip": "3.10.1",
"multimatch": "6.0.0",
"node-fetch": "3.3.2",
"node-notifier": "10.0.1",
"open": "9.1.0",
"parse-json": "7.1.1",
@ -5025,14 +5024,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
"engines": {
"node": ">= 12"
}
},
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@ -6155,28 +6146,6 @@
"pend": "~1.2.0"
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -6330,17 +6299,6 @@
"node": ">= 14.17"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/fromentries": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
@ -8603,41 +8561,6 @@
"type-detect": "4.0.8"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
@ -11321,14 +11244,6 @@
"defaults": "^1.0.3"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"engines": {
"node": ">= 8"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@ -15276,11 +15191,6 @@
"integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
"dev": true
},
"data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@ -16094,15 +16004,6 @@
"pend": "~1.2.0"
}
},
"fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
},
"file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -16219,14 +16120,6 @@
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
"integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw=="
},
"formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"requires": {
"fetch-blob": "^3.1.2"
}
},
"fromentries": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
@ -17853,21 +17746,6 @@
}
}
},
"node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
},
"node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"requires": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
}
},
"node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
@ -19814,11 +19692,6 @@
"defaults": "^1.0.3"
}
},
"web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",

Просмотреть файл

@ -72,7 +72,6 @@
"jose": "5.6.3",
"jszip": "3.10.1",
"multimatch": "6.0.0",
"node-fetch": "3.3.2",
"node-notifier": "10.0.1",
"open": "9.1.0",
"parse-json": "7.1.1",

Просмотреть файл

@ -1,9 +1,8 @@
import { basename } from 'path';
import { createHash } from 'crypto';
import { createWriteStream, promises as fsPromises } from 'fs';
import { createWriteStream, promises as fsPromises, readFileSync } from 'fs';
import { promises as streamPromises } from 'stream';
// eslint-disable-next-line no-shadow
import fetch, { FormData, fileFromSync } from 'node-fetch';
import { SignJWT } from 'jose';
import JSZip from 'jszip';
import { HttpsProxyAgent } from 'https-proxy-agent';
@ -15,6 +14,29 @@ const log = createLogger(import.meta.url);
export const defaultAsyncFsReadFile = fsPromises.readFile;
// Used by fileFromSync method to make sure the form-data entry will
// include a filename derived from the file path.
//
// TODO: Get rid of this hack when we will bump the web-ext nodejs
// version required to nodejs v20 (where the native File constructor
// exists).
export class FileBlob extends Blob {
#name = '';
constructor(fileBits, fileName, options) {
super(fileBits, options);
this.#name = String(fileName);
}
get name() {
return this.#name;
}
get [Symbol.toStringTag]() {
return 'File';
}
}
export class JwtApiAuth {
#apiKey;
#apiSecret;
@ -88,8 +110,13 @@ export default class Client {
this.userAgentString = userAgentString;
}
fileFromSync(path) {
return fileFromSync(path);
fileFromSync(filePath) {
// create a File blob from a file path, and ensure it to have the file path basename
// as the associated filename, the AMO server API will be checking it on the form-data
// submitted and fail with the error message:
// "Unsupported file type, please upload a supported file (.crx, .xpi, .zip)."
const fileData = readFileSync(filePath);
return new FileBlob([fileData], basename(filePath));
}
nodeFetch(url, { method, headers, body, agent }) {

Просмотреть файл

@ -8,8 +8,6 @@ import { assert, expect } from 'chai';
import JSZip from 'jszip';
import { afterEach, before, beforeEach, describe, it } from 'mocha';
import * as sinon from 'sinon';
// eslint-disable-next-line no-shadow
import { File, FormData, Response } from 'node-fetch';
import { AMO_BASE_URL } from '../../../src/program.js';
import Client, {
@ -18,6 +16,9 @@ import Client, {
saveIdToFile,
saveUploadUuidToFile,
signAddon,
// eslint-disable-next-line no-shadow -- Not actually available under Node 20. Use global once possible.
FileBlob as File,
} from '../../../src/util/submit-addon.js';
import { withTempDir } from '../../../src/util/temp-dir.js';
@ -27,6 +28,19 @@ class JSONResponse extends Response {
}
}
// Used to test responses with status < 100 (nodejs native constructor
// enforces status to be in the 200-599 range and throws if it is not).
class BadResponse extends Response {
constructor(data, fakeStatus) {
super(data);
this.fakeStatus = fakeStatus;
}
get status() {
return this.fakeStatus;
}
}
const mockNodeFetch = (nodeFetchStub, url, method, responses) => {
// Trust us... You don't want to know why... but if you really do like nightmares
// take a look to the details and links kindly provided in this comment
@ -42,6 +56,9 @@ const mockNodeFetch = (nodeFetchStub, url, method, responses) => {
for (let i = 0; i < responses.length; i++) {
const { body, status } = responses[i];
stubMatcher.onCall(i).callsFake(async () => {
if (status < 200) {
return new BadResponse(body, status);
}
if (typeof body === 'string') {
return new Response(body, { status });
}
@ -342,6 +359,21 @@ describe('util.submit-addon', () => {
assert.equal(client.apiUrl.href, new URL(`${cleanUrl}/addons/`).href);
});
describe('fileFromSync', () => {
it('should return a File with name set to the file path basename', () =>
withTempDir(async (tmpDir) => {
const client = new Client(clientDefaults);
const FILE_BASENAME = 'testfile.txt';
const FILE_CONTENT = 'somecontent';
const filePath = path.join(tmpDir.path(), FILE_BASENAME);
await fsPromises.writeFile(filePath, FILE_CONTENT);
const fileRes = client.fileFromSync(filePath);
assert.equal(fileRes.name, FILE_BASENAME);
assert.equal(await fileRes.text(), FILE_CONTENT);
assert.equal(String(fileRes), '[object File]');
}));
});
describe('getPreviousUuidOrUploadXpi', () => {
it('calls doUploadSubmit if previous hash is different to current', async () => {
const oldHash = 'some-hash';