@honua/react 0.0.20-alpha.0 → 0.1.1-beta.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 (363) hide show
  1. package/contract/discovery.d.ts +231 -0
  2. package/contract/discovery.d.ts.map +1 -0
  3. package/contract/discovery.js +554 -0
  4. package/contract/edit-sketch.d.ts +8 -0
  5. package/contract/edit-sketch.d.ts.map +1 -1
  6. package/contract/edit-sketch.js +15 -0
  7. package/contract/edit-snapping.d.ts +160 -0
  8. package/contract/edit-snapping.d.ts.map +1 -0
  9. package/contract/edit-snapping.js +675 -0
  10. package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
  11. package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
  12. package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
  13. package/contract/index.d.ts +12 -1
  14. package/contract/index.d.ts.map +1 -1
  15. package/contract/index.js +4 -0
  16. package/contract/pmtiles.d.ts +193 -0
  17. package/contract/pmtiles.d.ts.map +1 -0
  18. package/contract/pmtiles.js +195 -0
  19. package/contract/protocol-module.d.ts +70 -0
  20. package/contract/protocol-module.d.ts.map +1 -0
  21. package/contract/protocol-module.js +1 -0
  22. package/contract/schema-envelope.d.ts +26 -0
  23. package/contract/schema-envelope.d.ts.map +1 -0
  24. package/contract/schema-envelope.js +25 -0
  25. package/contract/schema.d.ts +582 -0
  26. package/contract/schema.d.ts.map +1 -0
  27. package/contract/schema.js +2483 -0
  28. package/contract/source-capability-support.d.ts +6 -0
  29. package/contract/source-capability-support.d.ts.map +1 -0
  30. package/contract/source-capability-support.js +154 -0
  31. package/contract/source.d.ts +57 -15
  32. package/contract/source.d.ts.map +1 -1
  33. package/contract/source.js +368 -65
  34. package/contract/types.d.ts +171 -6
  35. package/contract/types.d.ts.map +1 -1
  36. package/contract/types.js +14 -14
  37. package/core/auth/client-credentials-provider.d.ts +51 -0
  38. package/core/auth/client-credentials-provider.d.ts.map +1 -0
  39. package/core/auth/client-credentials-provider.js +115 -0
  40. package/core/auth/credential-store.d.ts +52 -0
  41. package/core/auth/credential-store.d.ts.map +1 -0
  42. package/core/auth/credential-store.js +82 -0
  43. package/core/auth/index.d.ts +23 -0
  44. package/core/auth/index.d.ts.map +1 -0
  45. package/core/auth/index.js +20 -0
  46. package/core/auth/oauth2-provider.d.ts +114 -0
  47. package/core/auth/oauth2-provider.d.ts.map +1 -0
  48. package/core/auth/oauth2-provider.js +408 -0
  49. package/core/auth/pkce.d.ts +25 -0
  50. package/core/auth/pkce.d.ts.map +1 -0
  51. package/core/auth/pkce.js +46 -0
  52. package/core/auth/static-providers.d.ts +20 -0
  53. package/core/auth/static-providers.d.ts.map +1 -0
  54. package/core/auth/static-providers.js +26 -0
  55. package/core/auth/token-endpoint.d.ts +40 -0
  56. package/core/auth/token-endpoint.d.ts.map +1 -0
  57. package/core/auth/token-endpoint.js +133 -0
  58. package/core/auth/types.d.ts +144 -0
  59. package/core/auth/types.d.ts.map +1 -0
  60. package/core/auth/types.js +8 -0
  61. package/core/bounded-json.d.ts +4 -0
  62. package/core/bounded-json.d.ts.map +1 -0
  63. package/core/bounded-json.js +38 -0
  64. package/core/cache-state.d.ts +9 -0
  65. package/core/cache-state.d.ts.map +1 -1
  66. package/core/cache-state.js +10 -0
  67. package/core/capabilities-xml.d.ts +33 -0
  68. package/core/capabilities-xml.d.ts.map +1 -0
  69. package/core/capabilities-xml.js +331 -0
  70. package/core/client.d.ts +35 -2
  71. package/core/client.d.ts.map +1 -1
  72. package/core/client.js +167 -29
  73. package/core/error-classifications.d.ts +153 -0
  74. package/core/error-classifications.d.ts.map +1 -0
  75. package/core/error-classifications.js +140 -0
  76. package/core/error-code-registry.d.ts +158 -0
  77. package/core/error-code-registry.d.ts.map +1 -0
  78. package/core/error-code-registry.js +143 -0
  79. package/core/error-envelope.d.ts +68 -0
  80. package/core/error-envelope.d.ts.map +1 -0
  81. package/core/error-envelope.js +357 -0
  82. package/core/errors.d.ts +73 -25
  83. package/core/errors.d.ts.map +1 -1
  84. package/core/errors.js +113 -46
  85. package/core/geoparquet-sql.d.ts +190 -0
  86. package/core/geoparquet-sql.d.ts.map +1 -0
  87. package/core/geoparquet-sql.js +368 -0
  88. package/core/odata-key-path.d.ts +12 -0
  89. package/core/odata-key-path.d.ts.map +1 -0
  90. package/core/odata-key-path.js +28 -0
  91. package/core/odata-write-codec.d.ts +66 -0
  92. package/core/odata-write-codec.d.ts.map +1 -0
  93. package/core/odata-write-codec.js +1083 -0
  94. package/core/odata.d.ts +59 -7
  95. package/core/odata.d.ts.map +1 -1
  96. package/core/odata.js +431 -99
  97. package/core/ogc-endpoint-layout.d.ts +70 -0
  98. package/core/ogc-endpoint-layout.d.ts.map +1 -0
  99. package/core/ogc-endpoint-layout.js +173 -0
  100. package/core/ogc-features.d.ts.map +1 -1
  101. package/core/ogc-features.js +35 -17
  102. package/core/ogc-maps.d.ts +7 -0
  103. package/core/ogc-maps.d.ts.map +1 -1
  104. package/core/ogc-maps.js +46 -7
  105. package/core/ogc-processes.d.ts +2 -1
  106. package/core/ogc-processes.d.ts.map +1 -1
  107. package/core/ogc-processes.js +33 -5
  108. package/core/ogc-records.d.ts +9 -0
  109. package/core/ogc-records.d.ts.map +1 -1
  110. package/core/ogc-records.js +78 -29
  111. package/core/ogc-tiles.d.ts +10 -1
  112. package/core/ogc-tiles.d.ts.map +1 -1
  113. package/core/ogc-tiles.js +56 -17
  114. package/core/path-utils.d.ts +9 -0
  115. package/core/path-utils.d.ts.map +1 -1
  116. package/core/path-utils.js +19 -0
  117. package/core/protocol-transport.d.ts +1 -0
  118. package/core/protocol-transport.d.ts.map +1 -1
  119. package/core/request-pipeline.d.ts.map +1 -1
  120. package/core/request-pipeline.js +1 -1
  121. package/core/spatial-filter.d.ts +8 -4
  122. package/core/spatial-filter.d.ts.map +1 -1
  123. package/core/spatial-filter.js +206 -16
  124. package/core/stac-static.d.ts +55 -0
  125. package/core/stac-static.d.ts.map +1 -0
  126. package/core/stac-static.js +386 -0
  127. package/core/stac.d.ts +12 -0
  128. package/core/stac.d.ts.map +1 -1
  129. package/core/stac.js +45 -15
  130. package/core/surfaces.d.ts +13 -0
  131. package/core/surfaces.d.ts.map +1 -1
  132. package/core/surfaces.js +127 -16
  133. package/core/types.d.ts +174 -7
  134. package/core/types.d.ts.map +1 -1
  135. package/core/wfs-capabilities.d.ts +12 -0
  136. package/core/wfs-capabilities.d.ts.map +1 -1
  137. package/core/wfs-capabilities.js +22 -3
  138. package/core/wfs.d.ts +13 -0
  139. package/core/wfs.d.ts.map +1 -1
  140. package/core/wfs.js +35 -5
  141. package/core/wms-capabilities.d.ts +56 -84
  142. package/core/wms-capabilities.d.ts.map +1 -1
  143. package/core/wms-capabilities.js +212 -509
  144. package/core/wmts-capabilities.d.ts +62 -62
  145. package/core/wmts-capabilities.d.ts.map +1 -1
  146. package/core/wmts-capabilities.js +224 -371
  147. package/esri-compat/editor.d.ts +8 -0
  148. package/esri-compat/editor.d.ts.map +1 -1
  149. package/esri-compat/editor.js +13 -0
  150. package/esri-compat/feature-layer.d.ts +2 -0
  151. package/esri-compat/feature-layer.d.ts.map +1 -1
  152. package/esri-compat/feature-layer.js +1 -0
  153. package/esri-compat/identity-manager.d.ts +43 -0
  154. package/esri-compat/identity-manager.d.ts.map +1 -1
  155. package/esri-compat/identity-manager.js +131 -1
  156. package/esri-compat/layer-list.d.ts +11 -0
  157. package/esri-compat/layer-list.d.ts.map +1 -1
  158. package/esri-compat/layer-list.js +49 -0
  159. package/esri-compat/legend.d.ts +10 -0
  160. package/esri-compat/legend.d.ts.map +1 -1
  161. package/esri-compat/legend.js +27 -0
  162. package/esri-compat/oauth-info.d.ts +15 -0
  163. package/esri-compat/oauth-info.d.ts.map +1 -1
  164. package/esri-compat/oauth-info.js +27 -0
  165. package/esri-compat/portal.d.ts +197 -0
  166. package/esri-compat/portal.d.ts.map +1 -0
  167. package/esri-compat/portal.js +251 -0
  168. package/esri-compat/renderer-objects.d.ts +40 -0
  169. package/esri-compat/renderer-objects.d.ts.map +1 -0
  170. package/esri-compat/renderer-objects.js +62 -0
  171. package/esri-compat/sketch.d.ts +43 -0
  172. package/esri-compat/sketch.d.ts.map +1 -1
  173. package/esri-compat/sketch.js +46 -0
  174. package/esri-compat/snapping.d.ts +43 -0
  175. package/esri-compat/snapping.d.ts.map +1 -0
  176. package/esri-compat/snapping.js +45 -0
  177. package/esri-compat/url.d.ts.map +1 -1
  178. package/esri-compat/url.js +1 -1
  179. package/esri-compat/widget-host.d.ts +84 -0
  180. package/esri-compat/widget-host.d.ts.map +1 -0
  181. package/esri-compat/widget-host.js +159 -0
  182. package/filter-registry/index.d.ts +145 -0
  183. package/filter-registry/index.d.ts.map +1 -0
  184. package/filter-registry/index.js +531 -0
  185. package/generated-app/errors.d.ts +18 -2
  186. package/generated-app/errors.d.ts.map +1 -1
  187. package/generated-app/errors.js +44 -11
  188. package/map/automatic-mount-integration.d.ts +134 -0
  189. package/map/automatic-mount-integration.d.ts.map +1 -0
  190. package/map/automatic-mount-integration.js +305 -0
  191. package/map/automatic-source-strategy.d.ts +125 -0
  192. package/map/automatic-source-strategy.d.ts.map +1 -0
  193. package/map/automatic-source-strategy.js +494 -0
  194. package/map/data-to-map-bridge.d.ts +293 -0
  195. package/map/data-to-map-bridge.d.ts.map +1 -0
  196. package/map/data-to-map-bridge.js +817 -0
  197. package/map/geojson-projection.d.ts +33 -0
  198. package/map/geojson-projection.d.ts.map +1 -0
  199. package/map/geojson-projection.js +118 -0
  200. package/map/index.d.ts +14 -0
  201. package/map/index.d.ts.map +1 -1
  202. package/map/index.js +8 -0
  203. package/map/raster-source-spec.d.ts +30 -0
  204. package/map/raster-source-spec.d.ts.map +1 -0
  205. package/map/raster-source-spec.js +190 -0
  206. package/map/raster-source-strategy.d.ts +65 -0
  207. package/map/raster-source-strategy.d.ts.map +1 -0
  208. package/map/raster-source-strategy.js +232 -0
  209. package/map/source-to-maplibre.d.ts +91 -0
  210. package/map/source-to-maplibre.d.ts.map +1 -0
  211. package/map/source-to-maplibre.js +454 -0
  212. package/map/temporal-playback.d.ts +139 -0
  213. package/map/temporal-playback.d.ts.map +1 -0
  214. package/map/temporal-playback.js +247 -0
  215. package/package.json +19 -1
  216. package/query-planner/canonical.d.ts +7 -0
  217. package/query-planner/canonical.d.ts.map +1 -0
  218. package/query-planner/canonical.js +145 -0
  219. package/query-planner/cql2-json.d.ts +17 -0
  220. package/query-planner/cql2-json.d.ts.map +1 -0
  221. package/query-planner/cql2-json.js +646 -0
  222. package/query-planner/diagnostics.d.ts +35 -0
  223. package/query-planner/diagnostics.d.ts.map +1 -0
  224. package/query-planner/diagnostics.js +373 -0
  225. package/query-planner/duckdb.d.ts +79 -0
  226. package/query-planner/duckdb.d.ts.map +1 -0
  227. package/query-planner/duckdb.js +758 -0
  228. package/query-planner/execution-context.d.ts +5 -0
  229. package/query-planner/execution-context.d.ts.map +1 -0
  230. package/query-planner/execution-context.js +50 -0
  231. package/query-planner/executor.d.ts +5 -0
  232. package/query-planner/executor.d.ts.map +1 -0
  233. package/query-planner/executor.js +223 -0
  234. package/query-planner/geoservices.d.ts +91 -0
  235. package/query-planner/geoservices.d.ts.map +1 -0
  236. package/query-planner/geoservices.js +667 -0
  237. package/query-planner/grpc.d.ts +100 -0
  238. package/query-planner/grpc.d.ts.map +1 -0
  239. package/query-planner/grpc.js +736 -0
  240. package/query-planner/index.d.ts +44 -0
  241. package/query-planner/index.d.ts.map +1 -0
  242. package/query-planner/index.js +30 -0
  243. package/query-planner/ir.d.ts +20 -0
  244. package/query-planner/ir.d.ts.map +1 -0
  245. package/query-planner/ir.js +417 -0
  246. package/query-planner/local-aggregate.d.ts +5 -0
  247. package/query-planner/local-aggregate.d.ts.map +1 -0
  248. package/query-planner/local-aggregate.js +126 -0
  249. package/query-planner/odata.d.ts +48 -0
  250. package/query-planner/odata.d.ts.map +1 -0
  251. package/query-planner/odata.js +662 -0
  252. package/query-planner/ogc-compiler.d.ts +55 -0
  253. package/query-planner/ogc-compiler.d.ts.map +1 -0
  254. package/query-planner/ogc-compiler.js +480 -0
  255. package/query-planner/ogc-features.d.ts +53 -0
  256. package/query-planner/ogc-features.d.ts.map +1 -0
  257. package/query-planner/ogc-features.js +617 -0
  258. package/query-planner/planner.d.ts +17 -0
  259. package/query-planner/planner.d.ts.map +1 -0
  260. package/query-planner/planner.js +818 -0
  261. package/query-planner/resource.d.ts +94 -0
  262. package/query-planner/resource.d.ts.map +1 -0
  263. package/query-planner/resource.js +526 -0
  264. package/query-planner/semantic-canonical.d.ts +15 -0
  265. package/query-planner/semantic-canonical.d.ts.map +1 -0
  266. package/query-planner/semantic-canonical.js +62 -0
  267. package/query-planner/semantic-compat.d.ts +10 -0
  268. package/query-planner/semantic-compat.d.ts.map +1 -0
  269. package/query-planner/semantic-compat.js +35 -0
  270. package/query-planner/semantic-compiler.d.ts +64 -0
  271. package/query-planner/semantic-compiler.d.ts.map +1 -0
  272. package/query-planner/semantic-compiler.js +81 -0
  273. package/query-planner/semantic-literals.d.ts +30 -0
  274. package/query-planner/semantic-literals.d.ts.map +1 -0
  275. package/query-planner/semantic-literals.js +133 -0
  276. package/query-planner/semantic-types.d.ts +265 -0
  277. package/query-planner/semantic-types.d.ts.map +1 -0
  278. package/query-planner/semantic-types.js +1 -0
  279. package/query-planner/semantic.d.ts +54 -0
  280. package/query-planner/semantic.d.ts.map +1 -0
  281. package/query-planner/semantic.js +1421 -0
  282. package/query-planner/types.d.ts +560 -0
  283. package/query-planner/types.d.ts.map +1 -0
  284. package/query-planner/types.js +49 -0
  285. package/query-planner/wfs-semantic.d.ts +58 -0
  286. package/query-planner/wfs-semantic.d.ts.map +1 -0
  287. package/query-planner/wfs-semantic.js +547 -0
  288. package/query-planner/wfs.d.ts +6 -0
  289. package/query-planner/wfs.d.ts.map +1 -0
  290. package/query-planner/wfs.js +71 -0
  291. package/react/external-map.d.ts +67 -0
  292. package/react/external-map.d.ts.map +1 -0
  293. package/react/external-map.js +63 -0
  294. package/react/honua-map.d.ts.map +1 -1
  295. package/react/honua-map.js +3 -2
  296. package/react/honua-source-layer.d.ts +110 -0
  297. package/react/honua-source-layer.d.ts.map +1 -0
  298. package/react/honua-source-layer.js +101 -0
  299. package/react/hooks.d.ts +28 -0
  300. package/react/hooks.d.ts.map +1 -1
  301. package/react/hooks.js +26 -4
  302. package/react/index.d.ts +8 -0
  303. package/react/index.d.ts.map +1 -1
  304. package/react/index.js +5 -0
  305. package/react/query-cache.d.ts +26 -4
  306. package/react/query-cache.d.ts.map +1 -1
  307. package/react/query-cache.js +51 -8
  308. package/react/selection.d.ts +177 -0
  309. package/react/selection.d.ts.map +1 -0
  310. package/react/selection.js +0 -0
  311. package/react/use-mounted-source.d.ts +69 -0
  312. package/react/use-mounted-source.d.ts.map +1 -0
  313. package/react/use-mounted-source.js +346 -0
  314. package/runtime/edit-snapping.d.ts +107 -0
  315. package/runtime/edit-snapping.d.ts.map +1 -0
  316. package/runtime/edit-snapping.js +190 -0
  317. package/runtime/errors.d.ts +3 -2
  318. package/runtime/errors.d.ts.map +1 -1
  319. package/runtime/errors.js +19 -2
  320. package/runtime/index.d.ts +8 -2
  321. package/runtime/index.d.ts.map +1 -1
  322. package/runtime/index.js +4 -4
  323. package/runtime/load-package.d.ts.map +1 -1
  324. package/runtime/load-package.js +8 -0
  325. package/runtime/map-package-validation.d.ts +0 -13
  326. package/runtime/map-package-validation.d.ts.map +1 -1
  327. package/runtime/map-package-validation.js +0 -12
  328. package/runtime/map-package.d.ts +1 -1
  329. package/runtime/map-package.d.ts.map +1 -1
  330. package/runtime/maplibre-renderer.d.ts +41 -0
  331. package/runtime/maplibre-renderer.d.ts.map +1 -0
  332. package/runtime/maplibre-renderer.js +322 -0
  333. package/runtime/pmtiles-protocol.d.ts +77 -0
  334. package/runtime/pmtiles-protocol.d.ts.map +1 -0
  335. package/runtime/pmtiles-protocol.js +120 -0
  336. package/runtime/query-tiles.d.ts +2 -1
  337. package/runtime/query-tiles.d.ts.map +1 -1
  338. package/runtime/query-tiles.js +6 -2
  339. package/runtime/source-bridge.d.ts +4 -4
  340. package/runtime/source-bridge.d.ts.map +1 -1
  341. package/runtime/source-bridge.js +36 -56
  342. package/runtime/style-interactions.d.ts +3 -2
  343. package/runtime/style-interactions.d.ts.map +1 -1
  344. package/runtime/style-interactions.js +11 -3
  345. package/runtime/terra-draw-sketch.d.ts +275 -0
  346. package/runtime/terra-draw-sketch.d.ts.map +1 -0
  347. package/runtime/terra-draw-sketch.js +404 -0
  348. package/source-capability-registry.d.ts +1 -0
  349. package/source-capability-registry.js +1 -0
  350. package/source-capability-types.d.ts +186 -0
  351. package/source-capability-types.js +7 -0
  352. package/style/index.d.ts +2 -0
  353. package/style/index.d.ts.map +1 -1
  354. package/style/index.js +2 -0
  355. package/style/renderers.d.ts +326 -0
  356. package/style/renderers.d.ts.map +1 -0
  357. package/style/renderers.js +517 -0
  358. package/webmap/convert-renderer.d.ts +24 -3
  359. package/webmap/convert-renderer.d.ts.map +1 -1
  360. package/webmap/convert-renderer.js +93 -112
  361. package/webmap/index.d.ts +1 -1
  362. package/webmap/index.d.ts.map +1 -1
  363. package/webmap/index.js +1 -1
