Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@uppy/companion: bump Node.js version support matrix #5035

Merged
merged 32 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
31aeefe
@uppy/companion: bump Node.js version support matrix
aduh95 Mar 27, 2024
b611a50
Merge branch '4.x' of https://github.com/transloadit/uppy
aduh95 Mar 28, 2024
4178e47
upgrade got to 12
aduh95 Mar 28, 2024
dd6757f
Upgrade to Got 13 and bump various packages
aduh95 Mar 28, 2024
178730b
w
aduh95 Mar 28, 2024
da3b63f
w
aduh95 Mar 28, 2024
97ba076
Merge branch '4.x' into companion-supported-versions
mifi Apr 12, 2024
5820c43
fix form data
mifi Apr 12, 2024
4724571
fix esm import
mifi Apr 13, 2024
7d33b9c
fix test flakiness
mifi Apr 13, 2024
8988847
fix test flakiness
mifi Apr 13, 2024
a6bf417
remove into-stream
mifi Apr 14, 2024
9a66c5f
fix node versions
mifi Apr 14, 2024
dd151bf
Update .github/workflows/companion.yml
mifi Apr 16, 2024
94f6457
patch Nock to workaround bug with Node.js
aduh95 Apr 17, 2024
5d472dd
Merge branch '4.x' of https://github.com/transloadit/uppy
aduh95 Apr 17, 2024
fb656eb
order patches
aduh95 Apr 17, 2024
6bb7125
Revert "fix form data"
aduh95 Apr 17, 2024
5140f07
nits
aduh95 Apr 17, 2024
5b7f3c0
add `Proxy` for got
aduh95 Apr 17, 2024
9b1d202
Update packages/@uppy/companion/src/server/got.js
aduh95 Apr 17, 2024
498a442
Revert "Update packages/@uppy/companion/src/server/got.js"
aduh95 Apr 17, 2024
6e94908
Revert "add `Proxy` for got"
aduh95 Apr 17, 2024
232920f
fix incomplete bodies reported by Nock
aduh95 Apr 18, 2024
bf1754c
remove unrelated changes
aduh95 Apr 18, 2024
afb687f
edit comment
aduh95 Apr 18, 2024
e22e885
avoid storing the full stream in memory
aduh95 Apr 22, 2024
43ba672
Update packages/@uppy/companion/test/__tests__/uploader.js
aduh95 Apr 22, 2024
88d8388
remove patch, try with a HTTP server
aduh95 Apr 22, 2024
773edee
prettier
aduh95 Apr 22, 2024
a45aafa
prettier again
aduh95 Apr 22, 2024
06a4bc8
Update packages/@uppy/companion/test/__tests__/uploader.js
aduh95 Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/companion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [18.x, 20.x, latest]
steps:
- name: Checkout sources
uses: actions/checkout@v3
Expand Down
13 changes: 13 additions & 0 deletions .yarn/patches/nock-npm-13.5.4-2c4f77b249.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/lib/intercepted_request_router.js b/lib/intercepted_request_router.js
index d82c2446b540759cbc54ad7b26222a80109b8ec9..bf24add845d12e436c97b3ea5e2e38f87b77d489 100644
--- a/lib/intercepted_request_router.js
+++ b/lib/intercepted_request_router.js
@@ -68,7 +68,7 @@ class InterceptedRequestRouter {
// For parity with Node, it's important the socket event is emitted before we begin playback.
// This flag is set when playback is triggered if we haven't yet gotten the
// socket event to indicate that playback should start as soon as it comes in.
- this.readyToStartPlaybackOnSocketEvent = false
+ this.readyToStartPlaybackOnSocketEvent = 'UPPY_TEST_DO_NOT_WAIT_FOR_COMPLETE_BODY' in process.env

this.attachToReq()

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,14 @@
"@types/react": "^18",
"@types/webpack-dev-server": "^4",
"@vitest/utils": "patch:@vitest/utils@npm%3A1.2.1#./.yarn/patches/@vitest-utils-npm-1.2.1-3028846845.patch",
"nock": "patch:nock@npm%3A13.5.4#./.yarn/patches/nock-npm-13.5.4-2c4f77b249.patch",
"p-queue": "patch:p-queue@npm%3A7.4.1#./.yarn/patches/p-queue-npm-7.4.1-e0cf0a6f17.patch",
"pre-commit": "patch:pre-commit@npm:1.2.2#.yarn/patches/pre-commit-npm-1.2.2-f30af83877.patch",
"preact": "patch:preact@npm:10.10.0#.yarn/patches/preact-npm-10.10.0-dd04de05e8.patch",
"resize-observer-polyfill": "patch:resize-observer-polyfill@npm%3A1.5.1#./.yarn/patches/resize-observer-polyfill-npm-1.5.1-603120e8a0.patch",
"start-server-and-test": "patch:start-server-and-test@npm:1.14.0#.yarn/patches/start-server-and-test-npm-1.14.0-841aa34fdf.patch",
"stylelint-config-rational-order": "patch:stylelint-config-rational-order@npm%3A0.1.2#./.yarn/patches/stylelint-config-rational-order-npm-0.1.2-d8336e84ed.patch",
"uuid@^8.3.2": "patch:uuid@npm:8.3.2#.yarn/patches/uuid-npm-8.3.2-eca0baba53.patch",
"tus-js-client": "patch:tus-js-client@npm%3A3.1.3#./.yarn/patches/tus-js-client-npm-3.1.3-dc57874d23.patch",
"resize-observer-polyfill": "patch:resize-observer-polyfill@npm%3A1.5.1#./.yarn/patches/resize-observer-polyfill-npm-1.5.1-603120e8a0.patch"
"uuid@^8.3.2": "patch:uuid@npm:8.3.2#.yarn/patches/uuid-npm-8.3.2-eca0baba53.patch"
}
}
23 changes: 10 additions & 13 deletions packages/@uppy/companion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@
"@aws-sdk/lib-storage": "^3.338.0",
"@aws-sdk/s3-presigned-post": "^3.338.0",
"@aws-sdk/s3-request-presigner": "^3.338.0",
"atob": "2.1.2",
"body-parser": "1.20.0",
"body-parser": "1.20.2",
"chalk": "4.1.2",
"common-tags": "1.8.2",
"connect-redis": "7.1.0",
"connect-redis": "7.1.1",
"content-disposition": "^0.5.4",
"cookie-parser": "1.4.6",
"cors": "^2.8.5",
Expand All @@ -48,26 +47,25 @@
"express-prom-bundle": "6.5.0",
"express-request-id": "1.4.1",
"express-session": "1.17.3",
"form-data": "^3.0.0",
"got": "11",
"grant": "5.4.21",
"got": "^13.0.0",
"grant": "5.4.22",
"helmet": "^4.6.0",
"ipaddr.js": "^2.0.1",
"jsonwebtoken": "9.0.0",
"jsonwebtoken": "9.0.2",
"lodash": "^4.17.21",
"mime-types": "2.1.35",
"moment": "^2.29.2",
"moment-timezone": "^0.5.31",
"morgan": "1.10.0",
"ms": "2.1.3",
"node-schedule": "2.1.0",
"node-schedule": "2.1.1",
"prom-client": "14.0.1",
"redis": "4.2.0",
"redis": "4.6.13",
"serialize-error": "^2.1.0",
"serialize-javascript": "^6.0.0",
"tus-js-client": "^3.1.3",
"validator": "^13.0.0",
"ws": "8.8.1"
"ws": "8.16.0"
},
"devDependencies": {
"@types/compression": "1.7.0",
Expand All @@ -84,7 +82,6 @@
"@types/request": "2.48.8",
"@types/webpack": "^5.28.0",
"@types/ws": "8.5.3",
"into-stream": "^6.0.0",
"jest": "^29.0.0",
"nock": "^13.1.3",
"supertest": "6.2.4",
Expand All @@ -109,10 +106,10 @@
"deploy": "kubectl apply -f infra/kube/companion-kube.yml",
"prepublishOnly": "yarn run build",
"start": "node ./lib/standalone/start-server.js",
"test": "jest"
"test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand"
},
"engines": {
"node": "^14.19.0 || ^16.15.0 || >=18.0.0"
"node": "^18.20.0 || ^20.10.0 || >=22.0.0"
},
"installConfig": {
"hoistingLimits": "workspaces"
Expand Down
20 changes: 10 additions & 10 deletions packages/@uppy/companion/src/server/Uploader.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// eslint-disable-next-line max-classes-per-file
const { blob } = require('node:stream/consumers');
const tus = require('tus-js-client')
const { randomUUID } = require('node:crypto')
const validator = require('validator')
const got = require('got').default
const { pipeline: pipelineCb } = require('node:stream')
const { join } = require('node:path')
const fs = require('node:fs')
const { promisify } = require('node:util')
const FormData = require('form-data')
const throttle = require('lodash/throttle')

const { Upload } = require('@aws-sdk/lib-storage')

const { rfc2047EncodeMetadata, getBucket } = require('./helpers/utils')

const got = require('./got')

// TODO move to `require('streams/promises').pipeline` when dropping support for Node.js 14.x.
const pipeline = promisify(pipelineCb)

Expand Down Expand Up @@ -613,16 +614,15 @@ class Uploader {
}

if (this.options.useFormData) {
// todo refactor once upgraded to got 12
const formData = new FormData()

Object.entries(this.options.metadata).forEach(([key, value]) => formData.append(key, value))

formData.append(this.options.fieldname, stream, {
filename: this.uploadFileName,
contentType: this.options.metadata.type,
knownLength: this.size,
})
formData.append(
this.options.fieldname,
// @ts-expect-error Node.js Blob is actually spec compliant
await blob(stream),
this.uploadFileName)

reqOptions.body = formData
} else {
Expand All @@ -632,7 +632,7 @@ class Uploader {

try {
const httpMethod = (this.options.httpMethod || '').toUpperCase() === 'PUT' ? 'put' : 'post'
const runRequest = got[httpMethod]
const runRequest = (await got)[httpMethod]

const response = await runRequest(url, reqOptions)

Expand Down Expand Up @@ -662,7 +662,7 @@ class Uploader {
extraData: getRespObj(err.response),
})
}
throw new Error('Unknown multipart upload error')
throw new Error('Unknown multipart upload error', {cause: err})
}
}

