dsh-zen-remote 2.3.11 → 2.4.1
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/CHANGELOG.md +45 -78
- package/README.md +94 -84
- package/README.zh-CN.md +90 -81
- package/bin/zen-remote.mjs +5 -0
- package/docs/interface.md +6 -6
- package/docs/remote-access.en.md +6 -4
- package/docs/remote-access.md +6 -4
- package/dsh-push.mjs +96 -10
- package/lib/adapters/dsh-better-sidebar/index.js +7 -3
- package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
- package/lib/admin-routes.js +10 -2
- package/lib/admin-routes.js.map +1 -1
- package/lib/cli/args.js +251 -0
- package/lib/cli/args.js.map +1 -0
- package/lib/cli/bootstrap.js +449 -0
- package/lib/cli/bootstrap.js.map +1 -0
- package/lib/cli/command-setup.js +484 -0
- package/lib/cli/command-setup.js.map +1 -0
- package/lib/cli/commands-client.js +359 -0
- package/lib/cli/commands-client.js.map +1 -0
- package/lib/cli/commands-host.js +1108 -0
- package/lib/cli/commands-host.js.map +1 -0
- package/lib/cli/commands-status.js +279 -0
- package/lib/cli/commands-status.js.map +1 -0
- package/lib/cli/config-writer.js +334 -0
- package/lib/cli/config-writer.js.map +1 -0
- package/lib/cli/context.js +10 -0
- package/lib/cli/context.js.map +1 -0
- package/lib/cli/i18n.js +620 -0
- package/lib/cli/i18n.js.map +1 -0
- package/lib/cli/ipc-client.js +160 -0
- package/lib/cli/ipc-client.js.map +1 -0
- package/lib/cli/ipc-server.js +464 -0
- package/lib/cli/ipc-server.js.map +1 -0
- package/lib/cli/main.js +245 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/qr-terminal.js +48 -0
- package/lib/cli/qr-terminal.js.map +1 -0
- package/lib/client-data/qr.js +286 -0
- package/lib/client-data/qr.js.map +1 -0
- package/lib/client-routes.js +308 -25
- package/lib/client-routes.js.map +1 -1
- package/lib/client.js +1013 -229
- package/lib/config.js +50 -12
- package/lib/config.js.map +1 -1
- package/lib/debug-report.js +28 -1
- package/lib/debug-report.js.map +1 -1
- package/lib/fetch-route-intercept.js +334 -26
- package/lib/fetch-route-intercept.js.map +1 -1
- package/lib/index.js +608 -375
- package/lib/index.js.map +1 -1
- package/lib/intercept.js +1833 -280
- package/lib/intercept.js.map +1 -1
- package/lib/lan-gate-server.cjs +36 -10
- package/lib/merge-streams.js +103 -11
- package/lib/merge-streams.js.map +1 -1
- package/lib/plugin-route-intercept.js +93 -63
- package/lib/plugin-route-intercept.js.map +1 -1
- package/lib/relay-access.js +8 -1
- package/lib/relay-access.js.map +1 -1
- package/lib/relay-client.js +133 -4
- package/lib/relay-client.js.map +1 -1
- package/lib/relay-pool.js +275 -0
- package/lib/relay-pool.js.map +1 -0
- package/lib/relay-server.js +269 -17
- package/lib/relay-server.js.map +1 -1
- package/lib/restart-fields.js +6 -4
- package/lib/restart-fields.js.map +1 -1
- package/lib/share-ops.js +68 -0
- package/lib/share-ops.js.map +1 -1
- package/lib/share-store.js +65 -27
- package/lib/share-store.js.map +1 -1
- package/lib/state-store.js +400 -0
- package/lib/state-store.js.map +1 -0
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts +3 -2
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
- package/lib/types/admin-routes.d.ts.map +1 -1
- package/lib/types/cli/args.d.ts +78 -0
- package/lib/types/cli/args.d.ts.map +1 -0
- package/lib/types/cli/bootstrap.d.ts +170 -0
- package/lib/types/cli/bootstrap.d.ts.map +1 -0
- package/lib/types/cli/command-setup.d.ts +72 -0
- package/lib/types/cli/command-setup.d.ts.map +1 -0
- package/lib/types/cli/commands-client.d.ts +36 -0
- package/lib/types/cli/commands-client.d.ts.map +1 -0
- package/lib/types/cli/commands-host.d.ts +82 -0
- package/lib/types/cli/commands-host.d.ts.map +1 -0
- package/lib/types/cli/commands-status.d.ts +46 -0
- package/lib/types/cli/commands-status.d.ts.map +1 -0
- package/lib/types/cli/config-writer.d.ts +92 -0
- package/lib/types/cli/config-writer.d.ts.map +1 -0
- package/lib/types/cli/context.d.ts +39 -0
- package/lib/types/cli/context.d.ts.map +1 -0
- package/lib/types/cli/i18n.d.ts +32 -0
- package/lib/types/cli/i18n.d.ts.map +1 -0
- package/lib/types/cli/ipc-client.d.ts +83 -0
- package/lib/types/cli/ipc-client.d.ts.map +1 -0
- package/lib/types/cli/ipc-server.d.ts +113 -0
- package/lib/types/cli/ipc-server.d.ts.map +1 -0
- package/lib/types/cli/main.d.ts +57 -0
- package/lib/types/cli/main.d.ts.map +1 -0
- package/lib/types/cli/qr-terminal.d.ts +17 -0
- package/lib/types/cli/qr-terminal.d.ts.map +1 -0
- package/lib/types/client/RemoteStatusIcon.d.ts.map +1 -1
- package/lib/types/client/current-session-report.d.ts +4 -0
- package/lib/types/client/current-session-report.d.ts.map +1 -1
- package/lib/types/client/effects/model-group-side.d.ts.map +1 -1
- package/lib/types/client/effects/remote-session.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +47 -3
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
- package/lib/types/client/settings/settings-css.d.ts +1 -1
- package/lib/types/client/settings/settings-css.d.ts.map +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
- package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -1
- package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts.map +1 -1
- package/lib/types/client-data/model-group-side.d.ts +23 -2
- package/lib/types/client-data/model-group-side.d.ts.map +1 -1
- package/lib/types/client-data/remote-status.d.ts +47 -1
- package/lib/types/client-data/remote-status.d.ts.map +1 -1
- package/lib/types/client-data/settings-form.d.ts +85 -1
- package/lib/types/client-data/settings-form.d.ts.map +1 -1
- package/lib/types/client-data/wizard.d.ts +56 -1
- package/lib/types/client-data/wizard.d.ts.map +1 -1
- package/lib/types/client-routes.d.ts +25 -1
- package/lib/types/client-routes.d.ts.map +1 -1
- package/lib/types/config.d.ts +40 -14
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/debug-report.d.ts.map +1 -1
- package/lib/types/fetch-route-intercept.d.ts +66 -8
- package/lib/types/fetch-route-intercept.d.ts.map +1 -1
- package/lib/types/index.d.ts +9 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/intercept.d.ts +72 -10
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts +79 -1
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/plugin-route-intercept.d.ts +25 -9
- package/lib/types/plugin-route-intercept.d.ts.map +1 -1
- package/lib/types/relay-access.d.ts +3 -1
- package/lib/types/relay-access.d.ts.map +1 -1
- package/lib/types/relay-client.d.ts +23 -2
- package/lib/types/relay-client.d.ts.map +1 -1
- package/lib/types/relay-pool.d.ts +148 -0
- package/lib/types/relay-pool.d.ts.map +1 -0
- package/lib/types/relay-server.d.ts +30 -3
- package/lib/types/relay-server.d.ts.map +1 -1
- package/lib/types/restart-fields.d.ts +5 -5
- package/lib/types/restart-fields.d.ts.map +1 -1
- package/lib/types/share-ops.d.ts +47 -1
- package/lib/types/share-ops.d.ts.map +1 -1
- package/lib/types/share-store.d.ts.map +1 -1
- package/lib/types/state-store.d.ts +179 -0
- package/lib/types/state-store.d.ts.map +1 -0
- package/lib/types/upload-limits.d.ts +15 -0
- package/lib/types/upload-limits.d.ts.map +1 -1
- package/lib/types/virtual-id.d.ts +21 -0
- package/lib/types/virtual-id.d.ts.map +1 -1
- package/lib/types/wizard/probe.d.ts.map +1 -1
- package/lib/types/wizard/proxy-snippets.d.ts +3 -0
- package/lib/types/wizard/proxy-snippets.d.ts.map +1 -1
- package/lib/types/wizard/routes.d.ts +1 -0
- package/lib/types/wizard/routes.d.ts.map +1 -1
- package/lib/types/wizard/status.d.ts +9 -0
- package/lib/types/wizard/status.d.ts.map +1 -1
- package/lib/types/wizard/verify.d.ts +3 -0
- package/lib/types/wizard/verify.d.ts.map +1 -1
- package/lib/upload-limits.js +15 -0
- package/lib/upload-limits.js.map +1 -1
- package/lib/virtual-id.js +60 -0
- package/lib/virtual-id.js.map +1 -1
- package/lib/wizard/probe.js +46 -1
- package/lib/wizard/probe.js.map +1 -1
- package/lib/wizard/proxy-snippets.js +14 -1
- package/lib/wizard/proxy-snippets.js.map +1 -1
- package/lib/wizard/routes.js +23 -4
- package/lib/wizard/routes.js.map +1 -1
- package/lib/wizard/status.js +21 -0
- package/lib/wizard/status.js.map +1 -1
- package/lib/wizard/verify.js +31 -8
- package/lib/wizard/verify.js.map +1 -1
- package/package.json +8 -4
- package/pwa/icons/badge-96.png +0 -0
- package/pwa/icons/badge.svg +1 -0
- package/pwa/manifest.json +2 -1
- package/pwa/sw.js +3 -1
- package/scripts/check-debug-report.mjs +41 -1
- package/scripts/check-settings-form.mjs +14 -3
- package/scripts/check-settings-view.mjs +247 -0
- package/scripts/check-wizard-ui.mjs +37 -0
- package/src/adapters/dsh-better-sidebar/index.ts +7 -3
- package/src/admin-routes.ts +10 -2
- package/src/cli/args.ts +289 -0
- package/src/cli/bootstrap.ts +569 -0
- package/src/cli/command-setup.ts +540 -0
- package/src/cli/commands-client.ts +369 -0
- package/src/cli/commands-host.ts +1127 -0
- package/src/cli/commands-status.ts +296 -0
- package/src/cli/config-writer.ts +354 -0
- package/src/cli/context.ts +38 -0
- package/src/cli/i18n.ts +645 -0
- package/src/cli/ipc-client.ts +216 -0
- package/src/cli/ipc-server.ts +531 -0
- package/src/cli/main.ts +285 -0
- package/src/cli/qr-terminal.ts +49 -0
- package/src/client/RemoteStatusIcon.tsx +4 -1
- package/src/client/current-session-report.ts +28 -4
- package/src/client/effects/model-group-side.ts +19 -5
- package/src/client/effects/remote-session.ts +26 -6
- package/src/client/locales.ts +96 -6
- package/src/client/settings/SettingsSection.tsx +287 -92
- package/src/client/settings/settings-css.ts +18 -0
- package/src/client/styles/remote-session.css.ts +15 -1
- package/src/client/wizard/GatewayWizard.tsx +470 -109
- package/src/client/wizard/cards/ProxyCard.tsx +2 -1
- package/src/client/wizard/wizard-css.ts +23 -0
- package/src/client-data/model-group-side.ts +37 -10
- package/src/client-data/remote-status.ts +112 -17
- package/src/client-data/settings-form.ts +164 -8
- package/src/client-data/wizard.ts +112 -2
- package/src/client-routes.ts +334 -26
- package/src/config.ts +62 -16
- package/src/debug-report.ts +27 -1
- package/src/fetch-route-intercept.ts +381 -32
- package/src/index.ts +608 -380
- package/src/intercept.ts +1866 -286
- package/src/merge-streams.ts +155 -10
- package/src/plugin-route-intercept.ts +120 -71
- package/src/relay-access.ts +14 -3
- package/src/relay-client.ts +163 -5
- package/src/relay-pool.ts +387 -0
- package/src/relay-server.ts +312 -16
- package/src/restart-fields.ts +6 -4
- package/src/share-ops.ts +82 -1
- package/src/share-store.ts +59 -26
- package/src/state-store.ts +428 -0
- package/src/upload-limits.ts +16 -0
- package/src/virtual-id.ts +57 -0
- package/src/wizard/probe.ts +54 -2
- package/src/wizard/proxy-snippets.ts +17 -2
- package/src/wizard/routes.ts +24 -5
- package/src/wizard/status.ts +28 -0
- package/src/wizard/verify.ts +33 -11
- package/AGENTS.md +0 -185
- package/docs/adr/0001-plugin-bridge-forwards-plugin-routes.md +0 -15
- package/docs/adr/0002-relay-emulates-websocket.md +0 -8
|
@@ -12,8 +12,17 @@
|
|
|
12
12
|
* row layer applies the same rule when the fields land there, so a client
|
|
13
13
|
* that accepts something the resolver would silently drop would only set
|
|
14
14
|
* the user up for a mystery.
|
|
15
|
+
*
|
|
16
|
+
* MS-6 adds the paired-pool overview pieces: the pool count is a first-class
|
|
17
|
+
* "configured" signal (MS-5 pairs straight into the pool store, not the
|
|
18
|
+
* row), and {@link deriveClientOverviewSummary} derives the overview card's
|
|
19
|
+
* counters and its two lights (connection health / pool fill) off the
|
|
20
|
+
* `client/status` pool list.
|
|
15
21
|
*/
|
|
16
22
|
|
|
23
|
+
import { MAX_PAIRED_SERVERS } from './settings-form.ts'
|
|
24
|
+
import type { ClientServerView } from './settings-form.ts'
|
|
25
|
+
|
|
17
26
|
/** Wizard route constants — mirror of src/wizard/routes.ts. */
|
|
18
27
|
export const WIZARD_STATUS_ROUTE = '/_dsh/zen-remote/admin/wizard/status'
|
|
19
28
|
export const WIZARD_VERIFY_ROUTE = '/_dsh/zen-remote/admin/wizard/verify'
|
|
@@ -130,7 +139,12 @@ export function initialStep(status: WizardStatusBody | undefined): WizardStep {
|
|
|
130
139
|
|
|
131
140
|
/**
|
|
132
141
|
* Whether the inline overview card should render the configured status
|
|
133
|
-
* dashboard instead of the first-time setup prompt.
|
|
142
|
+
* dashboard instead of the first-time setup prompt. MS-6: the paired pool's
|
|
143
|
+
* size is the client's first-class signal — since MS-5 a claim lands in the
|
|
144
|
+
* pool store and never touches the row's `serverUrl` / `deviceToken`, so a
|
|
145
|
+
* freshly multi-paired machine with an empty row must still read as
|
|
146
|
+
* configured. `> 0` answers true no matter what the other inputs say; the
|
|
147
|
+
* field is optional and an omitted one (or a zero) changes nothing.
|
|
134
148
|
*/
|
|
135
149
|
export function isWizardConfigured(input: {
|
|
136
150
|
effectiveClient: boolean
|
|
@@ -140,7 +154,9 @@ export function isWizardConfigured(input: {
|
|
|
140
154
|
tokenConfigured: boolean
|
|
141
155
|
clientServerUrl: string
|
|
142
156
|
clientState: string | undefined
|
|
157
|
+
pairedServerCount?: number
|
|
143
158
|
}): boolean {
|
|
159
|
+
if ((input.pairedServerCount ?? 0) > 0) return true
|
|
144
160
|
if (input.effectiveClient) {
|
|
145
161
|
return input.tokenConfigured || input.clientServerUrl.trim() !== '' || input.clientState === 'connected'
|
|
146
162
|
}
|
|
@@ -312,6 +328,68 @@ const CLIENT_FAIL_STATES: ReadonlySet<string> = new Set([
|
|
|
312
328
|
'unexpected',
|
|
313
329
|
])
|
|
314
330
|
|
|
331
|
+
/**
|
|
332
|
+
* The view states that will NOT come back on their own (MS-6): a revoked
|
|
333
|
+
* token, an incompatible interface, an address that no longer parses — each
|
|
334
|
+
* needs the settings page before that server serves again. They turn the
|
|
335
|
+
* overview's connection light red; a merely `unreachable` server is mid-retry
|
|
336
|
+
* and stays amber.
|
|
337
|
+
*/
|
|
338
|
+
const CLIENT_DEAD_STATES: ReadonlySet<string> = new Set(['revoked', 'incompatible', 'invalid-url'])
|
|
339
|
+
|
|
340
|
+
/** The overview card's derived counters and lights (MS-6): the 第 3 格
|
|
341
|
+
* 「连接状态」 shows `M / N 台在线` with {@link WizardOverviewSummary.connectionLight}
|
|
342
|
+
* summarizing the pool's health, and the 第 4 格 「已配对服务端」 shows
|
|
343
|
+
* `已配对 N / maxServers 台` with {@link WizardOverviewSummary.serversLight}
|
|
344
|
+
* turning red exactly at the cap. Input is the DERIVED pool list
|
|
345
|
+
* ({@link ClientServerView} — the view vocabulary's state words), in pairing
|
|
346
|
+
* order; order never matters to the counts. */
|
|
347
|
+
export interface WizardOverviewSummary {
|
|
348
|
+
totalCount: number
|
|
349
|
+
onlineCount: number
|
|
350
|
+
/** Everything that is neither connected nor revoked (unreachable,
|
|
351
|
+
* unexpected, incompatible, invalid-url, …). */
|
|
352
|
+
offlineCount: number
|
|
353
|
+
revokedCount: number
|
|
354
|
+
maxServers: number
|
|
355
|
+
limitReached: boolean
|
|
356
|
+
connectionLight: LightState
|
|
357
|
+
serversLight: LightState
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Derive the sub-client overview summary off one derived pool list: green
|
|
362
|
+
* only when EVERY paired server is connected; red when any server is in a
|
|
363
|
+
* state that will not recover on its own (revoked / incompatible /
|
|
364
|
+
* invalid-url) or when the pool is FULL — the cap is a servers fact, so a
|
|
365
|
+
* full pool of healthy connections still shows a red servers light while its
|
|
366
|
+
* connection light stays green; amber for the rest (nothing paired yet, or
|
|
367
|
+
* servers the retry ladder is still working on).
|
|
368
|
+
*/
|
|
369
|
+
export function deriveClientOverviewSummary(
|
|
370
|
+
servers: readonly ClientServerView[],
|
|
371
|
+
maxServers: number = MAX_PAIRED_SERVERS,
|
|
372
|
+
): WizardOverviewSummary {
|
|
373
|
+
const totalCount = servers.length
|
|
374
|
+
let onlineCount = 0
|
|
375
|
+
let revokedCount = 0
|
|
376
|
+
let deadCount = 0
|
|
377
|
+
for (const server of servers) {
|
|
378
|
+
if (server.state === 'connected') onlineCount += 1
|
|
379
|
+
if (server.state === 'revoked') revokedCount += 1
|
|
380
|
+
if (CLIENT_DEAD_STATES.has(server.state)) deadCount += 1
|
|
381
|
+
}
|
|
382
|
+
const offlineCount = totalCount - onlineCount - revokedCount
|
|
383
|
+
const limitReached = totalCount >= maxServers
|
|
384
|
+
const connectionLight: LightState = totalCount === 0
|
|
385
|
+
? 'pending'
|
|
386
|
+
: onlineCount === totalCount
|
|
387
|
+
? 'pass'
|
|
388
|
+
: deadCount > 0 ? 'fail' : 'pending'
|
|
389
|
+
const serversLight: LightState = limitReached ? 'fail' : totalCount > 0 ? 'pass' : 'pending'
|
|
390
|
+
return { totalCount, onlineCount, offlineCount, revokedCount, maxServers, limitReached, connectionLight, serversLight }
|
|
391
|
+
}
|
|
392
|
+
|
|
315
393
|
/**
|
|
316
394
|
* Derive the three status lights for the desktop sub-client verification
|
|
317
395
|
* step (`role === 'client'`).
|
|
@@ -330,6 +408,27 @@ export function deriveClientWizardLights(input: {
|
|
|
330
408
|
}
|
|
331
409
|
}
|
|
332
410
|
|
|
411
|
+
/**
|
|
412
|
+
* The wizard step-3's three lights for ONE selected paired server (MS-8):
|
|
413
|
+
* the credential is green by the row's own existence (the token lives in the
|
|
414
|
+
* pool store, never in the row) and red only when the server refused it
|
|
415
|
+
* (`revoked`); the connection follows the same fail-set the global lights
|
|
416
|
+
* use (an offline server mid-retry is red here too — the step is staring at
|
|
417
|
+
* THAT one server, not the pool); sync is green on a connected row whose
|
|
418
|
+
* interface groups all match, red on a compat mismatch, amber otherwise.
|
|
419
|
+
* `undefined` (nothing paired, or nothing selected yet) keeps all three
|
|
420
|
+
* amber.
|
|
421
|
+
*/
|
|
422
|
+
export function deriveClientServerLights(server: ClientServerView | undefined): ClientWizardLights {
|
|
423
|
+
if (server === undefined) return { credential: 'pending', connection: 'pending', sync: 'pending' }
|
|
424
|
+
const connected = server.state === 'connected'
|
|
425
|
+
return {
|
|
426
|
+
credential: server.state === 'revoked' ? 'fail' : 'pass',
|
|
427
|
+
connection: connected ? 'pass' : CLIENT_FAIL_STATES.has(server.state) ? 'fail' : 'pending',
|
|
428
|
+
sync: connected ? ((server.compat?.mismatchedGroups.length ?? 0) > 0 ? 'fail' : 'pass') : 'pending',
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
333
432
|
/** Pairing-code countdown, whole seconds, never negative. */
|
|
334
433
|
export function pairingSecondsLeft(expiresAt: number, now: number): number {
|
|
335
434
|
return Math.max(0, Math.ceil((expiresAt - now) / 1000))
|
|
@@ -367,6 +466,7 @@ export interface SnippetInput {
|
|
|
367
466
|
domain: string
|
|
368
467
|
upstreamHost: string
|
|
369
468
|
upstreamPort: number
|
|
469
|
+
lang?: 'zh' | 'en' | undefined
|
|
370
470
|
}
|
|
371
471
|
|
|
372
472
|
/** Same grammar the row layer and the host half enforce. */
|
|
@@ -380,8 +480,11 @@ function valid(input: SnippetInput): { domain: string; upstream: string; port: n
|
|
|
380
480
|
export function nginxSnippetText(input: SnippetInput): string | null {
|
|
381
481
|
const parts = valid(input)
|
|
382
482
|
if (parts === null) return null
|
|
483
|
+
const headerComment = input.lang === 'en'
|
|
484
|
+
? '# Place this in the http {} block (skip if you already have this map)'
|
|
485
|
+
: '# 这段放在 http {} 层(若已有同名 map 则跳过)'
|
|
383
486
|
return [
|
|
384
|
-
|
|
487
|
+
headerComment,
|
|
385
488
|
'map $http_upgrade $connection_upgrade {',
|
|
386
489
|
' default upgrade;',
|
|
387
490
|
" '' close;",
|
|
@@ -420,6 +523,13 @@ export function caddySnippetText(input: SnippetInput): string | null {
|
|
|
420
523
|
export function luckyStepTexts(input: SnippetInput): string[] | null {
|
|
421
524
|
const parts = valid(input)
|
|
422
525
|
if (parts === null) return null
|
|
526
|
+
if (input.lang === 'en') {
|
|
527
|
+
return [
|
|
528
|
+
'In Lucky "Web Service", create a new rule listening on port 443 and bind your domain.',
|
|
529
|
+
`Set the backend (reverse proxy target) to http://${parts.upstream}:${parts.port} and enable WebSocket support.`,
|
|
530
|
+
'Turn on the catch-all switch to allow all paths, then save.',
|
|
531
|
+
]
|
|
532
|
+
}
|
|
423
533
|
return [
|
|
424
534
|
'在 Lucky 的「Web 服务」里新建一条规则,监听 443 端口,绑定你的域名。',
|
|
425
535
|
`后端(反代目标)填 http://${parts.upstream}:${parts.port},开启 WebSocket 支持。`,
|