@graphty/graph-io 0.3.46 → 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,739 @@
1
+ /**
2
+ * The source context (design sections 2.1, 6.2, 7.2 and 9): the guarded `ctx.fetch` every source
3
+ * reads through. It applies the credential only to the origins it is bound to, refuses credentials
4
+ * in clear text and across redirects, retries what HTTP says is safe to retry, paces requests,
5
+ * enforces the caps, counts decoded bytes, times the load out and turns every failure into a coded
6
+ * issue. A source never sees the credential.
7
+ */
8
+ import { throwIfAborted } from "../common/input.js";
9
+ import { applyCredential, originOf } from "./credentials.js";
10
+ import { failOn, warnOn } from "./fail.js";
11
+ /** Statuses HTTP says a client may retry. */
12
+ const RETRY_STATUSES = new Set([429, 502, 503, 504]);
13
+ /** Statuses whose response has no body by definition. */
14
+ const NULL_BODY_STATUSES = new Set([101, 204, 205, 304]);
15
+ /** Redirect statuses. */
16
+ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
17
+ /** Same-origin redirects followed with a credential before giving up. */
18
+ const MAX_REDIRECTS = 5;
19
+ /**
20
+ * Thrown inside a load when a cap stops it under `onLimit: "stop"`; the runner catches it, keeps
21
+ * what came first and records where to resume. Never leaves graph-io.
22
+ */
23
+ export class LimitStop extends Error {
24
+ /**
25
+ * Create one.
26
+ * @param limit - the cap's option name
27
+ * @param value - the value that reached it
28
+ */
29
+ constructor(limit, value) {
30
+ super(`${limit} reached at ${String(value)}`);
31
+ this.limit = limit;
32
+ this.value = value;
33
+ this.name = "LimitStop";
34
+ }
35
+ }
36
+ /**
37
+ * Where code is running. Node is checked first, since a test may stub a `document`.
38
+ * @returns the runtime
39
+ */
40
+ export function detectRuntime() {
41
+ const g = globalThis;
42
+ if (typeof g.process?.versions?.node === "string") {
43
+ return "node";
44
+ }
45
+ if (typeof g.importScripts === "function") {
46
+ return "worker";
47
+ }
48
+ return g.window !== undefined && g.document !== undefined ? "browser" : "other";
49
+ }
50
+ /**
51
+ * A URL as reports show it: origin and path, never the query string.
52
+ * @param url - the URL
53
+ * @returns origin plus path
54
+ */
55
+ function originPath(url) {
56
+ return `${originOf(url)}${url.pathname}`;
57
+ }
58
+ /**
59
+ * Whether a host is this machine.
60
+ * @param hostname - the URL's hostname
61
+ * @returns true for localhost, 127.0.0.0/8 and ::1
62
+ */
63
+ export function isLoopback(hostname) {
64
+ const host = hostname.replaceAll(/(?:^\[)|(?:\]$)/g, "").toLowerCase();
65
+ return host === "localhost" || host.endsWith(".localhost") || /^127(\.\d{1,3}){3}$/.test(host) || host === "::1";
66
+ }
67
+ /**
68
+ * Whether a host is on a local network: loopback, private IPv4 ranges, link-local, unique local
69
+ * IPv6 or an mDNS `.local` name.
70
+ * @param hostname - the URL's hostname
71
+ * @returns true for a local-network host
72
+ */
73
+ export function isLocalNetwork(hostname) {
74
+ const host = hostname.replaceAll(/(?:^\[)|(?:\]$)/g, "").toLowerCase();
75
+ return (isLoopback(host) ||
76
+ host.endsWith(".local") ||
77
+ /^10(\.\d{1,3}){3}$/.test(host) ||
78
+ /^192\.168(\.\d{1,3}){2}$/.test(host) ||
79
+ /^169\.254(\.\d{1,3}){2}$/.test(host) ||
80
+ /^172\.(1[6-9]|2\d|3[01])(\.\d{1,3}){2}$/.test(host) ||
81
+ /^f[cd][0-9a-f]{2}:/.test(host) ||
82
+ host.startsWith("fe80:"));
83
+ }
84
+ /** One pacer per source id and origin, shared by every load in this process. */
85
+ const PACERS = new Map();
86
+ /**
87
+ * Wait, unless the signal aborts first.
88
+ * @param ms - milliseconds
89
+ * @param signal - the signal
90
+ * @returns a promise that settles after the wait
91
+ */
92
+ export function sleep(ms, signal) {
93
+ return new Promise((resolve, reject) => {
94
+ if (signal.aborted) {
95
+ reject(signal.reason);
96
+ return;
97
+ }
98
+ const onAbort = () => {
99
+ clearTimeout(timer);
100
+ reject(signal.reason);
101
+ };
102
+ const timer = setTimeout(() => {
103
+ signal.removeEventListener("abort", onAbort);
104
+ resolve();
105
+ }, ms);
106
+ signal.addEventListener("abort", onAbort, { once: true });
107
+ });
108
+ }
109
+ /**
110
+ * The milliseconds a readable Retry-After header asks for.
111
+ * @param response - the response
112
+ * @returns milliseconds, or null when absent or unreadable
113
+ */
114
+ function retryAfterMs(response) {
115
+ const value = response.headers.get("retry-after");
116
+ if (value === null) {
117
+ return null;
118
+ }
119
+ const seconds = Number(value);
120
+ if (Number.isFinite(seconds)) {
121
+ return Math.max(0, seconds * 1000);
122
+ }
123
+ const date = Date.parse(value);
124
+ return Number.isNaN(date) ? null : Math.max(0, date - Date.now());
125
+ }
126
+ /**
127
+ * The origins a credential goes to: its own, else the endpoint's.
128
+ * @param credential - the credential, if any
129
+ * @param endpoint - the endpoint, if any
130
+ * @returns the origins
131
+ */
132
+ function boundOrigins(credential, endpoint) {
133
+ if (credential === undefined) {
134
+ return [];
135
+ }
136
+ if (credential.origins.length > 0) {
137
+ return credential.origins;
138
+ }
139
+ return endpoint === null ? [] : [originOf(endpoint)];
140
+ }
141
+ /**
142
+ * The machinery behind one context: the guarded fetch, the caps, pacing, the timeout and the
143
+ * counters.
144
+ */
145
+ class SourceFetcher {
146
+ /**
147
+ * Set up one call.
148
+ * @param input - the source, options, report and counters
149
+ */
150
+ constructor(input) {
151
+ this.input = input;
152
+ this.state = { requests: 0, bytes: 0, finish: null };
153
+ this.controller = new AbortController();
154
+ this.warnedLimits = new Set();
155
+ /** Forward the caller's abort, with its reason. */
156
+ this.onCallerAbort = () => {
157
+ this.controller.abort(this.input.options.signal?.reason);
158
+ };
159
+ const { options, endpoint } = input;
160
+ this.runtime = input.runtime ?? detectRuntime();
161
+ this.fetchImpl = options.fetch ?? ((...args) => globalThis.fetch(...args));
162
+ this.limitOptions = options.limits ?? {};
163
+ const retry = options.retry === false ? { retries: 0 } : (options.retry ?? {});
164
+ this.retry = {
165
+ retries: retry.retries ?? 3,
166
+ baseDelayMs: retry.baseDelayMs ?? 500,
167
+ maxDelayMs: retry.maxDelayMs ?? 30000,
168
+ };
169
+ this.credentialOrigins = boundOrigins(options.credential, endpoint);
170
+ // one controller for the caller's signal and the load timeout; its reason is what rejects
171
+ const callerSignal = options.signal;
172
+ if (callerSignal?.aborted === true) {
173
+ this.controller.abort(callerSignal.reason);
174
+ }
175
+ else {
176
+ callerSignal?.addEventListener("abort", this.onCallerAbort, { once: true });
177
+ }
178
+ const { timeoutMs } = this.limitOptions;
179
+ this.timer =
180
+ timeoutMs === undefined
181
+ ? undefined
182
+ : setTimeout(() => {
183
+ this.timeOut(timeoutMs);
184
+ }, timeoutMs);
185
+ this.signal = this.controller.signal;
186
+ }
187
+ /** Clear the timeout and detach from the caller's signal. */
188
+ dispose() {
189
+ clearTimeout(this.timer);
190
+ this.input.options.signal?.removeEventListener("abort", this.onCallerAbort);
191
+ }
192
+ /**
193
+ * Abort the load with E_SOURCE_TIMEOUT as the reason.
194
+ * @param timeoutMs - the limit that passed
195
+ */
196
+ timeOut(timeoutMs) {
197
+ try {
198
+ failOn(this.input.report, "E_SOURCE_TIMEOUT", `the load ran longer than ${String(timeoutMs)} ms`, {
199
+ timeoutMs,
200
+ serverSide: false,
201
+ });
202
+ }
203
+ catch (err) {
204
+ this.controller.abort(err);
205
+ }
206
+ }
207
+ /**
208
+ * A cap was reached: fail under "error", else warn once and stop.
209
+ * @param limit - the option name
210
+ * @param value - the value reached
211
+ */
212
+ limitHit(limit, value) {
213
+ const { report } = this.input;
214
+ if ((this.limitOptions.onLimit ?? "stop") === "error") {
215
+ failOn(report, "E_SOURCE_LIMIT", `${limit} of ${String(value)} reached`, { limit, value });
216
+ }
217
+ if (!this.warnedLimits.has(limit)) {
218
+ this.warnedLimits.add(limit);
219
+ warnOn(report, "W_SOURCE_LIMIT", `${limit} reached at ${String(value)}; what came first is kept`, {
220
+ limit,
221
+ value,
222
+ });
223
+ }
224
+ throw new LimitStop(limit, value);
225
+ }
226
+ /**
227
+ * Whether a cap is reached; warns once under "stop", throws under "error".
228
+ * @returns true when the source should stop
229
+ */
230
+ reached() {
231
+ const { nodes, edges } = this.input.counts();
232
+ const caps = [
233
+ ["maxNodes", nodes, this.limitOptions.maxNodes],
234
+ ["maxEdges", edges, this.limitOptions.maxEdges],
235
+ ["maxBytes", this.state.bytes, this.limitOptions.maxBytes],
236
+ ["maxRequests", this.state.requests, this.limitOptions.maxRequests],
237
+ ];
238
+ const hit = caps.find(([, value, cap]) => cap !== undefined && value >= cap);
239
+ if (hit === undefined) {
240
+ return false;
241
+ }
242
+ try {
243
+ this.limitHit(hit[0], hit[1]);
244
+ }
245
+ catch (err) {
246
+ if (!(err instanceof LimitStop)) {
247
+ throw err;
248
+ }
249
+ }
250
+ return true;
251
+ }
252
+ /**
253
+ * Report progress.
254
+ * @param done - how much is done
255
+ * @param total - the total, when known
256
+ * @param unit - what is counted
257
+ */
258
+ progress(done, total, unit = "items") {
259
+ if (unit === "bytes") {
260
+ this.byteTotal = total;
261
+ }
262
+ this.input.options.onProgress?.(done, total, unit);
263
+ }
264
+ /**
265
+ * Resolve a request URL against the endpoint and refuse what must never be sent.
266
+ * @param target - the source's URL
267
+ * @returns the absolute URL
268
+ */
269
+ resolve(target) {
270
+ const { report, endpoint } = this.input;
271
+ let url;
272
+ try {
273
+ url = endpoint === null ? new URL(target) : new URL(target, endpoint);
274
+ }
275
+ catch {
276
+ return failOn(report, "E_SOURCE_PARAM", "a relative URL needs an endpoint", {
277
+ name: "endpoint",
278
+ reason: "missing",
279
+ });
280
+ }
281
+ if (url.username !== "" || url.password !== "") {
282
+ failOn(report, "E_SOURCE_PARAM", "a URL may not carry a user name or password", {
283
+ name: "endpoint",
284
+ reason: "credentials-in-url",
285
+ });
286
+ }
287
+ const page = globalThis.location;
288
+ const plain = url.protocol === "http:" || url.protocol === "ws:";
289
+ if (this.runtime === "browser" && page?.protocol === "https:" && plain && !isLoopback(url.hostname)) {
290
+ failOn(report, "E_SOURCE_RUNTIME", "an https page cannot reach a plain http endpoint", {
291
+ runtime: this.runtime,
292
+ reason: "insecure-endpoint",
293
+ });
294
+ }
295
+ return url;
296
+ }
297
+ /**
298
+ * Wait for a slot under the descriptor's rate limit.
299
+ * @param url - the request URL
300
+ * @returns a release function
301
+ */
302
+ async pace(url) {
303
+ const rate = this.input.descriptor?.rateLimit;
304
+ if (rate === undefined) {
305
+ return () => undefined;
306
+ }
307
+ const key = `${this.input.id} ${originOf(url)}`;
308
+ const p = PACERS.get(key) ?? { active: 0, times: [], waiters: [] };
309
+ PACERS.set(key, p);
310
+ for (;;) {
311
+ const now = Date.now();
312
+ p.times = p.times.filter((t) => now - t < rate.perMs);
313
+ if (rate.concurrent !== undefined && p.active >= rate.concurrent) {
314
+ await new Promise((r) => p.waiters.push(r));
315
+ }
316
+ else if (p.times.length >= rate.requests) {
317
+ await sleep(Math.max(1, rate.perMs - (now - p.times[0])), this.signal);
318
+ }
319
+ else {
320
+ p.times.push(now);
321
+ p.active++;
322
+ return () => {
323
+ p.active--;
324
+ p.waiters.shift()?.();
325
+ };
326
+ }
327
+ }
328
+ }
329
+ /**
330
+ * Count the decoded bytes of a body as it is read, against `maxBytes`.
331
+ * @param response - the response
332
+ * @returns the response, with a counted body
333
+ */
334
+ counted(response) {
335
+ if (response.body === null || NULL_BODY_STATUSES.has(response.status)) {
336
+ return response;
337
+ }
338
+ const counter = new TransformStream({
339
+ transform: (chunk, ctrl) => {
340
+ this.state.bytes += chunk.byteLength;
341
+ const cap = this.limitOptions.maxBytes;
342
+ if (cap !== undefined && this.state.bytes > cap) {
343
+ this.limitHit("maxBytes", this.state.bytes);
344
+ }
345
+ if (this.input.unit === "bytes") {
346
+ this.input.options.onProgress?.(this.state.bytes, this.byteTotal, "bytes");
347
+ }
348
+ ctrl.enqueue(chunk);
349
+ },
350
+ });
351
+ return new Response(response.body.pipeThrough(counter), {
352
+ status: response.status,
353
+ statusText: response.statusText,
354
+ headers: response.headers,
355
+ });
356
+ }
357
+ /**
358
+ * Raise the coded issue of a status outside 200 to 299.
359
+ * @param response - the response
360
+ * @param url - the request URL
361
+ * @returns never; it throws
362
+ */
363
+ async statusFailure(response, url) {
364
+ await response.body?.cancel().catch(() => undefined);
365
+ const { report } = this.input;
366
+ const { status } = response;
367
+ const where = originPath(url);
368
+ switch (status) {
369
+ case 401:
370
+ return failOn(report, "E_SOURCE_AUTH", `${where} answered 401`, {
371
+ origin: originOf(url),
372
+ status,
373
+ scheme: response.headers.get("www-authenticate")?.split(/\s/)[0] ?? null,
374
+ serverCode: null,
375
+ });
376
+ case 403:
377
+ return failOn(report, "E_SOURCE_FORBIDDEN", `${where} answered 403`, { status, serverCode: null });
378
+ case 404:
379
+ return failOn(report, "E_SOURCE_NOT_FOUND", `${where} answered 404`, { what: "url", value: where });
380
+ case 429:
381
+ return failOn(report, "E_SOURCE_QUOTA", `${where} answered 429`, {
382
+ retryAfterMs: retryAfterMs(response),
383
+ });
384
+ default:
385
+ return failOn(report, "E_FETCH", `${where} answered ${String(status)}`, { url: where, status });
386
+ }
387
+ }
388
+ /**
389
+ * Build one request, with the credential when the URL's origin is bound.
390
+ * @param url - the request URL
391
+ * @param init - the source's init
392
+ * @param attach - whether the credential goes with it
393
+ * @returns the request
394
+ */
395
+ async request(url, init, attach) {
396
+ const { options, report } = this.input;
397
+ const headers = new Headers(init.headers);
398
+ if (options.userAgent !== undefined && this.runtime === "node") {
399
+ headers.set("User-Agent", options.userAgent);
400
+ }
401
+ const { retry: _retry, idempotent: _idempotent, allowStatus: _allowStatus, ...requestInit } = init;
402
+ const guarded = {
403
+ cache: "no-store",
404
+ credentials: "omit",
405
+ redirect: this.runtime === "browser" ? "error" : "manual",
406
+ };
407
+ const request = new Request(url, { ...requestInit, headers, signal: this.signal, ...(attach ? guarded : {}) });
408
+ if (!attach || options.credential === undefined) {
409
+ return request;
410
+ }
411
+ const signed = await applyCredential(options.credential, request);
412
+ const after = new URL(signed.url);
413
+ if (originOf(after) !== originOf(url)) {
414
+ failOn(report, "E_SOURCE_REDIRECT", "the credential changed the request's origin", {
415
+ from: originPath(url),
416
+ to: originPath(after),
417
+ });
418
+ }
419
+ return signed;
420
+ }
421
+ /**
422
+ * Send one request, following same-origin redirects by hand while a credential is attached.
423
+ * @param url - the request URL
424
+ * @param init - the source's init
425
+ * @param hops - redirects followed so far
426
+ * @returns the response
427
+ */
428
+ async send(url, init, hops) {
429
+ const { options, report } = this.input;
430
+ const attach = options.credential !== undefined && this.credentialOrigins.includes(originOf(url));
431
+ const plain = url.protocol === "http:" || url.protocol === "ws:";
432
+ if (attach && plain && !isLoopback(url.hostname) && options.allowInsecure !== true) {
433
+ failOn(report, "E_SOURCE_PARAM", "a credential is never sent without TLS", {
434
+ name: "endpoint",
435
+ reason: "insecure-endpoint",
436
+ });
437
+ }
438
+ const request = await this.request(url, init, attach);
439
+ this.state.requests++;
440
+ const response = await this.fetchImpl(request);
441
+ if (!attach || !REDIRECT_STATUSES.has(response.status)) {
442
+ return response;
443
+ }
444
+ const location = response.headers.get("location");
445
+ await response.body?.cancel().catch(() => undefined);
446
+ const to = location === null ? null : new URL(location, url);
447
+ if (to === null || originOf(to) !== originOf(url) || hops >= MAX_REDIRECTS) {
448
+ return failOn(report, "E_SOURCE_REDIRECT", "a redirect while a credential was attached", {
449
+ from: originPath(url),
450
+ to: to === null ? null : originPath(to),
451
+ });
452
+ }
453
+ return this.send(to, response.status === 303 ? { ...init, method: "GET", body: null } : init, hops + 1);
454
+ }
455
+ /**
456
+ * Whether a browser refused a credentialed request because it was redirected (sent with
457
+ * `redirect: "error"`, which fails like a CORS refusal): the same URL once more, WITHOUT the
458
+ * credential, under `redirect: "manual"`, whose answer to a redirect is an opaque redirect.
459
+ * @param url - the refused URL
460
+ * @returns true when the URL answers with a redirect
461
+ */
462
+ async redirects(url) {
463
+ if (this.input.options.retry === false) {
464
+ return false;
465
+ }
466
+ try {
467
+ const response = await this.fetchImpl(url, {
468
+ method: "GET",
469
+ redirect: "manual",
470
+ credentials: "omit",
471
+ cache: "no-store",
472
+ signal: this.signal,
473
+ });
474
+ await response.body?.cancel().catch(() => undefined);
475
+ return response.type === "opaqueredirect";
476
+ }
477
+ catch {
478
+ throwIfAborted(this.signal);
479
+ return false;
480
+ }
481
+ }
482
+ /**
483
+ * Why the browser refused a request: one bodyless no-cors GET of the origin's root.
484
+ * @param url - the refused URL
485
+ * @returns the cause
486
+ */
487
+ async diagnose(url) {
488
+ const page = globalThis.location;
489
+ if (page?.hostname !== undefined && !isLocalNetwork(page.hostname) && isLocalNetwork(url.hostname)) {
490
+ return "local-network";
491
+ }
492
+ if (this.input.options.retry === false) {
493
+ return "unknown";
494
+ }
495
+ try {
496
+ await this.fetchImpl(`${originOf(url)}/`, {
497
+ mode: "no-cors",
498
+ method: "GET",
499
+ credentials: "omit",
500
+ cache: "no-store",
501
+ signal: this.signal,
502
+ });
503
+ return "cors";
504
+ }
505
+ catch {
506
+ throwIfAborted(this.signal);
507
+ return "unreachable";
508
+ }
509
+ }
510
+ /**
511
+ * A full-jitter backoff delay.
512
+ * @param attempt - the attempt that failed, from 0
513
+ * @returns milliseconds
514
+ */
515
+ backoff(attempt) {
516
+ const jitter = Math.random(); // NOSONAR(S2245): retry jitter, not a security value
517
+ return jitter * Math.min(this.retry.maxDelayMs, this.retry.baseDelayMs * 2 ** attempt);
518
+ }
519
+ /**
520
+ * What a network failure becomes: a retry (true), or the coded issue.
521
+ * @param err - what fetch threw
522
+ * @param url - the request URL
523
+ * @param attempt - the attempt, from 0
524
+ * @param tries - the retries allowed
525
+ * @param statuses - the statuses seen so far
526
+ * @param probeRedirect - whether a refused redirect may explain it (a credentialed GET or HEAD)
527
+ * @returns true to retry
528
+ */
529
+ async networkFailure(err, url, attempt, tries, statuses, probeRedirect) {
530
+ throwIfAborted(this.signal);
531
+ if (!(err instanceof TypeError)) {
532
+ throw err;
533
+ }
534
+ const { report } = this.input;
535
+ statuses.push(null);
536
+ if (this.runtime === "browser") {
537
+ if (probeRedirect && (await this.redirects(url))) {
538
+ return failOn(report, "E_SOURCE_REDIRECT", "a redirect while a credential was attached", {
539
+ from: originPath(url),
540
+ to: null,
541
+ });
542
+ }
543
+ const cause = await this.diagnose(url);
544
+ // a hidden 429 looks like a CORS refusal, so that one cause is retried once
545
+ if (cause === "cors" && attempt === 0 && tries > 0) {
546
+ await sleep(this.backoff(0), this.signal);
547
+ return true;
548
+ }
549
+ return failOn(report, "E_SOURCE_BLOCKED", `the browser refused ${originPath(url)}`, {
550
+ url: originPath(url),
551
+ cause,
552
+ });
553
+ }
554
+ if (attempt < tries) {
555
+ await sleep(this.backoff(attempt), this.signal);
556
+ return true;
557
+ }
558
+ return failOn(report, "E_FETCH", `${originPath(url)} could not be reached`, {
559
+ url: originPath(url),
560
+ status: null,
561
+ });
562
+ }
563
+ /**
564
+ * Send one attempt under the request cap and the rate limit.
565
+ * @param url - the request URL
566
+ * @param init - the source's init
567
+ * @param attempt - the attempt, from 0
568
+ * @param tries - the retries allowed
569
+ * @param statuses - the statuses seen so far
570
+ * @returns the response, or null to try again
571
+ */
572
+ async attempt(url, init, attempt, tries, statuses) {
573
+ const cap = this.limitOptions.maxRequests;
574
+ if (cap !== undefined && this.state.requests >= cap) {
575
+ this.limitHit("maxRequests", this.state.requests);
576
+ }
577
+ const release = await this.pace(url);
578
+ try {
579
+ return await this.send(url, init, 0);
580
+ }
581
+ catch (err) {
582
+ const method = (init.method ?? "GET").toUpperCase();
583
+ const credentialed = this.input.options.credential !== undefined && this.credentialOrigins.includes(originOf(url));
584
+ await this.networkFailure(err, url, attempt, tries, statuses, credentialed && (method === "GET" || method === "HEAD"));
585
+ return null;
586
+ }
587
+ finally {
588
+ release();
589
+ }
590
+ }
591
+ /**
592
+ * The guarded fetch handed to sources.
593
+ * @param target - the URL, relative to the endpoint or absolute
594
+ * @param init - fetch's init and the source options
595
+ * @returns the response
596
+ */
597
+ async fetch(target, init = {}) {
598
+ throwIfAborted(this.signal);
599
+ const url = this.resolve(target);
600
+ const method = (init.method ?? "GET").toUpperCase();
601
+ const idempotent = method === "GET" || method === "HEAD" || init.idempotent === true;
602
+ const tries = init.retry === false || !idempotent ? 0 : this.retry.retries;
603
+ const statuses = [];
604
+ for (let attempt = 0;; attempt++) {
605
+ const response = await this.attempt(url, init, attempt, tries, statuses);
606
+ if (response === null) {
607
+ continue;
608
+ }
609
+ if (!RETRY_STATUSES.has(response.status) || attempt >= tries) {
610
+ return this.settle(response, url, init, attempt, statuses);
611
+ }
612
+ statuses.push(response.status);
613
+ const asked = retryAfterMs(response);
614
+ await response.body?.cancel().catch(() => undefined);
615
+ await sleep(asked === null ? this.backoff(attempt) : Math.min(asked, this.retry.maxDelayMs), this.signal);
616
+ }
617
+ }
618
+ /**
619
+ * What a fetch returns: a retried success warned, a failing status raised, the body counted.
620
+ * @param response - the response
621
+ * @param url - the request URL
622
+ * @param init - the source's init
623
+ * @param attempt - the attempt, from 0
624
+ * @param statuses - the statuses retried before it
625
+ * @returns the counted response
626
+ */
627
+ settle(response, url, init, attempt, statuses) {
628
+ if (statuses.length > 0 && response.ok) {
629
+ const attempts = attempt + 1;
630
+ warnOn(this.input.report, "W_SOURCE_RETRIED", `${originPath(url)} answered after ${String(attempts)} attempts`, {
631
+ attempts,
632
+ statuses,
633
+ });
634
+ }
635
+ if (!response.ok && response.status !== 304 && !(init.allowStatus ?? []).includes(response.status)) {
636
+ return this.statusFailure(response, url);
637
+ }
638
+ return this.counted(response);
639
+ }
640
+ /**
641
+ * Fetch and parse JSON.
642
+ * @param target - the URL
643
+ * @param init - the request init
644
+ * @returns the parsed body
645
+ */
646
+ async fetchJson(target, init = {}) {
647
+ const headers = new Headers(init.headers);
648
+ if (!headers.has("accept")) {
649
+ headers.set("Accept", "application/json");
650
+ }
651
+ const response = await this.fetch(target, { ...init, headers });
652
+ let text;
653
+ try {
654
+ text = await response.text();
655
+ }
656
+ catch (err) {
657
+ throwIfAborted(this.signal);
658
+ throw err;
659
+ }
660
+ try {
661
+ return JSON.parse(text);
662
+ }
663
+ catch {
664
+ return failOn(this.input.report, "E_SOURCE_RESPONSE", "the response is not JSON", {
665
+ expected: "json",
666
+ contentType: response.headers.get("content-type"),
667
+ });
668
+ }
669
+ }
670
+ /**
671
+ * The report's `source` member as it stands.
672
+ * @param next - where to resume
673
+ * @returns the info
674
+ */
675
+ info(next) {
676
+ const { finish } = this.state;
677
+ const { id, descriptor, endpoint } = this.input;
678
+ return Object.freeze({
679
+ id,
680
+ version: descriptor?.version ?? 1,
681
+ endpoint: endpoint === null ? null : originPath(endpoint),
682
+ requests: this.state.requests,
683
+ bytes: this.state.bytes,
684
+ next,
685
+ ...(finish?.server === undefined ? {} : { server: finish.server }),
686
+ ...(finish?.budget === undefined ? {} : { budget: finish.budget }),
687
+ ...(finish?.validators === undefined ? {} : { validators: finish.validators }),
688
+ });
689
+ }
690
+ }
691
+ /** The caller's options behind each context, for transports that cannot go through ctx.fetch. */
692
+ const CONTEXT_OPTIONS = new WeakMap();
693
+ /**
694
+ * The credential and transport options of a context's load. Internal to graph-io: a transport that
695
+ * hands a credential to a driver (Bolt) reads it here and applies the origin and TLS rules itself.
696
+ * Sources outside graph-io never see a credential.
697
+ * @param ctx - the context
698
+ * @returns the options that matter to a transport
699
+ */
700
+ export function transportOptions(ctx) {
701
+ const options = CONTEXT_OPTIONS.get(ctx) ?? {};
702
+ return { credential: options.credential, allowInsecure: options.allowInsecure, userAgent: options.userAgent };
703
+ }
704
+ /**
705
+ * Create the context of one source call.
706
+ * @param input - the source, options, report and counters
707
+ * @returns the context and its controls
708
+ */
709
+ export function createSourceContext(input) {
710
+ const f = new SourceFetcher(input);
711
+ const limits = Object.freeze({ ...input.options.limits, reached: () => f.reached() });
712
+ const ctx = Object.freeze({
713
+ fetch: (target, init) => f.fetch(target, init),
714
+ fetchJson: (target, init) => f.fetchJson(target, init),
715
+ endpoint: input.endpoint,
716
+ signal: f.signal,
717
+ report: input.report,
718
+ limits,
719
+ cursor: input.cursor,
720
+ runtime: f.runtime,
721
+ progress: (done, total, unit) => {
722
+ f.progress(done, total, unit);
723
+ },
724
+ finish: (result) => {
725
+ f.state.finish = result ?? {};
726
+ return Object.freeze({ ...input.report.finish(), source: f.info(result?.next ?? null) });
727
+ },
728
+ });
729
+ CONTEXT_OPTIONS.set(ctx, input.options);
730
+ return {
731
+ ctx,
732
+ state: f.state,
733
+ info: (next) => f.info(next),
734
+ dispose: () => {
735
+ f.dispose();
736
+ },
737
+ };
738
+ }
739
+ //# sourceMappingURL=context.js.map