Expand Down
1 change: 0 additions & 1 deletion packages/@uppy/companion/src/server/controllers/connect.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const atob = require('atob')
const oAuthState = require('../helpers/oauth-state')

const queryString = (params, prefix = '?') => {
Expand Down
2 changes: 1 addition & 1 deletion packages/@uppy/companion/src/server/controllers/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const downloadURL = async (url, blockLocalIPs, traceId) => {
// TODO in next major, rename all blockLocalIPs to allowLocalUrls and invert the bool, to make it consistent
// see discussion https://github.com/transloadit/uppy/pull/4554/files#r1268677162
try {
const protectedGot = getProtectedGot({ blockLocalIPs })
const protectedGot = await getProtectedGot({ blockLocalIPs })
const stream = protectedGot.stream.get(url, { responseType: 'json' })
await prepareStream(stream)
return stream
Expand Down
4 changes: 4 additions & 0 deletions packages/@uppy/companion/src/server/got.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line import/no-unresolved
const gotPromise = import('got')

module.exports = gotPromise.then((got) => got.default)
1 change: 0 additions & 1 deletion packages/@uppy/companion/src/server/helpers/oauth-state.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const crypto = require('node:crypto')
const atob = require('atob')
const { encrypt, decrypt } = require('./utils')

module.exports.encodeState = (state, secret) => {
Expand Down
9 changes: 5 additions & 4 deletions packages/@uppy/companion/src/server/helpers/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ const http = require('node:http')
const https = require('node:https')
const dns = require('node:dns')
const ipaddr = require('ipaddr.js')
const got = require('got').default
const path = require('node:path')
const contentDisposition = require('content-disposition')
const validator = require('validator')

const got = require('../got')

const FORBIDDEN_IP_ADDRESS = 'Forbidden IP address'

// Example scary IPs that should return false (ipv6-to-ipv4 mapped):
Expand Down Expand Up @@ -84,15 +85,15 @@ const getProtectedHttpAgent = ({ protocol, blockLocalIPs }) => {

module.exports.getProtectedHttpAgent = getProtectedHttpAgent

function getProtectedGot ({ blockLocalIPs }) {
async function getProtectedGot ({ blockLocalIPs }) {
const HttpAgent = getProtectedHttpAgent({ protocol: 'http', blockLocalIPs })
const HttpsAgent = getProtectedHttpAgent({ protocol: 'https', blockLocalIPs })
const httpAgent = new HttpAgent()
const httpsAgent = new HttpsAgent()


// @ts-ignore
return got.extend({ agent: { http: httpAgent, https: httpsAgent } })
return (await got).extend({ agent: { http: httpAgent, https: httpsAgent } })
}

module.exports.getProtectedGot = getProtectedGot
Expand All @@ -106,7 +107,7 @@ module.exports.getProtectedGot = getProtectedGot
*/
exports.getURLMeta = async (url, blockLocalIPs = false) => {
async function requestWithMethod (method) {
const protectedGot = getProtectedGot({ blockLocalIPs })
const protectedGot = await getProtectedGot({ blockLocalIPs })
const stream = protectedGot.stream(url, { method, throwHttpErrors: false })

return new Promise((resolve, reject) => (
Expand Down
5 changes: 3 additions & 2 deletions packages/@uppy/companion/src/server/jobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ const schedule = require('node-schedule')
const fs = require('node:fs')
const path = require('node:path')
const { promisify } = require('node:util')
const got = require('got').default

const got = require('./got')

const { FILE_NAME_PREFIX } = require('./Uploader')
const logger = require('./logger')
Expand Down Expand Up @@ -65,7 +66,7 @@ async function runPeriodicPing ({ urls, payload, requestTimeout }) {
// Run requests in parallel
await Promise.all(urls.map(async (url) => {
try {
await got.post(url, { json: payload, timeout: { request: requestTimeout } })
await (await got).post(url, { json: payload, timeout: { request: requestTimeout } })
} catch (err) {
logger.warn(err, 'jobs.periodic.ping')
}
Expand Down
19 changes: 9 additions & 10 deletions packages/@uppy/companion/src/server/provider/box/index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
const got = require('got').default

const Provider = require('../Provider')
const adaptData = require('./adapter')
const { withProviderErrorHandling } = require('../providerErrors')
const { prepareStream } = require('../../helpers/utils')

const got = require('../../got')

const BOX_FILES_FIELDS = 'id,modified_at,name,permissions,size,type'
const BOX_THUMBNAIL_SIZE = 256

const getClient = ({ token }) => got.extend({
const getClient = async ({ token }) => (await got).extend({
prefixUrl: 'https://api.box.com/2.0',
headers: {
authorization: `Bearer ${token}`,
},
})

async function getUserInfo ({ token }) {
return getClient({ token }).get('users/me', { responseType: 'json' }).json()
return (await getClient({ token })).get('users/me', { responseType: 'json' }).json()
}

async function list ({ directory, query, token }) {
const rootFolderID = '0'
// https://developer.box.com/reference/resources/items/
return getClient({ token }).get(`folders/${directory || rootFolderID}/items`, { searchParams: { fields: BOX_FILES_FIELDS, offset: query.cursor, limit: 1000 }, responseType: 'json' }).json()
return (await getClient({ token })).get(`folders/${directory || rootFolderID}/items`, { searchParams: { fields: BOX_FILES_FIELDS, offset: query.cursor, limit: 1000 }, responseType: 'json' }).json()
}

/**
Expand Down Expand Up @@ -61,7 +60,7 @@ class Box extends Provider {

async download ({ id, token }) {
return this.#withErrorHandling('provider.box.download.error', async () => {
const stream = getClient({ token }).stream.get(`files/${id}/content`, { responseType: 'json' })
const stream = (await getClient({ token })).stream.get(`files/${id}/content`, { responseType: 'json' })

await prepareStream(stream)
return { stream }
Expand All @@ -81,7 +80,7 @@ class Box extends Provider {
// At that time, retry this endpoint to retrieve the thumbnail.
//
// This can be reproduced more easily by changing extension to png and trying on a newly uploaded image
const stream = getClient({ token }).stream.get(`files/${id}/thumbnail.${extension}`, {
const stream = (await getClient({ token })).stream.get(`files/${id}/thumbnail.${extension}`, {
searchParams: { max_height: BOX_THUMBNAIL_SIZE, max_width: BOX_THUMBNAIL_SIZE },
responseType: 'json',
})
Expand All @@ -93,15 +92,15 @@ class Box extends Provider {

async size ({ id, token }) {
return this.#withErrorHandling('provider.box.size.error', async () => {
const { size } = await getClient({ token }).get(`files/${id}`, { responseType: 'json' }).json()
const { size } = await (await getClient({ token })).get(`files/${id}`, { responseType: 'json' }).json()
return parseInt(size, 10)
aduh95 marked this conversation as resolved.
Show resolved Hide resolved
})
}

logout ({ companion, token }) {
return this.#withErrorHandling('provider.box.logout.error', async () => {
const { key, secret } = companion.options.providerOptions.box
await getClient({ token }).post('oauth2/revoke', {
await (await getClient({ token })).post('oauth2/revoke', {
prefixUrl: 'https://api.box.com',
form: {
client_id: key,
Expand Down
6 changes: 3 additions & 3 deletions packages/@uppy/companion/src/server/provider/credentials.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
const got = require('got').default
const atob = require('atob')
const { htmlEscape } = require('escape-goat')
const logger = require('../logger')
const oAuthState = require('../helpers/oauth-state')
const tokenService = require('../helpers/jwt')
// eslint-disable-next-line
const Provider = require('./Provider')

const got = require('../got')

/**
* @param {string} url
* @param {string} providerName
* @param {object|null} credentialRequestParams - null asks for default credentials.
*/
async function fetchKeys (url, providerName, credentialRequestParams) {
try {
const { credentials } = await got.post(url, {
const { credentials } = await (await got).post(url, {
json: { provider: providerName, parameters: credentialRequestParams },
}).json()

Expand Down
Loading
Loading