@honua/app-platform 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 (381) 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 +11 -2
  14. package/contract/index.d.ts.map +1 -1
  15. package/contract/index.js +4 -1
  16. package/contract/pmtiles.d.ts +31 -0
  17. package/contract/pmtiles.d.ts.map +1 -1
  18. package/contract/pmtiles.js +60 -20
  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 +35 -17
  32. package/contract/source.d.ts.map +1 -1
  33. package/contract/source.js +267 -71
  34. package/contract/types.d.ts +140 -4
  35. package/contract/types.d.ts.map +1 -1
  36. package/contract/types.js +6 -14
  37. package/core/bounded-json.d.ts +4 -0
  38. package/core/bounded-json.d.ts.map +1 -0
  39. package/core/bounded-json.js +38 -0
  40. package/core/cache-state.d.ts +9 -0
  41. package/core/cache-state.d.ts.map +1 -1
  42. package/core/cache-state.js +10 -0
  43. package/core/capabilities-xml.d.ts +33 -0
  44. package/core/capabilities-xml.d.ts.map +1 -0
  45. package/core/capabilities-xml.js +331 -0
  46. package/core/client.d.ts +4 -1
  47. package/core/client.d.ts.map +1 -1
  48. package/core/client.js +115 -29
  49. package/core/error-classifications.d.ts +153 -0
  50. package/core/error-classifications.d.ts.map +1 -0
  51. package/core/error-classifications.js +140 -0
  52. package/core/error-code-registry.d.ts +158 -0
  53. package/core/error-code-registry.d.ts.map +1 -0
  54. package/core/error-code-registry.js +143 -0
  55. package/core/error-envelope.d.ts +68 -0
  56. package/core/error-envelope.d.ts.map +1 -0
  57. package/core/error-envelope.js +357 -0
  58. package/core/errors.d.ts +45 -29
  59. package/core/errors.d.ts.map +1 -1
  60. package/core/errors.js +97 -50
  61. package/core/geoparquet-sql.d.ts +30 -2
  62. package/core/geoparquet-sql.d.ts.map +1 -1
  63. package/core/geoparquet-sql.js +38 -3
  64. package/core/odata-key-path.d.ts +12 -0
  65. package/core/odata-key-path.d.ts.map +1 -0
  66. package/core/odata-key-path.js +28 -0
  67. package/core/odata-write-codec.d.ts +66 -0
  68. package/core/odata-write-codec.d.ts.map +1 -0
  69. package/core/odata-write-codec.js +1083 -0
  70. package/core/odata.d.ts +59 -7
  71. package/core/odata.d.ts.map +1 -1
  72. package/core/odata.js +431 -99
  73. package/core/ogc-features.d.ts.map +1 -1
  74. package/core/ogc-features.js +3 -0
  75. package/core/ogc-maps.d.ts +7 -0
  76. package/core/ogc-maps.d.ts.map +1 -1
  77. package/core/ogc-maps.js +46 -7
  78. package/core/ogc-processes.d.ts +2 -1
  79. package/core/ogc-processes.d.ts.map +1 -1
  80. package/core/ogc-processes.js +33 -5
  81. package/core/ogc-records.d.ts +9 -0
  82. package/core/ogc-records.d.ts.map +1 -1
  83. package/core/ogc-records.js +78 -29
  84. package/core/ogc-tiles.d.ts +10 -1
  85. package/core/ogc-tiles.d.ts.map +1 -1
  86. package/core/ogc-tiles.js +56 -17
  87. package/core/path-utils.d.ts +9 -0
  88. package/core/path-utils.d.ts.map +1 -1
  89. package/core/path-utils.js +19 -0
  90. package/core/protocol-transport.d.ts +1 -0
  91. package/core/protocol-transport.d.ts.map +1 -1
  92. package/core/request-pipeline.d.ts.map +1 -1
  93. package/core/request-pipeline.js +1 -1
  94. package/core/spatial-filter.d.ts +8 -4
  95. package/core/spatial-filter.d.ts.map +1 -1
  96. package/core/spatial-filter.js +206 -16
  97. package/core/stac-static.d.ts +6 -2
  98. package/core/stac-static.d.ts.map +1 -1
  99. package/core/stac-static.js +260 -69
  100. package/core/surfaces.d.ts.map +1 -1
  101. package/core/surfaces.js +69 -5
  102. package/core/types.d.ts +125 -7
  103. package/core/types.d.ts.map +1 -1
  104. package/core/wfs-capabilities.d.ts +2 -0
  105. package/core/wfs-capabilities.d.ts.map +1 -1
  106. package/core/wfs-capabilities.js +8 -1
  107. package/core/wfs.d.ts.map +1 -1
  108. package/core/wfs.js +10 -0
  109. package/core/wms-capabilities.d.ts +56 -84
  110. package/core/wms-capabilities.d.ts.map +1 -1
  111. package/core/wms-capabilities.js +212 -509
  112. package/core/wmts-capabilities.d.ts +62 -62
  113. package/core/wmts-capabilities.d.ts.map +1 -1
  114. package/core/wmts-capabilities.js +224 -371
  115. package/esri-compat/editor.d.ts +8 -0
  116. package/esri-compat/editor.d.ts.map +1 -1
  117. package/esri-compat/editor.js +13 -0
  118. package/esri-compat/feature-layer.d.ts +2 -0
  119. package/esri-compat/feature-layer.d.ts.map +1 -1
  120. package/esri-compat/feature-layer.js +1 -0
  121. package/esri-compat/layer-list.d.ts +11 -0
  122. package/esri-compat/layer-list.d.ts.map +1 -1
  123. package/esri-compat/layer-list.js +49 -0
  124. package/esri-compat/legend.d.ts +10 -0
  125. package/esri-compat/legend.d.ts.map +1 -1
  126. package/esri-compat/legend.js +27 -0
  127. package/esri-compat/portal.d.ts +197 -0
  128. package/esri-compat/portal.d.ts.map +1 -0
  129. package/esri-compat/portal.js +251 -0
  130. package/esri-compat/renderer-objects.d.ts +40 -0
  131. package/esri-compat/renderer-objects.d.ts.map +1 -0
  132. package/esri-compat/renderer-objects.js +62 -0
  133. package/esri-compat/sketch.d.ts +43 -0
  134. package/esri-compat/sketch.d.ts.map +1 -1
  135. package/esri-compat/sketch.js +46 -0
  136. package/esri-compat/snapping.d.ts +43 -0
  137. package/esri-compat/snapping.d.ts.map +1 -0
  138. package/esri-compat/snapping.js +45 -0
  139. package/esri-compat/url.d.ts.map +1 -1
  140. package/esri-compat/url.js +1 -1
  141. package/esri-compat/widget-host.d.ts +84 -0
  142. package/esri-compat/widget-host.d.ts.map +1 -0
  143. package/esri-compat/widget-host.js +159 -0
  144. package/generated-app/errors.d.ts +18 -2
  145. package/generated-app/errors.d.ts.map +1 -1
  146. package/generated-app/errors.js +44 -11
  147. package/geocoding/index.d.ts +7 -0
  148. package/geocoding/index.d.ts.map +1 -1
  149. package/geocoding/index.js +5 -0
  150. package/geocoding/provider-http.d.ts +37 -0
  151. package/geocoding/provider-http.d.ts.map +1 -0
  152. package/geocoding/provider-http.js +91 -0
  153. package/geocoding/provider.d.ts +145 -0
  154. package/geocoding/provider.d.ts.map +1 -0
  155. package/geocoding/provider.js +41 -0
  156. package/geocoding/providers/honua.d.ts +28 -0
  157. package/geocoding/providers/honua.d.ts.map +1 -0
  158. package/geocoding/providers/honua.js +68 -0
  159. package/geocoding/providers/nominatim.d.ts +47 -0
  160. package/geocoding/providers/nominatim.d.ts.map +1 -0
  161. package/geocoding/providers/nominatim.js +105 -0
  162. package/geocoding/providers/pelias.d.ts +40 -0
  163. package/geocoding/providers/pelias.d.ts.map +1 -0
  164. package/geocoding/providers/pelias.js +115 -0
  165. package/geocoding/providers/photon.d.ts +39 -0
  166. package/geocoding/providers/photon.d.ts.map +1 -0
  167. package/geocoding/providers/photon.js +107 -0
  168. package/geometry/convert.d.ts +13 -0
  169. package/geometry/convert.d.ts.map +1 -0
  170. package/geometry/convert.js +12 -0
  171. package/geometry/index.d.ts +17 -0
  172. package/geometry/index.d.ts.map +1 -0
  173. package/geometry/index.js +15 -0
  174. package/geometry/internal.d.ts +25 -0
  175. package/geometry/internal.d.ts.map +1 -0
  176. package/geometry/internal.js +40 -0
  177. package/geometry/ops.d.ts +71 -0
  178. package/geometry/ops.d.ts.map +1 -0
  179. package/geometry/ops.js +147 -0
  180. package/geometry/project.d.ts +40 -0
  181. package/geometry/project.d.ts.map +1 -0
  182. package/geometry/project.js +88 -0
  183. package/geometry/types.d.ts +36 -0
  184. package/geometry/types.d.ts.map +1 -0
  185. package/geometry/types.js +12 -0
  186. package/map/automatic-mount-integration.d.ts +134 -0
  187. package/map/automatic-mount-integration.d.ts.map +1 -0
  188. package/map/automatic-mount-integration.js +305 -0
  189. package/map/automatic-source-strategy.d.ts +125 -0
  190. package/map/automatic-source-strategy.d.ts.map +1 -0
  191. package/map/automatic-source-strategy.js +494 -0
  192. package/map/data-to-map-bridge.d.ts +293 -0
  193. package/map/data-to-map-bridge.d.ts.map +1 -0
  194. package/map/data-to-map-bridge.js +817 -0
  195. package/map/geojson-projection.d.ts +33 -0
  196. package/map/geojson-projection.d.ts.map +1 -0
  197. package/map/geojson-projection.js +118 -0
  198. package/map/index.d.ts +14 -0
  199. package/map/index.d.ts.map +1 -1
  200. package/map/index.js +8 -0
  201. package/map/raster-source-spec.d.ts +30 -0
  202. package/map/raster-source-spec.d.ts.map +1 -0
  203. package/map/raster-source-spec.js +190 -0
  204. package/map/raster-source-strategy.d.ts +65 -0
  205. package/map/raster-source-strategy.d.ts.map +1 -0
  206. package/map/raster-source-strategy.js +232 -0
  207. package/map/source-to-maplibre.d.ts +91 -0
  208. package/map/source-to-maplibre.d.ts.map +1 -0
  209. package/map/source-to-maplibre.js +454 -0
  210. package/map/temporal-playback.d.ts +139 -0
  211. package/map/temporal-playback.d.ts.map +1 -0
  212. package/map/temporal-playback.js +247 -0
  213. package/package.json +33 -2
  214. package/query-planner/canonical.d.ts +7 -0
  215. package/query-planner/canonical.d.ts.map +1 -0
  216. package/query-planner/canonical.js +145 -0
  217. package/query-planner/cql2-json.d.ts +17 -0
  218. package/query-planner/cql2-json.d.ts.map +1 -0
  219. package/query-planner/cql2-json.js +646 -0
  220. package/query-planner/diagnostics.d.ts +35 -0
  221. package/query-planner/diagnostics.d.ts.map +1 -0
  222. package/query-planner/diagnostics.js +373 -0
  223. package/query-planner/duckdb.d.ts +79 -0
  224. package/query-planner/duckdb.d.ts.map +1 -0
  225. package/query-planner/duckdb.js +758 -0
  226. package/query-planner/execution-context.d.ts +5 -0
  227. package/query-planner/execution-context.d.ts.map +1 -0
  228. package/query-planner/execution-context.js +50 -0
  229. package/query-planner/executor.d.ts +5 -0
  230. package/query-planner/executor.d.ts.map +1 -0
  231. package/query-planner/executor.js +223 -0
  232. package/query-planner/geoservices.d.ts +91 -0
  233. package/query-planner/geoservices.d.ts.map +1 -0
  234. package/query-planner/geoservices.js +667 -0
  235. package/query-planner/grpc.d.ts +100 -0
  236. package/query-planner/grpc.d.ts.map +1 -0
  237. package/query-planner/grpc.js +736 -0
  238. package/query-planner/index.d.ts +44 -0
  239. package/query-planner/index.d.ts.map +1 -0
  240. package/query-planner/index.js +30 -0
  241. package/query-planner/ir.d.ts +20 -0
  242. package/query-planner/ir.d.ts.map +1 -0
  243. package/query-planner/ir.js +417 -0
  244. package/query-planner/local-aggregate.d.ts +5 -0
  245. package/query-planner/local-aggregate.d.ts.map +1 -0
  246. package/query-planner/local-aggregate.js +126 -0
  247. package/query-planner/odata.d.ts +48 -0
  248. package/query-planner/odata.d.ts.map +1 -0
  249. package/query-planner/odata.js +662 -0
  250. package/query-planner/ogc-compiler.d.ts +55 -0
  251. package/query-planner/ogc-compiler.d.ts.map +1 -0
  252. package/query-planner/ogc-compiler.js +480 -0
  253. package/query-planner/ogc-features.d.ts +53 -0
  254. package/query-planner/ogc-features.d.ts.map +1 -0
  255. package/query-planner/ogc-features.js +617 -0
  256. package/query-planner/planner.d.ts +17 -0
  257. package/query-planner/planner.d.ts.map +1 -0
  258. package/query-planner/planner.js +818 -0
  259. package/query-planner/resource.d.ts +94 -0
  260. package/query-planner/resource.d.ts.map +1 -0
  261. package/query-planner/resource.js +526 -0
  262. package/query-planner/semantic-canonical.d.ts +15 -0
  263. package/query-planner/semantic-canonical.d.ts.map +1 -0
  264. package/query-planner/semantic-canonical.js +62 -0
  265. package/query-planner/semantic-compat.d.ts +10 -0
  266. package/query-planner/semantic-compat.d.ts.map +1 -0
  267. package/query-planner/semantic-compat.js +35 -0
  268. package/query-planner/semantic-compiler.d.ts +64 -0
  269. package/query-planner/semantic-compiler.d.ts.map +1 -0
  270. package/query-planner/semantic-compiler.js +81 -0
  271. package/query-planner/semantic-literals.d.ts +30 -0
  272. package/query-planner/semantic-literals.d.ts.map +1 -0
  273. package/query-planner/semantic-literals.js +133 -0
  274. package/query-planner/semantic-types.d.ts +265 -0
  275. package/query-planner/semantic-types.d.ts.map +1 -0
  276. package/query-planner/semantic-types.js +1 -0
  277. package/query-planner/semantic.d.ts +54 -0
  278. package/query-planner/semantic.d.ts.map +1 -0
  279. package/query-planner/semantic.js +1421 -0
  280. package/query-planner/types.d.ts +560 -0
  281. package/query-planner/types.d.ts.map +1 -0
  282. package/query-planner/types.js +49 -0
  283. package/query-planner/wfs-semantic.d.ts +58 -0
  284. package/query-planner/wfs-semantic.d.ts.map +1 -0
  285. package/query-planner/wfs-semantic.js +547 -0
  286. package/query-planner/wfs.d.ts +6 -0
  287. package/query-planner/wfs.d.ts.map +1 -0
  288. package/query-planner/wfs.js +71 -0
  289. package/realtime/contract.d.ts +142 -0
  290. package/realtime/contract.d.ts.map +1 -0
  291. package/realtime/contract.js +154 -0
  292. package/realtime/honua-server.d.ts.map +1 -1
  293. package/realtime/honua-server.js +13 -8
  294. package/realtime/index.d.ts +19 -4
  295. package/realtime/index.d.ts.map +1 -1
  296. package/realtime/index.js +14 -4
  297. package/realtime/odata-delta.d.ts +114 -0
  298. package/realtime/odata-delta.d.ts.map +1 -0
  299. package/realtime/odata-delta.js +483 -0
  300. package/realtime/resumable-transport.d.ts +111 -0
  301. package/realtime/resumable-transport.d.ts.map +1 -0
  302. package/realtime/resumable-transport.js +406 -0
  303. package/realtime/resumable.d.ts +104 -0
  304. package/realtime/resumable.d.ts.map +1 -0
  305. package/realtime/resumable.js +632 -0
  306. package/realtime/sse.d.ts.map +1 -1
  307. package/realtime/sse.js +27 -23
  308. package/realtime/websocket.d.ts +60 -0
  309. package/realtime/websocket.d.ts.map +1 -0
  310. package/realtime/websocket.js +157 -0
  311. package/realtime/wire.d.ts +27 -0
  312. package/realtime/wire.d.ts.map +1 -0
  313. package/realtime/wire.js +57 -0
  314. package/replica-sync/errors.d.ts +2 -1
  315. package/replica-sync/errors.d.ts.map +1 -1
  316. package/replica-sync/errors.js +33 -2
  317. package/runtime/edit-snapping.d.ts +107 -0
  318. package/runtime/edit-snapping.d.ts.map +1 -0
  319. package/runtime/edit-snapping.js +190 -0
  320. package/runtime/errors.d.ts +3 -2
  321. package/runtime/errors.d.ts.map +1 -1
  322. package/runtime/errors.js +19 -2
  323. package/runtime/index.d.ts +6 -0
  324. package/runtime/index.d.ts.map +1 -1
  325. package/runtime/index.js +3 -0
  326. package/runtime/maplibre-renderer.d.ts +41 -0
  327. package/runtime/maplibre-renderer.d.ts.map +1 -0
  328. package/runtime/maplibre-renderer.js +322 -0
  329. package/runtime/query-tiles.d.ts +2 -1
  330. package/runtime/query-tiles.d.ts.map +1 -1
  331. package/runtime/query-tiles.js +6 -2
  332. package/runtime/source-bridge.d.ts +4 -4
  333. package/runtime/source-bridge.d.ts.map +1 -1
  334. package/runtime/source-bridge.js +9 -56
  335. package/runtime/style-interactions.d.ts +3 -2
  336. package/runtime/style-interactions.d.ts.map +1 -1
  337. package/runtime/style-interactions.js +11 -3
  338. package/runtime/terra-draw-sketch.d.ts +275 -0
  339. package/runtime/terra-draw-sketch.d.ts.map +1 -0
  340. package/runtime/terra-draw-sketch.js +404 -0
  341. package/scene-workspace/index.d.ts +4 -0
  342. package/scene-workspace/index.d.ts.map +1 -1
  343. package/scene-workspace/index.js +2 -0
  344. package/scene-workspace/source-to-cesium.d.ts +116 -0
  345. package/scene-workspace/source-to-cesium.d.ts.map +1 -0
  346. package/scene-workspace/source-to-cesium.js +791 -0
  347. package/scene-workspace/state-sync.d.ts +147 -0
  348. package/scene-workspace/state-sync.d.ts.map +1 -0
  349. package/scene-workspace/state-sync.js +1123 -0
  350. package/source-capability-registry.d.ts +1 -0
  351. package/source-capability-registry.js +1 -0
  352. package/source-capability-types.d.ts +186 -0
  353. package/source-capability-types.js +7 -0
  354. package/style/index.d.ts +2 -0
  355. package/style/index.d.ts.map +1 -1
  356. package/style/index.js +2 -0
  357. package/style/renderers.d.ts +326 -0
  358. package/style/renderers.d.ts.map +1 -0
  359. package/style/renderers.js +517 -0
  360. package/web-components/controller.d.ts +2 -0
  361. package/web-components/controller.d.ts.map +1 -1
  362. package/web-components/controller.js +49 -8
  363. package/web-components/elements.d.ts +95 -1
  364. package/web-components/elements.d.ts.map +1 -1
  365. package/web-components/elements.js +458 -19
  366. package/web-components/index.d.ts +8 -1
  367. package/web-components/index.d.ts.map +1 -1
  368. package/web-components/index.js +7 -0
  369. package/web-components/maplibre-renderer.d.ts.map +1 -1
  370. package/web-components/maplibre-renderer.js +87 -0
  371. package/web-components/measurement.d.ts +69 -0
  372. package/web-components/measurement.d.ts.map +1 -0
  373. package/web-components/measurement.js +523 -0
  374. package/web-components/types.d.ts +109 -0
  375. package/web-components/types.d.ts.map +1 -1
  376. package/webmap/convert-renderer.d.ts +24 -3
  377. package/webmap/convert-renderer.d.ts.map +1 -1
  378. package/webmap/convert-renderer.js +93 -112
  379. package/webmap/index.d.ts +1 -1
  380. package/webmap/index.d.ts.map +1 -1
  381. package/webmap/index.js +1 -1
