@depup/serverless 4.41.0-depup.0 → 4.42.0-depup.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 CHANGED
@@ -13,8 +13,8 @@ npm install @depup/serverless
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [serverless](https://www.npmjs.com/package/serverless) @ 4.41.0 |
17
- | Processed | 2026-08-16 |
16
+ | Original | [serverless](https://www.npmjs.com/package/serverless) @ 4.42.0 |
17
+ | Processed | 2026-09-13 |
18
18
  | Smoke test | failed |
19
19
  | Deps updated | 1 |
20
20
 
@@ -22,7 +22,7 @@ npm install @depup/serverless
22
22
 
23
23
  | Dependency | From | To |
24
24
  |------------|------|-----|
25
- | undici | 6.28.0 | ^8.10.0 |
25
+ | undici | 6.28.1 | ^8.10.2 |
26
26
 
27
27
  ---
28
28
 
package/binary.js CHANGED
@@ -10,6 +10,44 @@ const error = (msg) => {
10
10
  process.exit(1)
11
11
  }
12
12
 
13
+ // fetch() reports every network-level failure as a bare "fetch failed" and
14
+ // hides the actual reason (DNS, TLS, connection refused) in the `cause`
15
+ // chain, so the chain has to be included for failures to be diagnosable
16
+ // from install logs.
17
+ const describeNode = (e) => {
18
+ if (!(e instanceof Error)) return String(e)
19
+ const message = e.message || e.name
20
+ return e.code ? `${message} (${e.code})` : message
21
+ }
22
+
23
+ const describeError = (err) => {
24
+ if (!(err instanceof Error)) return String(err)
25
+ const parts = []
26
+ // A cyclic cause chain would otherwise hang the process — worse than exiting
27
+ const seen = new Set()
28
+ let node = err
29
+ while (node !== undefined && node !== null && !seen.has(node)) {
30
+ seen.add(node)
31
+ parts.push(describeNode(node))
32
+ if (Array.isArray(node.errors) && node.errors.length > 0) {
33
+ parts.push(node.errors.map(describeNode).join(', '))
34
+ }
35
+ node = node instanceof Error ? node.cause : undefined
36
+ }
37
+ return parts.join(': ')
38
+ }
39
+
40
+ // Shell convention for a process ended by a signal: 128 + signal number
41
+ const signalExitCode = (signal) => {
42
+ const signalNumber = os.constants.signals[signal]
43
+ return signalNumber ? 128 + signalNumber : 1
44
+ }
45
+
46
+ // spawnSync reports a signal-terminated child as `status: null`; passing
47
+ // that to process.exit() would report success.
48
+ const childExitCode = ({ status, signal }) =>
49
+ status !== null ? status : signalExitCode(signal)
50
+
13
51
  const formatHostName = (hostname) => hostname.replace(/^\.*/, '.').toLowerCase()
14
52
 
15
53
  const parseNoProxyZone = (zone) => {
@@ -22,7 +60,11 @@ const parseNoProxyZone = (zone) => {
22
60
  }
23
61
 
24
62
  const shouldBypassProxy = (requestURL) => {
25
- const noProxy = process.env.NO_PROXY || process.env.no_proxy || ''
63
+ const noProxy =
64
+ process.env.NO_PROXY ||
65
+ process.env.no_proxy ||
66
+ process.env.npm_config_noproxy ||
67
+ ''
26
68
  if (noProxy === '*') return true
27
69
  if (noProxy === '') return false
28
70
 
@@ -30,8 +72,10 @@ const shouldBypassProxy = (requestURL) => {
30
72
  requestURL.port || (requestURL.protocol === 'https:' ? '443' : '80')
31
73
  const hostname = formatHostName(requestURL.hostname)
32
74
 
75
+ // npm exports array-form `noproxy[]=` entries newline-joined
33
76
  return noProxy
34
- .split(',')
77
+ .split(/[,\n]/)
78
+ .filter((zone) => zone.trim() !== '')
35
79
  .map(parseNoProxyZone)
36
80
  .some((noProxyZone) => {
37
81
  const isMatchedAt = hostname.indexOf(noProxyZone.hostname)
@@ -45,16 +89,33 @@ const shouldBypassProxy = (requestURL) => {
45
89
  })
46
90
  }
47
91
 
92
+ // npm applies the proxy settings from .npmrc to its own downloads but does
93
+ // not translate them into HTTP(S)_PROXY for lifecycle scripts — they reach
94
+ // this script only as npm_config_* variables, so those serve as fallbacks
95
+ // when no proxy environment variables are set. Scheme mapping mirrors npm's
96
+ // own (npm-registry-fetch: `httpsProxy || proxy`): `https-proxy` is preferred
97
+ // for https requests and `proxy` is the fallback for both schemes.
48
98
  const getProxyUrl = (url) => {
49
99
  const requestURL = new URL(url)
50
100
 
51
101
  if (shouldBypassProxy(requestURL)) return null
52
102
 
53
103
  if (requestURL.protocol === 'http:') {
54
- return process.env.HTTP_PROXY || process.env.http_proxy || null
104
+ return (
105
+ process.env.HTTP_PROXY ||
106
+ process.env.http_proxy ||
107
+ process.env.npm_config_proxy ||
108
+ null
109
+ )
55
110
  }
56
111
  if (requestURL.protocol === 'https:') {
57
- return process.env.HTTPS_PROXY || process.env.https_proxy || null
112
+ return (
113
+ process.env.HTTPS_PROXY ||
114
+ process.env.https_proxy ||
115
+ process.env.npm_config_https_proxy ||
116
+ process.env.npm_config_proxy ||
117
+ null
118
+ )
58
119
  }
59
120
  return null
60
121
  }
@@ -103,7 +164,7 @@ class Binary {
103
164
  })
104
165
  errorMsg +=
105
166
  '\n\nCorrect usage: new Binary("my-binary", "https://example.com/binary/download.tar.gz", "v1.0.0")'
106
- error(errorMsg)
167
+ throw new Error(errorMsg)
107
168
  }
108
169
  this.url = url
109
170
  this.name = name
@@ -133,14 +194,17 @@ class Binary {
133
194
  }
134
195
  }
135
196
 
136
- install(suppressLogs = false) {
197
+ // Downloads the binary. Rejects on any failure — how a failure is handled
198
+ // (warn vs abort) is decided by the entrypoints (postInstall.js, run.js),
199
+ // never here.
200
+ async install(suppressLogs = false) {
137
201
  if (this.exists()) {
138
202
  if (!suppressLogs) {
139
203
  console.error(
140
204
  `${this.name} is already installed, skipping installation.`,
141
205
  )
142
206
  }
143
- return Promise.resolve()
207
+ return
144
208
  }
145
209
 
146
210
  // maxRetries/retryDelay cover transient EBUSY/EPERM on Windows, where
@@ -158,40 +222,35 @@ class Binary {
158
222
  console.error(`Downloading release from ${this.url}`)
159
223
  }
160
224
 
161
- process.on('SIGINT', () => {
162
- error('Could not download Serverless')
225
+ const abort = (signal) => {
163
226
  this.removeBinary()
164
- })
227
+ console.error('Serverless Framework binary download was interrupted')
228
+ process.exit(signalExitCode(signal))
229
+ }
230
+ process.on('SIGINT', abort)
231
+ process.on('SIGTERM', abort)
165
232
 
166
- process.on('SIGTERM', () => {
167
- error('Could not download Serverless')
233
+ try {
234
+ const proxyUrl = getProxyUrl(this.url)
235
+ const fetchOptions = proxyUrl
236
+ ? { dispatcher: new ProxyAgent(proxyUrl) }
237
+ : {}
238
+ const res = await fetch(this.url, fetchOptions)
239
+ if (!res.ok) {
240
+ throw new Error(`HTTP ${res.status}: ${res.statusText}`)
241
+ }
242
+ const buffer = await res.arrayBuffer()
243
+ writeFileSync(this.binaryPath, Buffer.from(buffer), { mode: 0o755 })
244
+ if (!suppressLogs) {
245
+ console.error(`${this.name} has been installed!`)
246
+ }
247
+ } catch (e) {
168
248
  this.removeBinary()
169
- })
170
-
171
- const proxyUrl = getProxyUrl(this.url)
172
- const fetchOptions = proxyUrl
173
- ? { dispatcher: new ProxyAgent(proxyUrl) }
174
- : {}
175
-
176
- return fetch(this.url, fetchOptions)
177
- .then((res) => {
178
- if (!res.ok) {
179
- throw new Error(`HTTP ${res.status}: ${res.statusText}`)
180
- }
181
- return res.arrayBuffer()
182
- })
183
- .then((buffer) => {
184
- writeFileSync(this.binaryPath, Buffer.from(buffer), { mode: 0o755 })
185
- })
186
- .then(() => {
187
- if (!suppressLogs) {
188
- console.error(`${this.name} has been installed!`)
189
- }
190
- })
191
- .catch((e) => {
192
- error(`Error fetching release: ${e.message}`)
193
- this.removeBinary()
194
- })
249
+ throw e
250
+ } finally {
251
+ process.removeListener('SIGINT', abort)
252
+ process.removeListener('SIGTERM', abort)
253
+ }
195
254
  }
196
255
 
197
256
  run() {
@@ -214,11 +273,12 @@ class Binary {
214
273
  error(result.error)
215
274
  }
216
275
 
217
- process.exit(result.status)
276
+ process.exit(childExitCode(result))
218
277
  })
219
278
  .catch((e) => {
220
- error(e.message)
221
- process.exit(1)
279
+ error(
280
+ `Could not download the Serverless Framework binary: ${describeError(e)}`,
281
+ )
222
282
  })
223
283
  }
224
284
  }
