pi-cursor-sdk 0.1.62 → 0.3.6

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 (279) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +57 -53
  3. package/dist/bundled-context-windows.js +39 -0
  4. package/dist/context-window-cache.js +92 -0
  5. package/dist/context.js +338 -0
  6. package/dist/cursor-active-tools.js +3 -0
  7. package/dist/cursor-agent-message-web-tools.js +165 -0
  8. package/dist/cursor-agents-context-registration.js +17 -0
  9. package/dist/cursor-agents-context.js +113 -0
  10. package/dist/cursor-api-key.js +34 -0
  11. package/dist/cursor-bridge-contract.js +27 -0
  12. package/dist/cursor-cloud-lifecycle.js +650 -0
  13. package/dist/cursor-cloud-local-state.js +460 -0
  14. package/dist/cursor-cloud-options.js +145 -0
  15. package/dist/cursor-cloud-reporting.js +222 -0
  16. package/dist/cursor-compact-tool-summary.js +75 -0
  17. package/dist/cursor-config.js +613 -0
  18. package/dist/cursor-context-tools.js +4 -0
  19. package/dist/cursor-display-only-trace.js +11 -0
  20. package/dist/cursor-display-text.js +18 -0
  21. package/dist/cursor-durable-fs.js +53 -0
  22. package/dist/cursor-edit-diff.js +13 -0
  23. package/dist/cursor-env-boolean.js +19 -0
  24. package/dist/cursor-fallback-models.generated.js +7760 -0
  25. package/dist/cursor-fallback-warning.js +15 -0
  26. package/dist/cursor-http1.js +45 -0
  27. package/dist/cursor-incomplete-tool-visibility.js +83 -0
  28. package/dist/cursor-live-run-accounting.js +55 -0
  29. package/dist/cursor-live-run-coordinator.js +406 -0
  30. package/dist/cursor-mcp-timeout-override.js +116 -0
  31. package/dist/cursor-model-lifecycle.js +32 -0
  32. package/dist/cursor-model.js +5 -0
  33. package/dist/cursor-native-replay-routing.js +35 -0
  34. package/dist/cursor-native-replay-trace.js +28 -0
  35. package/dist/cursor-native-tool-display-registration.js +102 -0
  36. package/dist/cursor-native-tool-display-replay.js +428 -0
  37. package/dist/cursor-native-tool-display-state.js +70 -0
  38. package/dist/cursor-native-tool-display-tools.js +123 -0
  39. package/dist/cursor-native-tool-names.js +11 -0
  40. package/dist/cursor-partial-content-emitter.js +118 -0
  41. package/dist/cursor-pi-tool-bridge-abort.js +114 -0
  42. package/dist/cursor-pi-tool-bridge-constants.js +6 -0
  43. package/dist/cursor-pi-tool-bridge-diagnostics.js +125 -0
  44. package/dist/cursor-pi-tool-bridge-env.js +18 -0
  45. package/dist/cursor-pi-tool-bridge-mcp.js +100 -0
  46. package/dist/cursor-pi-tool-bridge-run.js +355 -0
  47. package/dist/cursor-pi-tool-bridge-server.js +163 -0
  48. package/dist/cursor-pi-tool-bridge-snapshot.js +63 -0
  49. package/dist/cursor-pi-tool-bridge-types.js +1 -0
  50. package/dist/cursor-pi-tool-bridge.js +123 -0
  51. package/dist/cursor-provider-errors.js +311 -0
  52. package/dist/cursor-provider-lazy.js +39 -0
  53. package/dist/cursor-provider-live-run-drain.js +412 -0
  54. package/dist/cursor-provider-overflow.js +90 -0
  55. package/dist/cursor-provider-run-finalizer.js +176 -0
  56. package/dist/cursor-provider-run-outcome.js +76 -0
  57. package/dist/cursor-provider-turn-coordinator.js +275 -0
  58. package/dist/cursor-provider-turn-display-router.js +158 -0
  59. package/dist/cursor-provider-turn-emit.js +35 -0
  60. package/dist/cursor-provider-turn-finalize.js +154 -0
  61. package/dist/cursor-provider-turn-lifecycle-emitter.js +126 -0
  62. package/dist/cursor-provider-turn-prepare.js +374 -0
  63. package/dist/cursor-provider-turn-runner.js +146 -0
  64. package/dist/cursor-provider-turn-sdk-normalizer.js +74 -0
  65. package/dist/cursor-provider-turn-send.js +138 -0
  66. package/dist/cursor-provider-turn-shell-output.js +117 -0
  67. package/dist/cursor-provider-turn-tool-ledger.js +99 -0
  68. package/dist/cursor-provider-turn-types.js +1 -0
  69. package/dist/cursor-provider.js +72 -0
  70. package/dist/cursor-question-tool.js +194 -0
  71. package/dist/cursor-record-utils.js +61 -0
  72. package/dist/cursor-replay-activity-builders.js +114 -0
  73. package/dist/cursor-replay-source-names.js +27 -0
  74. package/dist/cursor-replay-summary-args.js +105 -0
  75. package/dist/cursor-replay-tool-details.js +167 -0
  76. package/dist/cursor-ripgrep-path.js +27 -0
  77. package/dist/cursor-run-final-text.js +63 -0
  78. package/dist/cursor-runtime-state.js +380 -0
  79. package/dist/cursor-sdk-billed-usage.js +86 -0
  80. package/dist/cursor-sdk-event-debug-constants.js +33 -0
  81. package/dist/cursor-sdk-event-debug-session.js +107 -0
  82. package/dist/cursor-sdk-event-debug.js +461 -0
  83. package/dist/cursor-sdk-output-filter.js +1 -0
  84. package/dist/cursor-sdk-process-error-guard.js +221 -0
  85. package/dist/cursor-sdk-runtime.js +3 -0
  86. package/dist/cursor-sensitive-text.js +23 -0
  87. package/dist/cursor-session-agent-cleanup.js +311 -0
  88. package/dist/cursor-session-agent-lifecycle.js +32 -0
  89. package/dist/cursor-session-agent-lineage.js +103 -0
  90. package/dist/cursor-session-agent-resume.js +417 -0
  91. package/dist/cursor-session-agent.js +507 -0
  92. package/dist/cursor-session-compaction-prep.js +21 -0
  93. package/dist/cursor-session-scope.js +113 -0
  94. package/dist/cursor-session-send-policy.js +18 -0
  95. package/dist/cursor-session-store.js +105 -0
  96. package/dist/cursor-session-turn-queue.js +50 -0
  97. package/dist/cursor-setting-sources.js +15 -0
  98. package/dist/cursor-skill-tool.js +230 -0
  99. package/dist/cursor-state.js +519 -0
  100. package/dist/cursor-task-presentation.js +59 -0
  101. package/dist/cursor-tool-lifecycle.js +94 -0
  102. package/dist/cursor-tool-manifest.js +34 -0
  103. package/dist/cursor-tool-presentation-registry.js +305 -0
  104. package/dist/cursor-tool-result-display-readers.js +158 -0
  105. package/dist/cursor-tool-transcript.js +32 -0
  106. package/dist/cursor-tool-visibility.js +28 -0
  107. package/dist/cursor-transcript-tool-formatters.js +618 -0
  108. package/dist/cursor-transcript-tool-specs.js +284 -0
  109. package/dist/cursor-transcript-utils.js +170 -0
  110. package/dist/cursor-usage-accounting.js +166 -0
  111. package/dist/cursor-web-tool-activity.js +23 -0
  112. package/dist/cursor-web-tool-args.js +12 -0
  113. package/dist/index.js +82 -0
  114. package/dist/model-discovery.js +305 -0
  115. package/dist/model-list-cache.js +156 -0
  116. package/docs/cursor-dogfood-checklist.md +2 -1
  117. package/docs/cursor-live-smoke-checklist.md +15 -14
  118. package/docs/cursor-model-ux-spec.md +29 -8
  119. package/docs/cursor-native-tool-replay.md +13 -13
  120. package/docs/cursor-native-tool-visual-audit.md +6 -3
  121. package/docs/cursor-testing-lessons.md +7 -7
  122. package/docs/cursor-tool-surfaces.md +5 -5
  123. package/docs/platform-smoke.md +6 -6
  124. package/node_modules/fast-uri/index.js +37 -1
  125. package/node_modules/fast-uri/package.json +1 -1
  126. package/node_modules/fast-uri/test/security.test.js +136 -0
  127. package/node_modules/hono/dist/cjs/context.js +28 -13
  128. package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
  129. package/node_modules/hono/dist/cjs/helper/streaming/sse.js +1 -1
  130. package/node_modules/hono/dist/cjs/hono-base.js +3 -2
  131. package/node_modules/hono/dist/cjs/jsx/base.js +27 -23
  132. package/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
  133. package/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
  134. package/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
  135. package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -2
  136. package/node_modules/hono/dist/cjs/middleware/etag/index.js +1 -1
  137. package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
  138. package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
  139. package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
  140. package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
  141. package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
  142. package/node_modules/hono/dist/cjs/request.js +7 -9
  143. package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +55 -56
  144. package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +64 -85
  145. package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +13 -5
  146. package/node_modules/hono/dist/cjs/router.js +1 -1
  147. package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
  148. package/node_modules/hono/dist/cjs/utils/cookie.js +3 -2
  149. package/node_modules/hono/dist/cjs/utils/url.js +8 -8
  150. package/node_modules/hono/dist/context.js +28 -13
  151. package/node_modules/hono/dist/helper/proxy/index.js +4 -0
  152. package/node_modules/hono/dist/helper/streaming/sse.js +1 -1
  153. package/node_modules/hono/dist/hono-base.js +3 -2
  154. package/node_modules/hono/dist/jsx/base.js +27 -23
  155. package/node_modules/hono/dist/jsx/hooks/index.js +16 -13
  156. package/node_modules/hono/dist/middleware/cache/index.js +103 -8
  157. package/node_modules/hono/dist/middleware/compress/index.js +5 -0
  158. package/node_modules/hono/dist/middleware/cors/index.js +2 -2
  159. package/node_modules/hono/dist/middleware/etag/index.js +1 -1
  160. package/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
  161. package/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
  162. package/node_modules/hono/dist/middleware/language/language.js +10 -6
  163. package/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
  164. package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
  165. package/node_modules/hono/dist/request.js +8 -10
  166. package/node_modules/hono/dist/router/reg-exp-router/node.js +55 -56
  167. package/node_modules/hono/dist/router/reg-exp-router/router.js +64 -85
  168. package/node_modules/hono/dist/router/reg-exp-router/trie.js +13 -5
  169. package/node_modules/hono/dist/router.js +1 -1
  170. package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
  171. package/node_modules/hono/dist/types/client/types.d.ts +1 -1
  172. package/node_modules/hono/dist/types/hono-base.d.ts +4 -3
  173. package/node_modules/hono/dist/types/jsx/base.d.ts +4 -2
  174. package/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
  175. package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
  176. package/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
  177. package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
  178. package/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
  179. package/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
  180. package/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
  181. package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
  182. package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
  183. package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
  184. package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
  185. package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +1 -1
  186. package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
  187. package/node_modules/hono/dist/types/router.d.ts +1 -1
  188. package/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
  189. package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
  190. package/node_modules/hono/dist/utils/accept.js +1 -1
  191. package/node_modules/hono/dist/utils/cookie.js +4 -3
  192. package/node_modules/hono/dist/utils/url.js +6 -7
  193. package/node_modules/hono/package.json +10 -3
  194. package/node_modules/ip-address/README.md +146 -126
  195. package/node_modules/ip-address/dist/common.d.ts +29 -0
  196. package/node_modules/ip-address/dist/common.js +44 -5
  197. package/node_modules/ip-address/dist/common.js.map +1 -1
  198. package/node_modules/ip-address/dist/ipv4.d.ts +8 -1
  199. package/node_modules/ip-address/dist/ipv4.js +24 -20
  200. package/node_modules/ip-address/dist/ipv4.js.map +1 -1
  201. package/node_modules/ip-address/dist/ipv6.d.ts +68 -3
  202. package/node_modules/ip-address/dist/ipv6.js +180 -53
  203. package/node_modules/ip-address/dist/ipv6.js.map +1 -1
  204. package/node_modules/ip-address/dist/v4/constants.js +5 -1
  205. package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
  206. package/node_modules/ip-address/dist/v6/constants.js +3 -2
  207. package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
  208. package/node_modules/ip-address/package.json +6 -4
  209. package/package.json +23 -11
  210. package/platform-smoke.config.mjs +1 -1
  211. package/scripts/build.mjs +126 -0
  212. package/scripts/cloud-runtime-smoke.mjs +3 -1
  213. package/scripts/debug-provider-events.mjs +3 -1
  214. package/scripts/debug-sdk-events.mjs +1 -1
  215. package/scripts/isolated-cursor-smoke.sh +5 -4
  216. package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +1 -1
  217. package/scripts/lib/cursor-visual-render.mjs +1 -1
  218. package/scripts/lib/ensure-built.mjs +16 -0
  219. package/scripts/lib/local-resume-smoke-harness.mjs +1 -1
  220. package/scripts/local-resume-smoke.mjs +3 -1
  221. package/scripts/platform-smoke/card-detect.mjs +1 -1
  222. package/scripts/platform-smoke/live-suite-runner.mjs +16 -40
  223. package/scripts/platform-smoke/platform-build-windows.ps1 +1 -1
  224. package/scripts/platform-smoke/render-ansi.mjs +1 -1
  225. package/scripts/platform-smoke/scenarios.mjs +1 -1
  226. package/scripts/platform-smoke/targets.mjs +2 -2
  227. package/scripts/platform-smoke.mjs +5 -5
  228. package/scripts/prepare.mjs +102 -0
  229. package/scripts/refresh-cursor-model-snapshots.mjs +16 -7
  230. package/scripts/steering-rpc-smoke.mjs +4 -2
  231. package/scripts/tmux-live-smoke.sh +11 -11
  232. package/scripts/visual-tui-smoke-self-test.mjs +4 -1
  233. package/scripts/visual-tui-smoke.mjs +51 -7
  234. package/shared/cursor-model-selection-identities.d.mts +21 -0
  235. package/shared/cursor-model-selection-identities.mjs +95 -0
  236. package/src/bundled-context-windows.ts +21 -12
  237. package/src/context.ts +1 -1
  238. package/src/cursor-agents-context-registration.ts +2 -2
  239. package/src/cursor-agents-context.ts +0 -2
  240. package/src/cursor-api-key.ts +5 -4
  241. package/src/cursor-cloud-reporting.ts +23 -2
  242. package/src/cursor-context-tools.ts +1 -1
  243. package/src/cursor-display-only-trace.ts +1 -1
  244. package/src/cursor-fallback-models.generated.ts +1726 -824
  245. package/src/cursor-live-run-accounting.ts +1 -1
  246. package/src/cursor-live-run-coordinator.ts +2 -1
  247. package/src/cursor-native-replay-routing.ts +1 -1
  248. package/src/cursor-native-tool-display-registration.ts +10 -11
  249. package/src/cursor-partial-content-emitter.ts +1 -1
  250. package/src/cursor-pi-tool-bridge-mcp.ts +1 -1
  251. package/src/cursor-pi-tool-bridge-run.ts +1 -1
  252. package/src/cursor-pi-tool-bridge-types.ts +1 -1
  253. package/src/cursor-provider-errors.ts +1 -1
  254. package/src/cursor-provider-lazy.ts +6 -5
  255. package/src/cursor-provider-live-run-drain.ts +2 -1
  256. package/src/cursor-provider-overflow.ts +1 -1
  257. package/src/cursor-provider-run-finalizer.ts +2 -1
  258. package/src/cursor-provider-turn-coordinator.ts +1 -1
  259. package/src/cursor-provider-turn-finalize.ts +12 -0
  260. package/src/cursor-provider-turn-lifecycle-emitter.ts +1 -1
  261. package/src/cursor-provider-turn-prepare.ts +1 -1
  262. package/src/cursor-provider-turn-types.ts +3 -1
  263. package/src/cursor-provider.ts +1 -1
  264. package/src/cursor-run-final-text.ts +1 -1
  265. package/src/cursor-sdk-billed-usage.ts +107 -0
  266. package/src/cursor-sdk-event-debug.ts +1 -1
  267. package/src/cursor-sdk-process-error-guard.ts +6 -4
  268. package/src/cursor-session-agent-lifecycle.ts +8 -9
  269. package/src/cursor-session-agent-resume.ts +23 -0
  270. package/src/cursor-session-agent.ts +1 -1
  271. package/src/cursor-session-compaction-prep.ts +4 -0
  272. package/src/cursor-session-send-policy.ts +1 -1
  273. package/src/cursor-tool-manifest.ts +1 -1
  274. package/src/cursor-usage-accounting.ts +71 -10
  275. package/src/index.ts +1 -1
  276. package/src/model-discovery.ts +32 -89
  277. package/tsconfig.build.json +8 -0
  278. package/tsconfig.json +16 -0
  279. package/node_modules/cross-spawn/node_modules/which/CHANGELOG.md +0 -166
