@graphty/graph-io 0.3.47 → 0.3.48

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 (460) hide show
  1. package/dist/chunks/{approximations-wWjCRzKj.js → approximations-C2riR4NT.js} +2 -2
  2. package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-C2riR4NT.js.map} +1 -1
  3. package/dist/chunks/{block-DiGq58c3.js → block-Cu22ewuS.js} +92 -21
  4. package/dist/chunks/block-Cu22ewuS.js.map +1 -0
  5. package/dist/chunks/{choose--jM0yYCo.js → choose-Cdx6Enl2.js} +3 -3
  6. package/dist/chunks/{choose--jM0yYCo.js.map → choose-Cdx6Enl2.js.map} +1 -1
  7. package/dist/chunks/codes-CV_Bhcyi.js +153 -0
  8. package/dist/chunks/codes-CV_Bhcyi.js.map +1 -0
  9. package/dist/chunks/{constants-BKwqelYD.js → constants-D0LqcsLJ.js} +2 -2
  10. package/dist/chunks/{constants-BKwqelYD.js.map → constants-D0LqcsLJ.js.map} +1 -1
  11. package/dist/chunks/context-cgmmOxZ2.js +663 -0
  12. package/dist/chunks/context-cgmmOxZ2.js.map +1 -0
  13. package/dist/chunks/credentials-BiQsnMTb.js +347 -0
  14. package/dist/chunks/credentials-BiQsnMTb.js.map +1 -0
  15. package/dist/chunks/cx-export-BEeF6ymo.js +259 -0
  16. package/dist/chunks/cx-export-BEeF6ymo.js.map +1 -0
  17. package/dist/chunks/descriptor-BJ-W0Jd-.js +137 -0
  18. package/dist/chunks/descriptor-BJ-W0Jd-.js.map +1 -0
  19. package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
  20. package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
  21. package/dist/chunks/{emit-CwU8cUmG.js → emit-CD8xnY8s.js} +70 -10
  22. package/dist/chunks/emit-CD8xnY8s.js.map +1 -0
  23. package/dist/chunks/{escape-CgzxiYPg.js → escape-DH2Egt-l.js} +12 -12
  24. package/dist/chunks/{escape-CgzxiYPg.js.map → escape-DH2Egt-l.js.map} +1 -1
  25. package/dist/chunks/{export-BvqAXCKh.js → export-CZ7VRm4I.js} +53 -1443
  26. package/dist/chunks/export-CZ7VRm4I.js.map +1 -0
  27. package/dist/chunks/{exporter-DndFlGSa.js → exporter-BIdaoIgh.js} +7 -6
  28. package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-BIdaoIgh.js.map} +1 -1
  29. package/dist/chunks/{exporter-CJgfhF-l.js → exporter-ChjL5fmP.js} +8 -7
  30. package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-ChjL5fmP.js.map} +1 -1
  31. package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-Dcw7Ldtq.js} +6 -4
  32. package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-Dcw7Ldtq.js.map} +1 -1
  33. package/dist/chunks/exporter-DtVU80Fa.js +1008 -0
  34. package/dist/chunks/exporter-DtVU80Fa.js.map +1 -0
  35. package/dist/chunks/{exporter-CrDWIyiq.js → exporter-bxxjOrDZ.js} +11 -9
  36. package/dist/chunks/{exporter-CrDWIyiq.js.map → exporter-bxxjOrDZ.js.map} +1 -1
  37. package/dist/chunks/format-BMS-1Nxb.js +64 -0
  38. package/dist/chunks/format-BMS-1Nxb.js.map +1 -0
  39. package/dist/chunks/{generic-Dq1ntt9q.js → generic-CP6YD34u.js} +4 -4
  40. package/dist/chunks/{generic-Dq1ntt9q.js.map → generic-CP6YD34u.js.map} +1 -1
  41. package/dist/chunks/{importer-DiZRmOQG.js → importer-B87_fmVx.js} +13 -17
  42. package/dist/chunks/importer-B87_fmVx.js.map +1 -0
  43. package/dist/chunks/{importer-BSvfrX_h.js → importer-Bji2MeWr.js} +18 -1014
  44. package/dist/chunks/importer-Bji2MeWr.js.map +1 -0
  45. package/dist/chunks/{importer-COTK9Tsl.js → importer-CB_zV5_L.js} +14 -11
  46. package/dist/chunks/importer-CB_zV5_L.js.map +1 -0
  47. package/dist/chunks/{importer-e6LGpqHB.js → importer-CVT-JyDE.js} +12 -9
  48. package/dist/chunks/importer-CVT-JyDE.js.map +1 -0
  49. package/dist/chunks/{importer-yh_aBCU6.js → importer-Cyy6UseH.js} +7 -6
  50. package/dist/chunks/{importer-yh_aBCU6.js.map → importer-Cyy6UseH.js.map} +1 -1
  51. package/dist/chunks/{importer-iFYPEKaJ.js → importer-DPZDN40-.js} +14 -10
  52. package/dist/chunks/{importer-iFYPEKaJ.js.map → importer-DPZDN40-.js.map} +1 -1
  53. package/dist/chunks/{importer-CMmeMWlC.js → importer-e3huMZbm.js} +8 -260
  54. package/dist/chunks/importer-e3huMZbm.js.map +1 -0
  55. package/dist/chunks/input-Ccg9I22A.js +1397 -0
  56. package/dist/chunks/input-Ccg9I22A.js.map +1 -0
  57. package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-By172SVq.js} +4 -4
  58. package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-By172SVq.js.map} +1 -1
  59. package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-u2SI5xcx.js} +19 -5
  60. package/dist/chunks/lexicon-u2SI5xcx.js.map +1 -0
  61. package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-BwgMyuF0.js} +4 -3
  62. package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-BwgMyuF0.js.map} +1 -1
  63. package/dist/chunks/{records-CiaWZrFH.js → records-Cgvxz-Vx.js} +2 -2
  64. package/dist/chunks/{records-CiaWZrFH.js.map → records-Cgvxz-Vx.js.map} +1 -1
  65. package/dist/chunks/{format-BpQBx8MZ.js → report-CgdsL9Hb.js} +72 -129
  66. package/dist/chunks/report-CgdsL9Hb.js.map +1 -0
  67. package/dist/chunks/sigv4-LkAzsLAu.js +247 -0
  68. package/dist/chunks/sigv4-LkAzsLAu.js.map +1 -0
  69. package/dist/chunks/{styles-BQnsga7p.js → styles-CaABMoO1.js} +76 -43
  70. package/dist/chunks/styles-CaABMoO1.js.map +1 -0
  71. package/dist/chunks/{styles-D3fRphrO.js → styles-P_gmFAOi.js} +101 -21
  72. package/dist/chunks/styles-P_gmFAOi.js.map +1 -0
  73. package/dist/chunks/{styles-yed-BF5x3_Y5.js → styles-yed-Cs1nmrjn.js} +60 -20
  74. package/dist/chunks/styles-yed-Cs1nmrjn.js.map +1 -0
  75. package/dist/chunks/{text-CzJNFOS9.js → text-BuKQVMz2.js} +2 -2
  76. package/dist/chunks/{text-CzJNFOS9.js.map → text-BuKQVMz2.js.map} +1 -1
  77. package/dist/chunks/{writer-DMKvthQE.js → writer-DvHTl36J.js} +5 -4
  78. package/dist/chunks/writer-DvHTl36J.js.map +1 -0
  79. package/dist/csv.js +7 -5
  80. package/dist/csv.js.map +1 -1
  81. package/dist/cx.js +5 -4
  82. package/dist/cx.js.map +1 -1
  83. package/dist/cx2.js +2 -2
  84. package/dist/cys.js +1 -1
  85. package/dist/dot.js +2 -2
  86. package/dist/gexf.js +7 -5
  87. package/dist/gexf.js.map +1 -1
  88. package/dist/gml.js +16 -13
  89. package/dist/gml.js.map +1 -1
  90. package/dist/graph-io.js +1181 -224
  91. package/dist/graph-io.js.map +1 -1
  92. package/dist/graphml.js +3 -3
  93. package/dist/json.js +1 -1
  94. package/dist/neo4j.js +6 -4
  95. package/dist/neo4j.js.map +1 -1
  96. package/dist/obo.js +1 -1
  97. package/dist/pajek.js +1 -1
  98. package/dist/sources-cypher.d.ts +1 -0
  99. package/dist/sources-cypher.js +1236 -0
  100. package/dist/sources-cypher.js.map +1 -0
  101. package/dist/sources-ndex.d.ts +1 -0
  102. package/dist/sources-ndex.js +278 -0
  103. package/dist/sources-ndex.js.map +1 -0
  104. package/dist/sources-rest.d.ts +1 -0
  105. package/dist/sources-rest.js +1367 -0
  106. package/dist/sources-rest.js.map +1 -0
  107. package/dist/src/common/report.d.ts +6 -3
  108. package/dist/src/common/report.d.ts.map +1 -1
  109. package/dist/src/common/report.js +15 -9
  110. package/dist/src/common/report.js.map +1 -1
  111. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  112. package/dist/src/formats/cx/styles.js +1 -0
  113. package/dist/src/formats/cx/styles.js.map +1 -1
  114. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  115. package/dist/src/formats/dot/styles.js +3 -1
  116. package/dist/src/formats/dot/styles.js.map +1 -1
  117. package/dist/src/formats/gexf/styles.d.ts +29 -12
  118. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  119. package/dist/src/formats/gexf/styles.js +160 -31
  120. package/dist/src/formats/gexf/styles.js.map +1 -1
  121. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  122. package/dist/src/formats/gml/styles.js +5 -4
  123. package/dist/src/formats/gml/styles.js.map +1 -1
  124. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  125. package/dist/src/formats/graphml/styles-plain.js +3 -3
  126. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  127. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  128. package/dist/src/formats/graphml/styles-yed.js +89 -19
  129. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  130. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  131. package/dist/src/formats/pajek/styles.js +1 -0
  132. package/dist/src/formats/pajek/styles.js.map +1 -1
  133. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  134. package/dist/src/formats/xgmml/styles.js +1 -0
  135. package/dist/src/formats/xgmml/styles.js.map +1 -1
  136. package/dist/src/index.d.ts +8 -1
  137. package/dist/src/index.d.ts.map +1 -1
  138. package/dist/src/index.js +9 -1
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/registry.d.ts +173 -1
  141. package/dist/src/registry.d.ts.map +1 -1
  142. package/dist/src/registry.js +196 -1
  143. package/dist/src/registry.js.map +1 -1
  144. package/dist/src/sources/builtins.d.ts +11 -0
  145. package/dist/src/sources/builtins.d.ts.map +1 -0
  146. package/dist/src/sources/builtins.js +47 -0
  147. package/dist/src/sources/builtins.js.map +1 -0
  148. package/dist/src/sources/codes.d.ts +230 -0
  149. package/dist/src/sources/codes.d.ts.map +1 -0
  150. package/dist/src/sources/codes.js +58 -0
  151. package/dist/src/sources/codes.js.map +1 -0
  152. package/dist/src/sources/context.d.ts +112 -0
  153. package/dist/src/sources/context.d.ts.map +1 -0
  154. package/dist/src/sources/context.js +739 -0
  155. package/dist/src/sources/context.js.map +1 -0
  156. package/dist/src/sources/credentials.d.ts +179 -0
  157. package/dist/src/sources/credentials.d.ts.map +1 -0
  158. package/dist/src/sources/credentials.js +301 -0
  159. package/dist/src/sources/credentials.js.map +1 -0
  160. package/dist/src/sources/cypher/descriptor.d.ts +21 -0
  161. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
  162. package/dist/src/sources/cypher/descriptor.js +119 -0
  163. package/dist/src/sources/cypher/descriptor.js.map +1 -0
  164. package/dist/src/sources/cypher/flatten.d.ts +72 -0
  165. package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
  166. package/dist/src/sources/cypher/flatten.js +279 -0
  167. package/dist/src/sources/cypher/flatten.js.map +1 -0
  168. package/dist/src/sources/cypher/index.d.ts +33 -0
  169. package/dist/src/sources/cypher/index.d.ts.map +1 -0
  170. package/dist/src/sources/cypher/index.js +405 -0
  171. package/dist/src/sources/cypher/index.js.map +1 -0
  172. package/dist/src/sources/cypher/params.d.ts +40 -0
  173. package/dist/src/sources/cypher/params.d.ts.map +1 -0
  174. package/dist/src/sources/cypher/params.js +6 -0
  175. package/dist/src/sources/cypher/params.js.map +1 -0
  176. package/dist/src/sources/cypher/profiles.d.ts +44 -0
  177. package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
  178. package/dist/src/sources/cypher/profiles.js +61 -0
  179. package/dist/src/sources/cypher/profiles.js.map +1 -0
  180. package/dist/src/sources/cypher/query-builder.d.ts +106 -0
  181. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
  182. package/dist/src/sources/cypher/query-builder.js +236 -0
  183. package/dist/src/sources/cypher/query-builder.js.map +1 -0
  184. package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
  185. package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
  186. package/dist/src/sources/cypher/transports/bolt.js +185 -0
  187. package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
  188. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
  189. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
  190. package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
  191. package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
  192. package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
  193. package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
  194. package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
  195. package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
  196. package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
  197. package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
  198. package/dist/src/sources/cypher/transports/query-api.js +80 -0
  199. package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
  200. package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
  201. package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
  202. package/dist/src/sources/cypher/transports/transport.js +77 -0
  203. package/dist/src/sources/cypher/transports/transport.js.map +1 -0
  204. package/dist/src/sources/cypher/types-map.d.ts +91 -0
  205. package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
  206. package/dist/src/sources/cypher/types-map.js +306 -0
  207. package/dist/src/sources/cypher/types-map.js.map +1 -0
  208. package/dist/src/sources/define.d.ts +47 -0
  209. package/dist/src/sources/define.d.ts.map +1 -0
  210. package/dist/src/sources/define.js +173 -0
  211. package/dist/src/sources/define.js.map +1 -0
  212. package/dist/src/sources/fail.d.ts +33 -0
  213. package/dist/src/sources/fail.d.ts.map +1 -0
  214. package/dist/src/sources/fail.js +49 -0
  215. package/dist/src/sources/fail.js.map +1 -0
  216. package/dist/src/sources/ids.d.ts +64 -0
  217. package/dist/src/sources/ids.d.ts.map +1 -0
  218. package/dist/src/sources/ids.js +64 -0
  219. package/dist/src/sources/ids.js.map +1 -0
  220. package/dist/src/sources/ndex/client.d.ts +31 -0
  221. package/dist/src/sources/ndex/client.d.ts.map +1 -0
  222. package/dist/src/sources/ndex/client.js +90 -0
  223. package/dist/src/sources/ndex/client.js.map +1 -0
  224. package/dist/src/sources/ndex/descriptor.d.ts +10 -0
  225. package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
  226. package/dist/src/sources/ndex/descriptor.js +55 -0
  227. package/dist/src/sources/ndex/descriptor.js.map +1 -0
  228. package/dist/src/sources/ndex/expand.d.ts +20 -0
  229. package/dist/src/sources/ndex/expand.d.ts.map +1 -0
  230. package/dist/src/sources/ndex/expand.js +87 -0
  231. package/dist/src/sources/ndex/expand.js.map +1 -0
  232. package/dist/src/sources/ndex/index.d.ts +25 -0
  233. package/dist/src/sources/ndex/index.d.ts.map +1 -0
  234. package/dist/src/sources/ndex/index.js +191 -0
  235. package/dist/src/sources/ndex/index.js.map +1 -0
  236. package/dist/src/sources/ndex/params.d.ts +17 -0
  237. package/dist/src/sources/ndex/params.d.ts.map +1 -0
  238. package/dist/src/sources/ndex/params.js +6 -0
  239. package/dist/src/sources/ndex/params.js.map +1 -0
  240. package/dist/src/sources/ndex/share-url.d.ts +40 -0
  241. package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
  242. package/dist/src/sources/ndex/share-url.js +64 -0
  243. package/dist/src/sources/ndex/share-url.js.map +1 -0
  244. package/dist/src/sources/params.d.ts +28 -0
  245. package/dist/src/sources/params.d.ts.map +1 -0
  246. package/dist/src/sources/params.js +6 -0
  247. package/dist/src/sources/params.js.map +1 -0
  248. package/dist/src/sources/registry.d.ts +118 -0
  249. package/dist/src/sources/registry.d.ts.map +1 -0
  250. package/dist/src/sources/registry.js +193 -0
  251. package/dist/src/sources/registry.js.map +1 -0
  252. package/dist/src/sources/rest/descriptor.d.ts +16 -0
  253. package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
  254. package/dist/src/sources/rest/descriptor.js +71 -0
  255. package/dist/src/sources/rest/descriptor.js.map +1 -0
  256. package/dist/src/sources/rest/index.d.ts +14 -0
  257. package/dist/src/sources/rest/index.d.ts.map +1 -0
  258. package/dist/src/sources/rest/index.js +13 -0
  259. package/dist/src/sources/rest/index.js.map +1 -0
  260. package/dist/src/sources/rest/mapping.d.ts +30 -0
  261. package/dist/src/sources/rest/mapping.d.ts.map +1 -0
  262. package/dist/src/sources/rest/mapping.js +362 -0
  263. package/dist/src/sources/rest/mapping.js.map +1 -0
  264. package/dist/src/sources/rest/openalex.d.ts +27 -0
  265. package/dist/src/sources/rest/openalex.d.ts.map +1 -0
  266. package/dist/src/sources/rest/openalex.js +269 -0
  267. package/dist/src/sources/rest/openalex.js.map +1 -0
  268. package/dist/src/sources/rest/paging.d.ts +53 -0
  269. package/dist/src/sources/rest/paging.d.ts.map +1 -0
  270. package/dist/src/sources/rest/paging.js +138 -0
  271. package/dist/src/sources/rest/paging.js.map +1 -0
  272. package/dist/src/sources/rest/params.d.ts +216 -0
  273. package/dist/src/sources/rest/params.d.ts.map +1 -0
  274. package/dist/src/sources/rest/params.js +7 -0
  275. package/dist/src/sources/rest/params.js.map +1 -0
  276. package/dist/src/sources/rest/records.d.ts +41 -0
  277. package/dist/src/sources/rest/records.d.ts.map +1 -0
  278. package/dist/src/sources/rest/records.js +240 -0
  279. package/dist/src/sources/rest/records.js.map +1 -0
  280. package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
  281. package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
  282. package/dist/src/sources/rest/samples/deps-dev.js +47 -0
  283. package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
  284. package/dist/src/sources/rest/samples/string.d.ts +9 -0
  285. package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
  286. package/dist/src/sources/rest/samples/string.js +42 -0
  287. package/dist/src/sources/rest/samples/string.js.map +1 -0
  288. package/dist/src/sources/rest/selectors.d.ts +41 -0
  289. package/dist/src/sources/rest/selectors.d.ts.map +1 -0
  290. package/dist/src/sources/rest/selectors.js +81 -0
  291. package/dist/src/sources/rest/selectors.js.map +1 -0
  292. package/dist/src/sources/rest/source.d.ts +67 -0
  293. package/dist/src/sources/rest/source.d.ts.map +1 -0
  294. package/dist/src/sources/rest/source.js +635 -0
  295. package/dist/src/sources/rest/source.js.map +1 -0
  296. package/dist/src/sources/rest/templates.d.ts +38 -0
  297. package/dist/src/sources/rest/templates.d.ts.map +1 -0
  298. package/dist/src/sources/rest/templates.js +125 -0
  299. package/dist/src/sources/rest/templates.js.map +1 -0
  300. package/dist/src/sources/run.d.ts +93 -0
  301. package/dist/src/sources/run.d.ts.map +1 -0
  302. package/dist/src/sources/run.js +673 -0
  303. package/dist/src/sources/run.js.map +1 -0
  304. package/dist/src/sources/sha256.d.ts +12 -0
  305. package/dist/src/sources/sha256.d.ts.map +1 -0
  306. package/dist/src/sources/sha256.js +95 -0
  307. package/dist/src/sources/sha256.js.map +1 -0
  308. package/dist/src/sources/sigv4.d.ts +24 -0
  309. package/dist/src/sources/sigv4.d.ts.map +1 -0
  310. package/dist/src/sources/sigv4.js +182 -0
  311. package/dist/src/sources/sigv4.js.map +1 -0
  312. package/dist/src/sources/testing.d.ts +96 -0
  313. package/dist/src/sources/testing.d.ts.map +1 -0
  314. package/dist/src/sources/testing.js +138 -0
  315. package/dist/src/sources/testing.js.map +1 -0
  316. package/dist/src/sources/types.d.ts +665 -0
  317. package/dist/src/sources/types.d.ts.map +1 -0
  318. package/dist/src/sources/types.js +10 -0
  319. package/dist/src/sources/types.js.map +1 -0
  320. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  321. package/dist/src/styles/canon/enums.js +1 -0
  322. package/dist/src/styles/canon/enums.js.map +1 -1
  323. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  324. package/dist/src/styles/cyjs/cascade.js +68 -2
  325. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  326. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  327. package/dist/src/styles/cyjs/defaults-table.js +2 -0
  328. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  329. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  330. package/dist/src/styles/cyjs/emit.js +18 -7
  331. package/dist/src/styles/cyjs/emit.js.map +1 -1
  332. package/dist/src/styles/cyjs/mappers.d.ts +4 -1
  333. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  334. package/dist/src/styles/cyjs/mappers.js +2 -0
  335. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  336. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  337. package/dist/src/styles/cytoscape/emit.js +59 -7
  338. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  339. package/dist/src/styles/cytoscape/lexicon.d.ts +6 -0
  340. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  341. package/dist/src/styles/cytoscape/lexicon.js +26 -2
  342. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  343. package/dist/src/styles/cytoscape/resolve.d.ts +4 -1
  344. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  345. package/dist/src/styles/cytoscape/resolve.js +10 -6
  346. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  347. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
  348. package/dist/src/styles/cytoscape/translate.js +10 -10
  349. package/dist/src/styles/cytoscape/translate.js.map +1 -1
  350. package/dist/src/styles/defaults.d.ts +30 -0
  351. package/dist/src/styles/defaults.d.ts.map +1 -1
  352. package/dist/src/styles/defaults.js +45 -4
  353. package/dist/src/styles/defaults.js.map +1 -1
  354. package/dist/src/styles/io/block.d.ts.map +1 -1
  355. package/dist/src/styles/io/block.js +9 -0
  356. package/dist/src/styles/io/block.js.map +1 -1
  357. package/dist/src/styles/io/writer.d.ts.map +1 -1
  358. package/dist/src/styles/io/writer.js +7 -3
  359. package/dist/src/styles/io/writer.js.map +1 -1
  360. package/dist/src/styles/plan/resolve.d.ts +2 -1
  361. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  362. package/dist/src/styles/plan/resolve.js +13 -2
  363. package/dist/src/styles/plan/resolve.js.map +1 -1
  364. package/dist/src/styles/types.d.ts +19 -2
  365. package/dist/src/styles/types.d.ts.map +1 -1
  366. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  367. package/dist/src/styles/vocabulary.js +15 -1
  368. package/dist/src/styles/vocabulary.js.map +1 -1
  369. package/dist/src/types.d.ts +19 -5
  370. package/dist/src/types.d.ts.map +1 -1
  371. package/dist/src/types.js.map +1 -1
  372. package/dist/styles.js +11 -11
  373. package/dist/xgmml.js +3 -3
  374. package/docs/samples/people.json +6 -0
  375. package/package.json +29 -4
  376. package/src/common/report.ts +27 -7
  377. package/src/formats/cx/styles.ts +1 -0
  378. package/src/formats/dot/styles.ts +3 -1
  379. package/src/formats/gexf/styles.ts +185 -37
  380. package/src/formats/gml/styles.ts +5 -4
  381. package/src/formats/graphml/styles-plain.ts +3 -9
  382. package/src/formats/graphml/styles-yed.ts +93 -20
  383. package/src/formats/pajek/styles.ts +1 -0
  384. package/src/formats/xgmml/styles.ts +1 -0
  385. package/src/index.ts +90 -0
  386. package/src/registry.ts +326 -1
  387. package/src/sources/builtins.ts +56 -0
  388. package/src/sources/codes.ts +235 -0
  389. package/src/sources/context.ts +893 -0
  390. package/src/sources/credentials.ts +409 -0
  391. package/src/sources/cypher/descriptor.ts +125 -0
  392. package/src/sources/cypher/flatten.ts +323 -0
  393. package/src/sources/cypher/index.ts +498 -0
  394. package/src/sources/cypher/params.ts +41 -0
  395. package/src/sources/cypher/profiles.ts +78 -0
  396. package/src/sources/cypher/query-builder.ts +294 -0
  397. package/src/sources/cypher/transports/bolt.ts +228 -0
  398. package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
  399. package/src/sources/cypher/transports/neptune-https.ts +122 -0
  400. package/src/sources/cypher/transports/query-api.ts +100 -0
  401. package/src/sources/cypher/transports/transport.ts +139 -0
  402. package/src/sources/cypher/types-map.ts +418 -0
  403. package/src/sources/define.ts +195 -0
  404. package/src/sources/fail.ts +70 -0
  405. package/src/sources/ids.ts +74 -0
  406. package/src/sources/ndex/client.ts +102 -0
  407. package/src/sources/ndex/descriptor.ts +64 -0
  408. package/src/sources/ndex/expand.ts +100 -0
  409. package/src/sources/ndex/index.ts +235 -0
  410. package/src/sources/ndex/params.ts +17 -0
  411. package/src/sources/ndex/share-url.ts +84 -0
  412. package/src/sources/params.ts +29 -0
  413. package/src/sources/registry.ts +325 -0
  414. package/src/sources/rest/descriptor.ts +74 -0
  415. package/src/sources/rest/index.ts +22 -0
  416. package/src/sources/rest/mapping.ts +401 -0
  417. package/src/sources/rest/openalex.ts +288 -0
  418. package/src/sources/rest/paging.ts +180 -0
  419. package/src/sources/rest/params.ts +243 -0
  420. package/src/sources/rest/records.ts +289 -0
  421. package/src/sources/rest/samples/deps-dev.ts +49 -0
  422. package/src/sources/rest/samples/string.ts +44 -0
  423. package/src/sources/rest/selectors.ts +91 -0
  424. package/src/sources/rest/source.ts +760 -0
  425. package/src/sources/rest/templates.ts +151 -0
  426. package/src/sources/run.ts +793 -0
  427. package/src/sources/sha256.ts +99 -0
  428. package/src/sources/sigv4.ts +207 -0
  429. package/src/sources/testing.ts +210 -0
  430. package/src/sources/types.ts +741 -0
  431. package/src/styles/canon/enums.ts +1 -0
  432. package/src/styles/cyjs/cascade.ts +81 -2
  433. package/src/styles/cyjs/defaults-table.ts +2 -0
  434. package/src/styles/cyjs/emit.ts +18 -7
  435. package/src/styles/cyjs/mappers.ts +6 -1
  436. package/src/styles/cytoscape/emit.ts +61 -7
  437. package/src/styles/cytoscape/lexicon.ts +28 -2
  438. package/src/styles/cytoscape/resolve.ts +22 -6
  439. package/src/styles/cytoscape/translate.ts +11 -11
  440. package/src/styles/defaults.ts +93 -4
  441. package/src/styles/io/block.ts +10 -0
  442. package/src/styles/io/writer.ts +8 -3
  443. package/src/styles/plan/resolve.ts +14 -2
  444. package/src/styles/types.ts +28 -2
  445. package/src/styles/vocabulary.ts +15 -1
  446. package/src/types.ts +19 -5
  447. package/dist/chunks/block-DiGq58c3.js.map +0 -1
  448. package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
  449. package/dist/chunks/export-BvqAXCKh.js.map +0 -1
  450. package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
  451. package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
  452. package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
  453. package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
  454. package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
  455. package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
  456. package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
  457. package/dist/chunks/styles-BQnsga7p.js.map +0 -1
  458. package/dist/chunks/styles-D3fRphrO.js.map +0 -1
  459. package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
  460. package/dist/chunks/writer-DMKvthQE.js.map +0 -1