@@ -240,11 +300,10 @@ const getBinaryName = () => {
240
300
  let architecture = os.arch()
241
301
 
242
302
  if (architecture !== 'arm64' && architecture !== 'x64') {
243
- console.error(`Architecture ${architecture} is not supported.`)
244
- process.exit(1)
245
- } else if (architecture === 'arm64' && osType === 'windows') {
246
- console.error(`Platform ${osType} - ${architecture} is not supported.`)
247
- process.exit(1)
303
+ throw new Error(`Architecture ${architecture} is not supported.`)
304
+ }
305
+ if (architecture === 'arm64' && osType === 'windows') {
306
+ throw new Error(`Platform ${osType} - ${architecture} is not supported.`)
248
307
  }
249
308
 
250
309
  if (architecture === 'x64') {
@@ -275,4 +334,8 @@ module.exports = {
275
334
  install,
276
335
  run,
277
336
  getBinary,
337
+ Binary,
338
+ childExitCode,
339
+ describeError,
340
+ getProxyUrl,
278
341
  }
package/changes.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "bumped": {
3
3
  "undici": {
4
- "from": "6.28.0",
5
- "to": "^8.10.0"
4
+ "from": "6.28.1",
5
+ "to": "^8.10.2"
6
6
  }
7
7
  },
8
- "timestamp": "2026-08-16T00:28:10.289Z",
8
+ "timestamp": "2026-09-13T00:59:47.973Z",
9
9
  "totalUpdated": 1
10
10
  }
package/package.json CHANGED
@@ -1,13 +1,21 @@
1
1
  {
2
2
  "name": "@depup/serverless",
3
- "version": "4.41.0-depup.0",
3
+ "version": "4.42.0-depup.0",
4
4
  "description": "serverless with all dependencies updated to latest",
5
5
  "main": "index.js",
6
+ "files": [
7
+ "binary.js",
8
+ "postInstall.js",
9
+ "run.js",
10
+ "changes.json",
11
+ "README.md"
12
+ ],
6
13
  "scripts": {
7
14
  "lint": "eslint",
8
15
  "lint:fix": "eslint --fix",
9
16
  "prettier": "prettier -c . --ignore-path ../../.prettierignore",
10
- "prettier:fix": "prettier -w . --ignore-path ../../.prettierignore"
17
+ "prettier:fix": "prettier -w . --ignore-path ../../.prettierignore",
18
+ "test": "node --test \"tests/*.test.js\""
11
19
  },
12
20
  "keywords": [
13
21
  "serverless",
@@ -27,7 +35,7 @@
27
35
  "sls": "run.js"
28
36
  },
29
37
  "dependencies": {
30
- "undici": "^8.10.0"
38
+ "undici": "^8.10.2"
31
39
  },
32
40
  "devDependencies": {},
33
41
  "engines": {
@@ -36,14 +44,14 @@
36
44
  "depup": {
37
45
  "changes": {
38
46
  "undici": {
39
- "from": "6.28.0",
40
- "to": "^8.10.0"
47
+ "from": "6.28.1",
48
+ "to": "^8.10.2"
41
49
  }
42
50
  },
43
51
  "depsUpdated": 1,
44
52
  "originalPackage": "serverless",
45
- "originalVersion": "4.41.0",
46
- "processedAt": "2026-08-16T00:28:11.206Z",
53
+ "originalVersion": "4.42.0",
54
+ "processedAt": "2026-09-13T00:59:48.872Z",
47
55
  "smokeTest": "failed"
48
56
  }
49
57
  }
package/postInstall.js CHANGED
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { install: maybeInstall } = require('./binary')
4
- maybeInstall().then(() => {})
3
+ const { install, describeError } = require('./binary')
4
+
5
+ // npm aborts the entire `npm install` when this script exits non-zero. A
6
+ // binary that could not be pre-downloaded here is always recoverable — run.js
7
+ // downloads it on first invocation — so no failure in this script justifies
8
+ // failing the install.
9
+ install().catch((e) => {
10
+ console.error(
11
+ `Could not pre-download the Serverless Framework binary: ${describeError(e)}\n` +
12
+ 'The download will be retried the first time "serverless" runs. If your ' +
13
+ 'network requires a proxy, set the HTTPS_PROXY environment variable (or ' +
14
+ "npm's https-proxy setting) and allow access to install.serverless.com. " +
15
+ 'See https://www.serverless.com/framework/docs/getting-started',
16
+ )
17
+ })
package/run.js CHANGED
@@ -1,4 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { run, install: maybeInstall } = require('./binary')
4
- maybeInstall().then(run)
3
+ const { run, install: maybeInstall, describeError } = require('./binary')
4
+
5
+ // Unlike postInstall.js, a missing binary is fatal here: without it there is
6
+ // nothing to run.
7
+ maybeInstall()
8
+ .then(run)
9
+ .catch((e) => {
10
+ console.error(
11
+ `Could not download the Serverless Framework binary: ${describeError(e)}`,
12
+ )
13
+ process.exit(1)
14
+ })