@jonathanleelx/meddle 0.4.0-beta.1 → 0.4.0-beta.10

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.
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Usage:
5
5
  * meddle update check and upgrade to the latest version
6
+ * meddle update --beta check and upgrade to the latest beta version
6
7
  * meddle update --check only check, print the available version
7
8
  * meddle update --version <x.y.z> install a specific version
8
9
  * meddle update --auto on|off enable/disable auto-update (default off)
@@ -23,6 +24,7 @@ const {
23
24
  downloadBinaryAsset,
24
25
  getAutoUpdate,
25
26
  setAutoUpdate,
27
+ inferChannel,
26
28
  } = require('../lib/update-check')
27
29
 
28
30
  const PACKAGE_NAME = '@jonathanleelx/meddle'
@@ -39,13 +41,37 @@ function isNpmInstall() {
39
41
  return installMethod === 'npm'
40
42
  }
41
43
 
44
+ function formatBytes(bytes) {
45
+ if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
46
+ if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`
47
+ return `${bytes} B`
48
+ }
49
+
50
+ const PROGRESS_WIDTH = 40
51
+
52
+ function drawProgressBar({ received, total, attempt, maxAttempts }) {
53
+ const label = attempt > 1 ? ` (第 ${attempt}/${maxAttempts} 次尝试)` : ''
54
+ if (total > 0) {
55
+ const ratio = Math.min(1, received / total)
56
+ const filled = Math.round(PROGRESS_WIDTH * ratio)
57
+ const bar = '#'.repeat(filled) + '-'.repeat(PROGRESS_WIDTH - filled)
58
+ const line = ` [${bar}] ${(ratio * 100).toFixed(1)}% ${formatBytes(received)}/${formatBytes(total)}${label}`
59
+ process.stdout.write(`\r${line}`)
60
+ } else {
61
+ process.stdout.write(`\r 下载中 ${formatBytes(received)}${label}...`)
62
+ }
63
+ }
64
+
42
65
  function showHelp() {
43
66
  output.plain(`
44
67
  meddle update - 检查并升级 meddle
45
68
 
46
69
  用法:
47
- meddle update 检查并升级到最新版本
70
+ meddle update 检查并升级(beta 版本默认走 beta 频道)
71
+ meddle update --beta 切换到 beta 频道并升级到最新 beta 版本
72
+ meddle update --stable 切换到稳定频道并升级到最新稳定版本(可降级)
48
73
  meddle update --check 仅检查,提示可用版本 (有新版本时退出码为 2)
74
+ meddle update --check --beta 仅检查 beta 版本
49
75
  meddle update --version <x.y.z> 安装指定版本
50
76
  meddle update --auto on|off 启用/禁用自动更新 (默认关闭)
51
77
  meddle update status 查看安装方式、当前版本和自动更新开关
@@ -53,18 +79,23 @@ meddle update - 检查并升级 meddle
53
79
  `)
54
80
  }
55
81
 
56
- async function resolveLatest({ force = false, notify = true } = {}) {
82
+ async function resolveLatest({ force = false, notify = true, channel = 'stable', explicitChannel = false } = {}) {
57
83
  const info = await checkForUpdate({
58
84
  home,
59
85
  installMethod,
60
86
  current,
61
87
  force,
88
+ channel,
89
+ explicitChannel,
62
90
  })
63
91
  if (notify) {
64
92
  if (info.outdated) {
65
93
  output.info(`发现新版本 ${info.latest} (当前 ${info.current})`)
66
- } else {
94
+ } else if (info.latest === info.current) {
67
95
  output.success(`已是最新版本 (${info.current})`)
96
+ } else {
97
+ const channelLabel = info.channel === 'beta' ? 'beta' : '稳定'
98
+ output.info(`当前 ${info.current} 已超过${channelLabel}频道最新版本 ${info.latest}`)
68
99
  }
69
100
  }
70
101
  return info
@@ -75,17 +106,32 @@ async function installVersion(version) {
75
106
  const binDir = process.env.MEDDLE_BIN_DIR || path.join(home, 'bin')
76
107
  const destFile = path.join(binDir, os.platform() === 'win32' ? 'meddle.exe' : 'meddle')
77
108
  output.info(`下载 meddle ${version} (${os.platform()}/${os.arch()})...`)
109
+ let progressShown = false
110
+ const showProgress = output.isJsonMode() ? () => {} : drawProgressBar
78
111
  try {
79
112
  const result = await downloadBinaryAsset({
80
113
  version,
81
114
  destFile,
82
115
  platform: os.platform(),
83
116
  arch: os.arch(),
117
+ onAttempt: (attempt, maxAttempts) => {
118
+ if (attempt > 1) {
119
+ process.stdout.write('\n')
120
+ progressShown = false
121
+ output.info(`连接中断,正在重试 (${attempt}/${maxAttempts})...`)
122
+ }
123
+ },
124
+ onProgress: (p) => {
125
+ showProgress(p)
126
+ progressShown = true
127
+ },
84
128
  })
129
+ if (progressShown) process.stdout.write('\n')
85
130
  output.success(`已安装 meddle ${version} 到 ${result.installed}`)
86
131
  if (result.backup) output.info(`旧版本已备份到 ${result.backup}`)
87
132
  output.info('重启 meddle 后新版本生效')
88
133
  } catch (err) {
134
+ if (progressShown) process.stdout.write('\n')
89
135
  output.error(`升级失败: ${err && err.message ? err.message : err}`)
90
136
  process.exit(1)
91
137
  }
@@ -114,6 +160,8 @@ async function run() {
114
160
  const flag = args.find((a) => a === '--check' || a === 'status' || a === '--help' || a === '-h')
115
161
  const versionFlagIndex = args.indexOf('--version')
116
162
  const autoFlagIndex = args.indexOf('--auto')
163
+ const explicitChannel = args.includes('--beta') || args.includes('--stable')
164
+ const channel = args.includes('--beta') ? 'beta' : args.includes('--stable') ? 'stable' : inferChannel(current)
117
165
 
118
166
  if (flag === '--help' || flag === '-h') {
119
167
  showHelp()
@@ -121,9 +169,10 @@ async function run() {
121
169
  }
122
170
 
123
171
  if (flag === 'status') {
124
- const info = await resolveLatest({ notify: false })
172
+ const info = await resolveLatest({ notify: false, channel, explicitChannel })
125
173
  output.header('Meddle Update Status')
126
174
  output.kv('Install method', installMethod)
175
+ output.kv('Channel', channel)
127
176
  output.kv('Current', info.current)
128
177
  output.kv('Latest', info.latest)
129
178
  output.kv('Auto-update', getAutoUpdate(home) ? 'on' : 'off')
@@ -170,13 +219,13 @@ async function run() {
170
219
  }
171
220
 
172
221
  if (flag === '--check') {
173
- const info = await resolveLatest()
222
+ const info = await resolveLatest({ channel, explicitChannel })
174
223
  if (info.outdated) process.exit(2)
175
224
  return
176
225
  }
177
226
 
178
227
  // default: check + upgrade
179
- const info = await resolveLatest()
228
+ const info = await resolveLatest({ channel, explicitChannel })
180
229
  if (!info.outdated) return
181
230
  await installVersion(info.latest)
182
231
  }
@@ -20,11 +20,12 @@ const { resolveMeddleHome } = require('./meddle-home')
20
20
  const PACKAGE_NAME = '@jonathanleelx/meddle'
21
21
  const REPO = 'JonathanLee-LX/meddle'
22
22
  const DEFAULT_NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`
23
+ const DEFAULT_NPM_BETA_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/beta`
23
24
  const DEFAULT_GITHUB_LATEST_URL = `https://github.com/${REPO}/releases/latest`
24
25
  const DEFAULT_DOWNLOAD_BASE_URL = `https://github.com/${REPO}/releases/download`
25
26
  const DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000
26
27
  const DEFAULT_TIMEOUT_MS = 5000
27
- const DEFAULT_DOWNLOAD_TIMEOUT_MS = 120 * 1000
28
+ const DEFAULT_DOWNLOAD_TIMEOUT_MS = 5 * 60 * 1000
28
29
 
29
30
  const VERSION_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/
30
31
 
@@ -95,12 +96,15 @@ function compareVersions(a, b) {
95
96
 
96
97
  /**
97
98
  * Fetch the latest version from the npm registry.
98
- * @param {{ fetchImpl?: Function, registryUrl?: string, timeoutMs?: number }} opts
99
+ * @param {{ fetchImpl?: Function, registryUrl?: string, timeoutMs?: number, distTag?: string }} opts
99
100
  * @returns {Promise<string>}
100
101
  */
101
- async function getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs } = {}) {
102
+ async function getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs, distTag } = {}) {
102
103
  const doFetch = fetchImpl || fetch
103
- const url = registryUrl || DEFAULT_NPM_REGISTRY_URL
104
+ const url = registryUrl
105
+ || (distTag === 'beta'
106
+ ? (process.env.MEDDLE_NPM_BETA_REGISTRY_URL || process.env.MEDDLE_NPM_REGISTRY_URL || DEFAULT_NPM_BETA_URL)
107
+ : (process.env.MEDDLE_NPM_REGISTRY_URL || DEFAULT_NPM_REGISTRY_URL))
104
108
  const response = await doFetch(url, { signal: AbortSignal.timeout(timeoutMs || DEFAULT_TIMEOUT_MS) })
105
109
  if (!response.ok) throw new Error(`npm registry responded ${response.status}`)
106
110
  const data = await response.json()
@@ -110,13 +114,15 @@ async function getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs } = {}) {
110
114
  }
