dsh-ris-yds 0.0.0-stage → 1.1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -2
  3. package/assets/yds-chrome-resource-override.crx +0 -0
  4. package/bin/check-listing.mjs +247 -0
  5. package/bin/yds.js +19 -0
  6. package/cordis.patch.yml +13 -0
  7. package/lib/browser.js +428 -0
  8. package/lib/build.js +115 -0
  9. package/lib/cli.js +1130 -0
  10. package/lib/confcenter.js +377 -0
  11. package/lib/config.js +552 -0
  12. package/lib/fe-dev.js +206 -0
  13. package/lib/ide-proxy.js +906 -0
  14. package/lib/ide-watch.js +188 -0
  15. package/lib/ide.js +728 -0
  16. package/lib/index.js +267 -0
  17. package/lib/proc.js +270 -0
  18. package/lib/risd-peer.js +353 -0
  19. package/lib/rules.js +193 -0
  20. package/lib/socks.js +279 -0
  21. package/lib/token.js +36 -0
  22. package/lib/yms.js +336 -0
  23. package/lib/yoncode.js +249 -0
  24. package/native/yds-rust.darwin-arm64.node +0 -0
  25. package/native/yds-rust.darwin-x64.node +0 -0
  26. package/native/yds-rust.linux-arm64.node +0 -0
  27. package/native/yds-rust.linux-x64.node +0 -0
  28. package/native/yds-rust.win32-arm64.node +0 -0
  29. package/native/yds-rust.win32-x64.node +0 -0
  30. package/package.json +58 -4
  31. package/skills/dsh-ris-yds/SKILL.md +134 -0
  32. package/test/browser.test.mjs +442 -0
  33. package/test/cli-stop.test.mjs +40 -0
  34. package/test/cli.test.mjs +246 -0
  35. package/test/config.test.mjs +106 -0
  36. package/test/fe-dev.test.mjs +93 -0
  37. package/test/hints.test.mjs +13 -0
  38. package/test/ide-config.test.mjs +155 -0
  39. package/test/ide-proxy.test.mjs +256 -0
  40. package/test/ide-watch.test.mjs +79 -0
  41. package/test/launch-proxy.test.mjs +83 -0
  42. package/test/lease-release.test.mjs +76 -0
  43. package/test/mode-separation.test.mjs +147 -0
  44. package/test/pidfile.test.mjs +105 -0
  45. package/test/proc.test.mjs +172 -0
  46. package/test/proxy-standalone.test.mjs +121 -0
  47. package/test/risd-leases.test.mjs +111 -0
  48. package/test/risd-tier.test.mjs +361 -0
  49. package/test/rules-e2e.test.mjs +122 -0
  50. package/test/rules.test.mjs +154 -0
  51. package/test/yoncode.test.mjs +159 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * YonCode bundle patch: detection and the patch/restore round trip, done on a
