@honua/react 0.1.0-beta.0 → 0.1.2-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 (315) 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/filter-registry/index.d.ts +145 -0
  145. package/filter-registry/index.d.ts.map +1 -0
  146. package/filter-registry/index.js +531 -0
  147. package/generated-app/errors.d.ts +18 -2
  148. package/generated-app/errors.d.ts.map +1 -1
  149. package/generated-app/errors.js +44 -11
  150. package/map/automatic-mount-integration.d.ts +134 -0
  151. package/map/automatic-mount-integration.d.ts.map +1 -0
  152. package/map/automatic-mount-integration.js +305 -0
  153. package/map/automatic-source-strategy.d.ts +125 -0
  154. package/map/automatic-source-strategy.d.ts.map +1 -0
  155. package/map/automatic-source-strategy.js +494 -0
  156. package/map/data-to-map-bridge.d.ts +293 -0
  157. package/map/data-to-map-bridge.d.ts.map +1 -0
  158. package/map/data-to-map-bridge.js +817 -0
  159. package/map/geojson-projection.d.ts +33 -0
  160. package/map/geojson-projection.d.ts.map +1 -0
  161. package/map/geojson-projection.js +118 -0
  162. package/map/index.d.ts +14 -0
  163. package/map/index.d.ts.map +1 -1
  164. package/map/index.js +8 -0
  165. package/map/raster-source-spec.d.ts +30 -0
  166. package/map/raster-source-spec.d.ts.map +1 -0
  167. package/map/raster-source-spec.js +190 -0
  168. package/map/raster-source-strategy.d.ts +65 -0
  169. package/map/raster-source-strategy.d.ts.map +1 -0
  170. package/map/raster-source-strategy.js +232 -0
  171. package/map/source-to-maplibre.d.ts +91 -0
  172. package/map/source-to-maplibre.d.ts.map +1 -0
  173. package/map/source-to-maplibre.js +454 -0
  174. package/map/temporal-playback.d.ts +139 -0
  175. package/map/temporal-playback.d.ts.map +1 -0
  176. package/map/temporal-playback.js +247 -0
  177. package/package.json +14 -1
  178. package/query-planner/canonical.d.ts +7 -0
  179. package/query-planner/canonical.d.ts.map +1 -0
  180. package/query-planner/canonical.js +145 -0
  181. package/query-planner/cql2-json.d.ts +17 -0
  182. package/query-planner/cql2-json.d.ts.map +1 -0
  183. package/query-planner/cql2-json.js +646 -0
  184. package/query-planner/diagnostics.d.ts +35 -0
  185. package/query-planner/diagnostics.d.ts.map +1 -0
  186. package/query-planner/diagnostics.js +373 -0
  187. package/query-planner/duckdb.d.ts +79 -0
  188. package/query-planner/duckdb.d.ts.map +1 -0
  189. package/query-planner/duckdb.js +758 -0
  190. package/query-planner/execution-context.d.ts +5 -0
  191. package/query-planner/execution-context.d.ts.map +1 -0
  192. package/query-planner/execution-context.js +50 -0
  193. package/query-planner/executor.d.ts +5 -0
  194. package/query-planner/executor.d.ts.map +1 -0
  195. package/query-planner/executor.js +223 -0
  196. package/query-planner/geoservices.d.ts +91 -0
  197. package/query-planner/geoservices.d.ts.map +1 -0
  198. package/query-planner/geoservices.js +667 -0
  199. package/query-planner/grpc.d.ts +100 -0
  200. package/query-planner/grpc.d.ts.map +1 -0
  201. package/query-planner/grpc.js +736 -0
  202. package/query-planner/index.d.ts +44 -0
  203. package/query-planner/index.d.ts.map +1 -0
  204. package/query-planner/index.js +30 -0
  205. package/query-planner/ir.d.ts +20 -0
  206. package/query-planner/ir.d.ts.map +1 -0
  207. package/query-planner/ir.js +417 -0
  208. package/query-planner/local-aggregate.d.ts +5 -0
  209. package/query-planner/local-aggregate.d.ts.map +1 -0
  210. package/query-planner/local-aggregate.js +126 -0
  211. package/query-planner/odata.d.ts +48 -0
  212. package/query-planner/odata.d.ts.map +1 -0
  213. package/query-planner/odata.js +662 -0
  214. package/query-planner/ogc-compiler.d.ts +55 -0
  215. package/query-planner/ogc-compiler.d.ts.map +1 -0
  216. package/query-planner/ogc-compiler.js +480 -0
  217. package/query-planner/ogc-features.d.ts +53 -0
  218. package/query-planner/ogc-features.d.ts.map +1 -0
  219. package/query-planner/ogc-features.js +617 -0
  220. package/query-planner/planner.d.ts +17 -0
  221. package/query-planner/planner.d.ts.map +1 -0
  222. package/query-planner/planner.js +818 -0
  223. package/query-planner/resource.d.ts +94 -0
  224. package/query-planner/resource.d.ts.map +1 -0
  225. package/query-planner/resource.js +526 -0
  226. package/query-planner/semantic-canonical.d.ts +15 -0
  227. package/query-planner/semantic-canonical.d.ts.map +1 -0
  228. package/query-planner/semantic-canonical.js +62 -0
  229. package/query-planner/semantic-compat.d.ts +10 -0
  230. package/query-planner/semantic-compat.d.ts.map +1 -0
  231. package/query-planner/semantic-compat.js +35 -0
  232. package/query-planner/semantic-compiler.d.ts +64 -0
  233. package/query-planner/semantic-compiler.d.ts.map +1 -0
  234. package/query-planner/semantic-compiler.js +81 -0
  235. package/query-planner/semantic-literals.d.ts +30 -0
  236. package/query-planner/semantic-literals.d.ts.map +1 -0
  237. package/query-planner/semantic-literals.js +133 -0
  238. package/query-planner/semantic-types.d.ts +265 -0
  239. package/query-planner/semantic-types.d.ts.map +1 -0
  240. package/query-planner/semantic-types.js +1 -0
  241. package/query-planner/semantic.d.ts +54 -0
  242. package/query-planner/semantic.d.ts.map +1 -0
  243. package/query-planner/semantic.js +1421 -0
  244. package/query-planner/types.d.ts +560 -0
  245. package/query-planner/types.d.ts.map +1 -0
  246. package/query-planner/types.js +49 -0
  247. package/query-planner/wfs-semantic.d.ts +58 -0
  248. package/query-planner/wfs-semantic.d.ts.map +1 -0
  249. package/query-planner/wfs-semantic.js +547 -0
  250. package/query-planner/wfs.d.ts +6 -0
  251. package/query-planner/wfs.d.ts.map +1 -0
  252. package/query-planner/wfs.js +71 -0
  253. package/react/external-map.d.ts +67 -0
  254. package/react/external-map.d.ts.map +1 -0
  255. package/react/external-map.js +63 -0
  256. package/react/honua-map.d.ts.map +1 -1
  257. package/react/honua-map.js +3 -2
  258. package/react/honua-source-layer.d.ts +110 -0
  259. package/react/honua-source-layer.d.ts.map +1 -0
  260. package/react/honua-source-layer.js +101 -0
  261. package/react/hooks.d.ts +28 -0
  262. package/react/hooks.d.ts.map +1 -1
  263. package/react/hooks.js +26 -4
  264. package/react/index.d.ts +8 -0
  265. package/react/index.d.ts.map +1 -1
  266. package/react/index.js +5 -0
  267. package/react/query-cache.d.ts +26 -4
  268. package/react/query-cache.d.ts.map +1 -1
  269. package/react/query-cache.js +51 -8
  270. package/react/selection.d.ts +177 -0
  271. package/react/selection.d.ts.map +1 -0
  272. package/react/selection.js +0 -0
  273. package/react/use-mounted-source.d.ts +69 -0
  274. package/react/use-mounted-source.d.ts.map +1 -0
  275. package/react/use-mounted-source.js +346 -0
  276. package/runtime/edit-snapping.d.ts +107 -0
  277. package/runtime/edit-snapping.d.ts.map +1 -0
  278. package/runtime/edit-snapping.js +190 -0
  279. package/runtime/errors.d.ts +3 -2
  280. package/runtime/errors.d.ts.map +1 -1
  281. package/runtime/errors.js +19 -2
  282. package/runtime/index.d.ts +6 -0
  283. package/runtime/index.d.ts.map +1 -1
  284. package/runtime/index.js +3 -0
  285. package/runtime/maplibre-renderer.d.ts +41 -0
  286. package/runtime/maplibre-renderer.d.ts.map +1 -0
  287. package/runtime/maplibre-renderer.js +322 -0
  288. package/runtime/query-tiles.d.ts +2 -1
  289. package/runtime/query-tiles.d.ts.map +1 -1
  290. package/runtime/query-tiles.js +6 -2
  291. package/runtime/source-bridge.d.ts +4 -4
  292. package/runtime/source-bridge.d.ts.map +1 -1
  293. package/runtime/source-bridge.js +9 -56
  294. package/runtime/style-interactions.d.ts +3 -2
  295. package/runtime/style-interactions.d.ts.map +1 -1
  296. package/runtime/style-interactions.js +11 -3
  297. package/runtime/terra-draw-sketch.d.ts +275 -0
  298. package/runtime/terra-draw-sketch.d.ts.map +1 -0
  299. package/runtime/terra-draw-sketch.js +404 -0
  300. package/source-capability-registry.d.ts +1 -0
  301. package/source-capability-registry.js +1 -0
  302. package/source-capability-types.d.ts +186 -0
  303. package/source-capability-types.js +7 -0
  304. package/style/index.d.ts +2 -0
  305. package/style/index.d.ts.map +1 -1
  306. package/style/index.js +2 -0
  307. package/style/renderers.d.ts +326 -0
  308. package/style/renderers.d.ts.map +1 -0
  309. package/style/renderers.js +517 -0
  310. package/webmap/convert-renderer.d.ts +24 -3
  311. package/webmap/convert-renderer.d.ts.map +1 -1
  312. package/webmap/convert-renderer.js +93 -112
  313. package/webmap/index.d.ts +1 -1
  314. package/webmap/index.d.ts.map +1 -1
  315. package/webmap/index.js +1 -1