111
115
 
112
116
  /**
113
- * Fetch the latest version from the GitHub releases/latest redirect.
117
+ * Fetch the latest stable version from the GitHub releases/latest redirect
118
+ * (prereleases are excluded by GitHub). Beta versions resolve through the npm
119
+ * registry `beta` dist-tag instead — see checkForUpdate.
114
120
  * @param {{ fetchImpl?: Function, latestUrl?: string, timeoutMs?: number }} opts
115
121
  * @returns {Promise<string>}
116
122
  */
117
123
  async function getLatestVersionGithub({ fetchImpl, latestUrl, timeoutMs } = {}) {
118
124
  const doFetch = fetchImpl || fetch
119
- const url = latestUrl || DEFAULT_GITHUB_LATEST_URL
125
+ const url = latestUrl || process.env.MEDDLE_GITHUB_LATEST_URL || DEFAULT_GITHUB_LATEST_URL
120
126
  const response = await doFetch(url, {
121
127
  redirect: 'manual',
122
128
  signal: AbortSignal.timeout(timeoutMs || DEFAULT_TIMEOUT_MS),
@@ -149,11 +155,34 @@ function updateCachePath(home) {
149
155
  return path.join(home, '.cache', 'update-check.json')
150
156
  }
151
157
 
158
+ /**
159
+ * Infer the update channel from the current version: prerelease versions
160
+ * (e.g. 0.4.0-beta.4) default to the beta channel, releases to stable.
161
+ * @param {string} current
162
+ * @returns {'stable' | 'beta'}
163
+ */
164
+ function inferChannel(current) {
165
+ return isValidVersion(current) && parseVersion(current).prerelease.length > 0 ? 'beta' : 'stable'
166
+ }
167
+
168
+ /**
169
+ * Decide whether the install should move to `latest`. Explicit channel flags
170
+ * (--beta/--stable) mean "switch channels", so a different channel always
171
+ * triggers the move (even a downgrade); the inferred channel only upgrades.
172
+ * @param {{ latest: string, current: string, channel: string, explicitChannel: boolean }} opts
173
+ * @returns {boolean}
174
+ */
175
+ function outdatedByChannel({ latest, current, channel, explicitChannel }) {
176
+ if (explicitChannel && channel !== inferChannel(current)) return true
177
+ return compareVersions(latest, current) > 0
178
+ }
179
+
152
180
  /**
153
181
  * @param {{ home: string, fetchImpl?: Function, installMethod: string, current: string,
154
182
  * now?: number, ttlMs?: number, force?: boolean,
155
- * registryUrl?: string, latestUrl?: string, timeoutMs?: number }} opts
156
- * @returns {Promise<{ current: string, latest: string, outdated: boolean, fromCache: boolean, checkedAt: number }>}
183
+ * registryUrl?: string, latestUrl?: string, timeoutMs?: number,
184
+ * channel?: string, explicitChannel?: boolean }} opts
185
+ * @returns {Promise<{ current: string, latest: string, outdated: boolean, fromCache: boolean, checkedAt: number, channel: string }>}
157
186
  */
158
187
  async function checkForUpdate(opts) {
159
188
  const {
@@ -167,6 +196,8 @@ async function checkForUpdate(opts) {
167
196
  registryUrl,
168
197
  latestUrl,
169
198
  timeoutMs,
199
+ channel = inferChannel(current),
200
+ explicitChannel = false,
170
201
  } = opts
171
202
 
172
203
  const cacheFile = updateCachePath(home)
@@ -175,34 +206,43 @@ async function checkForUpdate(opts) {
175
206
  cached = JSON.parse(fs.readFileSync(cacheFile, 'utf8'))
176
207
  } catch (_) {}
177
208
 
178
- if (!force && cached && typeof cached.version === 'string' && typeof cached.checkedAt === 'number') {
209
+ if (!force && cached && typeof cached.version === 'string' && typeof cached.checkedAt === 'number'
210
+ && (cached.channel || 'stable') === channel) {
179
211
  if (now - cached.checkedAt < ttlMs) {
180
212
  return {
181
213
  current,
182
214
  latest: cached.version,
183
- outdated: compareVersions(cached.version, current) > 0,
215
+ outdated: outdatedByChannel({ latest: cached.version, current, channel, explicitChannel }),
184
216
  fromCache: true,
185
217
  checkedAt: cached.checkedAt,
218
+ channel,
186
219
  }
187
220
  }
188
221
  }
189
222
 
190
- const latest = installMethod === 'binary'
191
- ? await getLatestVersionGithub({ fetchImpl, latestUrl, timeoutMs })
192
- : await getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs })
223
+ // Beta channel always resolves via the npm registry `beta` dist-tag — the
224
+ // GitHub releases API is rate-limited (403) for unauthenticated callers.
225
+ // Binary installs still download assets from GitHub, but resolve the
226
+ // version number from npm where it is published in lockstep with releases.
227
+ const latest = channel === 'beta'
228
+ ? await getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs, distTag: 'beta' })
229
+ : installMethod === 'binary'
230
+ ? await getLatestVersionGithub({ fetchImpl, latestUrl, timeoutMs })
231
+ : await getLatestVersionNpm({ fetchImpl, registryUrl, timeoutMs })
193
232
 
194
233
  const checkedAt = now
195
234
  try {
196
235
  fs.mkdirSync(path.dirname(cacheFile), { recursive: true })
197
- fs.writeFileSync(cacheFile, JSON.stringify({ version: latest, checkedAt }), 'utf8')
236
+ fs.writeFileSync(cacheFile, JSON.stringify({ version: latest, checkedAt, channel }), 'utf8')
198
237
  } catch (_) {}
199
238
 
200
239
  return {
201
240
  current,
202
241
  latest,
203
- outdated: compareVersions(latest, current) > 0,
242
+ outdated: outdatedByChannel({ latest, current, channel, explicitChannel }),
204
243
  fromCache: false,
205
244
  checkedAt,
245
+ channel,
206
246
  }
207
247
  }
208
248
 
@@ -238,17 +278,28 @@ function sha256Hex(buffer) {
238
278
  * the existing binary. The previous binary is kept as `<destFile>.bak`. When
239
279
  * the final replace fails the backup is restored and a descriptive error is
240
280
  * thrown (Windows commonly fails with EPERM on a running binary).
281
+ *
282
+ * The payload download is retried (default 3 attempts) because binaries are
283
+ * large (100MB+) and flaky connections drop mid-body. Progress is reported
284
+ * via `onProgress` while streaming (received/total bytes), and `onAttempt`
285
+ * fires before each attempt (skipping retries is visible to callers).
241
286
  * @param {{ version: string, destFile: string, platform: string, arch: string,
242
287
  * baseUrl?: string, fetchImpl?: Function, timeoutMs?: number,
288
+ * retries?: number, retryDelayMs?: number,
289
+ * onProgress?: Function, onAttempt?: Function,
243
290
  * fsImpl?: object }} opts
244
291
  * @returns {Promise<{ installed: string, backup: string, version: string }>}
245
292
  */
246
293
  async function downloadBinaryAsset(opts) {
247
294
  const { version, destFile, platform, arch } = opts
248
- const baseUrl = opts.baseUrl || DEFAULT_DOWNLOAD_BASE_URL
295
+ const baseUrl = opts.baseUrl || process.env.MEDDLE_UPDATE_BASE_URL || DEFAULT_DOWNLOAD_BASE_URL
249
296
  const doFetch = opts.fetchImpl || fetch
250
297
  const fsImpl = opts.fsImpl || fs
251
298
  const payloadTimeout = opts.timeoutMs || DEFAULT_DOWNLOAD_TIMEOUT_MS
299
+ const maxRetries = opts.retries === undefined ? 3 : opts.retries
300
+ const retryDelayMs = opts.retryDelayMs === undefined ? 1000 : opts.retryDelayMs
301
+ const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : () => {}
302
+ const onAttempt = typeof opts.onAttempt === 'function' ? opts.onAttempt : () => {}
252
303
 
253
304
  const asset = getAssetName({ platform, arch })
254
305
  const assetUrl = `${baseUrl}/v${version}/${asset}`
@@ -256,14 +307,47 @@ async function downloadBinaryAsset(opts) {
256
307
 
257
308
  // The binary is large (100MB+); the checksum sidecar is tiny. Use a long
258
309
  // timeout for the payload and the regular timeout for the metadata fetch.
259
- const [binaryResponse, shaResponse] = await Promise.all([
260
- doFetch(assetUrl, { signal: AbortSignal.timeout(payloadTimeout) }),
261
- doFetch(shaUrl, { signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS) }),
262
- ])
263
- if (!binaryResponse.ok) throw new Error(`download failed (${binaryResponse.status})`)
310
+ const fetchPayload = async () => {
311
+ let lastError = null
312
+ for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
313
+ if (attempt > 1 && retryDelayMs > 0) {
314
+ await new Promise((r) => setTimeout(r, retryDelayMs * (attempt - 1)))
315
+ }
316
+ onAttempt(attempt, maxRetries + 1)
317
+ try {
318
+ const response = await doFetch(assetUrl, { signal: AbortSignal.timeout(payloadTimeout) })
319
+ if (!response.ok) throw new Error(`download failed (${response.status})`)
320
+ const total = Number(response.headers.get('content-length')) || 0
321
+ const chunks = []
322
+ let received = 0
323
+ if (response.body && typeof response.body.getReader === 'function') {
324
+ const reader = response.body.getReader()
325
+ for (;;) {
326
+ const { done, value } = await reader.read()
327
+ if (done) break
328
+ chunks.push(Buffer.from(value))
329
+ received += value.byteLength
330
+ onProgress({ received, total })
331
+ }
332
+ } else {
333
+ const buf = Buffer.from(await response.arrayBuffer())
334
+ chunks.push(buf)
335
+ received = buf.length
336
+ onProgress({ received, total })
337
+ }
338
+ return Buffer.concat(chunks)
339
+ } catch (err) {
340
+ lastError = err
341
+ if (attempt > maxRetries) break
342
+ }
343
+ }
344
+ throw lastError || new Error(`download failed for ${assetUrl}`)
345
+ }
346
+
347
+ const shaResponse = await doFetch(shaUrl, { signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS) })
264
348
  if (!shaResponse.ok) throw new Error(`checksum sidecar missing (${shaResponse.status})`)
265
349
 
266
- const payload = Buffer.from(await binaryResponse.arrayBuffer())
350
+ const payload = await fetchPayload()
267
351
  const shaText = await shaResponse.text()
268
352
  const expected = shaText.trim().split(/\s+/)[0]
269
353
  if (!/^[0-9a-f]{64}$/i.test(expected)) throw new Error(`invalid checksum sidecar`)
@@ -425,6 +509,7 @@ module.exports = {
425
509
  compareVersions,
426
510
  isValidVersion,
427
511
  parseVersion,
512
+ inferChannel,
428
513
  getLatestVersionNpm,
429
514
  getLatestVersionGithub,
430
515
  getInstallMethod,
package/dist/helpers.d.ts CHANGED
@@ -23,6 +23,19 @@ export declare function routeRulesToLegacyMaps(rules: RouteRuleEntry[]): {
23
23
  excludeMap: ExcludeMap;
24
24
  };
25
25
  export declare function getFreePort(): Promise<number>;
26
+ /**
27
+ * Listen on a port, retrying with a fresh free port when the requested one is
28
+ * taken. Unlike a bare `server.listen()`, a port conflict surfaces as a
29
+ * retryable error here instead of an async 'error' event that would escape a
30
+ * try/catch and crash the process via uncaughtException.
31
+ * @returns the port the server actually bound to
32
+ * @throws the last listen error when all attempts fail
33
+ */
34
+ export declare function listenWithRetry(server: {
35
+ listen(port: number, host: string, cb?: () => void): unknown;
36
+ } & NodeJS.EventEmitter, host: string, port: number, opts?: {
37
+ maxRetries?: number;
38
+ }): Promise<number>;
26
39
  export declare const ROUTE_RULES_DIR: string;
27
40
  export interface ParseEprcResult {
28
41
  rules: RouteRuleEntry[];
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../helpers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAElD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACxB;AA2BD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAWvE;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAW9G;AAuDD,kDAAkD;AAClD,wBAAgB,oBAAoB,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,cAAc,EAAE,GACxB;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUvD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,IAAI,CAE7F;AAYD,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,cAAc,EAAE,GAAG,OAAO,EACtC,UAAU,CAAC,EAAE,UAAU,GACxB,MAAM,GAAG,IAAI,CAKf;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAQ5G;AAKD,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAKnD;AAED,eAAO,MAAM,eAAe,QAAmD,CAAC;AAKhF,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAmDxE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAmCnF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ/D"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../helpers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAElD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACxB;AA2BD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAWvE;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAW9G;AAuDD,kDAAkD;AAClD,wBAAgB,oBAAoB,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,cAAc,EAAE,GACxB;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUvD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,IAAI,CAE7F;AAYD,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,cAAc,EAAE,GAAG,OAAO,EACtC,UAAU,CAAC,EAAE,UAAU,GACxB,MAAM,GAAG,IAAI,CAKf;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAQ5G;AAKD,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAKnD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE;IAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,YAAY,EAC9F,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,eAAO,MAAM,eAAe,QAAmD,CAAC;AAKhF,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAmDxE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAmCnF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ/D"}
package/dist/helpers.js CHANGED
@@ -41,6 +41,7 @@ exports.resolveTargetUrlFromRules = resolveTargetUrlFromRules;
41
41
  exports.resolveTargetUrl = resolveTargetUrl;
42
42
  exports.routeRulesToLegacyMaps = routeRulesToLegacyMaps;
43
43
  exports.getFreePort = getFreePort;
44
+ exports.listenWithRetry = listenWithRetry;
44
45
  exports.parseEprcWithExclusions = parseEprcWithExclusions;
45
46
  exports.parseEprc = parseEprc;
46
47
  exports.ruleMapToEprcText = ruleMapToEprcText;
@@ -193,6 +194,47 @@ async function getFreePort() {
193
194
  (0, portfinder_1.setHighestPort)(highestPort);
194
195
  return (0, portfinder_1.getPortPromise)();
195
196
  }
197
+ /**
198
+ * Listen on a port, retrying with a fresh free port when the requested one is
199
+ * taken. Unlike a bare `server.listen()`, a port conflict surfaces as a
200
+ * retryable error here instead of an async 'error' event that would escape a
201
+ * try/catch and crash the process via uncaughtException.
202
+ * @returns the port the server actually bound to
203
+ * @throws the last listen error when all attempts fail
204
+ */
205
+ function listenWithRetry(server, host, port, opts = {}) {
206
+ const maxRetries = opts.maxRetries ?? 5;
207
+ return new Promise((resolve, reject) => {
208
+ let settled = false;
209
+ const settle = (fn) => {
210
+ if (settled)
211
+ return;
212
+ settled = true;
213
+ fn();
214
+ };
215
+ const attempt = (attemptPort, remaining) => {
216
+ const onListening = () => {
217
+ server.removeListener('error', onError);
218
+ const addr = server.address();
219
+ settle(() => resolve(addr ? addr.port : attemptPort));
220
+ };
221
+ const onError = (err) => {
222
+ server.removeListener('listening', onListening);
223
+ if (err && err.code === 'EADDRINUSE' && remaining > 0) {
224
+ getFreePort()
225
+ .then((nextPort) => attempt(nextPort, remaining - 1))
226
+ .catch((e) => settle(() => reject(e)));
227
+ return;
228
+ }
229
+ settle(() => reject(err));
230
+ };
231
+ server.once('error', onError);
232
+ server.once('listening', onListening);
233
+ server.listen(attemptPort, host);
234
+ };
235
+ attempt(port, maxRetries);
236
+ });
237
+ }
196
238
  exports.ROUTE_RULES_DIR = path.resolve((0, meddle_home_1.resolveMeddleHome)(), 'route-rules');
197
239
  const FILE_PATTERN = /^file:\/\//;
198
240
  const LOCAL_FILE_PATTERN = /^[A-Za-z]:\\|^\/|^\\/;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../helpers.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -4,7 +4,7 @@ const fs = require('fs')
4
4
  const path = require('path')
5
5
  const { connect } = require('net')
6
6
  const { WebSocket, WebSocketServer } = require('ws')
7
- const { resolveTargetUrl, getFreePort } = require('./dist/helpers')
7
+ const { resolveTargetUrl, getFreePort, listenWithRetry } = require('./dist/helpers')
8
8
  const { crtMgr, ensureRootCA, getRootCAPath } = require('./dist/cert')
9
9
  const { decideRoute } = require('./dist/core/route-decision')
10
10
  const { sendShortResponse } = require('./dist/core/short-response')
@@ -871,7 +871,8 @@ proxyServer.on('connect', async (req, socket, head) => {
871
871
  if (!server) {
872
872
  const port = await getFreePort()
873
873
  server = await createHttpsServerByCert()
874
- server.listen(port, '127.0.0.1', () => { proxyDebug('listening on ' + port) })
874
+ const boundPort = await listenWithRetry(server, '127.0.0.1', port)
875
+ proxyDebug('listening on ' + boundPort)
875
876
  ctx.httpsServerMap.set(originHost, server)
876
877
  } else {
877
878
  markMitmServerUsed(server)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jonathanleelx/meddle",
3
- "version": "0.4.0-beta.1",
3
+ "version": "0.4.0-beta.10",
4
4
  "description": "A simple development proxy server with custom routing rules, mock responses, HTTPS interception, and a plugin system",
5
5
  "type": "commonjs",
6
6
  "main": "index.js",
@@ -20,6 +20,7 @@
20
20
  "test:identity": "pnpm run build && node scripts/application-identity-smoke.js",
21
21
  "test:e2e": "npm run build:web && npm run build && node tests/e2e/interactions.e2e.cjs",
22
22
  "test:e2e:rule-drag": "npm run build:web && npm run build && node tests/e2e/rule-drag.e2e.cjs",
23
+ "test:e2e:update": "node tests/e2e/update.e2e.cjs",
23
24
  "test:watch": "vitest",
24
25
  "test:refactor": "npm run build && node -c index.js && npm test",
25
26
  "bench:logs": "node scripts/log-performance-benchmark.js",