@@ -0,0 +1,25 @@
1
+ /**
2
+ * PKCE (RFC 7636) primitives built exclusively on WebCrypto.
3
+ *
4
+ * `globalThis.crypto` (the WebCrypto API) is available in browsers and in
5
+ * Node ≥20, so no `node:crypto` import — and therefore no bundler/runtime
6
+ * branch — is needed. This keeps the auth flow dependency-free and identical
7
+ * across environments.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ /**
12
+ * A PKCE code verifier + its S256 challenge. The verifier is high-entropy
13
+ * (32 random bytes → 43-char base64url string, within the RFC's 43–128 range);
14
+ * the challenge is `BASE64URL(SHA-256(verifier))`.
15
+ */
16
+ export interface PkcePair {
17
+ codeVerifier: string;
18
+ codeChallenge: string;
19
+ codeChallengeMethod: "S256";
20
+ }
21
+ /** Create a fresh PKCE verifier/challenge pair using SHA-256 (S256). */
22
+ export declare function createPkcePair(): Promise<PkcePair>;
23
+ /** Random, unguessable `state` value for CSRF protection on the redirect. */
24
+ export declare function createStateToken(): string;
25
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../../../src/core/auth/pkce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA6BH;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,wEAAwE;AACxE,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAQxD;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * PKCE (RFC 7636) primitives built exclusively on WebCrypto.
3
+ *
4
+ * `globalThis.crypto` (the WebCrypto API) is available in browsers and in
5
+ * Node ≥20, so no `node:crypto` import — and therefore no bundler/runtime
6
+ * branch — is needed. This keeps the auth flow dependency-free and identical
7
+ * across environments.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ function requireWebCrypto() {
12
+ const cryptoRef = globalThis.crypto;
13
+ if (!cryptoRef?.subtle) {
14
+ throw new Error("WebCrypto (globalThis.crypto.subtle) is unavailable. OAuth2 PKCE requires a browser or Node.js >= 20.");
15
+ }
16
+ return cryptoRef;
17
+ }
18
+ /** Base64url-encode raw bytes (no padding), per RFC 7636 §A. */
19
+ function base64UrlEncode(bytes) {
20
+ let binary = "";
21
+ for (const byte of bytes) {
22
+ binary += String.fromCharCode(byte);
23
+ }
24
+ const base64 = typeof btoa === "function" ? btoa(binary) : Buffer.from(bytes).toString("base64");
25
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
26
+ }
27
+ /** Cryptographically-random base64url string derived from `byteLength` bytes. */
28
+ function randomBase64Url(byteLength) {
29
+ const bytes = new Uint8Array(byteLength);
30
+ requireWebCrypto().getRandomValues(bytes);
31
+ return base64UrlEncode(bytes);
32
+ }
33
+ /** Create a fresh PKCE verifier/challenge pair using SHA-256 (S256). */
34
+ export async function createPkcePair() {
35
+ const codeVerifier = randomBase64Url(32);
36
+ const digest = await requireWebCrypto().subtle.digest("SHA-256", new TextEncoder().encode(codeVerifier));
37
+ return {
38
+ codeVerifier,
39
+ codeChallenge: base64UrlEncode(new Uint8Array(digest)),
40
+ codeChallengeMethod: "S256",
41
+ };
42
+ }
43
+ /** Random, unguessable `state` value for CSRF protection on the redirect. */
44
+ export function createStateToken() {
45
+ return randomBase64Url(16);
46
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Static (non-interactive) {@link HonuaAuthProvider} built-ins for callers that
3
+ * already hold a long-lived credential.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ import type { HonuaAuthProvider } from "../types.js";
8
+ /**
9
+ * Provider that attaches a static API key as `X-API-Key` on every request.
10
+ * Equivalent to `new HonuaClient({ apiKey })` but composable as an
11
+ * {@link HonuaAuthProvider}.
12
+ */
13
+ export declare function apiKeyAuth(apiKey: string): HonuaAuthProvider;
14
+ /**
15
+ * Provider that attaches a static bearer token as `Authorization: Bearer …`.
16
+ * Equivalent to `new HonuaClient({ bearerToken })` but composable as an
17
+ * {@link HonuaAuthProvider}.
18
+ */
19
+ export declare function bearerTokenAuth(token: string): HonuaAuthProvider;
20
+ //# sourceMappingURL=static-providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-providers.d.ts","sourceRoot":"","sources":["../../../../src/core/auth/static-providers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAI5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAIhE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Static (non-interactive) {@link HonuaAuthProvider} built-ins for callers that
3
+ * already hold a long-lived credential.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ /**
8
+ * Provider that attaches a static API key as `X-API-Key` on every request.
9
+ * Equivalent to `new HonuaClient({ apiKey })` but composable as an
10
+ * {@link HonuaAuthProvider}.
11
+ */
12
+ export function apiKeyAuth(apiKey) {
13
+ return {
14
+ getCredentials: () => ({ apiKey }),
15
+ };
16
+ }
17
+ /**
18
+ * Provider that attaches a static bearer token as `Authorization: Bearer …`.
19
+ * Equivalent to `new HonuaClient({ bearerToken })` but composable as an
20
+ * {@link HonuaAuthProvider}.
21
+ */
22
+ export function bearerTokenAuth(token) {
23
+ return {
24
+ getCredentials: () => ({ bearerToken: token }),
25
+ };
26
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Shared helpers for talking to an OAuth2 token endpoint and turning responses
3
+ * into {@link StoredCredential}s. Used by both the PKCE and client-credentials
4
+ * providers.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { HonuaAuthCredentials } from "../types.js";
9
+ import type { OAuth2TokenResponse, StoredCredential } from "./types.js";
10
+ /**
11
+ * Project a {@link StoredCredential} into the {@link HonuaAuthCredentials} shape
12
+ * the client attaches to requests. Non-`Bearer` token types are emitted as a
13
+ * full `Authorization` value; the expiry drives the client's own refresh skew.
14
+ */
15
+ export declare function toHonuaCredentials(credential: StoredCredential): HonuaAuthCredentials;
16
+ /** Resolve `serviceKey`, defaulting to `${clientId}@${endpoint origin}`. */
17
+ export declare function resolveServiceKey(serviceKey: string | undefined, clientId: string, endpoint: string): string;
18
+ /** Default clock-skew tolerance (ms) applied to credential expiry checks. */
19
+ export declare const DEFAULT_CLOCK_SKEW_MS = 60000;
20
+ /** True when a credential is missing or within `skewMs` of (or past) expiry. */
21
+ export declare function isCredentialExpiring(credential: StoredCredential | undefined, skewMs: number): boolean;
22
+ /** Map a token response into a {@link StoredCredential} (clock-skew tolerant). */
23
+ export declare function credentialFromTokenResponse(response: OAuth2TokenResponse, previous?: StoredCredential): StoredCredential;
24
+ /**
25
+ * POST an `application/x-www-form-urlencoded` grant to the token endpoint and
26
+ * return the parsed {@link StoredCredential}.
27
+ *
28
+ * Errors are normalized to {@link HonuaAuthError}: an `invalid_grant` OAuth
29
+ * error (expired/revoked/invalid grant → re-auth needed) maps to code
30
+ * `invalid_grant`; every other transport/HTTP/parse failure maps to
31
+ * `refresh_failed` (transient, retry may succeed).
32
+ */
33
+ export declare function requestToken(options: {
34
+ fetchFn: typeof fetch;
35
+ tokenEndpoint: string;
36
+ params: Record<string, string>;
37
+ previous?: StoredCredential;
38
+ signal?: AbortSignal;
39
+ }): Promise<StoredCredential>;
40
+ //# sourceMappingURL=token-endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-endpoint.d.ts","sourceRoot":"","sources":["../../../../src/core/auth/token-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,GAAG,oBAAoB,CAWrF;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW5G;AAED,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQtG;AAED,kFAAkF;AAClF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,gBAAgB,CAwBlB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,OAAO,EAAE,OAAO,KAAK,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmD5B"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Shared helpers for talking to an OAuth2 token endpoint and turning responses
3
+ * into {@link StoredCredential}s. Used by both the PKCE and client-credentials
4
+ * providers.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import { HonuaAuthError } from "../errors.js";
9
+ /**
10
+ * Project a {@link StoredCredential} into the {@link HonuaAuthCredentials} shape
11
+ * the client attaches to requests. Non-`Bearer` token types are emitted as a
12
+ * full `Authorization` value; the expiry drives the client's own refresh skew.
13
+ */
14
+ export function toHonuaCredentials(credential) {
15
+ const result = {};
16
+ if (credential.tokenType && credential.tokenType.toLowerCase() !== "bearer") {
17
+ result.authorization = `${credential.tokenType} ${credential.accessToken}`;
18
+ }
19
+ else {
20
+ result.bearerToken = credential.accessToken;
21
+ }
22
+ if (credential.expiresAt !== undefined) {
23
+ result.expiresAt = credential.expiresAt;
24
+ }
25
+ return result;
26
+ }
27
+ /** Resolve `serviceKey`, defaulting to `${clientId}@${endpoint origin}`. */
28
+ export function resolveServiceKey(serviceKey, clientId, endpoint) {
29
+ if (serviceKey) {
30
+ return serviceKey;
31
+ }
32
+ let origin = endpoint;
33
+ try {
34
+ origin = new URL(endpoint).origin;
35
+ }
36
+ catch {
37
+ // Non-absolute endpoint (tests) — fall back to the raw string.
38
+ }
39
+ return `${clientId}@${origin}`;
40
+ }
41
+ /** Default clock-skew tolerance (ms) applied to credential expiry checks. */
42
+ export const DEFAULT_CLOCK_SKEW_MS = 60_000;
43
+ /** True when a credential is missing or within `skewMs` of (or past) expiry. */
44
+ export function isCredentialExpiring(credential, skewMs) {
45
+ if (!credential) {
46
+ return true;
47
+ }
48
+ if (credential.expiresAt === undefined) {
49
+ return false;
50
+ }
51
+ return credential.expiresAt - Date.now() <= skewMs;
52
+ }
53
+ /** Map a token response into a {@link StoredCredential} (clock-skew tolerant). */
54
+ export function credentialFromTokenResponse(response, previous) {
55
+ const credential = {
56
+ accessToken: response.access_token,
57
+ };
58
+ if (response.token_type) {
59
+ credential.tokenType = response.token_type;
60
+ }
61
+ // Some authorization servers omit a rotated refresh token on refresh; keep
62
+ // the previous one so silent refresh keeps working (RFC 6749 §6).
63
+ const refreshToken = response.refresh_token ?? previous?.refreshToken;
64
+ if (refreshToken) {
65
+ credential.refreshToken = refreshToken;
66
+ }
67
+ if (typeof response.expires_in === "number" && Number.isFinite(response.expires_in)) {
68
+ credential.expiresAt = Date.now() + response.expires_in * 1000;
69
+ }
70
+ const scope = response.scope ?? previous?.scope;
71
+ if (scope) {
72
+ credential.scope = scope;
73
+ }
74
+ if (response.id_token) {
75
+ credential.idToken = response.id_token;
76
+ }
77
+ return credential;
78
+ }
79
+ /**
80
+ * POST an `application/x-www-form-urlencoded` grant to the token endpoint and
81
+ * return the parsed {@link StoredCredential}.
82
+ *
83
+ * Errors are normalized to {@link HonuaAuthError}: an `invalid_grant` OAuth
84
+ * error (expired/revoked/invalid grant → re-auth needed) maps to code
85
+ * `invalid_grant`; every other transport/HTTP/parse failure maps to
86
+ * `refresh_failed` (transient, retry may succeed).
87
+ */
88
+ export async function requestToken(options) {
89
+ const body = new URLSearchParams(options.params);
90
+ let response;
91
+ try {
92
+ response = await options.fetchFn(options.tokenEndpoint, {
93
+ method: "POST",
94
+ headers: {
95
+ "Content-Type": "application/x-www-form-urlencoded",
96
+ Accept: "application/json",
97
+ },
98
+ body: body.toString(),
99
+ ...(options.signal ? { signal: options.signal } : {}),
100
+ });
101
+ }
102
+ catch (cause) {
103
+ throw new HonuaAuthError("refresh_failed", "Token request failed at the transport layer.", { cause });
104
+ }
105
+ const text = await response.text();
106
+ let payload;
107
+ try {
108
+ payload = text ? JSON.parse(text) : {};
109
+ }
110
+ catch (cause) {
111
+ throw new HonuaAuthError("refresh_failed", `Token endpoint returned a non-JSON response (HTTP ${response.status}).`, {
112
+ cause,
113
+ });
114
+ }
115
+ if (!response.ok) {
116
+ const oauthError = isObject(payload) && typeof payload.error === "string" ? payload.error : undefined;
117
+ const description = isObject(payload) && typeof payload.error_description === "string" ? payload.error_description : undefined;
118
+ const message = `Token endpoint rejected the grant (HTTP ${response.status}${oauthError ? `, ${oauthError}` : ""})${description ? `: ${description}` : ""}`;
119
+ if (oauthError === "invalid_grant") {
120
+ throw new HonuaAuthError("invalid_grant", message, { cause: payload });
121
+ }
122
+ throw new HonuaAuthError("refresh_failed", message, { cause: payload });
123
+ }
124
+ if (!isObject(payload) || typeof payload.access_token !== "string") {
125
+ throw new HonuaAuthError("refresh_failed", "Token endpoint response is missing an access_token.", {
126
+ cause: payload,
127
+ });
128
+ }
129
+ return credentialFromTokenResponse(payload, options.previous);
130
+ }
131
+ function isObject(value) {
132
+ return typeof value === "object" && value !== null;
133
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Shared types for the built-in {@link HonuaAuthProvider} implementations
3
+ * (`oauth2`, `clientCredentials`, `apiKeyAuth`, `bearerTokenAuth`) and the
4
+ * pluggable {@link CredentialStore}.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { HonuaAuthError } from "../errors.js";
9
+ /**
10
+ * A persisted OAuth2 credential. Access/refresh tokens plus expiry are stored
11
+ * in a {@link CredentialStore}; the SDK only ever attaches `accessToken` as a
12
+ * bearer credential and uses `refreshToken`/`expiresAt` to drive silent
13
+ * refresh.
14
+ */
15
+ export interface StoredCredential {
16
+ /** The bearer access token attached to outgoing requests. */
17
+ accessToken: string;
18
+ /** Token type from the token response; defaults to `Bearer`. */
19
+ tokenType?: string;
20
+ /** Refresh token, when the authorization server issued one. */
21
+ refreshToken?: string;
22
+ /** Absolute expiry as epoch milliseconds (from `expires_in`). */
23
+ expiresAt?: number;
24
+ /** Granted scope string, if the token response narrowed it. */
25
+ scope?: string;
26
+ /** OpenID Connect ID token, when present (never sent to resource servers). */
27
+ idToken?: string;
28
+ }
29
+ /**
30
+ * Pluggable credential persistence. The default is an in-memory store scoped to
31
+ * the provider instance. Browser adapters (`sessionStorageCredentialStore`,
32
+ * `localStorageCredentialStore`) are explicit opt-in because Web Storage is
33
+ * readable by any script on the origin (XSS exfiltration risk) — see
34
+ * `docs/auth.md`.
35
+ *
36
+ * Keys are namespaced per origin/service by the provider so tokens for one
37
+ * service are never returned for another.
38
+ */
39
+ export interface CredentialStore {
40
+ get(key: string): StoredCredential | undefined | Promise<StoredCredential | undefined>;
41
+ set(key: string, value: StoredCredential): void | Promise<void>;
42
+ delete(key: string): void | Promise<void>;
43
+ }
44
+ /** Lifecycle events emitted by the OAuth2 / client-credentials providers. */
45
+ export type HonuaAuthEvent = {
46
+ type: "signed-in";
47
+ credential: StoredCredential;
48
+ } | {
49
+ type: "token-refreshed";
50
+ credential: StoredCredential;
51
+ } | {
52
+ type: "refresh-failed";
53
+ error: HonuaAuthError;
54
+ } | {
55
+ type: "signed-out";
56
+ };
57
+ /** Listener registered with `provider.on(...)`. */
58
+ export type HonuaAuthEventListener = (event: HonuaAuthEvent) => void;
59
+ /** Handle returned by `provider.on(...)`; call `remove()` to unsubscribe. */
60
+ export interface HonuaAuthEventHandle {
61
+ remove(): void;
62
+ }
63
+ /** Interactive sign-in mode for the OAuth2 authorization-code + PKCE flow. */
64
+ export type OAuth2SignInMode = "redirect" | "popup";
65
+ /**
66
+ * Configuration for the OAuth2 authorization-code + PKCE provider produced by
67
+ * {@link oauth2}. Only WebCrypto is used for PKCE (Node ≥20 exposes
68
+ * `globalThis.crypto`); no new hard dependencies are introduced.
69
+ */
70
+ export interface OAuth2Config {
71
+ /** Authorization endpoint (where the browser is redirected to sign in). */
72
+ authorizationEndpoint: string;
73
+ /** Token endpoint (code exchange + refresh). */
74
+ tokenEndpoint: string;
75
+ /** Public client identifier. */
76
+ clientId: string;
77
+ /** Registered redirect URI that receives the authorization `code`+`state`. */
78
+ redirectUri: string;
79
+ /** Requested scopes. */
80
+ scopes?: readonly string[];
81
+ /** Interactive mode. Defaults to `redirect`. */
82
+ mode?: OAuth2SignInMode;
83
+ /**
84
+ * Credential store. Defaults to an in-memory store. Scoped per
85
+ * origin/service via {@link OAuth2Config.serviceKey}.
86
+ */
87
+ store?: CredentialStore;
88
+ /**
89
+ * Stable key that scopes stored credentials to this service. Defaults to
90
+ * `${clientId}@${origin of tokenEndpoint}` so tokens are never shared across
91
+ * services or origins.
92
+ */
93
+ serviceKey?: string;
94
+ /**
95
+ * Clock-skew tolerance in milliseconds. A credential is treated as expiring
96
+ * this long before its real expiry so a refresh happens before requests fail.
97
+ * Defaults to 60_000.
98
+ */
99
+ clockSkewMs?: number;
100
+ /** Optional revocation endpoint (RFC 7009) called on `signOut()`. */
101
+ revocationEndpoint?: string;
102
+ /** Extra query params appended to the authorization request. */
103
+ extraAuthorizationParams?: Record<string, string>;
104
+ /** Extra body params appended to token/refresh requests. */
105
+ extraTokenParams?: Record<string, string>;
106
+ /** Popup window features string (popup mode). */
107
+ popupFeatures?: string;
108
+ /** Override `fetch` (Node/tests). Defaults to `globalThis.fetch`. */
109
+ fetchFn?: typeof fetch;
110
+ /**
111
+ * Window used for redirect/popup + transaction persistence. Defaults to
112
+ * `globalThis.window`. Injectable for tests / non-DOM hosts.
113
+ */
114
+ windowRef?: Window;
115
+ /** Auth lifecycle listener. */
116
+ onEvent?: HonuaAuthEventListener;
117
+ }
118
+ /**
119
+ * Configuration for the OAuth2 client-credentials provider produced by
120
+ * {@link clientCredentials}. Intended for confidential Node clients — the
121
+ * client secret must never ship to a browser.
122
+ */
123
+ export interface ClientCredentialsConfig {
124
+ tokenEndpoint: string;
125
+ clientId: string;
126
+ clientSecret: string;
127
+ scopes?: readonly string[];
128
+ store?: CredentialStore;
129
+ serviceKey?: string;
130
+ clockSkewMs?: number;
131
+ extraTokenParams?: Record<string, string>;
132
+ fetchFn?: typeof fetch;
133
+ onEvent?: HonuaAuthEventListener;
134
+ }
135
+ /** Raw OAuth2 token endpoint response shape (RFC 6749 §5.1). */
136
+ export interface OAuth2TokenResponse {
137
+ access_token: string;
138
+ token_type?: string;
139
+ expires_in?: number;
140
+ refresh_token?: string;
141
+ scope?: string;
142
+ id_token?: string;
143
+ }
144
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/auth/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared types for the built-in {@link HonuaAuthProvider} implementations
3
+ * (`oauth2`, `clientCredentials`, `apiKeyAuth`, `bearerTokenAuth`) and the
4
+ * pluggable {@link CredentialStore}.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export {};
@@ -0,0 +1,4 @@
1
+ /** Internal structural guard for byte-bounded JSON received across trust boundaries. */
2
+ export type BoundedJsonStructureViolation = "max-depth" | "max-nodes" | "non-json";
3
+ export declare function boundedJsonStructureViolation(value: unknown, maxDepth: number, maxNodes: number): BoundedJsonStructureViolation | undefined;
4
+ //# sourceMappingURL=bounded-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-json.d.ts","sourceRoot":"","sources":["../../../src/core/bounded-json.ts"],"names":[],"mappings":"AAAA,wFAAwF;AAExF,MAAM,MAAM,6BAA6B,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AAEnF,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,6BAA6B,GAAG,SAAS,CAwB3C"}
@@ -0,0 +1,38 @@
1
+ /** Internal structural guard for byte-bounded JSON received across trust boundaries. */
2
+ export function boundedJsonStructureViolation(value, maxDepth, maxNodes) {
3
+ const pending = [{ value, depth: 0 }];
4
+ let nodes = 0;
5
+ while (pending.length > 0) {
6
+ const current = pending.pop();
7
+ nodes += 1;
8
+ if (nodes > maxNodes)
9
+ return "max-nodes";
10
+ if (current.depth > maxDepth)
11
+ return "max-depth";
12
+ if (current.value === null || typeof current.value === "string" || typeof current.value === "boolean")
13
+ continue;
14
+ if (typeof current.value === "number") {
15
+ if (!Number.isFinite(current.value))
16
+ return "non-json";
17
+ continue;
18
+ }
19
+ if (Array.isArray(current.value)) {
20
+ for (const entry of current.value)
21
+ pending.push({ value: entry, depth: current.depth + 1 });
22
+ continue;
23
+ }
24
+ if (isPlainObject(current.value)) {
25
+ for (const entry of Object.values(current.value))
26
+ pending.push({ value: entry, depth: current.depth + 1 });
27
+ continue;
28
+ }
29
+ return "non-json";
30
+ }
31
+ return undefined;
32
+ }
33
+ function isPlainObject(value) {
34
+ if (typeof value !== "object" || value === null || Array.isArray(value))
35
+ return false;
36
+ const prototype = Object.getPrototypeOf(value);
37
+ return prototype === Object.prototype || prototype === null;
38
+ }
@@ -39,6 +39,14 @@ export interface HonuaMetadataRequestOptions {
39
39
  readonly ttlMs?: number;
40
40
  /** Optional stale fallback window surfaced to callers in `HonuaCacheState`. */
41
41
  readonly staleIfErrorMs?: number;
42
+ /**
43
+ * Maximum decoded response-body bytes accepted before metadata parsing.
44
+ * Adapters that consume bounded discovery documents set this explicitly so
45
+ * a missing or dishonest `Content-Length` cannot turn metadata discovery
46
+ * into an unbounded allocation. The limit is enforced while streaming the
47
+ * body, not only from response headers.
48
+ */
49
+ readonly maxResponseBytes?: number;
42
50
  }
43
51
  export interface NormalizedHonuaMetadataRequestOptions {
44
52
  readonly signal?: AbortSignal;
@@ -47,6 +55,7 @@ export interface NormalizedHonuaMetadataRequestOptions {
47
55
  readonly staleIfError: boolean;
48
56
  readonly ttlMs?: number;
49
57
  readonly staleIfErrorMs?: number;
58
+ readonly maxResponseBytes?: number;
50
59
  }
51
60
  export declare const HONUA_DEFAULT_METADATA_CACHE_TTL_MS: number;
52
61
  export declare const HONUA_DEFAULT_METADATA_STALE_IF_ERROR_MS: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cache-state.d.ts","sourceRoot":"","sources":["../../../src/core/cache-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache-state.d.ts","sourceRoot":"","sources":["../../../src/core/cache-state.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@ export function createHonuaCacheState(init) {
18
18
  export function normalizeHonuaMetadataRequestOptions(options = {}) {
19
19
  const ttlMs = normalizeNonNegativeInteger(options.ttlMs) ?? HONUA_DEFAULT_METADATA_CACHE_TTL_MS;
20
20
  const staleIfErrorMs = normalizeNonNegativeInteger(options.staleIfErrorMs) ?? HONUA_DEFAULT_METADATA_STALE_IF_ERROR_MS;
21
+ const maxResponseBytes = normalizeMaximumResponseBytes(options.maxResponseBytes);
21
22
  return {
22
23
  ...(options.signal ? { signal: options.signal } : {}),
23
24
  refresh: options.refresh === true,
@@ -25,6 +26,7 @@ export function normalizeHonuaMetadataRequestOptions(options = {}) {
25
26
  staleIfError: options.staleIfError !== false,
26
27
  ttlMs,
27
28
  staleIfErrorMs,
29
+ ...(maxResponseBytes !== undefined ? { maxResponseBytes } : {}),
28
30
  };
29
31
  }
30
32
  export function isHonuaCacheEntryFresh(cachedAtMs, now, ttlMs) {
@@ -85,3 +87,11 @@ function normalizeNonNegativeInteger(value) {
85
87
  }
86
88
  return Math.max(0, Math.trunc(value));
87
89
  }
90
+ function normalizeMaximumResponseBytes(value) {
91
+ if (value === undefined)
92
+ return undefined;
93
+ if (!Number.isSafeInteger(value) || value <= 0) {
94
+ throw new TypeError("maxResponseBytes must be a positive safe integer.");
95
+ }
96
+ return value;
97
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bounded XML tree used by the WMS/WMTS capabilities readers.
3
+ *
4
+ * This is deliberately not a general XML implementation. It accepts the XML
5
+ * 1.0 subset used by OGC service metadata, matches namespace-qualified names
6
+ * by their local suffix, and rejects declarations that could introduce
7
+ * external entities. Every allocation is covered by a small fixed budget so a
8
+ * capabilities response cannot turn metadata discovery into an unbounded
9
+ * parser workload.
10
+ *
11
+ * @internal
12
+ */
13
+ export declare const OGC_CAPABILITIES_XML_LIMITS: Readonly<{
14
+ maxBytes: number;
15
+ maxElements: 12000;
16
+ maxDepth: 32;
17
+ maxAttributesPerElement: 64;
18
+ maxAttributeBytes: number;
19
+ maxTextBytes: number;
20
+ }>;
21
+ export interface CapabilitiesXmlElement {
22
+ readonly name: string;
23
+ readonly localName: string;
24
+ readonly attributes: Readonly<Record<string, string>>;
25
+ readonly children: readonly CapabilitiesXmlElement[];
26
+ readonly text: string;
27
+ }
28
+ export declare function parseCapabilitiesXml(xml: string, family: "WMS" | "WMTS"): CapabilitiesXmlElement;
29
+ export declare function xmlChild(node: CapabilitiesXmlElement | undefined, localName: string): CapabilitiesXmlElement | undefined;
30
+ export declare function xmlChildren(node: CapabilitiesXmlElement | undefined, localName: string): readonly CapabilitiesXmlElement[];
31
+ export declare function xmlAttribute(node: CapabilitiesXmlElement, name: string): string | undefined;
32
+ export declare function xmlText(node: CapabilitiesXmlElement | undefined): string | undefined;
33
+ //# sourceMappingURL=capabilities-xml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-xml.d.ts","sourceRoot":"","sources":["../../../src/core/capabilities-xml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,eAAO,MAAM,2BAA2B;;;;;;;EAOtC,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAWD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,sBAAsB,CAmGhG;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,sBAAsB,GAAG,SAAS,EACxC,SAAS,EAAE,MAAM,GAChB,sBAAsB,GAAG,SAAS,CAEpC;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,sBAAsB,GAAG,SAAS,EACxC,SAAS,EAAE,MAAM,GAChB,SAAS,sBAAsB,EAAE,CAEnC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE3F;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,sBAAsB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIpF"}