@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
@@ -1,402 +1,255 @@
1
- /**
2
- * WMTS 1.0.0 Capabilities parser. Hand-rolled, narrow-scope walker over
3
- * the `Capabilities` document advertised by honua-server (single
4
- * advertised TileMatrixSet today: `WebMercatorQuad`). Yields a typed
5
- * `WmtsCapabilities` shape so the SDK can route through the canonical
6
- * `Source` surface without leaking XML.
7
- *
8
- * @module
9
- */
10
- import { decodeXmlText as decodeXmlEntities } from "./xml-text.js";
11
- export class HonuaWmtsCapabilitiesParseError extends Error {
12
- constructor(message) {
13
- super(message);
1
+ /** Bounded WMTS 1.0 capabilities projection. @module */
2
+ import { parseCapabilitiesXml, xmlAttribute, xmlChild, xmlChildren, xmlText, } from "./capabilities-xml.js";
3
+ import { HonuaSdkError } from "./error-envelope.js";
4
+ const incompleteTileMatrixSets = new WeakSet();
5
+ export class HonuaWmtsCapabilitiesParseError extends HonuaSdkError {
6
+ constructor(message, options = {}) {
7
+ super("core.wmts-capabilities-parse", message, options);
14
8
  this.name = "HonuaWmtsCapabilitiesParseError";
15
9
  }
16
10
  }
17
- /**
18
- * Parse a `Capabilities` text body for WMTS 1.0 into the typed
19
- * `WmtsCapabilities` shape.
20
- */
21
11
  export function parseWmtsCapabilities(xml) {
22
- if (typeof xml !== "string" || xml.length === 0) {
23
- throw new HonuaWmtsCapabilitiesParseError("WMTS Capabilities body is empty");
12
+ try {
13
+ const root = parseCapabilitiesXml(xml, "WMTS");
14
+ if (root.localName !== "Capabilities")
15
+ throw new Error("missing <Capabilities> root element");
16
+ const warnings = [];
17
+ const serviceNode = xmlChild(root, "ServiceIdentification");
18
+ const contents = xmlChild(root, "Contents");
19
+ const service = compactObject({
20
+ title: xmlText(xmlChild(serviceNode, "Title")),
21
+ abstract: xmlText(xmlChild(serviceNode, "Abstract")),
22
+ });
23
+ const layers = Object.freeze(xmlChildren(contents, "Layer").flatMap((layer) => parseLayer(layer, warnings)));
24
+ const tileMatrixSets = Object.freeze(xmlChildren(contents, "TileMatrixSet").flatMap((matrixSet) => parseTileMatrixSet(matrixSet, warnings)));
25
+ const operations = Object.freeze(parseOperations(xmlChild(root, "OperationsMetadata")));
26
+ return Object.freeze({
27
+ version: xmlAttribute(root, "version") ?? "",
28
+ service,
29
+ layers,
30
+ tileMatrixSets,
31
+ operations,
32
+ warnings: Object.freeze(unique(warnings)),
33
+ });
24
34
  }
25
- const root = findElement(xml, 0, "Capabilities");
26
- if (!root) {
27
- throw new HonuaWmtsCapabilitiesParseError("missing <Capabilities> root element");
35
+ catch (cause) {
36
+ if (cause instanceof HonuaWmtsCapabilitiesParseError)
37
+ throw cause;
38
+ const message = cause instanceof Error ? cause.message : "WMTS Capabilities XML is malformed";
39
+ throw new HonuaWmtsCapabilitiesParseError(message, { cause });
28
40
  }
29
- const version = readAttribute(root.openTag, "version") ?? "1.0.0";
30
- const service = parseServiceMetadata(root.inner);
31
- const contents = findElement(root.inner, 0, "Contents");
32
- const layers = contents ? collectLayers(contents.inner) : [];
33
- const tileMatrixSets = contents ? collectTileMatrixSets(contents.inner) : [];
34
- return { version, service, layers, tileMatrixSets };
35
41
  }
36
- function parseServiceMetadata(xml) {
37
- const node = findElement(xml, 0, "ows:ServiceIdentification") ?? findElement(xml, 0, "ServiceIdentification");
38
- if (!node)
39
- return {};
40
- const out = {};
41
- const title = readTextElement(node.inner, "ows:Title") ?? readTextElement(node.inner, "Title");
42
- if (title !== undefined)
43
- out.title = title;
44
- const abstract = readTextElement(node.inner, "ows:Abstract") ?? readTextElement(node.inner, "Abstract");
45
- if (abstract !== undefined)
46
- out.abstract = abstract;
47
- return out;
48
- }
49
- function collectLayers(contentsInner) {
50
- const out = [];
51
- let cursor = 0;
52
- while (cursor < contentsInner.length) {
53
- const node = findElement(contentsInner, cursor, "Layer");
54
- if (!node)
55
- break;
56
- const identifier = readTextElement(node.inner, "Identifier") ?? readTextElement(node.inner, "ows:Identifier") ?? "";
57
- if (identifier.length > 0) {
58
- const title = readTextElement(node.inner, "Title") ?? readTextElement(node.inner, "ows:Title");
59
- const abstract = readTextElement(node.inner, "Abstract") ?? readTextElement(node.inner, "ows:Abstract");
60
- const formats = collectChildText(node.inner, "Format");
61
- const styles = collectStyles(node.inner);
62
- const tileMatrixSetIds = collectTileMatrixSetLinks(node.inner);
63
- const resources = collectResources(node.inner, "tile");
64
- const featureInfoResources = collectResources(node.inner, "FeatureInfo");
65
- const bbox = readWgs84BoundingBox(node.inner);
66
- const layer = {
67
- identifier,
68
- formats,
69
- styles,
70
- tileMatrixSetIds,
71
- resourceTemplates: resources,
72
- featureInfoTemplates: featureInfoResources,
73
- };
74
- if (title !== undefined)
75
- layer.title = title;
76
- if (abstract !== undefined)
77
- layer.abstract = abstract;
78
- if (bbox !== undefined)
79
- layer.bbox = bbox;
80
- out.push(layer);
42
+ function parseOperations(node) {
43
+ const seen = new Set();
44
+ return xmlChildren(node, "Operation").flatMap((operation) => {
45
+ const name = xmlAttribute(operation, "name");
46
+ if (!name)
47
+ return [];
48
+ if (seen.has(name))
49
+ throw new Error(`WMTS repeats ${name} operation metadata.`);
50
+ seen.add(name);
51
+ const methods = [];
52
+ const getUrls = [];
53
+ const postUrls = [];
54
+ for (const dcp of xmlChildren(operation, "DCP")) {
55
+ const http = xmlChild(dcp, "HTTP");
56
+ for (const method of http?.children ?? []) {
57
+ if (method.localName !== "Get" && method.localName !== "Post")
58
+ continue;
59
+ const normalized = method.localName === "Get" ? "GET" : "POST";
60
+ if (!methods.includes(normalized))
61
+ methods.push(normalized);
62
+ const href = xmlAttribute(method, "href");
63
+ if (href)
64
+ (normalized === "GET" ? getUrls : postUrls).push(href);
65
+ }
81
66
  }
82
- cursor = node.endIndex;
67
+ return [
68
+ Object.freeze({
69
+ name,
70
+ methods: Object.freeze(methods),
71
+ getUrls: Object.freeze(unique(getUrls)),
72
+ postUrls: Object.freeze(unique(postUrls)),
73
+ }),
74
+ ];
75
+ });
76
+ }
77
+ function parseLayer(node, warnings) {
78
+ const identifier = xmlText(xmlChild(node, "Identifier"));
79
+ if (!identifier) {
80
+ warnings.push("WMTS Layer metadata without an identifier was ignored.");
81
+ return [];
83
82
  }
84
- return out;
85
- }
86
- function collectStyles(layerInner) {
87
- const out = [];
88
- let cursor = 0;
89
- while (cursor < layerInner.length) {
90
- const node = findElement(layerInner, cursor, "Style");
91
- if (!node)
92
- break;
93
- const identifier = readTextElement(node.inner, "Identifier") ?? readTextElement(node.inner, "ows:Identifier") ?? "";
94
- if (identifier.length > 0) {
95
- const title = readTextElement(node.inner, "Title") ?? readTextElement(node.inner, "ows:Title");
96
- const isDefault = readAttribute(node.openTag, "isDefault") === "true";
97
- const legend = findElement(node.inner, 0, "LegendURL");
98
- const legendUrl = legend ? readAttribute(legend.openTag, "xlink:href") : undefined;
99
- const style = { identifier, isDefault };
100
- if (title !== undefined)
101
- style.title = title;
102
- if (legendUrl !== undefined)
103
- style.legendUrl = legendUrl;
104
- out.push(style);
105
- }
106
- cursor = node.endIndex;
83
+ const bbox = parseWgs84BoundingBox(xmlChild(node, "WGS84BoundingBox"), warnings);
84
+ return [
85
+ Object.freeze({
86
+ identifier,
87
+ ...optional("title", xmlText(xmlChild(node, "Title"))),
88
+ ...optional("abstract", xmlText(xmlChild(node, "Abstract"))),
89
+ formats: Object.freeze(unique(xmlChildren(node, "Format").flatMap((entry) => xmlText(entry) ?? []))),
90
+ infoFormats: Object.freeze(unique(xmlChildren(node, "InfoFormat").flatMap((entry) => xmlText(entry) ?? []))),
91
+ styles: Object.freeze(xmlChildren(node, "Style").flatMap((style) => parseStyle(style, warnings))),
92
+ dimensions: Object.freeze(xmlChildren(node, "Dimension").flatMap((dimension) => parseDimension(dimension, warnings))),
93
+ tileMatrixSetIds: Object.freeze(unique(xmlChildren(node, "TileMatrixSetLink").flatMap((link) => xmlText(xmlChild(link, "TileMatrixSet")) ?? []))),
94
+ resourceTemplates: Object.freeze(parseResources(node, "tile", warnings)),
95
+ featureInfoTemplates: Object.freeze(parseResources(node, "FeatureInfo", warnings)),
96
+ ...(bbox ? { bbox } : {}),
97
+ }),
98
+ ];
99
+ }
100
+ function parseStyle(node, warnings) {
101
+ const identifier = xmlText(xmlChild(node, "Identifier"));
102
+ if (!identifier) {
103
+ warnings.push("WMTS Style metadata without an identifier was ignored.");
104
+ return [];
107
105
  }
108
- return out;
109
- }
110
- function collectTileMatrixSetLinks(layerInner) {
111
- const out = [];
112
- let cursor = 0;
113
- while (cursor < layerInner.length) {
114
- const node = findElement(layerInner, cursor, "TileMatrixSetLink");
115
- if (!node)
116
- break;
117
- const tms = readTextElement(node.inner, "TileMatrixSet") ?? readTextElement(node.inner, "ows:TileMatrixSet");
118
- if (tms !== undefined && tms.length > 0)
119
- out.push(tms);
120
- cursor = node.endIndex;
106
+ const legend = xmlChild(node, "LegendURL");
107
+ const isDefault = xmlAttribute(node, "isDefault")?.toLowerCase();
108
+ if (isDefault !== undefined && !["0", "1", "false", "true"].includes(isDefault)) {
109
+ warnings.push("WMTS Style isDefault metadata was malformed and treated as false.");
121
110
  }
122
- return out;
123
- }
124
- function collectResources(layerInner, resourceType) {
125
- const out = [];
126
- let cursor = 0;
127
- while (cursor < layerInner.length) {
128
- const node = findElement(layerInner, cursor, "ResourceURL");
129
- if (!node)
130
- break;
131
- const type = readAttribute(node.openTag, "resourceType");
132
- if (type === resourceType) {
133
- const format = readAttribute(node.openTag, "format") ?? "";
134
- const template = readAttribute(node.openTag, "template") ?? "";
135
- if (template.length > 0) {
136
- out.push({ format, template });
137
- }
138
- }
139
- cursor = node.endIndex;
111
+ return [
112
+ Object.freeze({
113
+ identifier,
114
+ ...optional("title", xmlText(xmlChild(node, "Title"))),
115
+ isDefault: isDefault === "true" || isDefault === "1",
116
+ ...optional("legendUrl", legend ? xmlAttribute(legend, "href") : undefined),
117
+ ...optional("legendFormat", legend ? xmlAttribute(legend, "format") : undefined),
118
+ }),
119
+ ];
120
+ }
121
+ function parseDimension(node, warnings) {
122
+ const identifier = xmlText(xmlChild(node, "Identifier"));
123
+ if (!identifier) {
124
+ warnings.push("WMTS Dimension metadata without an identifier was ignored.");
125
+ return [];
126
+ }
127
+ const current = xmlText(xmlChild(node, "Current"))?.toLowerCase();
128
+ if (current !== undefined && !["0", "1", "false", "true"].includes(current)) {
129
+ warnings.push("WMTS Dimension Current metadata was malformed and treated as false.");
140
130
  }
141
- return out;
131
+ return [
132
+ Object.freeze({
133
+ identifier,
134
+ ...optional("default", xmlText(xmlChild(node, "Default"))),
135
+ current: current === "true" || current === "1",
136
+ values: Object.freeze(unique(xmlChildren(node, "Value").flatMap((entry) => xmlText(entry) ?? []))),
137
+ }),
138
+ ];
139
+ }
140
+ function parseResources(node, resourceType, warnings) {
141
+ return xmlChildren(node, "ResourceURL").flatMap((resource) => {
142
+ if (xmlAttribute(resource, "resourceType")?.toLowerCase() !== resourceType.toLowerCase())
143
+ return [];
144
+ const template = xmlAttribute(resource, "template");
145
+ const format = xmlAttribute(resource, "format");
146
+ if (!template || !format) {
147
+ warnings.push(`WMTS ${resourceType} ResourceURL metadata without a format or template was ignored.`);
148
+ return [];
149
+ }
150
+ return [Object.freeze({ format, template })];
151
+ });
142
152
  }
143
- function readWgs84BoundingBox(layerInner) {
144
- const node = findElement(layerInner, 0, "WGS84BoundingBox") ?? findElement(layerInner, 0, "ows:WGS84BoundingBox");
153
+ function parseWgs84BoundingBox(node, warnings) {
145
154
  if (!node)
146
155
  return undefined;
147
- const lower = readTextElement(node.inner, "LowerCorner") ?? readTextElement(node.inner, "ows:LowerCorner") ?? "";
148
- const upper = readTextElement(node.inner, "UpperCorner") ?? readTextElement(node.inner, "ows:UpperCorner") ?? "";
149
- const lowerParts = lower.trim().split(/\s+/).map(Number);
150
- const upperParts = upper.trim().split(/\s+/).map(Number);
151
- if (lowerParts.length !== 2 ||
152
- upperParts.length !== 2 ||
153
- !Number.isFinite(lowerParts[0]) ||
154
- !Number.isFinite(lowerParts[1]) ||
155
- !Number.isFinite(upperParts[0]) ||
156
- !Number.isFinite(upperParts[1])) {
156
+ const lower = coordinatePair(xmlText(xmlChild(node, "LowerCorner")));
157
+ const upper = coordinatePair(xmlText(xmlChild(node, "UpperCorner")));
158
+ if (!lower ||
159
+ !upper ||
160
+ lower[0] > upper[0] ||
161
+ lower[1] > upper[1] ||
162
+ lower[0] < -180 ||
163
+ upper[0] > 180 ||
164
+ lower[1] < -90 ||
165
+ upper[1] > 90) {
166
+ warnings.push("WMTS WGS84BoundingBox metadata was malformed and ignored.");
157
167
  return undefined;
158
168
  }
159
- return {
160
- west: lowerParts[0],
161
- south: lowerParts[1],
162
- east: upperParts[0],
163
- north: upperParts[1],
164
- };
165
- }
166
- function collectTileMatrixSets(contentsInner) {
167
- const out = [];
168
- let cursor = 0;
169
- while (cursor < contentsInner.length) {
170
- const node = findElement(contentsInner, cursor, "TileMatrixSet");
171
- if (!node)
172
- break;
173
- const identifier = readTextElement(node.inner, "Identifier") ?? readTextElement(node.inner, "ows:Identifier");
174
- // Skip the per-layer `TileMatrixSet` reference inside `TileMatrixSetLink`
175
- // (those carry only an identifier and no nested `TileMatrix` children).
176
- const matrices = collectTileMatrices(node.inner);
177
- if (identifier !== undefined && identifier.length > 0 && matrices.length > 0) {
178
- const supportedCrs = readTextElement(node.inner, "SupportedCRS") ?? readTextElement(node.inner, "ows:SupportedCRS");
179
- const wellKnown = readTextElement(node.inner, "WellKnownScaleSet") ?? readTextElement(node.inner, "ows:WellKnownScaleSet");
180
- const tms = {
181
- identifier,
182
- matrices,
183
- };
184
- if (supportedCrs !== undefined)
185
- tms.supportedCrs = supportedCrs;
186
- if (wellKnown !== undefined)
187
- tms.wellKnownScaleSet = wellKnown;
188
- out.push(tms);
189
- }
190
- cursor = node.endIndex;
169
+ return Object.freeze({ west: lower[0], south: lower[1], east: upper[0], north: upper[1] });
170
+ }
171
+ function parseTileMatrixSet(node, warnings) {
172
+ const identifier = xmlText(xmlChild(node, "Identifier"));
173
+ const matrixNodes = xmlChildren(node, "TileMatrix");
174
+ const matrices = Object.freeze(matrixNodes.flatMap((matrix) => parseTileMatrix(matrix, warnings)));
175
+ if (!identifier || matrices.length === 0) {
176
+ warnings.push("WMTS TileMatrixSet metadata without an identifier or valid matrices was ignored.");
177
+ return [];
191
178
  }
192
- return out;
193
- }
194
- function collectTileMatrices(tmsInner) {
195
- const out = [];
196
- let cursor = 0;
197
- while (cursor < tmsInner.length) {
198
- const node = findElement(tmsInner, cursor, "TileMatrix");
199
- if (!node)
200
- break;
201
- const identifier = readTextElement(node.inner, "Identifier") ?? readTextElement(node.inner, "ows:Identifier") ?? "";
202
- const scale = Number.parseFloat(readTextElement(node.inner, "ScaleDenominator") ?? "");
203
- const topLeft = (readTextElement(node.inner, "TopLeftCorner") ?? "").trim().split(/\s+/).map(Number);
204
- const tileWidth = Number.parseFloat(readTextElement(node.inner, "TileWidth") ?? "");
205
- const tileHeight = Number.parseFloat(readTextElement(node.inner, "TileHeight") ?? "");
206
- const matrixWidth = Number.parseFloat(readTextElement(node.inner, "MatrixWidth") ?? "");
207
- const matrixHeight = Number.parseFloat(readTextElement(node.inner, "MatrixHeight") ?? "");
208
- if (identifier.length > 0 &&
209
- Number.isFinite(scale) &&
210
- Number.isFinite(tileWidth) &&
211
- Number.isFinite(tileHeight) &&
212
- Number.isFinite(matrixWidth) &&
213
- Number.isFinite(matrixHeight) &&
214
- topLeft.length === 2 &&
215
- Number.isFinite(topLeft[0]) &&
216
- Number.isFinite(topLeft[1])) {
217
- out.push({
218
- identifier,
219
- scaleDenominator: scale,
220
- tileWidth,
221
- tileHeight,
222
- matrixWidth,
223
- matrixHeight,
224
- topLeftCorner: [topLeft[0], topLeft[1]],
225
- });
226
- }
227
- cursor = node.endIndex;
179
+ const matrixSet = Object.freeze({
180
+ identifier,
181
+ ...optional("supportedCrs", xmlText(xmlChild(node, "SupportedCRS"))),
182
+ ...optional("wellKnownScaleSet", xmlText(xmlChild(node, "WellKnownScaleSet"))),
183
+ matrices,
184
+ });
185
+ if (matrices.length !== matrixNodes.length)
186
+ incompleteTileMatrixSets.add(matrixSet);
187
+ return [matrixSet];
188
+ }
189
+ /** @internal Whether every matrix advertised by this parsed set was structurally valid. */
190
+ export function isWmtsCapabilityTileMatrixSetComplete(matrixSet) {
191
+ return !incompleteTileMatrixSets.has(matrixSet);
192
+ }
193
+ function parseTileMatrix(node, warnings) {
194
+ const identifier = xmlText(xmlChild(node, "Identifier"));
195
+ const scaleDenominator = positiveNumber(xmlText(xmlChild(node, "ScaleDenominator")));
196
+ const tileWidth = positiveSafeInteger(xmlText(xmlChild(node, "TileWidth")));
197
+ const tileHeight = positiveSafeInteger(xmlText(xmlChild(node, "TileHeight")));
198
+ const matrixWidth = positiveSafeInteger(xmlText(xmlChild(node, "MatrixWidth")));
199
+ const matrixHeight = positiveSafeInteger(xmlText(xmlChild(node, "MatrixHeight")));
200
+ const topLeftCorner = coordinatePair(xmlText(xmlChild(node, "TopLeftCorner")));
201
+ if (!identifier ||
202
+ scaleDenominator === undefined ||
203
+ tileWidth === undefined ||
204
+ tileHeight === undefined ||
205
+ matrixWidth === undefined ||
206
+ matrixHeight === undefined ||
207
+ !topLeftCorner) {
208
+ warnings.push("WMTS TileMatrix metadata with invalid numeric fields was ignored.");
209
+ return [];
228
210
  }
229
- return out;
230
- }
231
- function collectChildText(inner, tag) {
232
- const out = [];
233
- let cursor = 0;
234
- while (cursor < inner.length) {
235
- const node = findElement(inner, cursor, tag);
236
- if (!node)
237
- break;
238
- const text = decodeXmlText(node.inner.trim());
239
- if (text.length > 0)
240
- out.push(text);
241
- cursor = node.endIndex;
242
- }
243
- return out;
244
- }
245
- function findElement(xml, from, tag) {
246
- let i = from;
247
- while (i < xml.length) {
248
- if (xml[i] !== "<") {
249
- i += 1;
250
- continue;
251
- }
252
- const next = xml[i + 1];
253
- if (next === "!" && xml.startsWith("<!--", i)) {
254
- const end = xml.indexOf("-->", i + 4);
255
- if (end < 0)
256
- return undefined;
257
- i = end + 3;
258
- continue;
259
- }
260
- if (next === "!" && xml.startsWith("<![CDATA[", i)) {
261
- const end = xml.indexOf("]]>", i + 9);
262
- if (end < 0)
263
- return undefined;
264
- i = end + 3;
265
- continue;
266
- }
267
- if (next === "?" || next === "!") {
268
- const end = xml.indexOf(">", i);
269
- if (end < 0)
270
- return undefined;
271
- i = end + 1;
272
- continue;
273
- }
274
- const isClosing = next === "/";
275
- const nameStart = isClosing ? i + 2 : i + 1;
276
- const matchesTag = xml.startsWith(tag, nameStart) && isTagBoundary(xml.charCodeAt(nameStart + tag.length));
277
- if (!matchesTag) {
278
- const close = xml.indexOf(">", i);
279
- if (close < 0)
280
- return undefined;
281
- i = close + 1;
282
- continue;
283
- }
284
- const close = xml.indexOf(">", i);
285
- if (close < 0)
286
- return undefined;
287
- const openTag = xml.slice(i, close + 1);
288
- const selfClosing = !isClosing && xml.charCodeAt(close - 1) === 47;
289
- if (selfClosing)
290
- return { openTag, inner: "", endIndex: close + 1 };
291
- if (isClosing) {
292
- i = close + 1;
293
- continue;
294
- }
295
- let depth = 1;
296
- let cursor = close + 1;
297
- while (cursor < xml.length && depth > 0) {
298
- const angle = xml.indexOf("<", cursor);
299
- if (angle < 0)
300
- break;
301
- const next2 = xml[angle + 1];
302
- if (next2 === "!" && xml.startsWith("<!--", angle)) {
303
- const end = xml.indexOf("-->", angle + 4);
304
- if (end < 0)
305
- return undefined;
306
- cursor = end + 3;
307
- continue;
308
- }
309
- if (next2 === "!" && xml.startsWith("<![CDATA[", angle)) {
310
- const end = xml.indexOf("]]>", angle + 9);
311
- if (end < 0)
312
- return undefined;
313
- cursor = end + 3;
314
- continue;
315
- }
316
- const isCloser = next2 === "/";
317
- const inspectStart = isCloser ? angle + 2 : angle + 1;
318
- const matchesSame = xml.startsWith(tag, inspectStart) && isTagBoundary(xml.charCodeAt(inspectStart + tag.length));
319
- const angleClose = xml.indexOf(">", angle);
320
- if (angleClose < 0)
321
- return undefined;
322
- if (matchesSame) {
323
- if (isCloser) {
324
- depth -= 1;
325
- if (depth === 0) {
326
- return {
327
- openTag,
328
- inner: xml.slice(close + 1, angle),
329
- endIndex: angleClose + 1,
330
- };
331
- }
332
- }
333
- else {
334
- const innerSelfClose = xml.charCodeAt(angleClose - 1) === 47;
335
- if (!innerSelfClose)
336
- depth += 1;
337
- }
338
- }
339
- cursor = angleClose + 1;
340
- }
211
+ return [
212
+ Object.freeze({
213
+ identifier,
214
+ scaleDenominator,
215
+ tileWidth,
216
+ tileHeight,
217
+ matrixWidth,
218
+ matrixHeight,
219
+ topLeftCorner: Object.freeze(topLeftCorner),
220
+ }),
221
+ ];
222
+ }
223
+ function coordinatePair(value) {
224
+ if (!value)
341
225
  return undefined;
342
- }
343
- return undefined;
344
- }
345
- function isTagBoundary(code) {
346
- return code === 32 || code === 9 || code === 10 || code === 13 || code === 47 || code === 62;
226
+ const values = value.trim().split(/\s+/).map(Number);
227
+ return values.length === 2 && values.every(Number.isFinite) ? [values[0], values[1]] : undefined;
347
228
  }
348
- function readAttribute(openTag, name) {
349
- const idx = findAttributeIndex(openTag, name);
350
- if (idx < 0)
351
- return undefined;
352
- const after = openTag.slice(idx + name.length);
353
- const eq = after.indexOf("=");
354
- if (eq < 0)
229
+ function positiveNumber(value) {
230
+ if (!value)
355
231
  return undefined;
356
- let cursor = eq + 1;
357
- while (cursor < after.length && /\s/.test(after[cursor]))
358
- cursor += 1;
359
- const quote = after[cursor];
360
- if (quote !== '"' && quote !== "'")
361
- return undefined;
362
- const end = after.indexOf(quote, cursor + 1);
363
- if (end < 0)
232
+ const parsed = Number(value);
233
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
234
+ }
235
+ function positiveSafeInteger(value) {
236
+ if (!value)
364
237
  return undefined;
365
- return decodeXmlText(after.slice(cursor + 1, end));
238
+ const parsed = Number(value);
239
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
366
240
  }
367
- function findAttributeIndex(openTag, name) {
368
- let i = 0;
369
- while (i < openTag.length) {
370
- const found = openTag.indexOf(name, i);
371
- if (found < 0)
372
- return -1;
373
- const before = openTag.charCodeAt(found - 1);
374
- const isBoundaryStart = found === 0 || before === 32 || before === 9 || before === 10 || before === 13;
375
- const after = openTag.charCodeAt(found + name.length);
376
- const isBoundaryEnd = after === 61 || after === 32 || after === 9 || after === 10 || after === 13;
377
- if (isBoundaryStart && isBoundaryEnd) {
378
- return found;
379
- }
380
- i = found + 1;
381
- }
382
- return -1;
241
+ function unique(values) {
242
+ return [...new Set(values)];
383
243
  }
384
- function readTextElement(xml, tag) {
385
- const node = findElement(xml, 0, tag);
386
- if (!node)
387
- return undefined;
388
- return decodeXmlText(node.inner.trim());
244
+ function optional(key, value) {
245
+ return value === undefined ? {} : { [key]: value };
389
246
  }
390
- function decodeXmlText(text) {
391
- if (text.indexOf("&") < 0 && text.indexOf("<![CDATA[") < 0)
392
- return text;
393
- return decodeXmlEntities(text);
247
+ function compactObject(value) {
248
+ return Object.freeze(Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)));
394
249
  }
395
- /** Find a layer by identifier in a parsed `WmtsCapabilities`. */
396
250
  export function findWmtsLayer(capabilities, identifier) {
397
- return capabilities.layers.find((l) => l.identifier === identifier);
251
+ return capabilities.layers.find((layer) => layer.identifier === identifier);
398
252
  }
399
- /** Find a tile-matrix-set by identifier. */
400
253
  export function findWmtsTileMatrixSet(capabilities, identifier) {
401
- return capabilities.tileMatrixSets.find((t) => t.identifier === identifier);
254
+ return capabilities.tileMatrixSets.find((tileMatrixSet) => tileMatrixSet.identifier === identifier);
402
255
  }