@@ -73,7 +73,6 @@ function paddedHex(octet) {
73
73
  return parseInt(octet, 16).toString(16).padStart(4, '0');
74
74
  }
75
75
  function unsignByte(b) {
76
- // eslint-disable-next-line no-bitwise
77
76
  return b & 0xff;
78
77
  }
79
78
  /**
@@ -97,6 +96,13 @@ class Address6 {
97
96
  * @returns {boolean}
98
97
  */
99
98
  this.isInSubnet = common.isInSubnet;
99
+ /**
100
+ * Returns true if this address's host bits fall inside the given subnet,
101
+ * ignoring this address's own subnet mask. See
102
+ * {@link common.isHostInSubnet}.
103
+ * @returns {boolean}
104
+ */
105
+ this.isHostInSubnet = common.isHostInSubnet;
100
106
  /**
101
107
  * Returns true if the address is correct, false otherwise
102
108
  * @returns {boolean}
@@ -121,7 +127,10 @@ class Address6 {
121
127
  }
122
128
  address = address.replace(constants6.RE_SUBNET_STRING, '');
123
129
  }
124
- else if (/\//.test(address)) {
130
+ // RE_SUBNET_STRING anchors on the end of the address, so it strips only
131
+ // the trailing suffix. A second one left behind (`::/0/1`) is malformed
132
+ // and must be rejected rather than parsed as an address group.
133
+ if (/\//.test(address)) {
125
134
  throw new address_error_1.AddressError('Invalid subnet mask.');
126
135
  }
127
136
  const zone = constants6.RE_ZONE_STRING.exec(address);
@@ -145,7 +154,7 @@ class Address6 {
145
154
  new Address6(address);
146
155
  return true;
147
156
  }
148
- catch (e) {
157
+ catch {
149
158
  return false;
150
159
  }
151
160
  }
@@ -160,7 +169,7 @@ class Address6 {
160
169
  * address.correctForm(); // '::e8:d4a5:1000'
161
170
  */