@@ -0,0 +1,1083 @@
1
+ /**
2
+ * Metadata-driven OData write encoding primitives.
3
+ *
4
+ * This module deliberately has no transport dependencies. Callers supply the
5
+ * already-cached CSDL projection and decide how to attach the encoded body,
6
+ * content type, and key to an HTTP request.
7
+ */
8
+ import { encodeOdataKeyPredicatePath } from "./odata-key-path.js";
9
+ import { getOdataSourceSchemaProjectionDetails, getOdataSourceSchemaProjectionSafety, } from "./odata.js";
10
+ const DEFAULT_MAX_DEPTH = 32;
11
+ const MAX_CONFIGURED_DEPTH = 32;
12
+ const MAX_CONTAINER_ITEMS = 10_000;
13
+ const MAX_ENCODED_VALUE_NODES = 20_000;
14
+ const MAX_ERROR_PATH_SEGMENT_CODE_POINTS = 64;
15
+ const MAX_DECIMAL_LEXEME_CHARACTERS = 1_024;
16
+ const MAX_TEMPORAL_LEXEME_CHARACTERS = 1_024;
17
+ const MAX_ENTITY_SET_PATH_CODE_UNITS = 2_048;
18
+ const UNDECLARED_PROPERTY_PATH_SEGMENT = "<undeclared-property>";
19
+ const GUID_LEXEME = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
20
+ const JSON_NUMBER_LEXEME = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
21
+ const INTEGER_LEXEME = /^-?(?:0|[1-9]\d*)$/;
22
+ const ENUM_INTEGER_LEXEME = /^[+-]?\d{1,20}$/;
23
+ const DATE_LEXEME = /^(-?(?:0\d{3}|[1-9]\d{3,}))-(\d{2})-(\d{2})$/;
24
+ const TIME_OF_DAY_LEXEME = /^(?:[01]\d|2[0-3]):[0-5]\d(?::(?:[0-5]\d|60)(?:\.(\d{1,12}))?)?$/;
25
+ const DATE_TIME_OFFSET_LEXEME = /^(-?(?:0\d{3}|[1-9]\d{3,})-\d{2}-\d{2})T(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.(\d{1,12}))?)?(?:Z|[+-](?:(?:0\d|1[0-3]):[0-5]\d|14:00))$/;
26
+ const DURATION_LEXEME = /^[+-]?P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?$/;
27
+ const BASE64URL_LEXEME = /^[A-Za-z0-9_-]*$/;
28
+ const BASE64URL_B16_LAST = /^[AEIMQUYcgkosw048]$/;
29
+ const BASE64URL_B8_LAST = /^[AQgw]$/;
30
+ const QUALIFIED_IDENTIFIER = /^[\p{L}\p{Nl}_][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]*(?:\.[\p{L}\p{Nl}_][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]*)*$/u;
31
+ const SIMPLE_IDENTIFIER = /^[\p{L}\p{Nl}_][\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}\p{Cf}]*$/u;
32
+ const INTEGER_BOUNDS = Object.freeze({
33
+ "Edm.Byte": { minimum: 0n, maximum: 255n },
34
+ "Edm.SByte": { minimum: -128n, maximum: 127n },
35
+ "Edm.Int16": { minimum: -32768n, maximum: 32767n },
36
+ "Edm.Int32": { minimum: -2147483648n, maximum: 2147483647n },
37
+ "Edm.Int64": { minimum: -(1n << 63n), maximum: (1n << 63n) - 1n },
38
+ });
39
+ function integerBounds(type) {
40
+ return Object.hasOwn(INTEGER_BOUNDS, type) ? INTEGER_BOUNDS[type] : undefined;
41
+ }
42
+ /**
43
+ * A redacted local encoding failure.
44
+ *
45
+ * Messages contain a fixed explanation and a bounded, escaped property path.
46
+ * The rejected value and request body are intentionally never retained.
47
+ */
48
+ export class HonuaOdataEdmEncodingError extends TypeError {
49
+ code;
50
+ path;
51
+ constructor(code, path) {
52
+ super(`OData EDM encoding failed at ${path}: ${encodingErrorReason(code)}`);
53
+ this.name = "HonuaOdataEdmEncodingError";
54
+ this.code = code;
55
+ this.path = path;
56
+ }
57
+ }
58
+ /**
59
+ * Encode one entity body using the entity and complex property declarations in
60
+ * an existing OData metadata snapshot.
61
+ */
62
+ export function encodeOdataWriteBody(metadata, entitySet, body, options = {}) {
63
+ try {
64
+ const context = encodingContext(options);
65
+ const model = codecModel(metadata, entitySet);
66
+ const encoded = encodeStructuredValue(body, model.fields, model, [], 0, context);
67
+ return { body: encoded, requiresIeee754Compatible: context.requiresIeee754Compatible };
68
+ }
69
+ catch (error) {
70
+ rethrowEncodingError(error, "invalid-value", []);
71
+ }
72
+ }
73
+ /**
74
+ * Encode a single or composite primary key in metadata declaration order.
75
+ *
76
+ * A single key accepts either its scalar value or an object carrying the key
77
+ * property. Composite keys require an object so component names cannot be
78
+ * confused or reordered by the caller.
79
+ */
80
+ export function encodeOdataEntityKey(metadata, entitySet, key, options = {}) {
81
+ try {
82
+ const context = encodingContext(options);
83
+ const model = codecModel(metadata, entitySet);
84
+ const configuredKeyFields = dataProperty(options, "keyFields", ["options", "keyFields"], "invalid-options");
85
+ const keys = configuredKeyFields === undefined
86
+ ? model.keys
87
+ : keyFieldOverride(configuredKeyFields, model.keys, ["options", "keyFields"]);
88
+ if (keys.length === 0)
89
+ throw encodingError("invalid-metadata", ["key"]);
90
+ if (new Set(keys).size !== keys.length)
91
+ throw encodingError("invalid-metadata", ["key"]);
92
+ const fields = new Map(model.fields.map((field) => [field.name, field]));
93
+ const keyFields = keys.map((name) => {
94
+ if (!simpleIdentifier(name))
95
+ throw encodingError("invalid-metadata", ["key"]);
96
+ const field = fields.get(name);
97
+ if (!field)
98
+ throw encodingError("invalid-metadata", ["key", name]);
99
+ return field;
100
+ });
101
+ let literal;
102
+ if (keyFields.length === 1) {
103
+ const field = keyFields[0];
104
+ const value = isRecord(key, ["key"]) ? ownDataProperty(key, field.name, ["key", field.name]) : key;
105
+ if (value === undefined || value === null)
106
+ throw encodingError("missing-key", ["key", field.name]);
107
+ literal = encodeKeyPrimitive(value, field, model, ["key", field.name]);
108
+ }
109
+ else {
110
+ if (!isRecord(key, ["key"]))
111
+ throw encodingError("missing-key", ["key"]);
112
+ literal = keyFields
113
+ .map((field) => {
114
+ const value = ownDataProperty(key, field.name, ["key", field.name]);
115
+ if (value === undefined || value === null)
116
+ throw encodingError("missing-key", ["key", field.name]);
117
+ return `${field.name}=${encodeKeyPrimitive(value, field, model, ["key", field.name])}`;
118
+ })
119
+ .join(",");
120
+ }
121
+ return { literal, pathSegment: encodePathSegment(literal, ["key"]) };
122
+ }
123
+ catch (error) {
124
+ rethrowEncodingError(error, "invalid-value", ["key"]);
125
+ }
126
+ }
127
+ function keyFieldOverride(value, declaredKeys, path) {
128
+ if (!Array.isArray(value))
129
+ throw encodingError("invalid-options", path);
130
+ const fields = arrayDataValues(value, path, "invalid-options");
131
+ if (fields.length === 0 ||
132
+ fields.some((field) => typeof field !== "string") ||
133
+ new Set(fields).size !== fields.length) {
134
+ throw encodingError("invalid-options", path);
135
+ }
136
+ const selected = new Set(fields);
137
+ const ordered = declaredKeys.filter((field) => selected.has(field));
138
+ if (ordered.length !== fields.length || ordered.some((field, index) => field !== fields[index])) {
139
+ throw encodingError("invalid-options", path);
140
+ }
141
+ return ordered;
142
+ }
143
+ function codecModel(metadata, requestedEntitySet) {
144
+ try {
145
+ return uncheckedCodecModel(metadata, requestedEntitySet);
146
+ }
147
+ catch (error) {
148
+ rethrowEncodingError(error, "invalid-metadata", []);
149
+ }
150
+ }
151
+ function uncheckedCodecModel(metadata, requestedEntitySet) {
152
+ if (typeof requestedEntitySet !== "string" ||
153
+ requestedEntitySet.length === 0 ||
154
+ requestedEntitySet.length > MAX_ENTITY_SET_PATH_CODE_UNITS) {
155
+ throw encodingError("unknown-entity-set", []);
156
+ }
157
+ const metadataRecord = plainDataRecord(metadata, [], "invalid-metadata");
158
+ const suffix = requestedEntitySet.slice(requestedEntitySet.lastIndexOf("/") + 1);
159
+ const entitySets = plainDataRecord(dataProperty(metadataRecord, "entitySets", [], "invalid-metadata"), [], "invalid-metadata");
160
+ const entityType = ownLookup(entitySets, requestedEntitySet) ?? ownLookup(entitySets, suffix);
161
+ if (typeof entityType !== "string" || !qualifiedIdentifier(entityType)) {
162
+ throw encodingError("unknown-entity-set", []);
163
+ }
164
+ const detailsValue = getOdataSourceSchemaProjectionDetails(metadata);
165
+ const details = detailsValue === undefined ? undefined : plainDataRecord(detailsValue, [], "invalid-metadata");
166
+ const safetyValue = getOdataSourceSchemaProjectionSafety(metadata);
167
+ const safety = safetyValue === undefined ? undefined : plainDataRecord(safetyValue, [], "invalid-metadata");
168
+ const csdlVersion = safety ? dataProperty(safety, "csdlVersion", [], "invalid-metadata") : undefined;
169
+ if (csdlVersion !== undefined && csdlVersion !== "4.0" && csdlVersion !== "4.01") {
170
+ throw encodingError("invalid-metadata", []);
171
+ }
172
+ const unsafeTypeNames = new Set();
173
+ if (safety) {
174
+ for (const property of [
175
+ "ambiguousTypeNames",
176
+ "inheritedTypeNames",
177
+ "openComplexTypeNames",
178
+ "unqualifiedTypeNames",
179
+ ]) {
180
+ const names = metadataStringArray(dataProperty(safety, property, [], "invalid-metadata"), []);
181
+ for (const name of names)
182
+ unsafeTypeNames.add(name);
183
+ }
184
+ }
185
+ if (unsafeTypeNames.has(entityType))
186
+ throw encodingError("invalid-metadata", []);
187
+ const fieldsRecord = plainDataRecord(details
188
+ ? dataProperty(details, "fields", [], "invalid-metadata")
189
+ : dataProperty(metadataRecord, "fields", [], "invalid-metadata"), [], "invalid-metadata");
190
+ const fields = metadataFieldArray(ownLookup(fieldsRecord, entityType), []);
191
+ const keysRecord = plainDataRecord(dataProperty(metadataRecord, "keys", [], "invalid-metadata"), [], "invalid-metadata");
192
+ const complexTypes = plainDataRecord(details
193
+ ? dataProperty(details, "complexTypes", [], "invalid-metadata")
194
+ : (dataProperty(metadataRecord, "complexTypes", [], "invalid-metadata") ?? Object.freeze({})), [], "invalid-metadata");
195
+ const enumTypes = plainDataRecord(details
196
+ ? dataProperty(details, "enumTypes", [], "invalid-metadata")
197
+ : (dataProperty(metadataRecord, "enumTypes", [], "invalid-metadata") ?? Object.freeze({})), [], "invalid-metadata");
198
+ return {
199
+ entityType,
200
+ fields,
201
+ keys: metadataStringArray(ownLookup(keysRecord, entityType) ?? [], []),
202
+ complexTypes,
203
+ enumTypes,
204
+ unsafeTypeNames,
205
+ };
206
+ }
207
+ function encodingContext(options) {
208
+ if (typeof options !== "object" || options === null || Array.isArray(options)) {
209
+ throw encodingError("invalid-options", ["options"]);
210
+ }
211
+ const configuredDepth = dataProperty(options, "maxDepth", ["options", "maxDepth"], "invalid-options");
212
+ const maxDepth = configuredDepth === undefined ? DEFAULT_MAX_DEPTH : configuredDepth;
213
+ if (typeof maxDepth !== "number" ||
214
+ !Number.isSafeInteger(maxDepth) ||
215
+ maxDepth < 0 ||
216
+ maxDepth > MAX_CONFIGURED_DEPTH) {
217
+ throw encodingError("invalid-options", ["options", "maxDepth"]);
218
+ }
219
+ return { maxDepth, ancestors: new WeakSet(), nodes: 1, requiresIeee754Compatible: false };
220
+ }
221
+ function encodeStructuredValue(value, fields, model, path, depth, context) {
222
+ if (!isRecord(value, path))
223
+ throw encodingError("invalid-value", path);
224
+ enterContainer(value, path, depth, context);
225
+ try {
226
+ const declared = new Map(fields.map((field) => [field.name, field]));
227
+ const output = {};
228
+ for (const name of objectKeys(value, path)) {
229
+ const field = declared.get(name);
230
+ const childPath = [...path, field ? field.name : UNDECLARED_PROPERTY_PATH_SEGMENT];
231
+ consumeValueNode(childPath, context);
232
+ const input = ownDataProperty(value, name, childPath);
233
+ const encoded = field
234
+ ? encodeTypedValue(input, field, model, childPath, depth, context, field.nullable !== false)
235
+ : encodeUntypedValue(input, childPath, depth, context);
236
+ defineEnumerableValue(output, name, encoded);
237
+ }
238
+ return output;
239
+ }
240
+ finally {
241
+ context.ancestors.delete(value);
242
+ }
243
+ }
244
+ function encodeTypedValue(value, field, model, path, depth, context, nullable) {
245
+ if (value === null) {
246
+ if (!nullable)
247
+ throw encodingError("invalid-value", path);
248
+ return null;
249
+ }
250
+ if (value === undefined)
251
+ throw encodingError("invalid-value", path);
252
+ const collectionType = unwrapCollection(field.type);
253
+ if (collectionType !== undefined) {
254
+ if (!Array.isArray(value))
255
+ throw encodingError("invalid-value", path);
256
+ const childDepth = nextDepth(path, depth, context);
257
+ enterContainer(value, path, childDepth, context);
258
+ try {
259
+ const itemField = { ...field, type: collectionType, nullable: true };
260
+ return arrayDataValues(value, path).map((item, index) => {
261
+ const childPath = [...path, index];
262
+ consumeValueNode(childPath, context);
263
+ return encodeTypedValue(item, itemField, model, childPath, childDepth, context, true);
264
+ });
265
+ }
266
+ finally {
267
+ context.ancestors.delete(value);
268
+ }
269
+ }
270
+ const localType = stripNamespace(field.type);
271
+ if (!field.type.startsWith("Edm.") && model.unsafeTypeNames.has(localType)) {
272
+ throw encodingError("invalid-metadata", path);
273
+ }
274
+ const complexDeclaration = ownLookup(model.complexTypes, localType);
275
+ if (complexDeclaration !== undefined) {
276
+ const complexFields = metadataFieldArray(complexDeclaration, path);
277
+ return encodeStructuredValue(value, complexFields, model, path, nextDepth(path, depth, context), context);
278
+ }
279
+ const enumType = ownLookup(model.enumTypes, localType);
280
+ if (enumType) {
281
+ if (!qualifiedIdentifier(field.type))
282
+ throw encodingError("invalid-metadata", path);
283
+ return enumValue(value, enumType, path);
284
+ }
285
+ const bounds = integerBounds(field.type);
286
+ if (bounds) {
287
+ const integer = exactInteger(value, bounds, path);
288
+ if (field.type === "Edm.Int64") {
289
+ context.requiresIeee754Compatible = true;
290
+ return integer.toString();
291
+ }
292
+ return Number(integer);
293
+ }
294
+ switch (field.type) {
295
+ case "Edm.Decimal": {
296
+ const decimal = exactDecimal(value, field, path);
297
+ context.requiresIeee754Compatible = true;
298
+ return decimal;
299
+ }
300
+ case "Edm.Single":
301
+ return singleJsonValue(value, path);
302
+ case "Edm.Double":
303
+ return doubleJsonValue(value, path);
304
+ case "Edm.Guid":
305
+ return guidValue(value, path);
306
+ case "Edm.String":
307
+ if (typeof value !== "string")
308
+ throw encodingError("invalid-value", path);
309
+ if (typeof field.maxLength === "number" && codePointLengthExceeds(value, field.maxLength)) {
310
+ throw encodingError("invalid-value", path);
311
+ }
312
+ return value;
313
+ case "Edm.Boolean":
314
+ if (typeof value !== "boolean")
315
+ throw encodingError("invalid-value", path);
316
+ return value;
317
+ case "Edm.Binary":
318
+ return binaryValue(value, field, path);
319
+ case "Edm.Date":
320
+ return dateValue(value, path);
321
+ case "Edm.DateTimeOffset":
322
+ return dateTimeOffsetValue(value, field, path);
323
+ case "Edm.Duration":
324
+ return durationValue(value, field, path);
325
+ case "Edm.TimeOfDay":
326
+ return timeOfDayValue(value, field, path);
327
+ case "Edm.Geography":
328
+ case "Edm.GeographyPoint":
329
+ case "Edm.GeographyLineString":
330
+ case "Edm.GeographyPolygon":
331
+ case "Edm.GeographyMultiPoint":
332
+ case "Edm.GeographyMultiLineString":
333
+ case "Edm.GeographyMultiPolygon":
334
+ case "Edm.GeographyCollection":
335
+ case "Edm.Geometry":
336
+ case "Edm.GeometryPoint":
337
+ case "Edm.GeometryLineString":
338
+ case "Edm.GeometryPolygon":
339
+ case "Edm.GeometryMultiPoint":
340
+ case "Edm.GeometryMultiLineString":
341
+ case "Edm.GeometryMultiPolygon":
342
+ case "Edm.GeometryCollection":
343
+ case "Edm.Untyped":
344
+ return encodeUntypedValue(value, path, depth, context);
345
+ default:
346
+ throw encodingError("unsupported-type", path);
347
+ }
348
+ }
349
+ function encodeUntypedValue(value, path, depth, context) {
350
+ if (value === null || typeof value === "string" || typeof value === "boolean")
351
+ return value;
352
+ if (typeof value === "number") {
353
+ if (!Number.isFinite(value))
354
+ throw encodingError("invalid-value", path);
355
+ return value;
356
+ }
357
+ if (Array.isArray(value)) {
358
+ const childDepth = nextDepth(path, depth, context);
359
+ enterContainer(value, path, childDepth, context);
360
+ try {
361
+ return arrayDataValues(value, path).map((item, index) => {
362
+ const childPath = [...path, index];
363
+ consumeValueNode(childPath, context);
364
+ return encodeUntypedValue(item, childPath, childDepth, context);
365
+ });
366
+ }
367
+ finally {
368
+ context.ancestors.delete(value);
369
+ }
370
+ }
371
+ if (isRecord(value, path)) {
372
+ return encodeStructuredValue(value, [], emptyCodecModel(), path, nextDepth(path, depth, context), context);
373
+ }
374
+ throw encodingError("invalid-value", path);
375
+ }
376
+ function encodeKeyPrimitive(value, field, model, path) {
377
+ if (unwrapCollection(field.type) !== undefined ||
378
+ ownLookup(model.complexTypes, stripNamespace(field.type)) !== undefined) {
379
+ throw encodingError("unsupported-type", path);
380
+ }
381
+ if (!field.type.startsWith("Edm.") && model.unsafeTypeNames.has(stripNamespace(field.type))) {
382
+ throw encodingError("invalid-metadata", path);
383
+ }
384
+ const bounds = integerBounds(field.type);
385
+ if (bounds)
386
+ return exactInteger(value, bounds, path).toString();
387
+ const enumType = ownLookup(model.enumTypes, stripNamespace(field.type));
388
+ if (enumType) {
389
+ if (!qualifiedIdentifier(field.type))
390
+ throw encodingError("invalid-metadata", path);
391
+ return `${field.type}'${escapeOdataString(enumValue(value, enumType, path))}'`;
392
+ }
393
+ switch (field.type) {
394
+ case "Edm.Decimal":
395
+ return exactDecimal(value, field, path);
396
+ case "Edm.Single":
397
+ return singleKeyValue(value, path);
398
+ case "Edm.Double":
399
+ return floatingKeyValue(value, path);
400
+ case "Edm.Guid":
401
+ return guidValue(value, path);
402
+ case "Edm.String": {
403
+ if (typeof value !== "string")
404
+ throw encodingError("invalid-value", path);
405
+ if (typeof field.maxLength === "number" && codePointLengthExceeds(value, field.maxLength)) {
406
+ throw encodingError("invalid-value", path);
407
+ }
408
+ return `'${escapeOdataString(value)}'`;
409
+ }
410
+ case "Edm.Boolean":
411
+ if (typeof value !== "boolean")
412
+ throw encodingError("invalid-value", path);
413
+ return value ? "true" : "false";
414
+ case "Edm.Binary":
415
+ return `binary'${binaryValue(value, field, path)}'`;
416
+ case "Edm.Date":
417
+ return dateValue(value, path);
418
+ case "Edm.DateTimeOffset":
419
+ return dateTimeOffsetValue(value, field, path);
420
+ case "Edm.Duration":
421
+ return `duration'${durationValue(value, field, path)}'`;
422
+ case "Edm.TimeOfDay":
423
+ return timeOfDayValue(value, field, path);
424
+ default:
425
+ throw encodingError("unsupported-type", path);
426
+ }
427
+ }
428
+ function exactInteger(value, bounds, path) {
429
+ let parsed;
430
+ if (typeof value === "bigint") {
431
+ parsed = value;
432
+ }
433
+ else if (typeof value === "number") {
434
+ if (!Number.isSafeInteger(value))
435
+ throw encodingError("invalid-value", path);
436
+ parsed = BigInt(value);
437
+ }
438
+ else if (typeof value === "string" && value.length <= 20 && INTEGER_LEXEME.test(value)) {
439
+ try {
440
+ parsed = BigInt(value);
441
+ }
442
+ catch {
443
+ throw encodingError("invalid-value", path);
444
+ }
445
+ }
446
+ else {
447
+ throw encodingError("invalid-value", path);
448
+ }
449
+ if (parsed < bounds.minimum || parsed > bounds.maximum)
450
+ throw encodingError("invalid-value", path);
451
+ return parsed;
452
+ }
453
+ function exactDecimal(value, field, path) {
454
+ let lexeme;
455
+ if (typeof value === "bigint")
456
+ lexeme = value.toString();
457
+ else if (typeof value === "number" && Number.isFinite(value))
458
+ lexeme = numberToPlainDecimal(value);
459
+ else if (typeof value === "string")
460
+ lexeme = value;
461
+ else
462
+ throw encodingError("invalid-value", path);
463
+ const shape = decimalShape(lexeme);
464
+ if (!shape)
465
+ throw encodingError("invalid-value", path);
466
+ if (typeof field.precision === "number" && shape.digits > field.precision) {
467
+ throw encodingError("invalid-value", path);
468
+ }
469
+ if (typeof field.scale === "number" && shape.fractionalDigits > field.scale) {
470
+ throw encodingError("invalid-value", path);
471
+ }
472
+ return lexeme;
473
+ }
474
+ function decimalShape(value) {
475
+ if (value.length === 0 || value.length > MAX_DECIMAL_LEXEME_CHARACTERS)
476
+ return undefined;
477
+ let index = value[0] === "-" ? 1 : 0;
478
+ if (index === value.length)
479
+ return undefined;
480
+ let digits = 0;
481
+ let totalDigits = 0;
482
+ let fractionalDigits = 0;
483
+ let sawDot = false;
484
+ let digitsAfterDot = 0;
485
+ let sawNonZero = false;
486
+ for (; index < value.length; index += 1) {
487
+ const code = value.charCodeAt(index);
488
+ if (code >= 48 && code <= 57) {
489
+ totalDigits += 1;
490
+ if (code !== 48)
491
+ sawNonZero = true;
492
+ if (sawNonZero)
493
+ digits += 1;
494
+ if (sawDot) {
495
+ fractionalDigits += 1;
496
+ digitsAfterDot += 1;
497
+ }
498
+ continue;
499
+ }
500
+ if (value[index] === "." && !sawDot && totalDigits > 0) {
501
+ sawDot = true;
502
+ continue;
503
+ }
504
+ return undefined;
505
+ }
506
+ if (totalDigits === 0 || (sawDot && digitsAfterDot === 0))
507
+ return undefined;
508
+ return { digits: Math.max(1, digits), fractionalDigits };
509
+ }
510
+ function numberToPlainDecimal(value) {
511
+ if (Object.is(value, -0))
512
+ return "0";
513
+ const raw = String(value);
514
+ if (!/[eE]/.test(raw))
515
+ return raw;
516
+ const match = /^(-?)(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(raw);
517
+ if (!match)
518
+ return raw;
519
+ const sign = match[1] ?? "";
520
+ const integer = match[2] ?? "";
521
+ const fraction = match[3] ?? "";
522
+ const exponent = Number(match[4]);
523
+ const digits = `${integer}${fraction}`;
524
+ const decimalPosition = integer.length + exponent;
525
+ if (decimalPosition <= 0)
526
+ return `${sign}0.${"0".repeat(-decimalPosition)}${digits}`;
527
+ if (decimalPosition >= digits.length)
528
+ return `${sign}${digits}${"0".repeat(decimalPosition - digits.length)}`;
529
+ return `${sign}${digits.slice(0, decimalPosition)}.${digits.slice(decimalPosition)}`;
530
+ }
531
+ function floatingJsonValue(value, path) {
532
+ if (typeof value === "string") {
533
+ if (value === "INF" || value === "-INF" || value === "NaN")
534
+ return value;
535
+ if (!JSON_NUMBER_LEXEME.test(value))
536
+ throw encodingError("invalid-value", path);
537
+ const parsed = Number(value);
538
+ if (!Number.isFinite(parsed))
539
+ throw encodingError("invalid-value", path);
540
+ return parsed;
541
+ }
542
+ if (typeof value !== "number")
543
+ throw encodingError("invalid-value", path);
544
+ if (Number.isNaN(value))
545
+ return "NaN";
546
+ if (value === Number.POSITIVE_INFINITY)
547
+ return "INF";
548
+ if (value === Number.NEGATIVE_INFINITY)
549
+ return "-INF";
550
+ return value;
551
+ }
552
+ function validatedSingleValue(value, path) {
553
+ const encoded = floatingJsonValue(value, path);
554
+ if (typeof encoded === "string")
555
+ return encoded;
556
+ // Edm.Single's value space is IEEE-754 binary32. Admitting an arbitrary
557
+ // binary64 Number here would silently round during server decoding, which
558
+ // contradicts the opt-in codec's lossless contract. Callers can make that
559
+ // conversion explicit with Math.fround before encoding.
560
+ if (!Object.is(Math.fround(encoded), encoded))
561
+ throw encodingError("invalid-value", path);
562
+ return encoded;
563
+ }
564
+ function singleJsonValue(value, path) {
565
+ const encoded = validatedSingleValue(value, path);
566
+ if (typeof encoded === "number" && Object.is(encoded, -0)) {
567
+ // JSON.stringify(-0) emits 0, so the body projection cannot preserve the
568
+ // IEEE-754 sign bit without violating OData's JSON-number requirement.
569
+ throw encodingError("invalid-value", path);
570
+ }
571
+ return encoded;
572
+ }
573
+ function doubleJsonValue(value, path) {
574
+ const encoded = floatingJsonValue(value, path);
575
+ if (typeof encoded === "number" && Object.is(encoded, -0)) {
576
+ // JSON.stringify(-0) emits 0. OData requires finite Double values to be
577
+ // JSON numbers, so failing locally is the only lossless representation.
578
+ throw encodingError("invalid-value", path);
579
+ }
580
+ return encoded;
581
+ }
582
+ function floatingKeyValue(value, path) {
583
+ if (typeof value === "string") {
584
+ if (value === "INF" || value === "-INF" || value === "NaN")
585
+ return value;
586
+ if (!JSON_NUMBER_LEXEME.test(value) || !Number.isFinite(Number(value))) {
587
+ throw encodingError("invalid-value", path);
588
+ }
589
+ return value;
590
+ }
591
+ const encoded = floatingJsonValue(value, path);
592
+ if (typeof encoded === "number" && Object.is(encoded, -0))
593
+ return "-0";
594
+ return typeof encoded === "number" ? String(encoded) : encoded;
595
+ }
596
+ function singleKeyValue(value, path) {
597
+ const encoded = validatedSingleValue(value, path);
598
+ if (typeof encoded === "string")
599
+ return encoded;
600
+ if (Object.is(encoded, -0))
601
+ return "-0";
602
+ return typeof value === "string" ? value : String(encoded);
603
+ }
604
+ function guidValue(value, path) {
605
+ if (typeof value !== "string" || !GUID_LEXEME.test(value))
606
+ throw encodingError("invalid-value", path);
607
+ return value;
608
+ }
609
+ function binaryValue(value, field, path) {
610
+ if (typeof value !== "string")
611
+ throw encodingError("invalid-value", path);
612
+ const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
613
+ const unpadded = padding === 0 ? value : value.slice(0, -padding);
614
+ if (!BASE64URL_LEXEME.test(unpadded))
615
+ throw encodingError("invalid-value", path);
616
+ const remainder = unpadded.length % 4;
617
+ if (remainder === 1 ||
618
+ (padding === 1 && remainder !== 3) ||
619
+ (padding === 2 && remainder !== 2) ||
620
+ (remainder === 2 && !BASE64URL_B8_LAST.test(unpadded.at(-1) ?? "")) ||
621
+ (remainder === 3 && !BASE64URL_B16_LAST.test(unpadded.at(-1) ?? ""))) {
622
+ throw encodingError("invalid-value", path);
623
+ }
624
+ if (typeof field.maxLength === "number") {
625
+ if (!Number.isSafeInteger(field.maxLength) || field.maxLength < 0) {
626
+ throw encodingError("invalid-metadata", path);
627
+ }
628
+ if (Math.floor((unpadded.length * 3) / 4) > field.maxLength) {
629
+ throw encodingError("invalid-value", path);
630
+ }
631
+ }
632
+ return value;
633
+ }
634
+ function dateValue(value, path) {
635
+ if (typeof value !== "string" || value.length > MAX_TEMPORAL_LEXEME_CHARACTERS) {
636
+ throw encodingError("invalid-value", path);
637
+ }
638
+ const match = DATE_LEXEME.exec(value);
639
+ if (!match || !validCalendarDate(match[1], match[2], match[3])) {
640
+ throw encodingError("invalid-value", path);
641
+ }
642
+ return value;
643
+ }
644
+ function dateTimeOffsetValue(value, field, path) {
645
+ if (typeof value !== "string" || value.length > MAX_TEMPORAL_LEXEME_CHARACTERS) {
646
+ throw encodingError("invalid-value", path);
647
+ }
648
+ const match = DATE_TIME_OFFSET_LEXEME.exec(value);
649
+ if (!match)
650
+ throw encodingError("invalid-value", path);
651
+ dateValue(match[1], path);
652
+ validateTemporalPrecision(match[2], field, path);
653
+ return value;
654
+ }
655
+ function durationValue(value, field, path) {
656
+ if (typeof value !== "string" || value.length > MAX_TEMPORAL_LEXEME_CHARACTERS) {
657
+ throw encodingError("invalid-value", path);
658
+ }
659
+ const match = DURATION_LEXEME.exec(value);
660
+ const hasTimeDesignator = value.includes("T");
661
+ const hasTimeComponent = match?.[2] !== undefined || match?.[3] !== undefined || match?.[4] !== undefined;
662
+ if (!match || (match[1] === undefined && !hasTimeComponent) || (hasTimeDesignator && !hasTimeComponent)) {
663
+ throw encodingError("invalid-value", path);
664
+ }
665
+ validateTemporalPrecision(match[5], field, path);
666
+ return value;
667
+ }
668
+ function timeOfDayValue(value, field, path) {
669
+ if (typeof value !== "string" || value.length > MAX_TEMPORAL_LEXEME_CHARACTERS) {
670
+ throw encodingError("invalid-value", path);
671
+ }
672
+ const match = TIME_OF_DAY_LEXEME.exec(value);
673
+ if (!match)
674
+ throw encodingError("invalid-value", path);
675
+ validateTemporalPrecision(match[1], field, path);
676
+ return value;
677
+ }
678
+ function validCalendarDate(year, monthLexeme, dayLexeme) {
679
+ const month = Number(monthLexeme);
680
+ const day = Number(dayLexeme);
681
+ if (!Number.isSafeInteger(month) || month < 1 || month > 12 || !Number.isSafeInteger(day) || day < 1) {
682
+ return false;
683
+ }
684
+ const maximumDay = month === 2 ? (isLeapYear(year) ? 29 : 28) : month === 4 || month === 6 || month === 9 || month === 11 ? 30 : 31;
685
+ return day <= maximumDay;
686
+ }
687
+ function isLeapYear(year) {
688
+ const unsigned = year.startsWith("-") ? year.slice(1) : year;
689
+ const finalFourDigits = Number(unsigned.slice(-4));
690
+ return finalFourDigits % 4 === 0 && (finalFourDigits % 100 !== 0 || finalFourDigits % 400 === 0);
691
+ }
692
+ function validateTemporalPrecision(fraction, field, path) {
693
+ const precision = field.precision ?? 0;
694
+ if (!Number.isSafeInteger(precision) || precision < 0 || precision > 12) {
695
+ throw encodingError("invalid-metadata", path);
696
+ }
697
+ if ((fraction?.length ?? 0) > precision)
698
+ throw encodingError("invalid-value", path);
699
+ }
700
+ function enumValue(value, enumType, path) {
701
+ if (typeof value !== "string" || value.length === 0)
702
+ throw encodingError("invalid-value", path);
703
+ const validated = validatedEnumType(enumType, path);
704
+ if (ENUM_INTEGER_LEXEME.test(value)) {
705
+ let parsed;
706
+ try {
707
+ parsed = BigInt(value);
708
+ }
709
+ catch {
710
+ throw encodingError("invalid-value", path);
711
+ }
712
+ if (parsed < validated.bounds.minimum || parsed > validated.bounds.maximum || (validated.isFlags && parsed < 0n)) {
713
+ throw encodingError("invalid-value", path);
714
+ }
715
+ return preferredEnumRepresentation(parsed, validated) ?? parsed.toString();
716
+ }
717
+ const names = value.split(",");
718
+ if ((!validated.isFlags && names.length !== 1) || new Set(names).size !== names.length) {
719
+ throw encodingError("invalid-value", path);
720
+ }
721
+ const declaredNames = new Set(validated.members.map((member) => member.name));
722
+ if (names.some((name) => !simpleIdentifier(name) || !declaredNames.has(name))) {
723
+ throw encodingError("invalid-value", path);
724
+ }
725
+ return names.join(",");
726
+ }
727
+ function validatedEnumType(enumType, path) {
728
+ try {
729
+ const enumRecord = plainDataRecord(enumType, path, "invalid-metadata");
730
+ const underlyingType = dataProperty(enumRecord, "underlyingType", path, "invalid-metadata");
731
+ const bounds = typeof underlyingType === "string" ? integerBounds(underlyingType) : undefined;
732
+ const isFlags = dataProperty(enumRecord, "isFlags", path, "invalid-metadata");
733
+ const declarations = dataProperty(enumRecord, "members", path, "invalid-metadata");
734
+ const declaration = dataProperty(enumRecord, "declaration", path, "invalid-metadata");
735
+ if (!bounds || typeof isFlags !== "boolean" || !Array.isArray(declarations)) {
736
+ throw encodingError("invalid-metadata", path);
737
+ }
738
+ if (declaration !== undefined) {
739
+ const declarationRecord = plainDataRecord(declaration, path, "invalid-metadata");
740
+ const state = dataProperty(declarationRecord, "state", path, "invalid-metadata");
741
+ if (state !== "valid")
742
+ throw encodingError("invalid-metadata", path);
743
+ const valueMode = dataProperty(declarationRecord, "valueMode", path, "invalid-metadata");
744
+ if ((valueMode !== "explicit" && valueMode !== "implicit" && valueMode !== "mixed") ||
745
+ (isFlags && valueMode !== "explicit")) {
746
+ throw encodingError("invalid-metadata", path);
747
+ }
748
+ }
749
+ const members = [];
750
+ const names = new Set();
751
+ for (const member of arrayDataValues(declarations, path, "invalid-metadata")) {
752
+ const memberRecord = plainDataRecord(member, path, "invalid-metadata");
753
+ const name = dataProperty(memberRecord, "name", path, "invalid-metadata");
754
+ const rawValue = dataProperty(memberRecord, "value", path, "invalid-metadata");
755
+ const parsed = metadataInteger(rawValue);
756
+ if (typeof name !== "string" ||
757
+ !simpleIdentifier(name) ||
758
+ names.has(name) ||
759
+ parsed === undefined ||
760
+ parsed < bounds.minimum ||
761
+ parsed > bounds.maximum ||
762
+ (isFlags && parsed < 0n)) {
763
+ throw encodingError("invalid-metadata", path);
764
+ }
765
+ names.add(name);
766
+ members.push({ name, value: parsed });
767
+ }
768
+ if (members.length === 0)
769
+ throw encodingError("invalid-metadata", path);
770
+ return { bounds, isFlags, members };
771
+ }
772
+ catch (error) {
773
+ rethrowEncodingError(error, "invalid-metadata", path);
774
+ }
775
+ }
776
+ function metadataInteger(value) {
777
+ if (typeof value === "number")
778
+ return Number.isSafeInteger(value) ? BigInt(value) : undefined;
779
+ if (typeof value !== "string" || value.length > 20 || !/^[+-]?\d+$/.test(value))
780
+ return undefined;
781
+ try {
782
+ return BigInt(value);
783
+ }
784
+ catch {
785
+ return undefined;
786
+ }
787
+ }
788
+ function preferredEnumRepresentation(value, enumType) {
789
+ const exact = enumType.members.find((member) => member.value === value);
790
+ if (exact)
791
+ return exact.name;
792
+ if (!enumType.isFlags || value === 0n)
793
+ return undefined;
794
+ let combined = 0n;
795
+ const names = [];
796
+ for (const member of enumType.members) {
797
+ if (member.value === 0n || (member.value & value) !== member.value)
798
+ continue;
799
+ const next = combined | member.value;
800
+ if (next === combined)
801
+ continue;
802
+ combined = next;
803
+ names.push(member.name);
804
+ }
805
+ return combined === value ? names.join(",") : undefined;
806
+ }
807
+ function metadataFieldArray(value, path) {
808
+ if (!Array.isArray(value))
809
+ throw encodingError("invalid-metadata", path);
810
+ const declarations = arrayDataValues(value, path, "invalid-metadata");
811
+ const fields = [];
812
+ const names = new Set();
813
+ for (let index = 0; index < declarations.length; index += 1) {
814
+ const field = metadataField(declarations[index], path);
815
+ if (names.has(field.name))
816
+ throw encodingError("invalid-metadata", path);
817
+ names.add(field.name);
818
+ fields.push(field);
819
+ }
820
+ return Object.freeze(fields);
821
+ }
822
+ function metadataField(value, path) {
823
+ const record = plainDataRecord(value, path, "invalid-metadata");
824
+ const name = dataProperty(record, "name", path, "invalid-metadata");
825
+ const type = dataProperty(record, "type", path, "invalid-metadata");
826
+ const nullable = dataProperty(record, "nullable", path, "invalid-metadata");
827
+ const maxLength = dataProperty(record, "maxLength", path, "invalid-metadata");
828
+ const precision = dataProperty(record, "precision", path, "invalid-metadata");
829
+ const scale = dataProperty(record, "scale", path, "invalid-metadata");
830
+ if (typeof name !== "string" || !simpleIdentifier(name) || typeof type !== "string" || !metadataType(type)) {
831
+ throw encodingError("invalid-metadata", path);
832
+ }
833
+ if (nullable !== undefined && typeof nullable !== "boolean")
834
+ throw encodingError("invalid-metadata", path);
835
+ if (maxLength !== undefined &&
836
+ maxLength !== "max" &&
837
+ (typeof maxLength !== "number" || !Number.isSafeInteger(maxLength) || maxLength < 0)) {
838
+ throw encodingError("invalid-metadata", path);
839
+ }
840
+ if (precision !== undefined && (typeof precision !== "number" || !Number.isSafeInteger(precision) || precision < 0)) {
841
+ throw encodingError("invalid-metadata", path);
842
+ }
843
+ if (scale !== undefined &&
844
+ scale !== "variable" &&
845
+ scale !== "floating" &&
846
+ (typeof scale !== "number" || !Number.isSafeInteger(scale) || scale < 0)) {
847
+ throw encodingError("invalid-metadata", path);
848
+ }
849
+ if (typeof precision === "number" && typeof scale === "number" && scale > precision) {
850
+ throw encodingError("invalid-metadata", path);
851
+ }
852
+ return Object.freeze({
853
+ name,
854
+ type,
855
+ ...(nullable === undefined ? {} : { nullable }),
856
+ ...(maxLength === undefined ? {} : { maxLength }),
857
+ ...(precision === undefined ? {} : { precision }),
858
+ ...(scale === undefined ? {} : { scale }),
859
+ });
860
+ }
861
+ function metadataStringArray(value, path) {
862
+ if (!Array.isArray(value))
863
+ throw encodingError("invalid-metadata", path);
864
+ const declarations = arrayDataValues(value, path, "invalid-metadata");
865
+ const output = [];
866
+ for (let index = 0; index < declarations.length; index += 1) {
867
+ const declaration = declarations[index];
868
+ if (typeof declaration !== "string" || declaration.length === 0 || declaration.length > 512) {
869
+ throw encodingError("invalid-metadata", path);
870
+ }
871
+ output.push(declaration);
872
+ }
873
+ return Object.freeze(output);
874
+ }
875
+ function metadataType(value) {
876
+ if (value.length === 0 || value.length > 1_024)
877
+ return false;
878
+ const collectionType = unwrapCollection(value);
879
+ if (collectionType === undefined)
880
+ return qualifiedIdentifier(value);
881
+ return unwrapCollection(collectionType) === undefined && qualifiedIdentifier(collectionType);
882
+ }
883
+ function plainDataRecord(value, path, errorCode) {
884
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
885
+ throw encodingError(errorCode, path);
886
+ }
887
+ try {
888
+ const prototype = Object.getPrototypeOf(value);
889
+ if (prototype !== Object.prototype && prototype !== null)
890
+ throw encodingError(errorCode, path);
891
+ }
892
+ catch (error) {
893
+ rethrowEncodingError(error, errorCode, path);
894
+ }
895
+ return value;
896
+ }
897
+ function ownDataProperty(value, name, path) {
898
+ return dataProperty(value, name, path, "invalid-value");
899
+ }
900
+ function dataProperty(value, name, path, errorCode) {
901
+ try {
902
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
903
+ if (!descriptor)
904
+ return undefined;
905
+ if (!("value" in descriptor))
906
+ throw encodingError(errorCode, path);
907
+ return descriptor.value;
908
+ }
909
+ catch (error) {
910
+ rethrowEncodingError(error, errorCode, path);
911
+ }
912
+ }
913
+ function arrayDataValues(value, path, errorCode = "invalid-value") {
914
+ const length = dataProperty(value, "length", path, errorCode);
915
+ if (!Number.isSafeInteger(length) || length < 0) {
916
+ throw encodingError(errorCode, path);
917
+ }
918
+ if (length > MAX_CONTAINER_ITEMS) {
919
+ throw encodingError(errorCode === "invalid-value" ? "resource-limit-exceeded" : errorCode, path);
920
+ }
921
+ const output = new Array(length);
922
+ for (let index = 0; index < output.length; index += 1) {
923
+ output[index] = dataProperty(value, String(index), [...path, index], errorCode);
924
+ }
925
+ return output;
926
+ }
927
+ function objectKeys(value, path) {
928
+ let keys;
929
+ try {
930
+ keys = Object.keys(value);
931
+ }
932
+ catch {
933
+ throw encodingError("invalid-value", path);
934
+ }
935
+ if (keys.length > MAX_CONTAINER_ITEMS)
936
+ throw encodingError("resource-limit-exceeded", path);
937
+ return keys;
938
+ }
939
+ function consumeValueNode(path, context) {
940
+ context.nodes += 1;
941
+ if (context.nodes > MAX_ENCODED_VALUE_NODES) {
942
+ throw encodingError("resource-limit-exceeded", path);
943
+ }
944
+ }
945
+ function enterContainer(value, path, depth, context) {
946
+ if (depth > context.maxDepth)
947
+ throw encodingError("max-depth-exceeded", path);
948
+ if (context.ancestors.has(value))
949
+ throw encodingError("cyclic-value", path);
950
+ context.ancestors.add(value);
951
+ }
952
+ function nextDepth(path, depth, context) {
953
+ const next = depth + 1;
954
+ if (next > context.maxDepth)
955
+ throw encodingError("max-depth-exceeded", path);
956
+ return next;
957
+ }
958
+ function defineEnumerableValue(target, name, value) {
959
+ Object.defineProperty(target, name, {
960
+ configurable: true,
961
+ enumerable: true,
962
+ writable: true,
963
+ value,
964
+ });
965
+ }
966
+ function encodePathSegment(value, path) {
967
+ try {
968
+ return encodeOdataKeyPredicatePath(value);
969
+ }
970
+ catch {
971
+ throw encodingError("invalid-value", path);
972
+ }
973
+ }
974
+ function escapeOdataString(value) {
975
+ return value.replace(/'/g, "''");
976
+ }
977
+ function unwrapCollection(type) {
978
+ if (!type.startsWith("Collection(") || !type.endsWith(")"))
979
+ return undefined;
980
+ const inner = type.slice("Collection(".length, -1);
981
+ return inner.length > 0 ? inner : undefined;
982
+ }
983
+ function stripNamespace(type) {
984
+ const dot = type.lastIndexOf(".");
985
+ return dot === -1 ? type : type.slice(dot + 1);
986
+ }
987
+ function simpleIdentifier(value) {
988
+ return value.length <= 256 && SIMPLE_IDENTIFIER.test(value);
989
+ }
990
+ function qualifiedIdentifier(value) {
991
+ return value.length <= 512 && QUALIFIED_IDENTIFIER.test(value);
992
+ }
993
+ function codePointLengthExceeds(value, maximum) {
994
+ let length = 0;
995
+ for (const _character of value) {
996
+ length += 1;
997
+ if (length > maximum)
998
+ return true;
999
+ }
1000
+ return false;
1001
+ }
1002
+ function ownLookup(record, name) {
1003
+ return dataProperty(record, name, [], "invalid-metadata");
1004
+ }
1005
+ function isRecord(value, path) {
1006
+ if (typeof value !== "object" || value === null || Array.isArray(value))
1007
+ return false;
1008
+ try {
1009
+ const prototype = Object.getPrototypeOf(value);
1010
+ return prototype === Object.prototype || prototype === null;
1011
+ }
1012
+ catch {
1013
+ throw encodingError("invalid-value", path);
1014
+ }
1015
+ }
1016
+ function emptyCodecModel() {
1017
+ return {
1018
+ entityType: "",
1019
+ fields: [],
1020
+ keys: [],
1021
+ complexTypes: Object.freeze({}),
1022
+ enumTypes: Object.freeze({}),
1023
+ unsafeTypeNames: new Set(),
1024
+ };
1025
+ }
1026
+ function encodingError(code, path) {
1027
+ return new HonuaOdataEdmEncodingError(code, renderPath(path));
1028
+ }
1029
+ function rethrowEncodingError(error, fallbackCode, fallbackPath) {
1030
+ let isKnownEncodingError = false;
1031
+ try {
1032
+ isKnownEncodingError = error instanceof HonuaOdataEdmEncodingError;
1033
+ }
1034
+ catch { }
1035
+ if (isKnownEncodingError)
1036
+ throw error;
1037
+ throw encodingError(fallbackCode, fallbackPath);
1038
+ }
1039
+ function renderPath(path) {
1040
+ let rendered = "$";
1041
+ for (const segment of path) {
1042
+ if (typeof segment === "number") {
1043
+ rendered += `[${segment}]`;
1044
+ continue;
1045
+ }
1046
+ const safe = boundedPathSegment(segment);
1047
+ rendered += /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(safe) ? `.${safe}` : `[${JSON.stringify(safe)}]`;
1048
+ }
1049
+ return rendered;
1050
+ }
1051
+ function boundedPathSegment(value) {
1052
+ let output = "";
1053
+ let length = 0;
1054
+ for (const character of value) {
1055
+ if (length >= MAX_ERROR_PATH_SEGMENT_CODE_POINTS)
1056
+ return `${output}…`;
1057
+ output += character;
1058
+ length += 1;
1059
+ }
1060
+ return output;
1061
+ }
1062
+ function encodingErrorReason(code) {
1063
+ switch (code) {
1064
+ case "cyclic-value":
1065
+ return "cyclic values are not supported";
1066
+ case "invalid-metadata":
1067
+ return "the metadata declaration is incomplete or inconsistent";
1068
+ case "invalid-options":
1069
+ return "the encoder option is outside its supported bound";
1070
+ case "invalid-value":
1071
+ return "the value does not match its declared EDM type";
1072
+ case "max-depth-exceeded":
1073
+ return "the maximum nesting depth was exceeded";
1074
+ case "missing-key":
1075
+ return "a required key component is missing";
1076
+ case "resource-limit-exceeded":
1077
+ return "the value exceeds a supported resource limit";
1078
+ case "unknown-entity-set":
1079
+ return "the metadata snapshot does not declare the entity set";
1080
+ case "unsupported-type":
1081
+ return "the declared EDM type is not supported for this operation";
1082
+ }
1083
+ }