3
+ * fake installation so the real Program Files copy is never touched.
4
+ */
5
+ import assert from 'node:assert/strict'
6
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
7
+ import { tmpdir } from 'node:os'
8
+ import { join } from 'node:path'
9
+ import { test } from 'node:test'
10
+
11
+ import {
12
+ YONCODE_EXTENSION_RELATIVE,
13
+ detectYoncode,
14
+ patchYoncode,
15
+ restoreYoncode,
16
+ yoncodeWarning,
17
+ } from '../lib/yoncode.js'
18
+
19
+ const SHIPPED_WITH_VMARGS = `const VM_ARGS = \`-Dapp.metainfo.ping_connect_timeout=200 -Dapp.metainfo.preferred-networks=\${command:yds.serverBindAddress} -Dserver.port=\${config:yds.serverPort}\`.replaceAll(/\s+/g, ' ');
20
+
21
+ function getServerBindAddress() {
22
+ if (!_util.ipv4IsValid(ipv4)) {
23
+ throw new Error("Invalid IP address, no interface found with address " + ipv4 + ".");
24
+ }
25
+ }
26
+ `
27
+
28
+ const SHIPPED = `
29
+ function getServerBindAddress() {
30
+ let ipv4 = _vscode.workspace.getConfiguration().get(_config.KEY_SERVER_BIND_ADDRESS);
31
+ if (!ipv4) {
32
+ ipv4 = _util.getIpv4Address(pattern);
33
+ } else {
34
+ if (!_util.ipv4IsValid(ipv4)) {
35
+ throw new Error("Invalid IP address, no interface found with address " + ipv4 + ".");
36
+ }
37
+ }
38
+ return ipv4;
39
+ }
40
+ `
41
+
42
+ /** Build a fake YonCode install whose bundle holds `text`. */
43
+ function fakeInstall(text) {
44
+ const home = mkdtempSync(join(tmpdir(), 'yoncode-'))
45
+ const file = join(home, YONCODE_EXTENSION_RELATIVE)
46
+ mkdirSync(join(home, 'resources/app/extensions/yonbuilder-development-studio-core/dist'), { recursive: true })
47
+ writeFileSync(file, text)
48
+ return { home, file }
49
+ }
50
+
51
+ test('an unpatched bundle is detected as unpatched and reported as a problem', () => {
52
+ const { home } = fakeInstall(SHIPPED)
53
+ try {
54
+ const detected = detectYoncode({ yoncodeHome: home })
55
+ assert.equal(detected.state, 'unpatched')
56
+ assert.match(yoncodeWarning(detected), /YonCode/)
57
+ } finally {
58
+ rmSync(home, { recursive: true, force: true })
59
+ }
60
+ })
61
+
62
+ test('patch turns the throw into a warning, keeps a backup, and is idempotent', () => {
63
+ const { home, file } = fakeInstall(SHIPPED)
64
+ try {
65
+ const first = patchYoncode(detectYoncode({ yoncodeHome: home }))
66
+ assert.equal(first.ok, true)
67
+ assert.equal(first.changed, true)
68
+ const patched = readFileSync(file, 'utf8')
69
+ assert.match(patched, /yds-patch/)
70
+ assert.doesNotMatch(patched, /throw new Error\("Invalid IP address/)
71
+ assert.equal(existsSync(`${file}.bak`), true, 'the original must be recoverable')
72
+ assert.equal(readFileSync(`${file}.bak`, 'utf8'), SHIPPED)
73
+
74
+ const second = patchYoncode(detectYoncode({ yoncodeHome: home }))
75
+ assert.equal(second.ok, true)
76
+ assert.equal(second.changed, false, 'patching twice must be a no-op')
77
+
78
+ const detected = detectYoncode({ yoncodeHome: home })
79
+ assert.equal(detected.state, 'patched')
80
+ assert.equal(yoncodeWarning(detected), null, 'no warning once patched')
81
+ } finally {
82
+ rmSync(home, { recursive: true, force: true })
83
+ }
84
+ })
85
+
86
+ test('restore puts the shipped file back', () => {
87
+ const { home, file } = fakeInstall(SHIPPED)
88
+ try {
89
+ patchYoncode(detectYoncode({ yoncodeHome: home }))
90
+ const restored = restoreYoncode(detectYoncode({ yoncodeHome: home }))
91
+ assert.equal(restored.ok, true)
92
+ assert.equal(readFileSync(file, 'utf8'), SHIPPED)
93
+ assert.equal(detectYoncode({ yoncodeHome: home }).state, 'unpatched')
94
+ } finally {
95
+ rmSync(home, { recursive: true, force: true })
96
+ }
97
+ })
98
+
99
+ test('an unknown bundle shape is left alone instead of guessed at', () => {
100
+ const { home, file } = fakeInstall('function somethingElse() { return 1 }\n')
101
+ try {
102
+ const detected = detectYoncode({ yoncodeHome: home })
103
+ assert.equal(detected.state, 'unrecognised')
104
+ const result = patchYoncode(detected)
105
+ assert.equal(result.ok, false)
106
+ assert.equal(readFileSync(file, 'utf8'), 'function somethingElse() { return 1 }\n')
107
+ } finally {
108
+ rmSync(home, { recursive: true, force: true })
109
+ }
110
+ })
111
+
112
+ test('no installation is reported as absent, not as an error', () => {
113
+ const detected = detectYoncode({ yoncodeHome: join(tmpdir(), 'definitely-not-installed-xyz') })
114
+ assert.equal(detected.found, false)
115
+ assert.equal(detected.state, 'absent')
116
+ assert.equal(yoncodeWarning(detected), null)
117
+ })
118
+
119
+ test('the JVM SOCKS flags are appended to the YMS launch arguments', () => {
120
+ const { home, file } = fakeInstall(SHIPPED_WITH_VMARGS)
121
+ try {
122
+ const socks = { host: '10.3.91.121', port: 1080 }
123
+ const first = patchYoncode(detectYoncode({ yoncodeHome: home }), { socks })
124
+ assert.equal(first.ok, true)
125
+ assert.equal(first.changed, true)
126
+ assert.equal(first.socksState, 'patched')
127
+ const patched = readFileSync(file, 'utf8')
128
+ assert.match(patched, /-Dserver\.port=\$\{config:yds\.serverPort\} -DsocksProxyHost=10\.3\.91\.121 -DsocksProxyPort=1080/)
129
+ assert.match(patched, /yds-patch/, 'the NIC patch lands in the same write')
130
+
131
+ const second = patchYoncode(detectYoncode({ yoncodeHome: home }), { socks })
132
+ assert.equal(second.changed, false, 're-patching must not stack flags')
133
+ assert.equal(detectYoncode({ yoncodeHome: home }).socksState, 'patched')
134
+
135
+ const moved = patchYoncode(detectYoncode({ yoncodeHome: home }), { socks: { host: '10.0.0.9', port: 7890 } })
136
+ assert.equal(moved.changed, true, 'a different SOCKS server replaces the old flags')
137
+ const replaced = readFileSync(file, 'utf8')
138
+ assert.equal(replaced.includes('10.0.0.9:'), false)
139
+ assert.match(replaced, /-DsocksProxyHost=10\.0\.0\.9 -DsocksProxyPort=7890/)
140
+ assert.equal((replaced.match(/-DsocksProxyHost/g) ?? []).length, 1)
141
+
142
+ restoreYoncode(detectYoncode({ yoncodeHome: home }))
143
+ assert.equal(readFileSync(file, 'utf8'), SHIPPED_WITH_VMARGS, 'restore also drops the JVM flags')
144
+ } finally {
145
+ rmSync(home, { recursive: true, force: true })
146
+ }
147
+ })
148
+
149
+ test('a bundle without the vmArgs template reports why the JVM flags were skipped', () => {
150
+ const { home } = fakeInstall(SHIPPED)
151
+ try {
152
+ const r = patchYoncode(detectYoncode({ yoncodeHome: home }), { socks: { host: '10.3.91.121', port: 1080 } })
153
+ assert.equal(r.ok, false)
154
+ assert.equal(r.socksState, 'unrecognised')
155
+ assert.match(r.error, /启动参数模板/)
156
+ } finally {
157
+ rmSync(home, { recursive: true, force: true })
158
+ }
159
+ })