@@ -0,0 +1,55 @@
1
+ import type { CanonicalGeometry, CrsDefinition, ExecutableBoundingBox, ExecutableCrsBinding, ExecutableGeometryValue, JsonValue, LogicalField, SourceProtocol, SourceSchemaV2 } from "../contract/schema.js";
2
+ export interface OgcAxisPlan {
3
+ readonly srsName: string;
4
+ /** Target/definition-axis index to source/payload-axis index. */
5
+ readonly permutation: readonly number[];
6
+ }
7
+ export interface NormalizedNamespaceBindings {
8
+ readonly bindings: Readonly<Record<string, string>>;
9
+ readonly ordered: readonly (readonly [string, string])[];
10
+ }
11
+ /** @internal Normalize an explicit conformance declaration without inferring support. */
12
+ export declare function normalizeConformanceUris(value: readonly string[], path: string): readonly string[];
13
+ /** @internal Normalize explicit CRS/namespace-style URI evidence. */
14
+ export declare function normalizeIdentifierUris(value: readonly string[] | undefined, path: string): readonly string[];
15
+ /** @internal Stable identity for normalized source capability evidence. */
16
+ export declare function compilerEvidenceFingerprint(domain: string, evidence: JsonValue): `sha256:${string}`;
17
+ /** @internal Stable identity for an immutable compiled request pre-image. */
18
+ export declare function compiledRequestFingerprint(domain: string, artifact: JsonValue): `sha256:${string}`;
19
+ /** @internal Match only the OGC conformance identifier itself, not a substring. */
20
+ export declare function hasConformanceClass(conformsTo: readonly string[], standard: string, name: string): boolean;
21
+ /** @internal Select the physical source property represented by one logical field. */
22
+ export declare function ogcFieldPath(schema: SourceSchemaV2, name: string, protocol: Extract<SourceProtocol, "ogc-features" | "wfs">, path: string): readonly string[];
23
+ /** @internal Require a single CQL2 queryable name. */
24
+ export declare function cql2FieldName(schema: SourceSchemaV2, name: string, path: string): string;
25
+ /** @internal Require a namespace-safe FES ValueReference. */
26
+ export declare function fesValueReference(schema: SourceSchemaV2, name: string, namespaces: NormalizedNamespaceBindings, path: string): string;
27
+ /** @internal Validate and deterministically order namespace bindings. */
28
+ export declare function normalizeNamespaceBindings(value: Readonly<Record<string, string>> | undefined, path: string): NormalizedNamespaceBindings;
29
+ /** @internal Verify a QName used for a WFS feature type. */
30
+ export declare function validateFesTypeName(typeName: string, namespaces: NormalizedNamespaceBindings, path: string): string;
31
+ /** @internal Produce a URI usable as CQL2 filter-crs, WFS srsName, or output CRS. */
32
+ export declare function ogcCrsUri(definition: CrsDefinition, path: string): string;
33
+ /** @internal Build an executable axis reordering plan; this never transforms values or units. */
34
+ export declare function ogcAxisPlan(binding: ExecutableCrsBinding, dimensions: 2 | 3, path: string): OgcAxisPlan;
35
+ /** @internal Reorder a validated semantic geometry into CRS-definition axis order. */
36
+ export declare function geometryInDefinitionOrder(value: ExecutableGeometryValue, path: string): CanonicalGeometry;
37
+ /** @internal Reorder a validated semantic bounding box into CRS-definition axis order. */
38
+ export declare function bboxInDefinitionOrder(value: ExecutableBoundingBox, path: string): readonly number[];
39
+ /** @internal Return the executable filter CRS after verifying every spatial leaf agrees. */
40
+ export declare function sharedFilterCrs(current: ExecutableCrsBinding | undefined, next: ExecutableCrsBinding, path: string): ExecutableCrsBinding;
41
+ /** @internal Resolve the field metadata used to encode typed literals. */
42
+ export declare function compilerField(schema: SourceSchemaV2, name: string, path: string): LogicalField;
43
+ /** @internal CQL2 identifiers follow the XML-Name-derived grammar in CQL2 1.0. */
44
+ export declare function cql2Identifier(value: string, path: string): string;
45
+ /** @internal Encode a CQL2 character literal with all standardized control escapes. */
46
+ export declare function cql2StringLiteral(value: string, path: string): string;
47
+ /** @internal Escape XML 1.0 character data after rejecting unrepresentable code points. */
48
+ export declare function xmlText(value: string, path: string): string;
49
+ /** @internal Escape XML 1.0 attribute data after rejecting unrepresentable code points. */
50
+ export declare function xmlAttribute(value: string, path: string): string;
51
+ /** @internal Canonical finite-number rendering shared by CQL2, WKT, and GML. */
52
+ export declare function ogcNumber(value: number, path: string): string;
53
+ /** @internal Convert canonical geometry to deterministic WKT after axis reordering. */
54
+ export declare function geometryToWkt(value: CanonicalGeometry, layout: "xy" | "xyz", path: string): string;
55
+ //# sourceMappingURL=ogc-compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ogc-compiler.d.ts","sourceRoot":"","sources":["../../../src/query-planner/ogc-compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,480 @@
1
+ import { canonicalStringify, sha256, toJsonValue } from "./canonical.js";
2
+ import { semanticSchemaField, semanticUnsupported } from "./semantic-compiler.js";
3
+ import { HonuaQueryPlanningError } from "./types.js";
4
+ const MAX_EVIDENCE_ENTRIES = 256;
5
+ const MAX_EVIDENCE_TEXT_BYTES = 8_192;
6
+ const MAX_NAMESPACE_BINDINGS = 64;
7
+ const MAX_NAMESPACE_TEXT_BYTES = 2_048;
8
+ const TEXT_ENCODER = new TextEncoder();
9
+ /** @internal Normalize an explicit conformance declaration without inferring support. */
10
+ export function normalizeConformanceUris(value, path) {
11
+ if (!Array.isArray(value))
12
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be an array`);
13
+ if (value.length > MAX_EVIDENCE_ENTRIES) {
14
+ throw new HonuaQueryPlanningError("invalid-query", `${path} exceeds the ${MAX_EVIDENCE_ENTRIES}-entry evidence bound`);
15
+ }
16
+ const normalized = value.map((entry, index) => normalizeEvidenceUri(entry, `${path}[${index}]`));
17
+ normalized.sort(compareUtf8);
18
+ for (let index = 1; index < normalized.length; index += 1) {
19
+ if (normalized[index] === normalized[index - 1]) {
20
+ throw new HonuaQueryPlanningError("invalid-query", `${path} contains duplicate conformance URI`);
21
+ }
22
+ }
23
+ return Object.freeze(normalized);
24
+ }
25
+ /** @internal Normalize explicit CRS/namespace-style URI evidence. */
26
+ export function normalizeIdentifierUris(value, path) {
27
+ if (value === undefined)
28
+ return Object.freeze([]);
29
+ if (!Array.isArray(value))
30
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be an array`);
31
+ if (value.length > MAX_EVIDENCE_ENTRIES) {
32
+ throw new HonuaQueryPlanningError("invalid-query", `${path} exceeds the ${MAX_EVIDENCE_ENTRIES}-entry evidence bound`);
33
+ }
34
+ const normalized = value.map((entry, index) => {
35
+ if (typeof entry !== "string" || entry.length === 0 || byteLength(entry) > MAX_EVIDENCE_TEXT_BYTES) {
36
+ throw new HonuaQueryPlanningError("invalid-query", `${path}[${index}] must be a bounded non-empty URI`);
37
+ }
38
+ assertAbsolutePublicIdentifier(entry, `${path}[${index}]`);
39
+ return entry;
40
+ });
41
+ normalized.sort(compareUtf8);
42
+ for (let index = 1; index < normalized.length; index += 1) {
43
+ if (normalized[index] === normalized[index - 1]) {
44
+ throw new HonuaQueryPlanningError("invalid-query", `${path} contains duplicate URI evidence`);
45
+ }
46
+ }
47
+ return Object.freeze(normalized);
48
+ }
49
+ /** @internal Stable identity for normalized source capability evidence. */
50
+ export function compilerEvidenceFingerprint(domain, evidence) {
51
+ return sha256(`${domain}\n${canonicalStringify(evidence)}`);
52
+ }
53
+ /** @internal Stable identity for an immutable compiled request pre-image. */
54
+ export function compiledRequestFingerprint(domain, artifact) {
55
+ return sha256(`${domain}\n${canonicalStringify(artifact)}`);
56
+ }
57
+ /** @internal Match only the OGC conformance identifier itself, not a substring. */
58
+ export function hasConformanceClass(conformsTo, standard, name) {
59
+ const expected = `/spec/${standard.toLowerCase()}/conf/${name.toLowerCase()}`;
60
+ return conformsTo.some((entry) => {
61
+ const url = new URL(entry);
62
+ return (url.hostname.toLowerCase() === "www.opengis.net" && trimTrailingSlash(url.pathname).toLowerCase() === expected);
63
+ });
64
+ }
65
+ /** @internal Select the physical source property represented by one logical field. */
66
+ export function ogcFieldPath(schema, name, protocol, path) {
67
+ const field = semanticSchemaField(schema, name, path);
68
+ const nativePaths = field.native
69
+ .filter((entry) => entry.protocol === protocol && entry.path !== undefined)
70
+ .map((entry) => entry.path);
71
+ if (nativePaths.length > 1) {
72
+ const identities = new Set(nativePaths.map((entry) => canonicalStringify(toJsonValue(entry))));
73
+ if (identities.size > 1) {
74
+ semanticUnsupported("unsupported-source", path, `${protocol} field ${JSON.stringify(name)} has conflicting native property paths`);
75
+ }
76
+ }
77
+ return nativePaths[0] ?? field.path;
78
+ }
79
+ /** @internal Require a single CQL2 queryable name. */
80
+ export function cql2FieldName(schema, name, path) {
81
+ const fieldPath = ogcFieldPath(schema, name, "ogc-features", path);
82
+ if (fieldPath.length !== 1) {
83
+ semanticUnsupported("unsupported-source", path, `CQL2 property ${JSON.stringify(name)} must resolve to exactly one native path segment`);
84
+ }
85
+ return fieldPath[0];
86
+ }
87
+ /** @internal Require a namespace-safe FES ValueReference. */
88
+ export function fesValueReference(schema, name, namespaces, path) {
89
+ const segments = ogcFieldPath(schema, name, "wfs", path);
90
+ for (const [index, segment] of segments.entries()) {
91
+ assertFesPathSegment(segment, namespaces, `${path}.nativePath[${index}]`);
92
+ }
93
+ return segments.join("/");
94
+ }
95
+ /** @internal Validate and deterministically order namespace bindings. */
96
+ export function normalizeNamespaceBindings(value, path) {
97
+ if (value === undefined)
98
+ return { bindings: Object.freeze({}), ordered: Object.freeze([]) };
99
+ if (value === null || Array.isArray(value) || typeof value !== "object") {
100
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a plain object`);
101
+ }
102
+ const prototype = Object.getPrototypeOf(value);
103
+ if (prototype !== Object.prototype && prototype !== null) {
104
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a plain object`);
105
+ }
106
+ const entries = Object.entries(value);
107
+ if (entries.length > MAX_NAMESPACE_BINDINGS) {
108
+ throw new HonuaQueryPlanningError("invalid-query", `${path} exceeds the ${MAX_NAMESPACE_BINDINGS}-binding namespace bound`);
109
+ }
110
+ const bindings = {};
111
+ for (const [prefix, uri] of entries) {
112
+ if (!XML_PREFIX.test(prefix) ||
113
+ prefix.toLowerCase().startsWith("xml") ||
114
+ RESERVED_FES_PREFIXES.has(prefix.toLowerCase())) {
115
+ throw new HonuaQueryPlanningError("invalid-query", `${path}.${prefix} is not a safe XML namespace prefix`);
116
+ }
117
+ if (typeof uri !== "string" || uri.length === 0 || byteLength(uri) > MAX_NAMESPACE_TEXT_BYTES) {
118
+ throw new HonuaQueryPlanningError("invalid-query", `${path}.${prefix} must be a bounded non-empty URI`);
119
+ }
120
+ assertAbsolutePublicIdentifier(uri, `${path}.${prefix}`);
121
+ bindings[prefix] = uri;
122
+ }
123
+ const ordered = Object.entries(bindings).sort(([left], [right]) => compareUtf8(left, right));
124
+ const normalizedBindings = Object.fromEntries(ordered);
125
+ return {
126
+ bindings: Object.freeze(normalizedBindings),
127
+ ordered: Object.freeze(ordered.map((entry) => Object.freeze(entry))),
128
+ };
129
+ }
130
+ /** @internal Verify a QName used for a WFS feature type. */
131
+ export function validateFesTypeName(typeName, namespaces, path) {
132
+ if (typeof typeName !== "string" || typeName.length === 0 || typeName.length > 512) {
133
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a bounded non-empty QName`);
134
+ }
135
+ assertFesPathSegment(typeName, namespaces, path);
136
+ return typeName;
137
+ }
138
+ /** @internal Produce a URI usable as CQL2 filter-crs, WFS srsName, or output CRS. */
139
+ export function ogcCrsUri(definition, path) {
140
+ if (definition.kind === "authority") {
141
+ if (definition.uri !== undefined) {
142
+ assertAbsolutePublicIdentifier(definition.uri, path);
143
+ return definition.uri;
144
+ }
145
+ const authority = encodeURIComponent(definition.authority);
146
+ const version = encodeURIComponent(definition.version ?? "0");
147
+ const code = encodeURIComponent(definition.code);
148
+ return `http://www.opengis.net/def/crs/${authority}/${version}/${code}`;
149
+ }
150
+ if (definition.kind === "uri") {
151
+ assertAbsolutePublicIdentifier(definition.uri, path);
152
+ return definition.uri;
153
+ }
154
+ semanticUnsupported("unsupported-crs", path, `OGC request parameters require an authority or URI CRS, not ${definition.kind}`);
155
+ }
156
+ /** @internal Build an executable axis reordering plan; this never transforms values or units. */
157
+ export function ogcAxisPlan(binding, dimensions, path) {
158
+ if (binding.coordinateEpoch !== undefined) {
159
+ semanticUnsupported("crs-transform-required", path, "OGC filter encodings cannot preserve a coordinate epoch");
160
+ }
161
+ const targetOrder = binding.definition.definitionAxisOrder;
162
+ if (targetOrder.state !== "known") {
163
+ semanticUnsupported("unsupported-crs", path, "OGC filter execution requires known CRS-definition axis order");
164
+ }
165
+ const sourceAxes = binding.coordinateOrder.axes;
166
+ const targetAxes = targetOrder.axes;
167
+ if (sourceAxes.length !== dimensions || targetAxes.length !== dimensions) {
168
+ semanticUnsupported("crs-transform-required", path, `OGC filter execution requires exactly ${dimensions} source and CRS-definition axes for the coordinate layout`);
169
+ }
170
+ const unused = new Set(sourceAxes.map((_, index) => index));
171
+ const permutation = targetAxes.map((target) => {
172
+ const matches = [...unused].filter((index) => {
173
+ const source = sourceAxes[index];
174
+ return source?.direction === target.direction && normalizeUnit(source.unit) === normalizeUnit(target.unit);
175
+ });
176
+ if (matches.length !== 1) {
177
+ semanticUnsupported("crs-transform-required", path, "payload axes cannot be reordered losslessly into CRS-definition order");
178
+ }
179
+ const index = matches[0];
180
+ unused.delete(index);
181
+ return index;
182
+ });
183
+ return { srsName: ogcCrsUri(binding.definition, path), permutation };
184
+ }
185
+ /** @internal Reorder a validated semantic geometry into CRS-definition axis order. */
186
+ export function geometryInDefinitionOrder(value, path) {
187
+ if (value.layout !== "xy" && value.layout !== "xyz") {
188
+ semanticUnsupported("unsupported-geometry", `${path}.layout`, "OGC CQL2/FES geometry literals cannot preserve measured coordinate layouts");
189
+ }
190
+ const dimensions = value.layout === "xy" ? 2 : 3;
191
+ const plan = ogcAxisPlan(value.crs, dimensions, `${path}.crs`);
192
+ return mapGeometryPositions(value.geometry, (position) => reorderPosition(position, plan.permutation));
193
+ }
194
+ /** @internal Reorder a validated semantic bounding box into CRS-definition axis order. */
195
+ export function bboxInDefinitionOrder(value, path) {
196
+ const layout = value.box.layout;
197
+ if (layout !== "xy" && layout !== "xyz") {
198
+ semanticUnsupported("unsupported-geometry", `${path}.box.layout`, "OGC CQL2/FES bounding boxes cannot preserve measured coordinate layouts");
199
+ }
200
+ const dimensions = layout === "xy" ? 2 : 3;
201
+ const plan = ogcAxisPlan(value.crs, dimensions, `${path}.crs`);
202
+ const lower = value.box.bounds.slice(0, dimensions);
203
+ const upper = value.box.bounds.slice(dimensions);
204
+ return [
205
+ ...plan.permutation.map((index) => lower[index]),
206
+ ...plan.permutation.map((index) => upper[index]),
207
+ ];
208
+ }
209
+ /** @internal Return the executable filter CRS after verifying every spatial leaf agrees. */
210
+ export function sharedFilterCrs(current, next, path) {
211
+ if (current === undefined)
212
+ return next;
213
+ const left = canonicalStringify(toJsonValue({
214
+ definition: current.definition,
215
+ coordinateOrder: current.coordinateOrder,
216
+ coordinateEpoch: current.coordinateEpoch ?? null,
217
+ }));
218
+ const right = canonicalStringify(toJsonValue({
219
+ definition: next.definition,
220
+ coordinateOrder: next.coordinateOrder,
221
+ coordinateEpoch: next.coordinateEpoch ?? null,
222
+ }));
223
+ if (left !== right) {
224
+ semanticUnsupported("crs-transform-required", path, "one compiled filter cannot mix spatial operands with different executable CRS bindings");
225
+ }
226
+ return current;
227
+ }
228
+ /** @internal Resolve the field metadata used to encode typed literals. */
229
+ export function compilerField(schema, name, path) {
230
+ return semanticSchemaField(schema, name, path);
231
+ }
232
+ /** @internal CQL2 identifiers follow the XML-Name-derived grammar in CQL2 1.0. */
233
+ export function cql2Identifier(value, path) {
234
+ if (!CQL_IDENTIFIER.test(value)) {
235
+ semanticUnsupported("unsupported-source", path, `CQL2 text cannot represent queryable identifier ${JSON.stringify(value)}`);
236
+ }
237
+ return CQL_KEYWORDS.has(value.toUpperCase()) ? `"${value}"` : value;
238
+ }
239
+ /** @internal Encode a CQL2 character literal with all standardized control escapes. */
240
+ export function cql2StringLiteral(value, path) {
241
+ let output = "";
242
+ for (const character of value) {
243
+ const code = character.codePointAt(0);
244
+ const controlEscape = CQL2_CONTROL_ESCAPES[code];
245
+ if (character === "\\")
246
+ output += "\\\\";
247
+ else if (character === "'")
248
+ output += "''";
249
+ else if (controlEscape !== undefined)
250
+ output += controlEscape;
251
+ else if (code < 0x20 || code === 0x7f) {
252
+ semanticUnsupported("unsupported-node", path, `CQL2 text cannot preserve control character U+${hex(code)}`);
253
+ }
254
+ else
255
+ output += character;
256
+ }
257
+ return `'${output}'`;
258
+ }
259
+ const CQL2_CONTROL_ESCAPES = Object.freeze({
260
+ 7: "\\a",
261
+ 8: "\\b",
262
+ 9: "\\t",
263
+ 10: "\\n",
264
+ 11: "\\v",
265
+ 12: "\\f",
266
+ 13: "\\r",
267
+ });
268
+ /** @internal Escape XML 1.0 character data after rejecting unrepresentable code points. */
269
+ export function xmlText(value, path) {
270
+ assertXmlCharacters(value, path);
271
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
272
+ }
273
+ /** @internal Escape XML 1.0 attribute data after rejecting unrepresentable code points. */
274
+ export function xmlAttribute(value, path) {
275
+ return xmlText(value, path).replaceAll('"', "&quot;").replaceAll("'", "&apos;");
276
+ }
277
+ /** @internal Canonical finite-number rendering shared by CQL2, WKT, and GML. */
278
+ export function ogcNumber(value, path) {
279
+ if (!Number.isFinite(value))
280
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be finite`);
281
+ return Object.is(value, -0) ? "0" : String(value);
282
+ }
283
+ /** @internal Convert canonical geometry to deterministic WKT after axis reordering. */
284
+ export function geometryToWkt(value, layout, path) {
285
+ const suffix = layout === "xyz" ? " Z" : "";
286
+ const position = (entry, entryPath) => entry.map((ordinate, index) => ogcNumber(ordinate, `${entryPath}[${index}]`)).join(" ");
287
+ const sequence = (entries, entryPath) => entries.map((entry, index) => position(entry, `${entryPath}[${index}]`)).join(", ");
288
+ const polygon = (rings, entryPath) => rings.map((ring, index) => `(${sequence(ring, `${entryPath}[${index}]`)})`).join(", ");
289
+ switch (value.type) {
290
+ case "Point":
291
+ return `POINT${suffix} (${position(value.coordinates, `${path}.coordinates`)})`;
292
+ case "MultiPoint":
293
+ return `MULTIPOINT${suffix} (${value.coordinates
294
+ .map((entry, index) => `(${position(entry, `${path}.coordinates[${index}]`)})`)
295
+ .join(", ")})`;
296
+ case "LineString":
297
+ return `LINESTRING${suffix} (${sequence(value.coordinates, `${path}.coordinates`)})`;
298
+ case "MultiLineString":
299
+ return `MULTILINESTRING${suffix} (${value.coordinates
300
+ .map((entry, index) => `(${sequence(entry, `${path}.coordinates[${index}]`)})`)
301
+ .join(", ")})`;
302
+ case "Polygon":
303
+ return `POLYGON${suffix} (${polygon(value.coordinates, `${path}.coordinates`)})`;
304
+ case "MultiPolygon":
305
+ return `MULTIPOLYGON${suffix} (${value.coordinates
306
+ .map((entry, index) => `(${polygon(entry, `${path}.coordinates[${index}]`)})`)
307
+ .join(", ")})`;
308
+ case "GeometryCollection":
309
+ return `GEOMETRYCOLLECTION${suffix} (${value.geometries
310
+ .map((entry, index) => geometryToWkt(entry, layout, `${path}.geometries[${index}]`))
311
+ .join(", ")})`;
312
+ }
313
+ }
314
+ /** @internal JSON-safe deep coordinate reorder. */
315
+ function mapGeometryPositions(value, transform) {
316
+ const mapPositions = (input) => {
317
+ if (!Array.isArray(input))
318
+ return input;
319
+ if (input.length >= 2 && input.every((entry) => typeof entry === "number")) {
320
+ return transform(input);
321
+ }
322
+ return input.map(mapPositions);
323
+ };
324
+ if (value.type === "GeometryCollection") {
325
+ return {
326
+ type: value.type,
327
+ geometries: value.geometries.map((entry) => mapGeometryPositions(entry, transform)),
328
+ };
329
+ }
330
+ return { type: value.type, coordinates: mapPositions(value.coordinates) };
331
+ }
332
+ function reorderPosition(value, permutation) {
333
+ return permutation.map((index) => value[index]);
334
+ }
335
+ function normalizeEvidenceUri(value, path) {
336
+ if (typeof value !== "string" || value.length === 0 || byteLength(value) > MAX_EVIDENCE_TEXT_BYTES) {
337
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a bounded non-empty URI`);
338
+ }
339
+ let url;
340
+ try {
341
+ url = new URL(value);
342
+ }
343
+ catch {
344
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be an absolute URI`);
345
+ }
346
+ if ((url.protocol !== "http:" && url.protocol !== "https:") ||
347
+ url.username ||
348
+ url.password ||
349
+ url.search ||
350
+ url.hash) {
351
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a credential-free HTTP(S) conformance URI`);
352
+ }
353
+ url.protocol = "https:";
354
+ url.hostname = url.hostname.toLowerCase();
355
+ url.pathname = trimTrailingSlash(url.pathname);
356
+ return url.toString();
357
+ }
358
+ function assertAbsolutePublicIdentifier(value, path) {
359
+ let url;
360
+ try {
361
+ url = new URL(value);
362
+ }
363
+ catch {
364
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be an absolute URI`);
365
+ }
366
+ if (!new Set(["http:", "https:", "urn:"]).has(url.protocol) ||
367
+ url.username ||
368
+ url.password ||
369
+ url.search ||
370
+ url.hash) {
371
+ throw new HonuaQueryPlanningError("invalid-query", `${path} must be a credential-free HTTP(S) URI or URN`);
372
+ }
373
+ }
374
+ function assertFesPathSegment(value, namespaces, path) {
375
+ if (!FES_PATH_SEGMENT.test(value)) {
376
+ semanticUnsupported("unsupported-source", path, `FES ValueReference segment ${JSON.stringify(value)} is outside the safe QName subset`);
377
+ }
378
+ const colon = value.indexOf(":");
379
+ if (colon >= 0) {
380
+ const prefix = value.slice(0, colon);
381
+ if (!Object.hasOwn(namespaces.bindings, prefix)) {
382
+ semanticUnsupported("unsupported-source", path, `FES QName prefix ${JSON.stringify(prefix)} has no namespace binding`);
383
+ }
384
+ }
385
+ }
386
+ function assertXmlCharacters(value, path) {
387
+ for (const character of value) {
388
+ const code = character.codePointAt(0);
389
+ const valid = code === 0x09 ||
390
+ code === 0x0a ||
391
+ code === 0x0d ||
392
+ (code >= 0x20 && code <= 0xd7ff) ||
393
+ (code >= 0xe000 && code <= 0xfffd) ||
394
+ (code >= 0x10000 && code <= 0x10ffff);
395
+ if (!valid)
396
+ semanticUnsupported("unsupported-node", path, `XML 1.0 cannot preserve character U+${hex(code)}`);
397
+ }
398
+ }
399
+ function byteLength(value) {
400
+ return TEXT_ENCODER.encode(value).byteLength;
401
+ }
402
+ function trimTrailingSlash(value) {
403
+ return value.length > 1 ? value.replace(/\/+$/, "") : value;
404
+ }
405
+ function compareUtf8(left, right) {
406
+ const leftBytes = TEXT_ENCODER.encode(left);
407
+ const rightBytes = TEXT_ENCODER.encode(right);
408
+ const length = Math.min(leftBytes.length, rightBytes.length);
409
+ for (let index = 0; index < length; index += 1) {
410
+ const difference = leftBytes[index] - rightBytes[index];
411
+ if (difference !== 0)
412
+ return difference;
413
+ }
414
+ return leftBytes.length - rightBytes.length;
415
+ }
416
+ function normalizeUnit(value) {
417
+ return value.trim().toLowerCase().replaceAll(" ", "-");
418
+ }
419
+ function hex(value) {
420
+ return value.toString(16).toUpperCase().padStart(4, "0");
421
+ }
422
+ const XML_NAME_START = "(?:[_\\p{L}]|[\\p{Nl}])";
423
+ const XML_NAME_PART = "(?:[-._\\p{L}\\p{Nl}\\p{N}\\p{M}\\u00B7\\u203F\\u2040])";
424
+ const XML_PREFIX = new RegExp(`^${XML_NAME_START}${XML_NAME_PART}*$`, "u");
425
+ const RESERVED_FES_PREFIXES = new Set(["fes", "gml", "wfs", "xs", "xsi"]);
426
+ const FES_QNAME = `(?:${XML_NAME_START}${XML_NAME_PART}*:)?${XML_NAME_START}${XML_NAME_PART}*`;
427
+ const FES_PATH_SEGMENT = new RegExp(`^${FES_QNAME}$`, "u");
428
+ const CQL_IDENTIFIER = new RegExp(`^(?::|${XML_NAME_START})(?::|${XML_NAME_PART})*$`, "u");
429
+ const CQL_KEYWORDS = new Set([
430
+ "A_EQUALS",
431
+ "A_CONTAINS",
432
+ "A_CONTAINEDBY",
433
+ "A_OVERLAPS",
434
+ "ACCENTI",
435
+ "AND",
436
+ "BBOX",
437
+ "BETWEEN",
438
+ "CASEI",
439
+ "DATE",
440
+ "DIV",
441
+ "FALSE",
442
+ "GEOMETRYCOLLECTION",
443
+ "IN",
444
+ "IS",
445
+ "LIKE",
446
+ "LINESTRING",
447
+ "MULTILINESTRING",
448
+ "MULTIPOINT",
449
+ "MULTIPOLYGON",
450
+ "NOT",
451
+ "NULL",
452
+ "OR",
453
+ "POINT",
454
+ "POLYGON",
455
+ "S_INTERSECTS",
456
+ "S_EQUALS",
457
+ "S_DISJOINT",
458
+ "S_TOUCHES",
459
+ "S_WITHIN",
460
+ "S_OVERLAPS",
461
+ "S_CROSSES",
462
+ "S_CONTAINS",
463
+ "T_AFTER",
464
+ "T_BEFORE",
465
+ "T_CONTAINS",
466
+ "T_DISJOINT",
467
+ "T_DURING",
468
+ "T_EQUALS",
469
+ "T_FINISHEDBY",
470
+ "T_FINISHES",
471
+ "T_INTERSECTS",
472
+ "T_MEETS",
473
+ "T_METBY",
474
+ "T_OVERLAPPEDBY",
475
+ "T_OVERLAPS",
476
+ "T_STARTEDBY",
477
+ "T_STARTS",
478
+ "TIMESTAMP",
479
+ "TRUE",
480
+ ]);
@@ -0,0 +1,53 @@
1
+ import type { ExecutableCrsBinding, SourceSchemaV2 } from "../contract/schema.js";
2
+ import { type SemanticCompilationResult } from "./semantic-compiler.js";
3
+ import type { SemanticQuery, SourceSpatiality } from "./semantic-types.js";
4
+ import type { CanonicalQuery, OgcApiFeaturesCompiledQueryV1, QueryIrSourceIdentity } from "./types.js";
5
+ export type Cql2FilterLanguage = "cql2-json" | "cql2-text";
6
+ /** Explicit metadata discovered for the concrete OGC API Features source. */
7
+ export interface OgcApiFeaturesFilterConformanceEvidence {
8
+ /** Exact `/conformance` response values. No protocol defaults are inferred. */
9
+ readonly conformsTo: readonly string[];
10
+ /** Collection/filter CRS identifiers discovered from Part 2/OpenAPI metadata. */
11
+ readonly supportedFilterCrs?: readonly string[];
12
+ /** Collection response CRS identifiers discovered from Part 2 metadata. */
13
+ readonly supportedOutputCrs?: readonly string[];
14
+ }
15
+ export interface SemanticOgcApiFeaturesSourceIdentity {
16
+ readonly collectionId: string | number;
17
+ }
18
+ export interface SemanticOgcApiFeaturesCompileOptions<TRecord = Record<string, unknown>, TSpatiality extends SourceSpatiality = SourceSpatiality> {
19
+ readonly query: SemanticQuery<TRecord, "ogc-features", TSpatiality>;
20
+ readonly schema: SourceSchemaV2;
21
+ readonly source: SemanticOgcApiFeaturesSourceIdentity;
22
+ readonly conformance: OgcApiFeaturesFilterConformanceEvidence;
23
+ /** Deterministic preference used only when both encodings were explicitly discovered. */
24
+ readonly preferredFilterLanguage?: Cql2FilterLanguage;
25
+ /** External CRS context for a native CQL2 escape hatch. Semantic spatial nodes carry their own binding. */
26
+ readonly nativeFilterCrs?: ExecutableCrsBinding;
27
+ }
28
+ /** Canonical, wire-ready OGC API Features `/items` request semantics. */
29
+ export interface SemanticOgcApiFeaturesCompiledQueryV1 {
30
+ readonly compiler: "ogc-api-features-semantic-query-v1";
31
+ readonly dialect?: Cql2FilterLanguage;
32
+ readonly schemaFingerprint: SourceSchemaV2["fingerprint"];
33
+ readonly queryFingerprint: `sha256:${string}`;
34
+ readonly capabilityFingerprint: `sha256:${string}`;
35
+ readonly requestFingerprint: `sha256:${string}`;
36
+ readonly collectionId: string | number;
37
+ /** Text value for the `filter` query parameter; JSON is canonical JSON text. */
38
+ readonly filter?: string;
39
+ readonly filterLang?: Cql2FilterLanguage;
40
+ readonly filterCrs?: string;
41
+ readonly crs?: string;
42
+ readonly limit?: number;
43
+ readonly usesNativeFilter: boolean;
44
+ }
45
+ /**
46
+ * Compile canonical query IR to an OGC API Features `/items` request. The
47
+ * compiler is side-effect free and deliberately supports only semantics the
48
+ * first-party OGC adapter can preserve exactly.
49
+ */
50
+ export declare function compileOgcApiFeaturesQuery(source: QueryIrSourceIdentity, query: CanonicalQuery): OgcApiFeaturesCompiledQueryV1;
51
+ /** Compile a typed semantic query using only explicitly discovered OGC/CQL2 support. */
52
+ export declare function compileSemanticOgcApiFeaturesQuery<TRecord, TSpatiality extends SourceSpatiality>(options: SemanticOgcApiFeaturesCompileOptions<TRecord, TSpatiality>): SemanticCompilationResult<SemanticOgcApiFeaturesCompiledQueryV1>;
53
+ //# sourceMappingURL=ogc-features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ogc-features.d.ts","sourceRoot":"","sources":["../../../src/query-planner/ogc-features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAA2B,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAqB3G,OAAO,EAEL,KAAK,yBAAyB,EAI/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAGV,aAAa,EACb,gBAAgB,EAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGvG,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,WAAW,CAAC;AAE3D,6EAA6E;AAC7E,MAAM,WAAW,uCAAuC;IACtD,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,iFAAiF;IACjF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,2EAA2E;IAC3E,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,oCAAoC,CACnD,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,SAAS,gBAAgB,GAAG,gBAAgB;IAEvD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,oCAAoC,CAAC;IACtD,QAAQ,CAAC,WAAW,EAAE,uCAAuC,CAAC;IAC9D,yFAAyF;IACzF,QAAQ,CAAC,uBAAuB,CAAC,EAAE,kBAAkB,CAAC;IACtD,2GAA2G;IAC3G,QAAQ,CAAC,eAAe,CAAC,EAAE,oBAAoB,CAAC;CACjD;AAED,yEAAyE;AACzE,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,oCAAoC,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,UAAU,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,UAAU,MAAM,EAAE,CAAC;IACnD,QAAQ,CAAC,kBAAkB,EAAE,UAAU,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAuED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,cAAc,GACpB,6BAA6B,CAuC/B;AAED,wFAAwF;AACxF,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,WAAW,SAAS,gBAAgB,EAC9F,OAAO,EAAE,oCAAoC,CAAC,OAAO,EAAE,WAAW,CAAC,GAClE,yBAAyB,CAAC,qCAAqC,CAAC,CAiDlE"}