162
171
  static fromBigInt(bigInt) {
163
- if (bigInt < 0n || bigInt > (1n << BigInt(constants6.BITS)) - 1n) {
172
+ if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) {
164
173
  throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1');
165
174
  }
166
175
  const hex = bigInt.toString(16).padStart(32, '0');
@@ -181,12 +190,15 @@ class Address6 {
181
190
  * addressAndPort.port; // 8080
182
191
  */
183
192
  static fromURL(url) {
193
+ var _a;
184
194
  let host;
185
195
  let port = null;
186
196
  let result;
197
+ // Remove the protocol prefix, if any
198
+ const stripped = url.replace(/^[a-z][a-z0-9+.-]*:\/\//i, '');
187
199
  // If we have brackets parse them and find a port
188
- if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) {
189
- result = constants6.RE_URL_WITH_PORT.exec(url);
200
+ if (stripped.indexOf('[') !== -1 && stripped.indexOf(']:') !== -1) {
201
+ result = constants6.RE_URL_WITH_PORT.exec(stripped);
190
202
  if (result === null) {
191
203
  return {
192
204
  error: 'failed to parse address with port',
@@ -196,13 +208,9 @@ class Address6 {
196
208
  }
197
209
  host = result[1];
198
210
  port = result[2];
199
- // If there's a URL extract the address
200
211
  }
201
- else if (url.indexOf('/') !== -1) {
202
- // Remove the protocol prefix
203
- url = url.replace(/^[a-z0-9]+:\/\//, '');
204
- // Parse the address
205
- result = constants6.RE_URL.exec(url);
212
+ else {
213
+ result = constants6.RE_URL.exec(stripped);
206
214
  if (result === null) {
207
215
  return {
208
216
  error: 'failed to parse address from URL',
@@ -210,17 +218,13 @@ class Address6 {
210
218
  port: null,
211
219
  };
212
220
  }
213
- host = result[1];
214
- // Otherwise just assign the URL to the host and let the library parse it
215
- }
216
- else {
217
- host = url;
221
+ host = (_a = result[1]) !== null && _a !== void 0 ? _a : result[2];
218
222
  }
219
223
  // If there's a port convert it to an integer
220
224
  if (port) {
221
225
  port = parseInt(port, 10);
222
- // squelch out of range ports
223
- if (port < 0 || port > 65536) {
226
+ // squelch out of range ports (valid ports are 0-65535)
227
+ if (port < 0 || port > 65535) {
224
228
  port = null;
225
229
  }
226
230
  }
@@ -258,7 +262,6 @@ class Address6 {
258
262
  static fromAddressAndWildcardMask(address, wildcardMask) {
259
263
  const wildcard = new Address6(wildcardMask).bigInt();
260
264
  const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1);
261
- // eslint-disable-next-line no-bitwise
262
265
  const mask = wildcard ^ allOnes;
263
266
  const bits = common.prefixLengthFromMask(mask, constants6.BITS);
264
267
  return new Address6(`${address}/${bits}`);
@@ -493,7 +496,7 @@ class Address6 {
493
496
  getType() {
494
497
  for (let i = 0; i < TYPE_SUBNETS.length; i++) {
495
498
  const entry = TYPE_SUBNETS[i];
496
- if (this.isInSubnet(entry[0])) {
499
+ if (this.isHostInSubnet(entry[0])) {
497
500
  return entry[1];
498
501
  }
499
502
  }
@@ -635,20 +638,27 @@ class Address6 {
635
638
  }
636
639
  const groups = address.split(':');
637
640
  const lastGroup = groups.slice(-1)[0];
641
+ // RE_ADDRESS rejects octets with a leading zero, so a dotted-quad tail is
642
+ // matched permissively first: that way this notation still gets its own
643
+ // message with the offending octet highlighted, rather than falling
644
+ // through as an unrecognized group.
645
+ const v4Octets = lastGroup.split('.');
646
+ if (v4Octets.length === constants4.GROUPS &&
647
+ v4Octets.every((octet) => /^\d{1,3}$/.test(octet))) {
648
+ if (v4Octets.some((octet) => /^0\d/.test(octet))) {
649
+ // The prefix groups haven't been through the bad-character check
650
+ // yet, so escape them before including in the error HTML.
651
+ const highlighted = v4Octets.map(spanLeadingZeroes4).join('.');
652
+ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');
653
+ const separator = groups.length > 1 ? ':' : '';
654
+ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
655
+ }
656
+ }
638
657
  const address4 = lastGroup.match(constants4.RE_ADDRESS);
639
658
  if (address4) {
640
659
  this.parsedAddress4 = address4[0];
641
- this.address4 = new ipv4_1.Address4(this.parsedAddress4);
642
- for (let i = 0; i < this.address4.groups; i++) {
643
- if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) {
644
- // The prefix groups haven't been through the bad-character check
645
- // yet, so escape them before including in the error HTML.
646
- const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.');
647
- const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':');
648
- const separator = groups.length > 1 ? ':' : '';
649
- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`);
650
- }
651
- }
660
+ const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : '';
661
+ this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`);
652
662
  this.v4 = true;
653
663
  groups[groups.length - 1] = this.address4.toGroup6();
654
664
  address = groups.join(':');
@@ -734,7 +744,11 @@ class Address6 {
734
744
  return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`);
735
745
  }
736
746
  /**
737
- * Return the last two groups of this address as an IPv4 address string
747
+ * Return the last two groups of this address as an IPv4 address string.
748
+ * If this address carries a CIDR prefix that covers the trailing 32 bits
749
+ * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the
750
+ * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to
751
+ * `/32`.
738
752
  * @returns {Address4}
739
753
  * @example
740
754
  * var address = new Address6('2001:4860:4001::1825:bf11');
@@ -742,7 +756,18 @@ class Address6 {
742
756
  */
743
757
  to4() {
744
758
  const binary = this.binaryZeroPad().split('');
745
- return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16).padStart(8, '0'));
759
+ const hex = BigInt(`0b${binary.slice(96, 128).join('')}`)
760
+ .toString(16)
761
+ .padStart(8, '0');
762
+ if (this.subnetMask >= 96) {
763
+ const v4Mask = this.subnetMask - 96;
764
+ const groups = [];
765
+ for (let i = 0; i < 8; i += 2) {
766
+ groups.push(parseInt(hex.slice(i, i + 2), 16));
767
+ }
768
+ return new ipv4_1.Address4(`${groups.join('.')}/${v4Mask}`);
769
+ }
770
+ return ipv4_1.Address4.fromHex(hex);
746
771
  }
747
772
  /**
748
773
  * Return the v4-in-v6 form of the address
@@ -756,7 +781,7 @@ class Address6 {
756
781
  if (!/:$/.test(correct)) {
757
782
  infix = ':';
758
783
  }
759
- return correct + infix + address4.address;
784
+ return correct + infix + address4.correctForm();
760
785
  }
761
786
  /**
762
787
  * Decodes the Teredo tunneling fields embedded in this address. Returns the
@@ -788,11 +813,9 @@ class Address6 {
788
813
  */
789
814
  const prefix = this.getBitsBase16(0, 32);
790
815
  const bitsForUdpPort = this.getBits(80, 96);
791
- // eslint-disable-next-line no-bitwise
792
816
  const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString();
793
817
  const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64));
794
818
  const bitsForClient4 = this.getBits(96, 128);
795
- // eslint-disable-next-line no-bitwise
796
819
  const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0'));
797
820
  const flagsBase2 = this.getBitsBase2(64, 80);
798
821
  const coneNat = (0, common_1.testBit)(flagsBase2, 15);
@@ -874,12 +897,14 @@ class Address6 {
874
897
  }
875
898
  else {
876
899
  const beforeU = 64 - pl;
877
- bits =
878
- prefixBits.slice(0, pl) +
879
- v4Bits.slice(0, beforeU) +
880
- '00000000' +
881
- v4Bits.slice(beforeU) +
882
- '0'.repeat(128 - 72 - (32 - beforeU));
900
+ bits = [
901
+ prefixBits.slice(0, pl),
902
+ v4Bits.slice(0, beforeU),
903
+ // Bits 64 to 71 are the reserved u octet and are always zero.
904
+ '00000000',
905
+ v4Bits.slice(beforeU),
906
+ '0'.repeat(128 - 72 - (32 - beforeU)),
907
+ ].join('');
883
908
  }
884
909
  const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0');
885
910
  const groups = [];
@@ -902,7 +927,7 @@ class Address6 {
902
927
  if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) {
903
928
  throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96');
904
929
  }
905
- if (!this.isInSubnet(prefix6)) {
930
+ if (!this.isHostInSubnet(prefix6)) {
906
931
  return null;
907
932
  }
908
933
  const bits = this.binaryZeroPad();
@@ -927,9 +952,9 @@ class Address6 {
927
952
  * @returns {Array}
928
953
  */
929
954
  toByteArray() {
930
- const valueWithoutPadding = this.bigInt().toString(16);
931
- const leadingPad = '0'.repeat(valueWithoutPadding.length % 2);
932
- const value = `${leadingPad}${valueWithoutPadding}`;
955
+ const value = this.bigInt()
956
+ .toString(16)
957
+ .padStart(constants6.BITS / 4, '0');
933
958
  const bytes = [];
934
959
  for (let i = 0, length = value.length; i < length; i += 2) {
935
960
  bytes.push(parseInt(value.substring(i, i + 2), 16));
@@ -943,24 +968,39 @@ class Address6 {
943
968
  * @returns {Array}
944
969
  */
945
970
  toUnsignedByteArray() {
971
+ // toByteArray() emits 0 to 255, so unsigning it is an identity mapping and
972
+ // the two methods return equal arrays. 11.0.0 keeps one of them and makes
973
+ // this a deprecated alias; test/common-test.ts fails at that version.
946
974
  return this.toByteArray().map(unsignByte);
947
975
  }
948
976
  /**
949
977
  * Convert a byte array to an Address6 object.
950
978
  *
979
+ * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an
980
+ * `Int8Array` or a Java `byte[]` holds them), folding signed values to their
981
+ * unsigned equivalent. Throws `AddressError` unless given exactly 16
982
+ * integers from -128 to 255.
983
+ *
951
984
  * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`.
952
985
  * @returns {Address6}
953
986
  */
954
987
  static fromByteArray(bytes) {
988
+ // Address4.fromByteArray takes unsigned bytes only. 11.0.0 aligns this
989
+ // method with it, at which point the -128 floor here, unsignByte, and the
990
+ // mapping below all go; test/common-test.ts fails at that version.
991
+ common.assertByteArray(bytes, 16, 'IPv6', -128);
955
992
  return this.fromUnsignedByteArray(bytes.map(unsignByte));
956
993
  }
957
994
  /**
958
995
  * Convert an unsigned byte array to an Address6 object.
959
996
  *
997
+ * Throws `AddressError` unless given exactly 16 integers from 0 to 255.
998
+ *
960
999
  * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`.
961
1000
  * @returns {Address6}
962
1001
  */
963
1002
  static fromUnsignedByteArray(bytes) {
1003
+ common.assertByteArray(bytes, 16, 'IPv6', 0);
964
1004
  const BYTE_MAX = BigInt('256');
965
1005
  let result = BigInt('0');
966
1006
  let multiplier = BigInt('1');
@@ -982,7 +1022,11 @@ class Address6 {
982
1022
  * @returns {boolean}
983
1023
  */
984
1024
  isLinkLocal() {
985
- // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10'
1025
+ const embedded = this.embeddedIPv4();
1026
+ if (embedded) {
1027
+ return embedded.isLinkLocal();
1028
+ }
1029
+ // Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10'
986
1030
  if (this.getBitsBase2(0, 64) ===
987
1031
  '1111111010000000000000000000000000000000000000000000000000000000') {
988
1032
  return true;
@@ -994,6 +1038,10 @@ class Address6 {
994
1038
  * @returns {boolean}
995
1039
  */
996
1040
  isMulticast() {
1041
+ const embedded = this.embeddedIPv4();
1042
+ if (embedded) {
1043
+ return embedded.isMulticast();
1044
+ }
997
1045
  const type = this.getType();
998
1046
  return type === 'Multicast' || type.startsWith('Multicast ');
999
1047
  }
@@ -1016,27 +1064,54 @@ class Address6 {
1016
1064
  * @returns {boolean}
1017
1065
  */
1018
1066
  isMapped4() {
1019
- return this.isInSubnet(IPV4_MAPPED_SUBNET);
1067
+ return this.isHostInSubnet(IPV4_MAPPED_SUBNET);
1068
+ }
1069
+ /**
1070
+ * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped
1071
+ * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`,
1072
+ * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that
1073
+ * embedded address as an {@link Address4}; otherwise return null.
1074
+ *
1075
+ * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`,
1076
+ * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and
1077
+ * delegate to the embedded {@link Address4} when present, so a literal such as
1078
+ * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback)
1079
+ * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped).
1080
+ * This matters wherever the checks back a trust-boundary decision (e.g. an
1081
+ * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`,
1082
+ * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as
1083
+ * non-internal.
1084
+ * @returns {Address4 | null}
1085
+ */
1086
+ embeddedIPv4() {
1087
+ if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) {
1088
+ return this.to4();
1089
+ }
1090
+ return null;
1020
1091
  }
1021
1092
  /**
1022
1093
  * Returns true if the address is a Teredo address, false otherwise
1023
1094
  * @returns {boolean}
1024
1095
  */
1025
1096
  isTeredo() {
1026
- return this.isInSubnet(TEREDO_SUBNET);
1097
+ return this.isHostInSubnet(TEREDO_SUBNET);
1027
1098
  }
1028
1099
  /**
1029
1100
  * Returns true if the address is a 6to4 address, false otherwise
1030
1101
  * @returns {boolean}
1031
1102
  */
1032
1103
  is6to4() {
1033
- return this.isInSubnet(SIX_TO_FOUR_SUBNET);
1104
+ return this.isHostInSubnet(SIX_TO_FOUR_SUBNET);
1034
1105
  }
1035
1106
  /**
1036
1107
  * Returns true if the address is a loopback address, false otherwise
1037
1108
  * @returns {boolean}
1038
1109
  */
1039
1110
  isLoopback() {
1111
+ const embedded = this.embeddedIPv4();
1112
+ if (embedded) {
1113
+ return embedded.isLoopback();
1114
+ }
1040
1115
  return this.getType() === 'Loopback';
1041
1116
  }
1042
1117
  /**
@@ -1044,13 +1119,64 @@ class Address6 {
1044
1119
  * @returns {boolean}
1045
1120
  */
1046
1121
  isULA() {
1047
- return this.isInSubnet(ULA_SUBNET);
1122
+ return this.isHostInSubnet(ULA_SUBNET);
1123
+ }
1124
+ /**
1125
+ * Returns true if the address is private, i.e. a Unique Local Address in
1126
+ * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)) or an
1127
+ * IPv4-mapped / NAT64 address whose embedded IPv4 address is in one of the
1128
+ * [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges
1129
+ * (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to
1130
+ * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to
1131
+ * catch mapped RFC 1918 addresses as well as native ULAs.
1132
+ * @returns {boolean}
1133
+ */
1134
+ isPrivate() {
1135
+ const embedded = this.embeddedIPv4();
1136
+ if (embedded) {
1137
+ return embedded.isPrivate();
1138
+ }
1139
+ return this.isULA();
1140
+ }
1141
+ /**
1142
+ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded
1143
+ * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10`
1144
+ * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false
1145
+ * otherwise. There is no native IPv6 CGNAT range, so this only ever returns
1146
+ * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`).
1147
+ * @returns {boolean}
1148
+ */
1149
+ isCGNAT() {
1150
+ const embedded = this.embeddedIPv4();
1151
+ if (embedded) {
1152
+ return embedded.isCGNAT();
1153
+ }
1154
+ return false;
1155
+ }
1156
+ /**
1157
+ * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded
1158
+ * IPv4 address is the limited broadcast address `255.255.255.255`
1159
+ * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise.
1160
+ * There is no IPv6 broadcast, so this only ever returns true for an embedded
1161
+ * IPv4 address (e.g. `::ffff:255.255.255.255`).
1162
+ * @returns {boolean}
1163
+ */
1164
+ isBroadcast() {
1165
+ const embedded = this.embeddedIPv4();
1166
+ if (embedded) {
1167
+ return embedded.isBroadcast();
1168
+ }
1169
+ return false;
1048
1170
  }
1049
1171
  /**
1050
1172
  * Returns true if the address is the unspecified address `::`.
1051
1173
  * @returns {boolean}
1052
1174
  */
1053
1175
  isUnspecified() {
1176
+ const embedded = this.embeddedIPv4();
1177
+ if (embedded) {
1178
+ return embedded.isUnspecified();
1179
+ }
1054
1180
  return this.getType() === 'Unspecified';
1055
1181
  }
1056
1182
  /**
@@ -1058,7 +1184,7 @@ class Address6 {
1058
1184
  * @returns {boolean}
1059
1185
  */
1060
1186
  isDocumentation() {
1061
- return this.isInSubnet(DOCUMENTATION_SUBNET);
1187
+ return this.isHostInSubnet(DOCUMENTATION_SUBNET);
1062
1188
  }
1063
1189
  // #endregion
1064
1190
  // #region HTML
@@ -1214,4 +1340,5 @@ const SIX_TO_FOUR_SUBNET = new Address6('2002::/16');
1214
1340
  const ULA_SUBNET = new Address6('fc00::/7');
1215
1341
  const DOCUMENTATION_SUBNET = new Address6('2001:db8::/32');
1216
1342
  const IPV4_MAPPED_SUBNET = new Address6('::ffff:0:0/96');
1343
+ const NAT64_WELL_KNOWN_SUBNET = new Address6('64:ff9b::/96');
1217
1344
  //# sourceMappingURL=ipv6.js.map