@@ -0,0 +1,1367 @@
1
+ import { R as REST_DESCRIPTOR, O as OPENALEX_DESCRIPTOR } from "./chunks/descriptor-BJ-W0Jd-.js";
2
+ import { D, S } from "./chunks/descriptor-BJ-W0Jd-.js";
3
+ import { f as failOn, S as SOURCE_ENTITY_ATTR, e as SOURCE_STUB_ATTR, d as defineSource, R as REST_SOURCE_ID, b as failAlone, o as originOf, w as warnOn, O as OPENALEX_SOURCE_ID } from "./chunks/credentials-BiQsnMTb.js";
4
+ import { b as throwIfAborted } from "./chunks/input-Ccg9I22A.js";
5
+ import { ah as ImportError } from "./chunks/report-CgdsL9Hb.js";
6
+ import { s as sleep } from "./chunks/context-cgmmOxZ2.js";
7
+ const STEP = /^([^.[\]]+)(\[\])?$/;
8
+ const PARSED = /* @__PURE__ */ new Map();
9
+ function parseSelector(selector) {
10
+ const cached = PARSED.get(selector);
11
+ if (cached !== void 0) {
12
+ return cached;
13
+ }
14
+ let steps = [];
15
+ if (selector !== ".") {
16
+ for (const part of selector.split(".")) {
17
+ const m = STEP.exec(part);
18
+ if (m === null) {
19
+ steps = null;
20
+ break;
21
+ }
22
+ steps.push({ key: m[1], flatten: m[2] !== void 0 });
23
+ }
24
+ }
25
+ PARSED.set(selector, steps);
26
+ return steps;
27
+ }
28
+ function select(value, selector) {
29
+ let out = value === void 0 ? [] : [value];
30
+ for (const step of parseSelector(selector) ?? []) {
31
+ const next = [];
32
+ for (const v of out) {
33
+ if (typeof v !== "object" || v === null || !Object.hasOwn(v, step.key)) {
34
+ continue;
35
+ }
36
+ const got = v[step.key];
37
+ if (step.flatten && Array.isArray(got)) {
38
+ next.push(...got);
39
+ } else if (got !== void 0 && got !== null) {
40
+ next.push(got);
41
+ }
42
+ }
43
+ out = next;
44
+ }
45
+ return out.filter((v) => v !== null && v !== void 0);
46
+ }
47
+ function selectOne(value, selector) {
48
+ return select(value, selector)[0];
49
+ }
50
+ function selectRecords(body, selector) {
51
+ const out = select(body, selector);
52
+ return out.length === 1 && Array.isArray(out[0]) ? out[0] : out;
53
+ }
54
+ const SLOT = /\{([^{}]*)\}/g;
55
+ const NAME = /^[A-Za-z_][A-Za-z0-9_-]*$/;
56
+ function templateNames(template) {
57
+ const names = [];
58
+ for (const m of template.matchAll(SLOT)) {
59
+ if (!NAME.test(m[1])) {
60
+ return null;
61
+ }
62
+ names.push(m[1]);
63
+ }
64
+ return /[{}]/.test(template.replaceAll(SLOT, "")) ? null : names;
65
+ }
66
+ function fill(template, values, encode, report) {
67
+ return template.replaceAll(SLOT, (_, name) => {
68
+ const value = values[name];
69
+ if (value === void 0) {
70
+ failOn(report, "E_SOURCE_PARAM", `the mapping's template needs ${name}`, { name, reason: "required" });
71
+ }
72
+ return encode(value);
73
+ });
74
+ }
75
+ function pathValue(report) {
76
+ return (value) => {
77
+ if (value === "." || value === ".." || value === "") {
78
+ failOn(report, "E_SOURCE_PARAM", "a path value may not be empty or a dot segment", {
79
+ name: "path",
80
+ reason: "path"
81
+ });
82
+ }
83
+ return encodeURIComponent(value);
84
+ };
85
+ }
86
+ function checkOrigin(url, endpoint, report) {
87
+ const base = endpoint.pathname.replace(/\/$/, "");
88
+ if (url.origin !== endpoint.origin || !(url.pathname === base || url.pathname.startsWith(`${base}/`))) {
89
+ failOn(report, "E_SOURCE_PARAM", "a request left the mapping's endpoint", { name: "url", reason: "origin" });
90
+ }
91
+ return url;
92
+ }
93
+ function buildRequest(endpoint, request, values, report) {
94
+ const path = fill(request.path, values, pathValue(report), report);
95
+ const url = new URL(`${endpoint.origin}${endpoint.pathname.replace(/\/$/, "")}${path}`);
96
+ for (const [key, template] of Object.entries(request.query ?? {})) {
97
+ url.searchParams.set(
98
+ key,
99
+ fill(template, values, (v) => v, report)
100
+ );
101
+ }
102
+ checkOrigin(url, endpoint, report);
103
+ if (request.method !== "POST") {
104
+ return { url, init: {} };
105
+ }
106
+ const body = fillBody(request.body, values, report);
107
+ return {
108
+ url,
109
+ init: {
110
+ method: "POST",
111
+ headers: { "content-type": "application/json" },
112
+ body: JSON.stringify(body ?? null),
113
+ // a mapping's POST reads; it is a query, so it is as safe to retry as a GET
114
+ idempotent: true
115
+ }
116
+ };
117
+ }
118
+ function fillBody(body, values, report) {
119
+ if (typeof body === "string") {
120
+ return fill(body, values, (v) => v, report);
121
+ }
122
+ if (Array.isArray(body)) {
123
+ return body.map((b) => fillBody(b, values, report));
124
+ }
125
+ if (typeof body === "object" && body !== null) {
126
+ return Object.fromEntries(Object.entries(body).map(([k, v]) => [k, fillBody(v, values, report)]));
127
+ }
128
+ return body;
129
+ }
130
+ function isObject(v) {
131
+ return typeof v === "object" && v !== null && !Array.isArray(v);
132
+ }
133
+ function checkSelector(value, at, push, required, index = false) {
134
+ if (value === void 0 && !required) {
135
+ return;
136
+ }
137
+ if (typeof value !== "string") {
138
+ push("missing", at);
139
+ } else if (!(index && value === "#") && parseSelector(value) === null) {
140
+ push("selector", at);
141
+ }
142
+ }
143
+ function checkTemplate(value, at, push) {
144
+ if (typeof value !== "string") {
145
+ push("missing", at);
146
+ } else if (templateNames(value) === null) {
147
+ push("template", at);
148
+ }
149
+ }
150
+ function checkQuery(query, at, push) {
151
+ if (query === void 0) {
152
+ return;
153
+ }
154
+ if (!isObject(query)) {
155
+ push("missing", `${at}.query`);
156
+ return;
157
+ }
158
+ for (const [k, v] of Object.entries(query)) {
159
+ checkTemplate(v, `${at}.query.${k}`, push);
160
+ }
161
+ }
162
+ function isBatch(batch) {
163
+ return isObject(batch) && Number.isInteger(batch.max) && batch.max >= 1 && typeof batch.join === "string";
164
+ }
165
+ function checkRequest(r, at, entities, push) {
166
+ if (!isObject(r)) {
167
+ push("missing", at);
168
+ return;
169
+ }
170
+ if (r.method !== void 0 && r.method !== "GET" && r.method !== "POST") {
171
+ push("missing", `${at}.method`);
172
+ }
173
+ checkTemplate(r.path, `${at}.path`, push);
174
+ if (typeof r.path === "string" && !r.path.startsWith("/")) {
175
+ push("template", `${at}.path`);
176
+ }
177
+ checkQuery(r.query, at, push);
178
+ checkSelector(r.records, `${at}.records`, push, true);
179
+ if (typeof r.entity !== "string") {
180
+ push("missing", `${at}.entity`);
181
+ } else if (!entities.has(r.entity)) {
182
+ push("unknown-entity", `${at}.entity`);
183
+ }
184
+ if (r.batch !== void 0 && !isBatch(r.batch)) {
185
+ push("batch", `${at}.batch`);
186
+ }
187
+ if (r.paging !== void 0) {
188
+ checkPaging(r.paging, `${at}.paging`, push);
189
+ }
190
+ }
191
+ function checkPaging(p, at, push) {
192
+ const paging = p;
193
+ if (!isObject(paging)) {
194
+ push("paging", at);
195
+ return;
196
+ }
197
+ switch (paging.style) {
198
+ case "cursor":
199
+ if (typeof paging.param !== "string" || typeof paging.first !== "string") {
200
+ push("paging", at);
201
+ }
202
+ checkSelector(paging.next, `${at}.next`, push, true);
203
+ break;
204
+ case "offset": {
205
+ const size = paging.size;
206
+ const ok = typeof paging.param === "string" && isObject(size) && typeof size.param === "string" && Number.isInteger(size.value) && size.value > 0 && (paging.unit === void 0 || paging.unit === "items" || paging.unit === "pages") && (paging.base === void 0 || paging.base === 0 || paging.base === 1);
207
+ if (!ok) {
208
+ push("paging", at);
209
+ }
210
+ break;
211
+ }
212
+ case "link-header":
213
+ if (paging.rel !== void 0 && typeof paging.rel !== "string") {
214
+ push("paging", at);
215
+ }
216
+ break;
217
+ case "next-url":
218
+ checkSelector(paging.next, `${at}.next`, push, true);
219
+ break;
220
+ default:
221
+ push("paging", `${at}.style`);
222
+ }
223
+ }
224
+ function checkEdgeRule(rule, at, entities, push) {
225
+ if (!isObject(rule)) {
226
+ push("missing", at);
227
+ return;
228
+ }
229
+ const r = rule;
230
+ if (typeof r.type !== "string") {
231
+ push("missing", `${at}.type`);
232
+ }
233
+ checkSelector(r.each, `${at}.each`, push, false);
234
+ if ("pairs" in r) {
235
+ checkSelector(r.pairs, `${at}.pairs`, push, true);
236
+ } else {
237
+ checkSelector(r.to, `${at}.to`, push, true);
238
+ checkSelector(r.from, `${at}.from`, push, false);
239
+ if (isObject(r.fields)) {
240
+ for (const [k, v] of Object.entries(r.fields)) {
241
+ checkSelector(v, `${at}.fields.${k}`, push, true);
242
+ }
243
+ } else if (r.fields !== void 0) {
244
+ push("missing", `${at}.fields`);
245
+ }
246
+ }
247
+ if (r.entity !== void 0 && (typeof r.entity !== "string" || !entities.has(r.entity))) {
248
+ push("unknown-entity", `${at}.entity`);
249
+ }
250
+ }
251
+ function checkEntity(e, at, entities, push) {
252
+ if (!isObject(e)) {
253
+ push("missing", at);
254
+ return;
255
+ }
256
+ checkSelector(e.id, `${at}.id`, push, true, true);
257
+ if (e.stripPrefix !== void 0 && typeof e.stripPrefix !== "string") {
258
+ push("missing", `${at}.stripPrefix`);
259
+ }
260
+ if (e.label !== void 0 && typeof e.label !== "string") {
261
+ push("missing", `${at}.label`);
262
+ }
263
+ if (e.node !== void 0 && e.node) {
264
+ push("missing", `${at}.node`);
265
+ }
266
+ if (isObject(e.fields)) {
267
+ for (const [k, v] of Object.entries(e.fields)) {
268
+ checkSelector(v, `${at}.fields.${k}`, push, true, true);
269
+ }
270
+ } else if (e.fields !== void 0) {
271
+ push("missing", `${at}.fields`);
272
+ }
273
+ if (Array.isArray(e.edges)) {
274
+ e.edges.forEach((rule, i) => {
275
+ checkEdgeRule(rule, `${at}.edges.${String(i)}`, entities, push);
276
+ });
277
+ } else if (e.edges !== void 0) {
278
+ push("missing", `${at}.edges`);
279
+ }
280
+ if (Array.isArray(e.embedded)) {
281
+ e.embedded.forEach((em, i) => {
282
+ const where = `${at}.embedded.${String(i)}`;
283
+ if (!isObject(em)) {
284
+ push("missing", where);
285
+ return;
286
+ }
287
+ checkSelector(em.at, `${where}.at`, push, true);
288
+ if (typeof em.entity !== "string" || !entities.has(em.entity)) {
289
+ push("unknown-entity", `${where}.entity`);
290
+ }
291
+ });
292
+ } else if (e.embedded !== void 0) {
293
+ push("missing", `${at}.embedded`);
294
+ }
295
+ }
296
+ function checkRequestNames(m, requests, push) {
297
+ const names = [
298
+ ["load", m.load],
299
+ ["hydrate", m.hydrate],
300
+ ["seed", m.seed]
301
+ ];
302
+ if (isObject(m.expand)) {
303
+ names.push(["expand.in", m.expand.in], ["expand.out", m.expand.out]);
304
+ } else {
305
+ names.push(["expand", m.expand]);
306
+ }
307
+ for (const [at, name] of names) {
308
+ if (name === void 0 && at !== "load") {
309
+ continue;
310
+ }
311
+ if (typeof name !== "string") {
312
+ push("missing", at);
313
+ } else if (!requests.has(name)) {
314
+ push("unknown-request", at);
315
+ }
316
+ }
317
+ }
318
+ function checkEndpoint(endpoint, push) {
319
+ let url = null;
320
+ try {
321
+ url = new URL(typeof endpoint === "string" ? endpoint : "");
322
+ } catch {
323
+ }
324
+ if (url === null || url.protocol !== "https:" && url.protocol !== "http:" || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "") {
325
+ push("endpoint", "endpoint");
326
+ }
327
+ }
328
+ function checkRestMapping(mapping) {
329
+ const issues = [];
330
+ const push = (code, at) => {
331
+ issues.push(Object.freeze({ code, at }));
332
+ };
333
+ if (!isObject(mapping)) {
334
+ push("missing", "");
335
+ return issues;
336
+ }
337
+ const m = mapping;
338
+ if (m.version !== 1) {
339
+ push("version", "version");
340
+ }
341
+ checkEndpoint(m.endpoint, push);
342
+ const requests = isObject(m.requests) ? m.requests : {};
343
+ const entities = isObject(m.entities) ? m.entities : {};
344
+ if (!isObject(m.requests)) {
345
+ push("missing", "requests");
346
+ }
347
+ if (!isObject(m.entities)) {
348
+ push("missing", "entities");
349
+ }
350
+ const entityNames = new Set(Object.keys(entities));
351
+ for (const [name, r] of Object.entries(requests)) {
352
+ checkRequest(r, `requests.${name}`, entityNames, push);
353
+ }
354
+ for (const [name, e] of Object.entries(entities)) {
355
+ checkEntity(e, `entities.${name}`, entityNames, push);
356
+ }
357
+ checkRequestNames(m, new Set(Object.keys(requests)), push);
358
+ checkLimits(m, push);
359
+ checkSelector(m.modified, "modified", push, false);
360
+ if (m.directed !== void 0 && typeof m.directed !== "boolean") {
361
+ push("missing", "directed");
362
+ }
363
+ return issues;
364
+ }
365
+ function checkLimits(m, push) {
366
+ for (const [at, value] of [
367
+ ["rateLimit.requests", m.rateLimit?.requests],
368
+ ["rateLimit.perMs", m.rateLimit?.perMs]
369
+ ]) {
370
+ if (m.rateLimit !== void 0 && !(typeof value === "number" && value > 0)) {
371
+ push("number", at);
372
+ }
373
+ }
374
+ if (m.budgetHeaders !== void 0 && (typeof m.budgetHeaders.remaining !== "string" || m.budgetHeaders.reset !== void 0 && typeof m.budgetHeaders.reset !== "string")) {
375
+ push("missing", "budgetHeaders");
376
+ }
377
+ }
378
+ function firstPosition(paging) {
379
+ switch (paging?.style) {
380
+ case "cursor":
381
+ return paging.first;
382
+ case "offset":
383
+ return paging.base ?? 0;
384
+ default:
385
+ return null;
386
+ }
387
+ }
388
+ function pageUrl(url, paging, position, endpoint, report) {
389
+ if (position === null) {
390
+ return url;
391
+ }
392
+ const out = new URL(url);
393
+ switch (paging?.style) {
394
+ case "cursor":
395
+ out.searchParams.set(paging.param, String(position));
396
+ return out;
397
+ case "offset":
398
+ out.searchParams.set(paging.param, String(position));
399
+ out.searchParams.set(paging.size.param, String(paging.size.value));
400
+ return out;
401
+ default:
402
+ return checkOrigin(new URL(String(position), url), endpoint, report);
403
+ }
404
+ }
405
+ function firstPageUrl(url, paging, endpoint, report) {
406
+ return pageUrl(url, paging, firstPosition(paging), endpoint, report);
407
+ }
408
+ function linkOf(header, rel) {
409
+ for (const part of header.split(/,(?=\s*<)/)) {
410
+ const m = /^\s*<([^>]*)>(.*)$/.exec(part);
411
+ if (m === null) {
412
+ continue;
413
+ }
414
+ const rels = /;\s*rel="?([^";]+)"?/i.exec(m[2]);
415
+ if (rels?.[1].split(/\s+/).includes(rel)) {
416
+ return m[1];
417
+ }
418
+ }
419
+ return null;
420
+ }
421
+ function nextLink(rel, page, endpoint, report) {
422
+ const header = page.headers.get("link");
423
+ if (header === null) {
424
+ if (page.runtime === "browser") {
425
+ failOn(report, "E_SOURCE_RESPONSE", "the Link header cannot be read", {
426
+ expected: "link-header",
427
+ contentType: page.headers.get("content-type")
428
+ });
429
+ }
430
+ return null;
431
+ }
432
+ const next = linkOf(header, rel);
433
+ return next === null ? null : checkOrigin(new URL(next, page.url), endpoint, report).href;
434
+ }
435
+ function nextPosition(paging, position, page, endpoint, report) {
436
+ switch (paging?.style) {
437
+ case "cursor": {
438
+ const next = selectOne(page.body, paging.next);
439
+ return typeof next === "string" && next !== "" || typeof next === "number" ? next : null;
440
+ }
441
+ case "offset": {
442
+ if (page.records < paging.size.value || page.records === 0) {
443
+ return null;
444
+ }
445
+ const step = paging.unit === "pages" ? 1 : paging.size.value;
446
+ return Number(position) + step;
447
+ }
448
+ case "link-header":
449
+ return nextLink(paging.rel ?? "next", page, endpoint, report);
450
+ case "next-url": {
451
+ const next = selectOne(page.body, paging.next);
452
+ return typeof next === "string" && next !== "" ? checkOrigin(new URL(next, page.url), endpoint, report).href : null;
453
+ }
454
+ default:
455
+ return null;
456
+ }
457
+ }
458
+ function newState(known = []) {
459
+ return { full: /* @__PURE__ */ new Set(), stubs: /* @__PURE__ */ new Set(), known: new Set(known), modified: null };
460
+ }
461
+ function idText(value, entity) {
462
+ if (typeof value !== "string" && typeof value !== "number") {
463
+ return null;
464
+ }
465
+ const text = String(value);
466
+ const prefix = entity?.stripPrefix;
467
+ return prefix !== void 0 && prefix !== "" && text.startsWith(prefix) ? text.slice(prefix.length) : text;
468
+ }
469
+ function fieldValue(record, selector, index) {
470
+ if (selector === "#") {
471
+ return index;
472
+ }
473
+ return selector.includes("[]") ? select(record, selector) : selectOne(record, selector);
474
+ }
475
+ class PageWriter {
476
+ /**
477
+ * Create one.
478
+ * @param mapping - the mapping
479
+ * @param state - the load's state
480
+ */
481
+ constructor(mapping, state) {
482
+ this.mapping = mapping;
483
+ this.state = state;
484
+ this.out = { nodes: [], edges: [] };
485
+ this.pending = [];
486
+ }
487
+ /**
488
+ * Add the records of an entity, and their embedded records.
489
+ * @param records - the records
490
+ * @param entityName - their entity
491
+ */
492
+ addRecords(records, entityName) {
493
+ const entity = this.mapping.entities[entityName];
494
+ records.forEach((record, index) => {
495
+ const id = entity.node === false ? null : idText(fieldValue(record, entity.id, index), entity);
496
+ if (entity.node !== false) {
497
+ if (id === null) {
498
+ return;
499
+ }
500
+ this.addNode(record, index, id, entityName, entity);
501
+ }
502
+ const modified = this.mapping.modified === void 0 ? void 0 : selectOne(record, this.mapping.modified);
503
+ if (typeof modified === "string" && (this.state.modified === null || modified > this.state.modified)) {
504
+ this.state.modified = modified;
505
+ }
506
+ this.pending.push({ record, entity: entityName, id });
507
+ for (const em of entity.embedded ?? []) {
508
+ this.addRecords(select(record, em.at), em.entity);
509
+ }
510
+ });
511
+ }
512
+ /**
513
+ * Write a full record.
514
+ * @param record - the record
515
+ * @param index - its position
516
+ * @param id - its id
517
+ * @param entityName - its entity
518
+ * @param entity - the entity
519
+ */
520
+ addNode(record, index, id, entityName, entity) {
521
+ const attrs = { labels: [entity.label ?? entityName] };
522
+ if (entity.fields === void 0) {
523
+ for (const [k, v] of Object.entries(record)) {
524
+ if (k !== "id" && k !== "labels" && (typeof v === "string" || typeof v === "number" || typeof v === "boolean")) {
525
+ attrs[k] = v;
526
+ }
527
+ }
528
+ } else {
529
+ for (const [name, selector] of Object.entries(entity.fields)) {
530
+ const v = fieldValue(record, selector, index);
531
+ if (v !== void 0) {
532
+ attrs[name] = v;
533
+ }
534
+ }
535
+ }
536
+ if (this.state.stubs.has(id)) {
537
+ attrs[SOURCE_STUB_ATTR] = false;
538
+ }
539
+ this.state.full.add(id);
540
+ this.out.nodes.push({ id, ...attrs });
541
+ }
542
+ /**
543
+ * Make sure an edge end exists: a stub when no record of it was written and the caller does not
544
+ * hold it.
545
+ * @param id - the id
546
+ * @param entity - its entity, when known
547
+ */
548
+ end(id, entity) {
549
+ const { full, stubs, known } = this.state;
550
+ if (full.has(id) || stubs.has(id) || known.has(id)) {
551
+ return;
552
+ }
553
+ stubs.add(id);
554
+ this.out.nodes.push({
555
+ id,
556
+ [SOURCE_STUB_ATTR]: true,
557
+ ...entity === void 0 ? {} : { [SOURCE_ENTITY_ATTR]: entity }
558
+ });
559
+ }
560
+ /**
561
+ * Run one edge rule over a record.
562
+ * @param rule - the rule
563
+ * @param record - the record
564
+ * @param entityName - the record's entity
565
+ * @param recordId - the record's id (null for a container)
566
+ */
567
+ runRule(rule, record, entityName, recordId) {
568
+ const scopes = rule.each === void 0 ? [record] : select(record, rule.each);
569
+ if ("pairs" in rule) {
570
+ this.runPairsRule(rule, scopes, entityName);
571
+ } else {
572
+ this.runLinkRule(rule, scopes, entityName, recordId);
573
+ }
574
+ }
575
+ /**
576
+ * Run a pairs rule: an edge between every two distinct ids in each scope.
577
+ * @param rule - the rule
578
+ * @param scopes - the scopes it runs over
579
+ * @param entityName - the record's entity
580
+ */
581
+ runPairsRule(rule, scopes, entityName) {
582
+ const entityOf = rule.entity ?? entityName;
583
+ const entity = this.mapping.entities[entityOf];
584
+ for (const scope of scopes) {
585
+ const ids = [...new Set(select(scope, rule.pairs).map((v) => idText(v, entity)))].filter(
586
+ (v) => v !== null
587
+ );
588
+ for (let i = 0; i < ids.length; i++) {
589
+ for (let j = i + 1; j < ids.length; j++) {
590
+ this.end(ids[i], entityOf);
591
+ this.end(ids[j], entityOf);
592
+ this.out.edges.push({ source: ids[i], target: ids[j], type: rule.type });
593
+ }
594
+ }
595
+ }
596
+ }
597
+ /**
598
+ * Run a from/to rule: an edge from the record (or a selected id) to each selected id.
599
+ * @param rule - the rule
600
+ * @param scopes - the scopes it runs over
601
+ * @param entityName - the record's entity
602
+ * @param recordId - the record's id (null for a container)
603
+ */
604
+ runLinkRule(rule, scopes, entityName, recordId) {
605
+ const own = this.mapping.entities[entityName];
606
+ const targetEntity = rule.entity === void 0 ? own : this.mapping.entities[rule.entity];
607
+ for (const scope of scopes) {
608
+ const from = rule.from === void 0 ? recordId : idText(selectOne(scope, rule.from), own);
609
+ if (from === null) {
610
+ continue;
611
+ }
612
+ const tos = select(scope, rule.to).map((t) => idText(t, targetEntity)).filter((v) => v !== null);
613
+ for (const to of tos) {
614
+ this.end(from, rule.from === void 0 ? entityName : void 0);
615
+ this.end(to, rule.entity);
616
+ this.out.edges.push({ ...edgeFields(rule.fields, scope), source: from, target: to, type: rule.type });
617
+ }
618
+ }
619
+ }
620
+ /**
621
+ * Run the edge rules of every record added.
622
+ * @returns the page
623
+ */
624
+ finish() {
625
+ for (const { record, entity, id } of this.pending) {
626
+ for (const rule of this.mapping.entities[entity].edges ?? []) {
627
+ this.runRule(rule, record, entity, id);
628
+ }
629
+ }
630
+ this.pending.length = 0;
631
+ return this.out;
632
+ }
633
+ }
634
+ function edgeFields(fields, scope) {
635
+ const out = {};
636
+ for (const [name, selector] of Object.entries(fields ?? {})) {
637
+ const v = fieldValue(scope, selector, 0);
638
+ if (v !== void 0) {
639
+ out[name] = v;
640
+ }
641
+ }
642
+ return out;
643
+ }
644
+ function toRecords(mapping, groups, state) {
645
+ const writer = new PageWriter(mapping, state);
646
+ for (const g of groups) {
647
+ writer.addRecords(g.records, g.entity);
648
+ }
649
+ return writer.finish();
650
+ }
651
+ const AUTH_CODES = /* @__PURE__ */ new Set(["E_SOURCE_AUTH", "E_SOURCE_FORBIDDEN"]);
652
+ function resetDelayMs(reset) {
653
+ return Math.max(0, reset > 1e9 ? reset * 1e3 - Date.now() : reset * 1e3);
654
+ }
655
+ class RestRun {
656
+ /**
657
+ * Create one.
658
+ * @param plan - the mapping and values
659
+ * @param ctx - the context
660
+ * @param paced - whether this run paces itself (the generic source, whose descriptor cannot)
661
+ */
662
+ constructor(plan2, ctx, paced) {
663
+ this.plan = plan2;
664
+ this.ctx = ctx;
665
+ this.paced = paced;
666
+ this.facts = {};
667
+ this.last = 0;
668
+ this.endpoint = new URL(plan2.mapping.endpoint);
669
+ if (ctx.endpoint !== null && originOf(ctx.endpoint) !== this.endpoint.origin) {
670
+ failOn(ctx.report, "E_SOURCE_PARAM", "the endpoint is not the mapping's", {
671
+ name: "endpoint",
672
+ reason: "origin"
673
+ });
674
+ }
675
+ }
676
+ /** Wait out the mapping's own rate limit (the generic source only). */
677
+ async pace() {
678
+ const rate = this.plan.mapping.rateLimit;
679
+ if (!this.paced || rate === void 0) {
680
+ return;
681
+ }
682
+ const wait = this.last + rate.perMs / rate.requests - Date.now();
683
+ if (wait > 0) {
684
+ await sleep(wait, this.ctx.signal);
685
+ }
686
+ this.last = Date.now();
687
+ }
688
+ /**
689
+ * Record the budget headers of a response.
690
+ * @param headers - the response headers
691
+ */
692
+ noteBudget(headers) {
693
+ const names = this.plan.mapping.budgetHeaders;
694
+ const remaining = names === void 0 ? null : headers.get(names.remaining);
695
+ if (names === void 0 || remaining === null || !Number.isFinite(Number(remaining))) {
696
+ return;
697
+ }
698
+ const reset = names.reset === void 0 ? null : Number(headers.get(names.reset) ?? Number.NaN);
699
+ const resetMs = reset === null || !Number.isFinite(reset) ? void 0 : resetDelayMs(reset);
700
+ this.facts.budget = { remaining: Number(remaining), ...resetMs === void 0 ? {} : { resetMs } };
701
+ }
702
+ /**
703
+ * Read one page of a request.
704
+ * @param name - the request name
705
+ * @param values - the template values
706
+ * @param position - the page's position, or undefined for the first page
707
+ * @param headers - extra request headers (validation)
708
+ * @returns the page
709
+ */
710
+ async read(name, values, position, headers) {
711
+ const request = this.plan.mapping.requests[name];
712
+ const { report } = this.ctx;
713
+ const built = buildRequest(this.endpoint, request, values, report);
714
+ const url = position === void 0 ? firstPageUrl(built.url, request.paging, this.endpoint, report) : pageUrl(built.url, request.paging, position, this.endpoint, report);
715
+ await this.pace();
716
+ const response = await this.ctx.fetch(url, {
717
+ ...built.init,
718
+ headers: { accept: "application/json", ...built.init.headers, ...headers },
719
+ allowStatus: [304]
720
+ });
721
+ this.noteBudget(response.headers);
722
+ if (response.status === 304) {
723
+ return { records: [], next: null, headers: response.headers, status: 304 };
724
+ }
725
+ const text = await response.text();
726
+ let body;
727
+ try {
728
+ body = JSON.parse(text);
729
+ } catch {
730
+ failOn(report, "E_SOURCE_RESPONSE", "the response is not JSON", {
731
+ expected: "json",
732
+ contentType: response.headers.get("content-type")
733
+ });
734
+ }
735
+ const records = selectRecords(body, request.records);
736
+ const here = position ?? null;
737
+ const next = nextPosition(
738
+ request.paging,
739
+ position ?? (request.paging?.style === "offset" ? request.paging.base ?? 0 : here),
740
+ { body, headers: response.headers, url, records: records.length, runtime: this.ctx.runtime },
741
+ this.endpoint,
742
+ report
743
+ );
744
+ return { records, next, headers: response.headers, status: response.status };
745
+ }
746
+ /**
747
+ * Record what the facts say so far, so the report carries them even when a later page fails.
748
+ * @param state - the load's record state
749
+ * @param next - where to resume, for an expansion
750
+ * @returns the report so far
751
+ */
752
+ finish(state, next = null) {
753
+ if (state?.modified !== null && state?.modified !== void 0) {
754
+ this.facts.validators = { ...this.facts.validators, modified: state.modified };
755
+ }
756
+ return this.ctx.finish({ ...this.facts, next });
757
+ }
758
+ /**
759
+ * Note the HTTP validators of a load's first response.
760
+ * @param headers - its headers
761
+ */
762
+ noteValidators(headers) {
763
+ const etag = headers.get("etag");
764
+ const lastModified = headers.get("last-modified");
765
+ this.facts.validators = {
766
+ ...this.facts.validators,
767
+ ...etag === null ? {} : { etag },
768
+ ...lastModified === null ? {} : { lastModified }
769
+ };
770
+ }
771
+ /**
772
+ * The graph facts of a first page.
773
+ * @returns the meta
774
+ */
775
+ meta() {
776
+ const { directed } = this.plan.mapping;
777
+ return directed === void 0 ? void 0 : { directed };
778
+ }
779
+ }
780
+ function stringValues(params, skip) {
781
+ const out = {};
782
+ for (const [k, v] of Object.entries(params)) {
783
+ if (k !== skip && (typeof v === "string" || typeof v === "number" || typeof v === "boolean")) {
784
+ out[k] = String(v);
785
+ }
786
+ }
787
+ return out;
788
+ }
789
+ async function* loadPages(run) {
790
+ const { mapping, values } = run.plan;
791
+ const { cursor } = run.ctx;
792
+ if (cursor !== null && cursor.r !== mapping.load) {
793
+ failOn(run.ctx.report, "E_SOURCE_PARAM", "the cursor is not this mapping's", {
794
+ name: "cursor",
795
+ reason: "stale-cursor"
796
+ });
797
+ }
798
+ const state = newState();
799
+ const groups = [];
800
+ if (cursor === null && mapping.seed !== void 0) {
801
+ const seed = await run.read(mapping.seed, values, void 0);
802
+ groups.push({ records: seed.records, entity: mapping.requests[mapping.seed].entity });
803
+ }
804
+ const { entity } = mapping.requests[mapping.load];
805
+ let position = cursor === null ? void 0 : cursor.at;
806
+ let first = true;
807
+ for (; ; ) {
808
+ const page = await run.read(mapping.load, values, position);
809
+ if (first && cursor === null) {
810
+ run.noteValidators(page.headers);
811
+ }
812
+ const out = toRecords(mapping, [...groups.splice(0), { records: page.records, entity }], state);
813
+ run.finish(state);
814
+ const next = page.next === null ? null : { r: mapping.load, at: page.next };
815
+ yield { nodes: out.nodes, edges: out.edges, next, meta: first ? run.meta() : void 0 };
816
+ if (page.next === null) {
817
+ return;
818
+ }
819
+ first = false;
820
+ position = page.next;
821
+ }
822
+ }
823
+ function writePage(out, sink, ctx, types) {
824
+ const { report } = ctx;
825
+ let n = 0;
826
+ for (const { id, ...attrs } of out.nodes) {
827
+ if (n++ % 64 === 0) {
828
+ throwIfAborted(ctx.signal);
829
+ }
830
+ try {
831
+ sink.addNodeRecord(id, attrs);
832
+ report.counts.nodes++;
833
+ } catch (err) {
834
+ report.recordError(err, { element: String(id) });
835
+ report.counts.skippedNodes++;
836
+ }
837
+ }
838
+ for (const { source, target, ...attrs } of out.edges) {
839
+ if (n++ % 64 === 0) {
840
+ throwIfAborted(ctx.signal);
841
+ }
842
+ if (types !== void 0 && !types.has(String(attrs.type))) {
843
+ continue;
844
+ }
845
+ try {
846
+ sink.addEdgeRecord(source, target, attrs);
847
+ report.counts.edges++;
848
+ } catch (err) {
849
+ report.recordError(err, { element: `${String(source)} -> ${String(target)}` });
850
+ report.counts.skippedEdges++;
851
+ }
852
+ }
853
+ }
854
+ function expandRequests(mapping, request) {
855
+ if (request.depth === 0) {
856
+ return mapping.hydrate === void 0 ? [] : [mapping.hydrate];
857
+ }
858
+ const { expand } = mapping;
859
+ if (typeof expand === "string" || expand === void 0) {
860
+ return expand === void 0 ? [] : [expand];
861
+ }
862
+ const direction = request.direction ?? "both";
863
+ const names = [direction !== "out" ? expand.in : void 0, direction !== "in" ? expand.out : void 0];
864
+ return [...new Set(names.filter((n) => n !== void 0))];
865
+ }
866
+ function batches(ids, max) {
867
+ const out = [];
868
+ for (let i = 0; i < ids.length; i += max) {
869
+ out.push(ids.slice(i, i + max));
870
+ }
871
+ return out;
872
+ }
873
+ async function expandInto(run, request, sink) {
874
+ return new Expansion(run, request, sink).expand();
875
+ }
876
+ class Expansion {
877
+ /**
878
+ * Check the expansion and set the sink's direction.
879
+ * @param run - the call
880
+ * @param request - the seeds and how far to go
881
+ * @param sink - where to write
882
+ */
883
+ constructor(run, request, sink) {
884
+ this.run = run;
885
+ this.request = request;
886
+ this.sink = sink;
887
+ this.added = 0;
888
+ this.wrote = false;
889
+ const { ctx } = run;
890
+ this.mapping = run.plan.mapping;
891
+ this.names = expandRequests(this.mapping, request);
892
+ if (this.names.length === 0) {
893
+ failOn(ctx.report, "E_SOURCE_UNSUPPORTED", "the mapping has no request for this expansion", {
894
+ feature: request.depth === 0 ? "hydrate" : "expand"
895
+ });
896
+ }
897
+ if (request.ids.length === 0) {
898
+ failOn(ctx.report, "E_SOURCE_PARAM", "an expansion needs seed ids", { name: "ids", reason: "required" });
899
+ }
900
+ this.state = newState([...request.ids.map(String), ...(request.exclude ?? []).map(String)]);
901
+ this.types = request.relationshipTypes === void 0 ? void 0 : new Set(request.relationshipTypes);
902
+ if (this.mapping.directed !== void 0 && sink.edgeCount === 0) {
903
+ sink.setDirected(this.mapping.directed);
904
+ }
905
+ }
906
+ /**
907
+ * Run every hop.
908
+ * @returns the report
909
+ */
910
+ async expand() {
911
+ let frontier = this.request.ids.map(String);
912
+ const depth = Math.max(1, this.request.depth ?? 1);
913
+ for (let hop = 1; hop <= depth && frontier.length > 0; hop++) {
914
+ const reached = [];
915
+ const stop = await this.hop(hop, frontier, reached);
916
+ if (stop !== null) {
917
+ return stop;
918
+ }
919
+ frontier = [...new Set(reached)];
920
+ }
921
+ return this.run.finish(this.state, null);
922
+ }
923
+ /**
924
+ * Run one hop: every request over every batch of the frontier.
925
+ * @param hop - the hop, from 1
926
+ * @param frontier - the ids this hop starts from
927
+ * @param reached - collects the ids this hop adds
928
+ * @returns the report when the expansion stopped, else null
929
+ */
930
+ async hop(hop, frontier, reached) {
931
+ for (const [x, name] of this.names.entries()) {
932
+ const max = this.mapping.requests[name].batch?.max ?? 1;
933
+ for (const [b, batch] of batches(frontier, max).entries()) {
934
+ if (this.skipped({ hop, x, b })) {
935
+ continue;
936
+ }
937
+ const stop = await this.readBatch({ hop, x, b }, name, batch, frontier, reached);
938
+ if (stop !== null) {
939
+ return stop;
940
+ }
941
+ }
942
+ }
943
+ return null;
944
+ }
945
+ /**
946
+ * Whether a resumed first hop already read this batch.
947
+ * @param at - the batch
948
+ * @returns true to skip it
949
+ */
950
+ skipped(at) {
951
+ const { hop, x, b } = at;
952
+ const resume = this.run.ctx.cursor;
953
+ if (hop !== 1 || resume === null) {
954
+ return false;
955
+ }
956
+ const rx = Number(resume.x);
957
+ return x < rx || x === rx && b < Number(resume.b);
958
+ }
959
+ /**
960
+ * Where a batch starts: the recorded position for the batch a first hop stopped in.
961
+ * @param at - the batch
962
+ * @returns the position, or undefined for the first page
963
+ */
964
+ startPosition(at) {
965
+ const { hop, x, b } = at;
966
+ const resume = this.run.ctx.cursor;
967
+ return hop === 1 && resume !== null && x === Number(resume.x) && b === Number(resume.b) ? resume.at ?? void 0 : void 0;
968
+ }
969
+ /**
970
+ * Read one batch page by page.
971
+ * @param at - the batch
972
+ * @param name - the request
973
+ * @param batch - its ids
974
+ * @param frontier - the hop's ids
975
+ * @param reached - collects the ids it adds
976
+ * @returns the report when the expansion stopped, else null
977
+ */
978
+ async readBatch(at, name, batch, frontier, reached) {
979
+ const r = this.mapping.requests[name];
980
+ const own = { ...this.run.plan.values, id: batch[0], ids: batch.join(r.batch?.join ?? ",") };
981
+ let position = this.startPosition(at);
982
+ for (; ; ) {
983
+ let page;
984
+ try {
985
+ page = await this.run.read(name, own, position);
986
+ } catch (err) {
987
+ return this.authStop(err, at.hop === 1 ? { x: at.x, b: at.b, at: position ?? null } : null);
988
+ }
989
+ this.writeNew(page, r.entity, reached);
990
+ const stop = this.capStop(at, page, frontier);
991
+ if (stop !== null || page.next === null) {
992
+ return stop;
993
+ }
994
+ position = page.next;
995
+ }
996
+ }
997
+ /**
998
+ * Keep what was written when a later page needs a credential; rethrow anything else.
999
+ * @param err - what the page threw
1000
+ * @param cursor - where to resume
1001
+ * @returns the report
1002
+ */
1003
+ authStop(err, cursor) {
1004
+ if (!this.wrote || !(err instanceof ImportError) || !AUTH_CODES.has(String(err.issue?.code))) {
1005
+ throw err;
1006
+ }
1007
+ const p = err.issue?.params ?? {};
1008
+ warnOn(this.run.ctx.report, "W_SOURCE_AUTH", "a later page needs a credential; the pages before it are kept", {
1009
+ origin: typeof p.origin === "string" ? p.origin : this.run.endpoint.origin,
1010
+ status: typeof p.status === "number" ? p.status : null
1011
+ });
1012
+ return this.run.finish(this.state, cursor);
1013
+ }
1014
+ /**
1015
+ * Write a page and collect the nodes it added.
1016
+ * @param page - the page
1017
+ * @param entity - its records' entity
1018
+ * @param reached - collects the ids it adds
1019
+ */
1020
+ writeNew(page, entity, reached) {
1021
+ const { state } = this;
1022
+ const before = /* @__PURE__ */ new Set([...state.full, ...state.stubs]);
1023
+ const out = toRecords(this.mapping, [{ records: page.records, entity }], state);
1024
+ writePage(out, this.sink, this.run.ctx, this.types);
1025
+ this.wrote = true;
1026
+ for (const node of out.nodes) {
1027
+ const id = String(node.id);
1028
+ if (!before.has(id) && !state.known.has(id)) {
1029
+ reached.push(id);
1030
+ this.added++;
1031
+ }
1032
+ }
1033
+ }
1034
+ /**
1035
+ * Stop at the expansion's limit or the load's caps.
1036
+ * @param at - the batch
1037
+ * @param page - the page just written
1038
+ * @param frontier - the hop's ids
1039
+ * @returns the report when a cap was reached, else null
1040
+ */
1041
+ capStop(at, page, frontier) {
1042
+ const { hop, x, b } = at;
1043
+ const { ctx } = this.run;
1044
+ const limited = this.request.limit !== void 0 && this.added >= this.request.limit;
1045
+ if (limited) {
1046
+ warnOn(ctx.report, "W_SOURCE_LIMIT", "the expansion reached its limit", {
1047
+ limit: "limit",
1048
+ value: this.added
1049
+ });
1050
+ }
1051
+ if (!limited && !ctx.limits.reached()) {
1052
+ return null;
1053
+ }
1054
+ const more = page.next === null ? null : { x, b, at: page.next };
1055
+ return this.run.finish(
1056
+ this.state,
1057
+ hop === 1 ? more ?? nextBatch(x, b, this.names, frontier, this.mapping) : null
1058
+ );
1059
+ }
1060
+ }
1061
+ function nextBatch(x, b, names, frontier, mapping) {
1062
+ const count = Math.ceil(frontier.length / (mapping.requests[names[x]].batch?.max ?? 1));
1063
+ if (b + 1 < count) {
1064
+ return { x, b: b + 1, at: null };
1065
+ }
1066
+ return x + 1 < names.length ? { x: x + 1, b: 0, at: null } : null;
1067
+ }
1068
+ async function validateRun(run, seen) {
1069
+ const { mapping, values } = run.plan;
1070
+ const headers = {};
1071
+ if (seen.etag !== void 0) {
1072
+ headers["if-none-match"] = seen.etag;
1073
+ }
1074
+ if (seen.lastModified !== void 0) {
1075
+ headers["if-modified-since"] = seen.lastModified;
1076
+ }
1077
+ const state = newState();
1078
+ const groups = [];
1079
+ if (mapping.seed !== void 0) {
1080
+ const seed = await run.read(mapping.seed, values, void 0);
1081
+ groups.push({ records: seed.records, entity: mapping.requests[mapping.seed].entity });
1082
+ }
1083
+ const page = await run.read(mapping.load, values, void 0, headers);
1084
+ if (page.status === 304) {
1085
+ return { status: "current", via: seen.etag === void 0 ? "modified" : "etag", validators: seen };
1086
+ }
1087
+ toRecords(mapping, [...groups, { records: page.records, entity: mapping.requests[mapping.load].entity }], state);
1088
+ run.noteValidators(page.headers);
1089
+ const now = {
1090
+ ...run.facts.validators,
1091
+ ...state.modified === null ? {} : { modified: state.modified }
1092
+ };
1093
+ if (seen.etag !== void 0 && now.etag !== void 0) {
1094
+ return { status: seen.etag === now.etag ? "current" : "changed", via: "etag", validators: now };
1095
+ }
1096
+ if (seen.modified !== void 0 && now.modified !== void 0) {
1097
+ return now.modified > seen.modified ? { status: "changed", via: "modified", changedAt: now.modified, validators: now } : { status: "current", via: "modified", validators: now };
1098
+ }
1099
+ return { status: "unverifiable", validators: now };
1100
+ }
1101
+ function restMethods(plan2, paced) {
1102
+ return {
1103
+ records: (params, ctx) => loadPages(new RestRun(plan2(params, ctx, "load"), ctx, paced)),
1104
+ expand: (request, sink, ctx) => expandInto(new RestRun(plan2(request.params, ctx, "expand"), ctx, paced), request, sink),
1105
+ async probe(params, ctx) {
1106
+ const run = new RestRun(plan2(params, ctx, "probe"), ctx, paced);
1107
+ const page = await run.read(run.plan.mapping.load, run.plan.values, void 0);
1108
+ if (page.records.length === 0 && page.status !== 304) {
1109
+ failOn(ctx.report, "E_SOURCE_NOT_FOUND", "the load request found no records", {
1110
+ what: "records",
1111
+ value: run.plan.mapping.load
1112
+ });
1113
+ }
1114
+ return { ok: true };
1115
+ },
1116
+ validate: (params, seen, ctx) => validateRun(new RestRun(plan2(params, ctx, "validate"), ctx, paced), seen)
1117
+ };
1118
+ }
1119
+ function checkedMapping(mapping, ctx) {
1120
+ const [issue] = checkRestMapping(mapping);
1121
+ if (issue !== void 0) {
1122
+ failOn(ctx.report, "E_SOURCE_PARAM", `the mapping is invalid at ${issue.at}`, {
1123
+ name: "mapping",
1124
+ reason: issue.code,
1125
+ at: issue.at
1126
+ });
1127
+ }
1128
+ return mapping;
1129
+ }
1130
+ function restSource(mapping, info) {
1131
+ const [issue] = checkRestMapping(mapping);
1132
+ if (issue !== void 0) {
1133
+ failAlone("E_SOURCE_INVALID", `the mapping of ${info.id} is invalid at ${issue.at}`, {
1134
+ id: info.id,
1135
+ reason: "mapping",
1136
+ at: issue.at
1137
+ });
1138
+ }
1139
+ const { id, ...fields } = info;
1140
+ const auth = mapping.auth === void 0 ? [] : [mapping.auth.kind];
1141
+ const descriptor = Object.freeze({
1142
+ plainName: id,
1143
+ kind: "rest",
1144
+ params: mapping.params ?? [],
1145
+ defaultEndpoint: mapping.endpoint,
1146
+ auth,
1147
+ authRequired: auth.length === 0 ? "none" : "optional",
1148
+ ...mapping.rateLimit === void 0 ? {} : { rateLimit: mapping.rateLimit },
1149
+ ...fields
1150
+ });
1151
+ return defineSource({
1152
+ id,
1153
+ descriptor,
1154
+ ...restMethods((params) => ({ mapping, values: stringValues(params) }), false)
1155
+ });
1156
+ }
1157
+ const restMappingSource = defineSource({
1158
+ id: REST_SOURCE_ID,
1159
+ descriptor: REST_DESCRIPTOR,
1160
+ ...restMethods(
1161
+ (params, ctx) => ({ mapping: checkedMapping(params.mapping, ctx), values: stringValues(params, "mapping") }),
1162
+ true
1163
+ )
1164
+ });
1165
+ const PREFIX = "https://openalex.org/";
1166
+ const WORK_FIELDS = "id,display_name,publication_year,cited_by_count,updated_date,referenced_works";
1167
+ function works(filter, perPage, paged) {
1168
+ return {
1169
+ path: "/works",
1170
+ query: { filter, "per-page": perPage, select: "{select}" },
1171
+ batch: { max: 50, join: "|" },
1172
+ records: "results",
1173
+ entity: "work",
1174
+ ...paged ? { paging: { style: "cursor", param: "cursor", first: "*", next: "meta.next_cursor" } } : {}
1175
+ };
1176
+ }
1177
+ const named = { id: "id", stripPrefix: PREFIX, fields: { name: "display_name" } };
1178
+ const OPENALEX_MAPPING = Object.freeze({
1179
+ version: 1,
1180
+ endpoint: "https://api.openalex.org",
1181
+ load: "citing",
1182
+ seed: "by-id",
1183
+ expand: { in: "citing", out: "by-id" },
1184
+ hydrate: "by-id",
1185
+ directed: true,
1186
+ modified: "updated_date",
1187
+ auth: { kind: "api-key", query: "api_key" },
1188
+ rateLimit: { requests: 10, perMs: 1e3 },
1189
+ budgetHeaders: { remaining: "x-ratelimit-remaining", reset: "x-ratelimit-reset" },
1190
+ requests: {
1191
+ citing: works("cites:{ids}", "200", true),
1192
+ "by-id": works("openalex:{ids}", "50", false),
1193
+ authored: works("authorships.author.id:{ids}", "200", true),
1194
+ "authors-by-id": {
1195
+ path: "/authors",
1196
+ query: { filter: "openalex:{ids}", "per-page": "50", select: "id,display_name" },
1197
+ batch: { max: 50, join: "|" },
1198
+ records: "results",
1199
+ entity: "author"
1200
+ }
1201
+ },
1202
+ entities: {
1203
+ work: {
1204
+ id: "id",
1205
+ stripPrefix: PREFIX,
1206
+ fields: {
1207
+ title: "display_name",
1208
+ year: "publication_year",
1209
+ citedBy: "cited_by_count",
1210
+ updated: "updated_date"
1211
+ },
1212
+ edges: [
1213
+ { to: "referenced_works[]", type: "cites", entity: "work" },
1214
+ { to: "authorships[].author.id", type: "authored_by", entity: "author" },
1215
+ {
1216
+ each: "authorships[]",
1217
+ from: "author.id",
1218
+ to: "institutions[].id",
1219
+ type: "affiliated_with",
1220
+ entity: "institution"
1221
+ },
1222
+ { to: "topics[].id", type: "has_topic", entity: "topic" }
1223
+ ],
1224
+ embedded: [
1225
+ { at: "authorships[].author", entity: "author" },
1226
+ { at: "authorships[].institutions[]", entity: "institution" },
1227
+ { at: "topics[]", entity: "topic" }
1228
+ ]
1229
+ },
1230
+ author: named,
1231
+ institution: named,
1232
+ topic: named
1233
+ }
1234
+ });
1235
+ function includes(include) {
1236
+ const list = typeof include === "string" ? include.split(",") : [];
1237
+ if (Array.isArray(include)) {
1238
+ list.push(...include);
1239
+ }
1240
+ const out = new Set(list.map((v) => String(v).trim()).filter((v) => v !== ""));
1241
+ if (out.has("institutions")) {
1242
+ out.add("authors");
1243
+ }
1244
+ return out;
1245
+ }
1246
+ function citationMapping(include) {
1247
+ const { work } = OPENALEX_MAPPING.entities;
1248
+ const keepEdge = (type) => type === "cites" || type === "authored_by" && include.has("authors") || type === "affiliated_with" && include.has("institutions") || type === "has_topic" && include.has("topics");
1249
+ const keepEmbedded = (entity) => include.has(`${entity}s`);
1250
+ return {
1251
+ ...OPENALEX_MAPPING,
1252
+ entities: {
1253
+ ...OPENALEX_MAPPING.entities,
1254
+ work: {
1255
+ ...work,
1256
+ edges: work.edges?.filter((e) => keepEdge(e.type)),
1257
+ embedded: work.embedded?.filter((e) => keepEmbedded(e.entity))
1258
+ }
1259
+ }
1260
+ };
1261
+ }
1262
+ function coauthorshipMapping(include, seedIsWork) {
1263
+ const institutions = include.has("institutions");
1264
+ return {
1265
+ ...OPENALEX_MAPPING,
1266
+ load: seedIsWork ? "by-id" : "authored",
1267
+ seed: void 0,
1268
+ expand: "authored",
1269
+ hydrate: "authors-by-id",
1270
+ directed: false,
1271
+ entities: {
1272
+ ...OPENALEX_MAPPING.entities,
1273
+ work: {
1274
+ id: "id",
1275
+ // a rule's `from` is read with the record's own prefix
1276
+ stripPrefix: PREFIX,
1277
+ node: false,
1278
+ edges: [
1279
+ { pairs: "authorships[].author.id", type: "coauthor", entity: "author" },
1280
+ ...institutions ? [
1281
+ {
1282
+ each: "authorships[]",
1283
+ from: "author.id",
1284
+ to: "institutions[].id",
1285
+ type: "affiliated_with",
1286
+ entity: "institution"
1287
+ }
1288
+ ] : []
1289
+ ],
1290
+ embedded: [
1291
+ { at: "authorships[].author", entity: "author" },
1292
+ ...institutions ? [{ at: "authorships[].institutions[]", entity: "institution" }] : []
1293
+ ]
1294
+ }
1295
+ }
1296
+ };
1297
+ }
1298
+ function openalexId(value, name, letter, ctx) {
1299
+ const text = typeof value === "string" ? value.trim().replace(PREFIX, "") : "";
1300
+ if (!new RegExp(String.raw`^${letter}\d+$`, "i").test(text)) {
1301
+ failOn(ctx.report, "E_SOURCE_PARAM", `${name} is not an OpenAlex id`, { name, reason: "format" });
1302
+ }
1303
+ return text.toUpperCase();
1304
+ }
1305
+ function plan(params, ctx, purpose) {
1306
+ const graph = params.graph ?? "citation";
1307
+ const include = includes(params.include);
1308
+ const hasWork = params.work !== void 0 && params.work !== "";
1309
+ const hasAuthor = params.author !== void 0 && params.author !== "";
1310
+ if (purpose !== "expand" && hasWork === hasAuthor) {
1311
+ failOn(ctx.report, "E_SOURCE_PARAM", "give exactly one of work and author", {
1312
+ name: "work",
1313
+ reason: hasWork ? "exclusive" : "required"
1314
+ });
1315
+ }
1316
+ let seed = "";
1317
+ if (hasWork) {
1318
+ seed = openalexId(params.work, "work", "W", ctx);
1319
+ } else if (hasAuthor) {
1320
+ seed = openalexId(params.author, "author", "A", ctx);
1321
+ }
1322
+ if (graph === "coauthorship") {
1323
+ return {
1324
+ mapping: coauthorshipMapping(include, hasWork),
1325
+ values: { ids: seed, select: purpose === "validate" ? "id,updated_date" : "id,updated_date,authorships" }
1326
+ };
1327
+ }
1328
+ let select2 = WORK_FIELDS + (include.has("authors") ? ",authorships" : "") + (include.has("topics") ? ",topics" : "");
1329
+ if (purpose === "validate") {
1330
+ select2 = "id,updated_date";
1331
+ }
1332
+ const mapping = citationMapping(include);
1333
+ return {
1334
+ mapping: hasWork ? mapping : { ...mapping, load: "authored", seed: void 0 },
1335
+ values: { ids: seed, select: select2 }
1336
+ };
1337
+ }
1338
+ const ANY_ID = /^[WAIT]\d+$/;
1339
+ const methods = restMethods(plan, false);
1340
+ const openalexSource = defineSource({
1341
+ id: OPENALEX_SOURCE_ID,
1342
+ descriptor: OPENALEX_DESCRIPTOR,
1343
+ ...methods,
1344
+ expand(request, sink, ctx) {
1345
+ for (const id of request.ids) {
1346
+ if (!ANY_ID.test(String(id))) {
1347
+ failOn(ctx.report, "E_SOURCE_PARAM", "an expansion seed is not an OpenAlex id", {
1348
+ name: "ids",
1349
+ reason: "format"
1350
+ });
1351
+ }
1352
+ }
1353
+ return methods.expand(request, sink, ctx);
1354
+ }
1355
+ });
1356
+ export {
1357
+ D as DEPS_DEV_MAPPING,
1358
+ OPENALEX_DESCRIPTOR,
1359
+ OPENALEX_MAPPING,
1360
+ REST_DESCRIPTOR,
1361
+ S as STRING_MAPPING,
1362
+ checkRestMapping,
1363
+ openalexSource,
1364
+ restMappingSource,
1365
+ restSource
1366
+ };
1367
+ //# sourceMappingURL=sources-rest.js.map