@digital-science-dsl/dimensions-analytics-mcp 0.5.3

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 (722) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +152 -0
  3. package/bin/dimensions-analytics-mcp-http.js +2 -0
  4. package/bin/dimensions-analytics-mcp.js +2 -0
  5. package/dist/client/auth/config-loaders.d.ts +22 -0
  6. package/dist/client/auth/config-loaders.d.ts.map +1 -0
  7. package/dist/client/auth/config-loaders.js +68 -0
  8. package/dist/client/auth/config-loaders.js.map +1 -0
  9. package/dist/client/auth/decorators/index.d.ts +7 -0
  10. package/dist/client/auth/decorators/index.d.ts.map +1 -0
  11. package/dist/client/auth/decorators/index.js +6 -0
  12. package/dist/client/auth/decorators/index.js.map +1 -0
  13. package/dist/client/auth/decorators/with-caching.d.ts +81 -0
  14. package/dist/client/auth/decorators/with-caching.d.ts.map +1 -0
  15. package/dist/client/auth/decorators/with-caching.js +168 -0
  16. package/dist/client/auth/decorators/with-caching.js.map +1 -0
  17. package/dist/client/auth/factory.d.ts +13 -0
  18. package/dist/client/auth/factory.d.ts.map +1 -0
  19. package/dist/client/auth/factory.js +29 -0
  20. package/dist/client/auth/factory.js.map +1 -0
  21. package/dist/client/auth/index.d.ts +7 -0
  22. package/dist/client/auth/index.d.ts.map +1 -0
  23. package/dist/client/auth/index.js +6 -0
  24. package/dist/client/auth/index.js.map +1 -0
  25. package/dist/client/auth/jwt-utils.d.ts +17 -0
  26. package/dist/client/auth/jwt-utils.d.ts.map +1 -0
  27. package/dist/client/auth/jwt-utils.js +33 -0
  28. package/dist/client/auth/jwt-utils.js.map +1 -0
  29. package/dist/client/auth/node.d.ts +16 -0
  30. package/dist/client/auth/node.d.ts.map +1 -0
  31. package/dist/client/auth/node.js +15 -0
  32. package/dist/client/auth/node.js.map +1 -0
  33. package/dist/client/auth/providers/index.d.ts +2 -0
  34. package/dist/client/auth/providers/index.d.ts.map +1 -0
  35. package/dist/client/auth/providers/index.js +2 -0
  36. package/dist/client/auth/providers/index.js.map +1 -0
  37. package/dist/client/auth/providers/jwt-auth-provider.d.ts +70 -0
  38. package/dist/client/auth/providers/jwt-auth-provider.d.ts.map +1 -0
  39. package/dist/client/auth/providers/jwt-auth-provider.js +134 -0
  40. package/dist/client/auth/providers/jwt-auth-provider.js.map +1 -0
  41. package/dist/client/auth/schemas.d.ts +19 -0
  42. package/dist/client/auth/schemas.d.ts.map +1 -0
  43. package/dist/client/auth/schemas.js +23 -0
  44. package/dist/client/auth/schemas.js.map +1 -0
  45. package/dist/client/auth/types.d.ts +25 -0
  46. package/dist/client/auth/types.d.ts.map +1 -0
  47. package/dist/client/auth/types.js +9 -0
  48. package/dist/client/auth/types.js.map +1 -0
  49. package/dist/client/command.d.ts +44 -0
  50. package/dist/client/command.d.ts.map +1 -0
  51. package/dist/client/command.js +23 -0
  52. package/dist/client/command.js.map +1 -0
  53. package/dist/client/config/index.d.ts +11 -0
  54. package/dist/client/config/index.d.ts.map +1 -0
  55. package/dist/client/config/index.js +8 -0
  56. package/dist/client/config/index.js.map +1 -0
  57. package/dist/client/config/loader.d.ts +27 -0
  58. package/dist/client/config/loader.d.ts.map +1 -0
  59. package/dist/client/config/loader.js +128 -0
  60. package/dist/client/config/loader.js.map +1 -0
  61. package/dist/client/config/node.d.ts +18 -0
  62. package/dist/client/config/node.d.ts.map +1 -0
  63. package/dist/client/config/node.js +17 -0
  64. package/dist/client/config/node.js.map +1 -0
  65. package/dist/client/config/schemas.d.ts +23 -0
  66. package/dist/client/config/schemas.d.ts.map +1 -0
  67. package/dist/client/config/schemas.js +24 -0
  68. package/dist/client/config/schemas.js.map +1 -0
  69. package/dist/client/config/types.d.ts +37 -0
  70. package/dist/client/config/types.d.ts.map +1 -0
  71. package/dist/client/config/types.js +6 -0
  72. package/dist/client/config/types.js.map +1 -0
  73. package/dist/client/config/unified-loader.d.ts +41 -0
  74. package/dist/client/config/unified-loader.d.ts.map +1 -0
  75. package/dist/client/config/unified-loader.js +86 -0
  76. package/dist/client/config/unified-loader.js.map +1 -0
  77. package/dist/client/config.d.ts +43 -0
  78. package/dist/client/config.d.ts.map +1 -0
  79. package/dist/client/config.js +56 -0
  80. package/dist/client/config.js.map +1 -0
  81. package/dist/client/deployment-config.d.ts +36 -0
  82. package/dist/client/deployment-config.d.ts.map +1 -0
  83. package/dist/client/deployment-config.js +79 -0
  84. package/dist/client/deployment-config.js.map +1 -0
  85. package/dist/client/errors.d.ts +180 -0
  86. package/dist/client/errors.d.ts.map +1 -0
  87. package/dist/client/errors.js +253 -0
  88. package/dist/client/errors.js.map +1 -0
  89. package/dist/client/http-client.d.ts +215 -0
  90. package/dist/client/http-client.d.ts.map +1 -0
  91. package/dist/client/http-client.js +419 -0
  92. package/dist/client/http-client.js.map +1 -0
  93. package/dist/client/index.d.ts +28 -0
  94. package/dist/client/index.d.ts.map +1 -0
  95. package/dist/client/index.js +18 -0
  96. package/dist/client/index.js.map +1 -0
  97. package/dist/client/internal-dsl-client.d.ts +30 -0
  98. package/dist/client/internal-dsl-client.d.ts.map +1 -0
  99. package/dist/client/internal-dsl-client.js +101 -0
  100. package/dist/client/internal-dsl-client.js.map +1 -0
  101. package/dist/client/rate-limiter.d.ts +79 -0
  102. package/dist/client/rate-limiter.d.ts.map +1 -0
  103. package/dist/client/rate-limiter.js +118 -0
  104. package/dist/client/rate-limiter.js.map +1 -0
  105. package/dist/client/resolve-api-key-user.d.ts +24 -0
  106. package/dist/client/resolve-api-key-user.d.ts.map +1 -0
  107. package/dist/client/resolve-api-key-user.js +80 -0
  108. package/dist/client/resolve-api-key-user.js.map +1 -0
  109. package/dist/client/types.d.ts +44 -0
  110. package/dist/client/types.d.ts.map +1 -0
  111. package/dist/client/types.js +10 -0
  112. package/dist/client/types.js.map +1 -0
  113. package/dist/dsl/client.d.ts +330 -0
  114. package/dist/dsl/client.d.ts.map +1 -0
  115. package/dist/dsl/client.js +433 -0
  116. package/dist/dsl/client.js.map +1 -0
  117. package/dist/dsl/commands/apply-filters.d.ts +15 -0
  118. package/dist/dsl/commands/apply-filters.d.ts.map +1 -0
  119. package/dist/dsl/commands/apply-filters.js +29 -0
  120. package/dist/dsl/commands/apply-filters.js.map +1 -0
  121. package/dist/dsl/commands/facet/index.d.ts +6 -0
  122. package/dist/dsl/commands/facet/index.d.ts.map +1 -0
  123. package/dist/dsl/commands/facet/index.js +6 -0
  124. package/dist/dsl/commands/facet/index.js.map +1 -0
  125. package/dist/dsl/commands/facet/schemas.d.ts +71 -0
  126. package/dist/dsl/commands/facet/schemas.d.ts.map +1 -0
  127. package/dist/dsl/commands/facet/schemas.js +84 -0
  128. package/dist/dsl/commands/facet/schemas.js.map +1 -0
  129. package/dist/dsl/commands/functions/ClassifyCommand.d.ts +96 -0
  130. package/dist/dsl/commands/functions/ClassifyCommand.d.ts.map +1 -0
  131. package/dist/dsl/commands/functions/ClassifyCommand.js +95 -0
  132. package/dist/dsl/commands/functions/ClassifyCommand.js.map +1 -0
  133. package/dist/dsl/commands/functions/ExtractAffiliationsCommand.d.ts +86 -0
  134. package/dist/dsl/commands/functions/ExtractAffiliationsCommand.d.ts.map +1 -0
  135. package/dist/dsl/commands/functions/ExtractAffiliationsCommand.js +131 -0
  136. package/dist/dsl/commands/functions/ExtractAffiliationsCommand.js.map +1 -0
  137. package/dist/dsl/commands/functions/ExtractConceptsCommand.d.ts +73 -0
  138. package/dist/dsl/commands/functions/ExtractConceptsCommand.d.ts.map +1 -0
  139. package/dist/dsl/commands/functions/ExtractConceptsCommand.js +110 -0
  140. package/dist/dsl/commands/functions/ExtractConceptsCommand.js.map +1 -0
  141. package/dist/dsl/commands/functions/ExtractGrantsCommand.d.ts +66 -0
  142. package/dist/dsl/commands/functions/ExtractGrantsCommand.d.ts.map +1 -0
  143. package/dist/dsl/commands/functions/ExtractGrantsCommand.js +87 -0
  144. package/dist/dsl/commands/functions/ExtractGrantsCommand.js.map +1 -0
  145. package/dist/dsl/commands/functions/index.d.ts +10 -0
  146. package/dist/dsl/commands/functions/index.d.ts.map +1 -0
  147. package/dist/dsl/commands/functions/index.js +10 -0
  148. package/dist/dsl/commands/functions/index.js.map +1 -0
  149. package/dist/dsl/commands/index.d.ts +8 -0
  150. package/dist/dsl/commands/index.d.ts.map +1 -0
  151. package/dist/dsl/commands/index.js +7 -0
  152. package/dist/dsl/commands/index.js.map +1 -0
  153. package/dist/dsl/commands/validate-input.d.ts +18 -0
  154. package/dist/dsl/commands/validate-input.d.ts.map +1 -0
  155. package/dist/dsl/commands/validate-input.js +27 -0
  156. package/dist/dsl/commands/validate-input.js.map +1 -0
  157. package/dist/dsl/create-client.d.ts +32 -0
  158. package/dist/dsl/create-client.d.ts.map +1 -0
  159. package/dist/dsl/create-client.js +58 -0
  160. package/dist/dsl/create-client.js.map +1 -0
  161. package/dist/dsl/fluent-query-builder.d.ts +439 -0
  162. package/dist/dsl/fluent-query-builder.d.ts.map +1 -0
  163. package/dist/dsl/fluent-query-builder.js +534 -0
  164. package/dist/dsl/fluent-query-builder.js.map +1 -0
  165. package/dist/dsl/index.d.ts +32 -0
  166. package/dist/dsl/index.d.ts.map +1 -0
  167. package/dist/dsl/index.js +31 -0
  168. package/dist/dsl/index.js.map +1 -0
  169. package/dist/dsl/pagination.d.ts +82 -0
  170. package/dist/dsl/pagination.d.ts.map +1 -0
  171. package/dist/dsl/pagination.js +135 -0
  172. package/dist/dsl/pagination.js.map +1 -0
  173. package/dist/dsl/query-builder.d.ts +456 -0
  174. package/dist/dsl/query-builder.d.ts.map +1 -0
  175. package/dist/dsl/query-builder.js +994 -0
  176. package/dist/dsl/query-builder.js.map +1 -0
  177. package/dist/dsl/response-parser.d.ts +111 -0
  178. package/dist/dsl/response-parser.d.ts.map +1 -0
  179. package/dist/dsl/response-parser.js +210 -0
  180. package/dist/dsl/response-parser.js.map +1 -0
  181. package/dist/dsl/schema/cache.d.ts +52 -0
  182. package/dist/dsl/schema/cache.d.ts.map +1 -0
  183. package/dist/dsl/schema/cache.js +97 -0
  184. package/dist/dsl/schema/cache.js.map +1 -0
  185. package/dist/dsl/schema/extract.d.ts +18 -0
  186. package/dist/dsl/schema/extract.d.ts.map +1 -0
  187. package/dist/dsl/schema/extract.js +41 -0
  188. package/dist/dsl/schema/extract.js.map +1 -0
  189. package/dist/dsl/schema/index.d.ts +13 -0
  190. package/dist/dsl/schema/index.d.ts.map +1 -0
  191. package/dist/dsl/schema/index.js +12 -0
  192. package/dist/dsl/schema/index.js.map +1 -0
  193. package/dist/dsl/schema/load.d.ts +41 -0
  194. package/dist/dsl/schema/load.d.ts.map +1 -0
  195. package/dist/dsl/schema/load.js +119 -0
  196. package/dist/dsl/schema/load.js.map +1 -0
  197. package/dist/dsl/schema/store.d.ts +137 -0
  198. package/dist/dsl/schema/store.d.ts.map +1 -0
  199. package/dist/dsl/schema/store.js +204 -0
  200. package/dist/dsl/schema/store.js.map +1 -0
  201. package/dist/dsl/schema/structured-entities.d.ts +21 -0
  202. package/dist/dsl/schema/structured-entities.d.ts.map +1 -0
  203. package/dist/dsl/schema/structured-entities.js +39 -0
  204. package/dist/dsl/schema/structured-entities.js.map +1 -0
  205. package/dist/dsl/schema/summary.d.ts +51 -0
  206. package/dist/dsl/schema/summary.d.ts.map +1 -0
  207. package/dist/dsl/schema/summary.js +61 -0
  208. package/dist/dsl/schema/summary.js.map +1 -0
  209. package/dist/dsl/schema/types.d.ts +36 -0
  210. package/dist/dsl/schema/types.d.ts.map +1 -0
  211. package/dist/dsl/schema/types.js +6 -0
  212. package/dist/dsl/schema/types.js.map +1 -0
  213. package/dist/dsl/schema/validation.d.ts +21 -0
  214. package/dist/dsl/schema/validation.d.ts.map +1 -0
  215. package/dist/dsl/schema/validation.js +44 -0
  216. package/dist/dsl/schema/validation.js.map +1 -0
  217. package/dist/dsl/types/buckets.d.ts +18 -0
  218. package/dist/dsl/types/buckets.d.ts.map +1 -0
  219. package/dist/dsl/types/buckets.js +6 -0
  220. package/dist/dsl/types/buckets.js.map +1 -0
  221. package/dist/dsl/types/common.d.ts +91 -0
  222. package/dist/dsl/types/common.d.ts.map +1 -0
  223. package/dist/dsl/types/common.js +6 -0
  224. package/dist/dsl/types/common.js.map +1 -0
  225. package/dist/dsl/types/entities.d.ts +35 -0
  226. package/dist/dsl/types/entities.d.ts.map +1 -0
  227. package/dist/dsl/types/entities.js +11 -0
  228. package/dist/dsl/types/entities.js.map +1 -0
  229. package/dist/dsl/types/index.d.ts +12 -0
  230. package/dist/dsl/types/index.d.ts.map +1 -0
  231. package/dist/dsl/types/index.js +7 -0
  232. package/dist/dsl/types/index.js.map +1 -0
  233. package/dist/dsl/types/return-clauses.d.ts +107 -0
  234. package/dist/dsl/types/return-clauses.d.ts.map +1 -0
  235. package/dist/dsl/types/return-clauses.js +22 -0
  236. package/dist/dsl/types/return-clauses.js.map +1 -0
  237. package/dist/dsl/types/special-functions.d.ts +175 -0
  238. package/dist/dsl/types/special-functions.d.ts.map +1 -0
  239. package/dist/dsl/types/special-functions.js +25 -0
  240. package/dist/dsl/types/special-functions.js.map +1 -0
  241. package/dist/dsl/types/vocabulary.d.ts +21 -0
  242. package/dist/dsl/types/vocabulary.d.ts.map +1 -0
  243. package/dist/dsl/types/vocabulary.js +44 -0
  244. package/dist/dsl/types/vocabulary.js.map +1 -0
  245. package/dist/dsl/usage-policy.d.ts +87 -0
  246. package/dist/dsl/usage-policy.d.ts.map +1 -0
  247. package/dist/dsl/usage-policy.js +133 -0
  248. package/dist/dsl/usage-policy.js.map +1 -0
  249. package/dist/dsl/utils/escape.d.ts +24 -0
  250. package/dist/dsl/utils/escape.d.ts.map +1 -0
  251. package/dist/dsl/utils/escape.js +124 -0
  252. package/dist/dsl/utils/escape.js.map +1 -0
  253. package/dist/dsl/utils/sanitize.d.ts +13 -0
  254. package/dist/dsl/utils/sanitize.d.ts.map +1 -0
  255. package/dist/dsl/utils/sanitize.js +19 -0
  256. package/dist/dsl/utils/sanitize.js.map +1 -0
  257. package/dist/dsl/utils/string-utils.d.ts +35 -0
  258. package/dist/dsl/utils/string-utils.d.ts.map +1 -0
  259. package/dist/dsl/utils/string-utils.js +145 -0
  260. package/dist/dsl/utils/string-utils.js.map +1 -0
  261. package/dist/dsl/utils/validate-field-name.d.ts +11 -0
  262. package/dist/dsl/utils/validate-field-name.d.ts.map +1 -0
  263. package/dist/dsl/utils/validate-field-name.js +18 -0
  264. package/dist/dsl/utils/validate-field-name.js.map +1 -0
  265. package/dist/examples/dsl-examples.d.ts +11 -0
  266. package/dist/examples/dsl-examples.d.ts.map +1 -0
  267. package/dist/examples/dsl-examples.js +49 -0
  268. package/dist/examples/dsl-examples.js.map +1 -0
  269. package/dist/examples/usage-scenarios.d.ts +22 -0
  270. package/dist/examples/usage-scenarios.d.ts.map +1 -0
  271. package/dist/examples/usage-scenarios.js +173 -0
  272. package/dist/examples/usage-scenarios.js.map +1 -0
  273. package/dist/funder-org-names.d.ts +12 -0
  274. package/dist/funder-org-names.d.ts.map +1 -0
  275. package/dist/funder-org-names.js +30 -0
  276. package/dist/funder-org-names.js.map +1 -0
  277. package/dist/http-main.d.ts +7 -0
  278. package/dist/http-main.d.ts.map +1 -0
  279. package/dist/http-main.js +36 -0
  280. package/dist/http-main.js.map +1 -0
  281. package/dist/http.d.ts +29 -0
  282. package/dist/http.d.ts.map +1 -0
  283. package/dist/http.js +173 -0
  284. package/dist/http.js.map +1 -0
  285. package/dist/index.d.ts +9 -0
  286. package/dist/index.d.ts.map +1 -0
  287. package/dist/index.js +7 -0
  288. package/dist/index.js.map +1 -0
  289. package/dist/kwq/build-query.d.ts +26 -0
  290. package/dist/kwq/build-query.d.ts.map +1 -0
  291. package/dist/kwq/build-query.js +37 -0
  292. package/dist/kwq/build-query.js.map +1 -0
  293. package/dist/kwq/concept-groups.d.ts +49 -0
  294. package/dist/kwq/concept-groups.d.ts.map +1 -0
  295. package/dist/kwq/concept-groups.js +55 -0
  296. package/dist/kwq/concept-groups.js.map +1 -0
  297. package/dist/kwq/dsl-assembler.d.ts +28 -0
  298. package/dist/kwq/dsl-assembler.d.ts.map +1 -0
  299. package/dist/kwq/dsl-assembler.js +124 -0
  300. package/dist/kwq/dsl-assembler.js.map +1 -0
  301. package/dist/kwq/ensemble.d.ts +38 -0
  302. package/dist/kwq/ensemble.d.ts.map +1 -0
  303. package/dist/kwq/ensemble.js +107 -0
  304. package/dist/kwq/ensemble.js.map +1 -0
  305. package/dist/kwq/index.d.ts +16 -0
  306. package/dist/kwq/index.d.ts.map +1 -0
  307. package/dist/kwq/index.js +14 -0
  308. package/dist/kwq/index.js.map +1 -0
  309. package/dist/kwq/types.d.ts +120 -0
  310. package/dist/kwq/types.d.ts.map +1 -0
  311. package/dist/kwq/types.js +11 -0
  312. package/dist/kwq/types.js.map +1 -0
  313. package/dist/lambda.d.ts +10 -0
  314. package/dist/lambda.d.ts.map +1 -0
  315. package/dist/lambda.js +4 -0
  316. package/dist/lambda.js.map +1 -0
  317. package/dist/main.d.ts +8 -0
  318. package/dist/main.d.ts.map +1 -0
  319. package/dist/main.js +33 -0
  320. package/dist/main.js.map +1 -0
  321. package/dist/mcp/batch-fetch.d.ts +89 -0
  322. package/dist/mcp/batch-fetch.d.ts.map +1 -0
  323. package/dist/mcp/batch-fetch.js +178 -0
  324. package/dist/mcp/batch-fetch.js.map +1 -0
  325. package/dist/mcp/examples/dsl-examples.d.ts +21 -0
  326. package/dist/mcp/examples/dsl-examples.d.ts.map +1 -0
  327. package/dist/mcp/examples/dsl-examples.js +61 -0
  328. package/dist/mcp/examples/dsl-examples.js.map +1 -0
  329. package/dist/mcp/examples/usage-scenarios.d.ts +20 -0
  330. package/dist/mcp/examples/usage-scenarios.d.ts.map +1 -0
  331. package/dist/mcp/examples/usage-scenarios.js +169 -0
  332. package/dist/mcp/examples/usage-scenarios.js.map +1 -0
  333. package/dist/mcp/export-format.d.ts +43 -0
  334. package/dist/mcp/export-format.d.ts.map +1 -0
  335. package/dist/mcp/export-format.js +92 -0
  336. package/dist/mcp/export-format.js.map +1 -0
  337. package/dist/mcp/funder-org-names.d.ts +12 -0
  338. package/dist/mcp/funder-org-names.d.ts.map +1 -0
  339. package/dist/mcp/funder-org-names.js +30 -0
  340. package/dist/mcp/funder-org-names.js.map +1 -0
  341. package/dist/mcp/http-server.d.ts +20 -0
  342. package/dist/mcp/http-server.d.ts.map +1 -0
  343. package/dist/mcp/http-server.js +118 -0
  344. package/dist/mcp/http-server.js.map +1 -0
  345. package/dist/mcp/middleware/field-aliases.d.ts +97 -0
  346. package/dist/mcp/middleware/field-aliases.d.ts.map +1 -0
  347. package/dist/mcp/middleware/field-aliases.js +208 -0
  348. package/dist/mcp/middleware/field-aliases.js.map +1 -0
  349. package/dist/mcp/resources/schema.d.ts +13 -0
  350. package/dist/mcp/resources/schema.d.ts.map +1 -0
  351. package/dist/mcp/resources/schema.js +262 -0
  352. package/dist/mcp/resources/schema.js.map +1 -0
  353. package/dist/mcp/schema/context.d.ts +10 -0
  354. package/dist/mcp/schema/context.d.ts.map +1 -0
  355. package/dist/mcp/schema/context.js +6 -0
  356. package/dist/mcp/schema/context.js.map +1 -0
  357. package/dist/mcp/schema/index.d.ts +8 -0
  358. package/dist/mcp/schema/index.d.ts.map +1 -0
  359. package/dist/mcp/schema/index.js +6 -0
  360. package/dist/mcp/schema/index.js.map +1 -0
  361. package/dist/mcp/server.d.ts +56 -0
  362. package/dist/mcp/server.d.ts.map +1 -0
  363. package/dist/mcp/server.js +168 -0
  364. package/dist/mcp/server.js.map +1 -0
  365. package/dist/mcp/shared-schema.d.ts +13 -0
  366. package/dist/mcp/shared-schema.d.ts.map +1 -0
  367. package/dist/mcp/shared-schema.js +28 -0
  368. package/dist/mcp/shared-schema.js.map +1 -0
  369. package/dist/mcp/tools/analytics-filters.d.ts +18 -0
  370. package/dist/mcp/tools/analytics-filters.d.ts.map +1 -0
  371. package/dist/mcp/tools/analytics-filters.js +35 -0
  372. package/dist/mcp/tools/analytics-filters.js.map +1 -0
  373. package/dist/mcp/tools/analytics.d.ts +16 -0
  374. package/dist/mcp/tools/analytics.d.ts.map +1 -0
  375. package/dist/mcp/tools/analytics.js +381 -0
  376. package/dist/mcp/tools/analytics.js.map +1 -0
  377. package/dist/mcp/tools/concept-profile.d.ts +14 -0
  378. package/dist/mcp/tools/concept-profile.d.ts.map +1 -0
  379. package/dist/mcp/tools/concept-profile.js +130 -0
  380. package/dist/mcp/tools/concept-profile.js.map +1 -0
  381. package/dist/mcp/tools/dataset-profile.d.ts +15 -0
  382. package/dist/mcp/tools/dataset-profile.d.ts.map +1 -0
  383. package/dist/mcp/tools/dataset-profile.js +194 -0
  384. package/dist/mcp/tools/dataset-profile.js.map +1 -0
  385. package/dist/mcp/tools/fetch-search-pages.d.ts +15 -0
  386. package/dist/mcp/tools/fetch-search-pages.d.ts.map +1 -0
  387. package/dist/mcp/tools/fetch-search-pages.js +237 -0
  388. package/dist/mcp/tools/fetch-search-pages.js.map +1 -0
  389. package/dist/mcp/tools/functions.d.ts +14 -0
  390. package/dist/mcp/tools/functions.d.ts.map +1 -0
  391. package/dist/mcp/tools/functions.js +87 -0
  392. package/dist/mcp/tools/functions.js.map +1 -0
  393. package/dist/mcp/tools/impact-chain.d.ts +15 -0
  394. package/dist/mcp/tools/impact-chain.d.ts.map +1 -0
  395. package/dist/mcp/tools/impact-chain.js +96 -0
  396. package/dist/mcp/tools/impact-chain.js.map +1 -0
  397. package/dist/mcp/tools/kwq.d.ts +19 -0
  398. package/dist/mcp/tools/kwq.d.ts.map +1 -0
  399. package/dist/mcp/tools/kwq.js +156 -0
  400. package/dist/mcp/tools/kwq.js.map +1 -0
  401. package/dist/mcp/tools/lookup.d.ts +14 -0
  402. package/dist/mcp/tools/lookup.d.ts.map +1 -0
  403. package/dist/mcp/tools/lookup.js +146 -0
  404. package/dist/mcp/tools/lookup.js.map +1 -0
  405. package/dist/mcp/tools/policy-profile.d.ts +15 -0
  406. package/dist/mcp/tools/policy-profile.d.ts.map +1 -0
  407. package/dist/mcp/tools/policy-profile.js +174 -0
  408. package/dist/mcp/tools/policy-profile.js.map +1 -0
  409. package/dist/mcp/tools/profile.d.ts +14 -0
  410. package/dist/mcp/tools/profile.d.ts.map +1 -0
  411. package/dist/mcp/tools/profile.js +349 -0
  412. package/dist/mcp/tools/profile.js.map +1 -0
  413. package/dist/mcp/tools/query.d.ts +16 -0
  414. package/dist/mcp/tools/query.d.ts.map +1 -0
  415. package/dist/mcp/tools/query.js +75 -0
  416. package/dist/mcp/tools/query.js.map +1 -0
  417. package/dist/mcp/tools/schema.d.ts +23 -0
  418. package/dist/mcp/tools/schema.d.ts.map +1 -0
  419. package/dist/mcp/tools/schema.js +124 -0
  420. package/dist/mcp/tools/schema.js.map +1 -0
  421. package/dist/mcp/tools/search-entity-metadata.d.ts +18 -0
  422. package/dist/mcp/tools/search-entity-metadata.d.ts.map +1 -0
  423. package/dist/mcp/tools/search-entity-metadata.js +221 -0
  424. package/dist/mcp/tools/search-entity-metadata.js.map +1 -0
  425. package/dist/mcp/tools/search-input.d.ts +58 -0
  426. package/dist/mcp/tools/search-input.d.ts.map +1 -0
  427. package/dist/mcp/tools/search-input.js +76 -0
  428. package/dist/mcp/tools/search-input.js.map +1 -0
  429. package/dist/mcp/tools/search.d.ts +24 -0
  430. package/dist/mcp/tools/search.d.ts.map +1 -0
  431. package/dist/mcp/tools/search.js +115 -0
  432. package/dist/mcp/tools/search.js.map +1 -0
  433. package/dist/mcp/utils.d.ts +82 -0
  434. package/dist/mcp/utils.d.ts.map +1 -0
  435. package/dist/mcp/utils.js +126 -0
  436. package/dist/mcp/utils.js.map +1 -0
  437. package/dist/middleware/field-aliases.d.ts +97 -0
  438. package/dist/middleware/field-aliases.d.ts.map +1 -0
  439. package/dist/middleware/field-aliases.js +208 -0
  440. package/dist/middleware/field-aliases.js.map +1 -0
  441. package/dist/resources/schema.d.ts +13 -0
  442. package/dist/resources/schema.d.ts.map +1 -0
  443. package/dist/resources/schema.js +204 -0
  444. package/dist/resources/schema.js.map +1 -0
  445. package/dist/schema/context.d.ts +10 -0
  446. package/dist/schema/context.d.ts.map +1 -0
  447. package/dist/schema/context.js +6 -0
  448. package/dist/schema/context.js.map +1 -0
  449. package/dist/schema/index.d.ts +9 -0
  450. package/dist/schema/index.d.ts.map +1 -0
  451. package/dist/schema/index.js +6 -0
  452. package/dist/schema/index.js.map +1 -0
  453. package/dist/schema/load.d.ts +43 -0
  454. package/dist/schema/load.d.ts.map +1 -0
  455. package/dist/schema/load.js +139 -0
  456. package/dist/schema/load.js.map +1 -0
  457. package/dist/schema/store.d.ts +112 -0
  458. package/dist/schema/store.d.ts.map +1 -0
  459. package/dist/schema/store.js +173 -0
  460. package/dist/schema/store.js.map +1 -0
  461. package/dist/schema/structured-entities.d.ts +21 -0
  462. package/dist/schema/structured-entities.d.ts.map +1 -0
  463. package/dist/schema/structured-entities.js +39 -0
  464. package/dist/schema/structured-entities.js.map +1 -0
  465. package/dist/schema/types.d.ts +36 -0
  466. package/dist/schema/types.d.ts.map +1 -0
  467. package/dist/schema/types.js +6 -0
  468. package/dist/schema/types.js.map +1 -0
  469. package/dist/server.d.ts +57 -0
  470. package/dist/server.d.ts.map +1 -0
  471. package/dist/server.js +144 -0
  472. package/dist/server.js.map +1 -0
  473. package/dist/telemetry.d.ts +172 -0
  474. package/dist/telemetry.d.ts.map +1 -0
  475. package/dist/telemetry.js +233 -0
  476. package/dist/telemetry.js.map +1 -0
  477. package/dist/tools/analytics-filters.d.ts +18 -0
  478. package/dist/tools/analytics-filters.d.ts.map +1 -0
  479. package/dist/tools/analytics-filters.js +35 -0
  480. package/dist/tools/analytics-filters.js.map +1 -0
  481. package/dist/tools/analytics.d.ts +16 -0
  482. package/dist/tools/analytics.d.ts.map +1 -0
  483. package/dist/tools/analytics.js +381 -0
  484. package/dist/tools/analytics.js.map +1 -0
  485. package/dist/tools/concept-profile.d.ts +14 -0
  486. package/dist/tools/concept-profile.d.ts.map +1 -0
  487. package/dist/tools/concept-profile.js +130 -0
  488. package/dist/tools/concept-profile.js.map +1 -0
  489. package/dist/tools/dataset-profile.d.ts +15 -0
  490. package/dist/tools/dataset-profile.d.ts.map +1 -0
  491. package/dist/tools/dataset-profile.js +194 -0
  492. package/dist/tools/dataset-profile.js.map +1 -0
  493. package/dist/tools/functions.d.ts +14 -0
  494. package/dist/tools/functions.d.ts.map +1 -0
  495. package/dist/tools/functions.js +294 -0
  496. package/dist/tools/functions.js.map +1 -0
  497. package/dist/tools/impact-chain.d.ts +15 -0
  498. package/dist/tools/impact-chain.d.ts.map +1 -0
  499. package/dist/tools/impact-chain.js +96 -0
  500. package/dist/tools/impact-chain.js.map +1 -0
  501. package/dist/tools/kwq.d.ts +19 -0
  502. package/dist/tools/kwq.d.ts.map +1 -0
  503. package/dist/tools/kwq.js +156 -0
  504. package/dist/tools/kwq.js.map +1 -0
  505. package/dist/tools/lookup.d.ts +14 -0
  506. package/dist/tools/lookup.d.ts.map +1 -0
  507. package/dist/tools/lookup.js +213 -0
  508. package/dist/tools/lookup.js.map +1 -0
  509. package/dist/tools/policy-profile.d.ts +15 -0
  510. package/dist/tools/policy-profile.d.ts.map +1 -0
  511. package/dist/tools/policy-profile.js +174 -0
  512. package/dist/tools/policy-profile.js.map +1 -0
  513. package/dist/tools/profile.d.ts +14 -0
  514. package/dist/tools/profile.d.ts.map +1 -0
  515. package/dist/tools/profile.js +349 -0
  516. package/dist/tools/profile.js.map +1 -0
  517. package/dist/tools/query.d.ts +16 -0
  518. package/dist/tools/query.d.ts.map +1 -0
  519. package/dist/tools/query.js +53 -0
  520. package/dist/tools/query.js.map +1 -0
  521. package/dist/tools/schema.d.ts +23 -0
  522. package/dist/tools/schema.d.ts.map +1 -0
  523. package/dist/tools/schema.js +124 -0
  524. package/dist/tools/schema.js.map +1 -0
  525. package/dist/tools/search-entity-metadata.d.ts +18 -0
  526. package/dist/tools/search-entity-metadata.d.ts.map +1 -0
  527. package/dist/tools/search-entity-metadata.js +221 -0
  528. package/dist/tools/search-entity-metadata.js.map +1 -0
  529. package/dist/tools/search.d.ts +23 -0
  530. package/dist/tools/search.d.ts.map +1 -0
  531. package/dist/tools/search.js +110 -0
  532. package/dist/tools/search.js.map +1 -0
  533. package/dist/tools/solr-fields.d.ts +39 -0
  534. package/dist/tools/solr-fields.d.ts.map +1 -0
  535. package/dist/tools/solr-fields.js +40 -0
  536. package/dist/tools/solr-fields.js.map +1 -0
  537. package/dist/utils.d.ts +70 -0
  538. package/dist/utils.d.ts.map +1 -0
  539. package/dist/utils.js +104 -0
  540. package/dist/utils.js.map +1 -0
  541. package/package.json +41 -0
  542. package/src/client/auth/config-loaders.ts +81 -0
  543. package/src/client/auth/decorators/index.ts +7 -0
  544. package/src/client/auth/decorators/with-caching.ts +237 -0
  545. package/src/client/auth/factory.ts +34 -0
  546. package/src/client/auth/index.ts +6 -0
  547. package/src/client/auth/jwt-utils.ts +36 -0
  548. package/src/client/auth/node.ts +16 -0
  549. package/src/client/auth/providers/index.ts +1 -0
  550. package/src/client/auth/providers/jwt-auth-provider.ts +153 -0
  551. package/src/client/auth/schemas.ts +25 -0
  552. package/src/client/auth/types.ts +30 -0
  553. package/src/client/command.ts +54 -0
  554. package/src/client/config/index.ts +15 -0
  555. package/src/client/config/loader.ts +155 -0
  556. package/src/client/config/node.ts +22 -0
  557. package/src/client/config/schemas.ts +28 -0
  558. package/src/client/config/types.ts +39 -0
  559. package/src/client/config/unified-loader.ts +118 -0
  560. package/src/client/config.ts +69 -0
  561. package/src/client/deployment-config.ts +98 -0
  562. package/src/client/errors.ts +295 -0
  563. package/src/client/http-client.ts +577 -0
  564. package/src/client/index.ts +68 -0
  565. package/src/client/internal-dsl-client.ts +128 -0
  566. package/src/client/rate-limiter.ts +139 -0
  567. package/src/client/resolve-api-key-user.ts +99 -0
  568. package/src/client/types.ts +44 -0
  569. package/src/dsl/client.ts +538 -0
  570. package/src/dsl/commands/apply-filters.ts +35 -0
  571. package/src/dsl/commands/facet/index.ts +12 -0
  572. package/src/dsl/commands/facet/schemas.ts +101 -0
  573. package/src/dsl/commands/functions/ClassifyCommand.ts +129 -0
  574. package/src/dsl/commands/functions/ExtractAffiliationsCommand.ts +163 -0
  575. package/src/dsl/commands/functions/ExtractConceptsCommand.ts +141 -0
  576. package/src/dsl/commands/functions/ExtractGrantsCommand.ts +112 -0
  577. package/src/dsl/commands/functions/index.ts +31 -0
  578. package/src/dsl/commands/index.ts +29 -0
  579. package/src/dsl/commands/validate-input.ts +29 -0
  580. package/src/dsl/create-client.ts +80 -0
  581. package/src/dsl/fluent-query-builder.ts +684 -0
  582. package/src/dsl/index.ts +206 -0
  583. package/src/dsl/pagination.ts +202 -0
  584. package/src/dsl/query-builder.ts +1120 -0
  585. package/src/dsl/response-parser.ts +299 -0
  586. package/src/dsl/schema/cache.ts +124 -0
  587. package/src/dsl/schema/extract.ts +44 -0
  588. package/src/dsl/schema/index.ts +50 -0
  589. package/src/dsl/schema/load.ts +160 -0
  590. package/src/dsl/schema/store.ts +253 -0
  591. package/src/dsl/schema/structured-entities.ts +44 -0
  592. package/src/dsl/schema/summary.ts +94 -0
  593. package/src/dsl/schema/types.ts +40 -0
  594. package/src/dsl/schema/validation.ts +56 -0
  595. package/src/dsl/types/buckets.ts +22 -0
  596. package/src/dsl/types/common.ts +99 -0
  597. package/src/dsl/types/entities.ts +43 -0
  598. package/src/dsl/types/index.ts +63 -0
  599. package/src/dsl/types/return-clauses.ts +147 -0
  600. package/src/dsl/types/special-functions.ts +220 -0
  601. package/src/dsl/types/vocabulary.ts +82 -0
  602. package/src/dsl/usage-policy.ts +219 -0
  603. package/src/dsl/utils/escape.ts +123 -0
  604. package/src/dsl/utils/sanitize.ts +21 -0
  605. package/src/dsl/utils/string-utils.ts +147 -0
  606. package/src/dsl/utils/validate-field-name.ts +19 -0
  607. package/src/http-main.ts +41 -0
  608. package/src/index.ts +14 -0
  609. package/src/main.ts +40 -0
  610. package/src/mcp/batch-fetch.ts +255 -0
  611. package/src/mcp/examples/dsl-examples.ts +66 -0
  612. package/src/mcp/examples/usage-scenarios.ts +185 -0
  613. package/src/mcp/export-format.ts +113 -0
  614. package/src/mcp/funder-org-names.ts +30 -0
  615. package/src/mcp/http-server.ts +148 -0
  616. package/src/mcp/middleware/field-aliases.ts +274 -0
  617. package/src/mcp/resources/schema.ts +364 -0
  618. package/src/mcp/schema/context.ts +11 -0
  619. package/src/mcp/schema/index.ts +38 -0
  620. package/src/mcp/server.ts +247 -0
  621. package/src/mcp/shared-schema.ts +34 -0
  622. package/src/mcp/tools/analytics-filters.ts +46 -0
  623. package/src/mcp/tools/analytics.ts +453 -0
  624. package/src/mcp/tools/fetch-search-pages.ts +329 -0
  625. package/src/mcp/tools/functions.ts +105 -0
  626. package/src/mcp/tools/lookup.ts +182 -0
  627. package/src/mcp/tools/query.ts +91 -0
  628. package/src/mcp/tools/schema.ts +147 -0
  629. package/src/mcp/tools/search-entity-metadata.ts +253 -0
  630. package/src/mcp/tools/search-input.ts +87 -0
  631. package/src/mcp/tools/search.ts +168 -0
  632. package/src/mcp/utils.ts +199 -0
  633. package/test/client/auth/config-loaders.test.ts +92 -0
  634. package/test/client/auth/decorators/with-caching.test.ts +482 -0
  635. package/test/client/auth/factory.test.ts +68 -0
  636. package/test/client/auth/providers/jwt-auth-provider.test.ts +398 -0
  637. package/test/client/auth/types.test.ts +18 -0
  638. package/test/client/command.test.ts +163 -0
  639. package/test/client/config/loader.test.ts +377 -0
  640. package/test/client/config/unified-loader.test.ts +136 -0
  641. package/test/client/deployment-config.test.ts +69 -0
  642. package/test/client/errors/index.test.ts +408 -0
  643. package/test/client/helpers/mock-fetch.ts +42 -0
  644. package/test/client/http-client.test.ts +1148 -0
  645. package/test/client/integration/auth-providers.integration.test.ts +186 -0
  646. package/test/client/internal-dsl-client.test.ts +76 -0
  647. package/test/client/rate-limiter.test.ts +204 -0
  648. package/test/client/resolve-api-key-user.test.ts +87 -0
  649. package/test/dsl/client.special-functions.test.ts +387 -0
  650. package/test/dsl/client.test.ts +457 -0
  651. package/test/dsl/commands/apply-filters.test.ts +147 -0
  652. package/test/dsl/commands/functions/ClassifyCommand.test.ts +170 -0
  653. package/test/dsl/commands/functions/ExtractAffiliationsCommand.test.ts +306 -0
  654. package/test/dsl/commands/functions/ExtractConceptsCommand.test.ts +136 -0
  655. package/test/dsl/commands/functions/ExtractGrantsCommand.test.ts +202 -0
  656. package/test/dsl/commands/search/filters.test.ts +42 -0
  657. package/test/dsl/fluent-query-builder.test.ts +865 -0
  658. package/test/dsl/integration/client.integration.test.ts +294 -0
  659. package/test/dsl/integration/facet-api.integration.test.ts +276 -0
  660. package/test/dsl/integration/field-existence.integration.test.ts +148 -0
  661. package/test/dsl/integration/fluent-api-docs-examples.integration.test.ts +988 -0
  662. package/test/dsl/integration/fluent-api.integration.test.ts +615 -0
  663. package/test/dsl/integration/search-helpers.ts +27 -0
  664. package/test/dsl/integration/special-functions.integration.test.ts +224 -0
  665. package/test/dsl/integration/test-config.ts +52 -0
  666. package/test/dsl/pagination.test.ts +86 -0
  667. package/test/dsl/query-builder.test.ts +1775 -0
  668. package/test/dsl/response-parser.test.ts +520 -0
  669. package/test/dsl/schema/cache.test.ts +53 -0
  670. package/test/dsl/schema/load.test.ts +165 -0
  671. package/test/dsl/schema/summary.test.ts +61 -0
  672. package/test/dsl/schema/validation.test.ts +46 -0
  673. package/test/dsl/time-series.test.ts +135 -0
  674. package/test/dsl/unnest.test.ts +151 -0
  675. package/test/dsl/usage-policy.test.ts +100 -0
  676. package/test/dsl/utils/escape.property.test.ts +109 -0
  677. package/test/dsl/utils/escape.test.ts +140 -0
  678. package/test/dsl/utils/validate-field-name.property.test.ts +99 -0
  679. package/test/dsl/utils/validate-field-name.test.ts +55 -0
  680. package/test/examples/dsl-examples.test.ts +29 -0
  681. package/test/examples/usage-scenarios.test.ts +90 -0
  682. package/test/fixtures/describe-schema.json +4000 -0
  683. package/test/funder-org-names.test.ts +20 -0
  684. package/test/helpers/schema-fixture.ts +18 -0
  685. package/test/helpers/tool-test-harness.ts +114 -0
  686. package/test/integration/assertions.ts +263 -0
  687. package/test/integration/env.ts +108 -0
  688. package/test/integration/harness.ts +307 -0
  689. package/test/integration/hosted-client.ts +56 -0
  690. package/test/integration/hosted-mocks.ts +81 -0
  691. package/test/integration/hosted-run.ts +86 -0
  692. package/test/integration/hosted.e2e.test.ts +101 -0
  693. package/test/integration/reporter.ts +100 -0
  694. package/test/integration/run.ts +74 -0
  695. package/test/integration/suites/analytics.integration.ts +72 -0
  696. package/test/integration/suites/functions.integration.ts +37 -0
  697. package/test/integration/suites/hosted-smoke.integration.ts +38 -0
  698. package/test/integration/suites/index.ts +22 -0
  699. package/test/integration/suites/lookup.integration.ts +57 -0
  700. package/test/integration/suites/query.integration.ts +49 -0
  701. package/test/integration/suites/resources.integration.ts +68 -0
  702. package/test/integration/suites/search.integration.ts +80 -0
  703. package/test/integration/types.ts +92 -0
  704. package/test/integration/verify-usage-scenarios.ts +162 -0
  705. package/test/mcp/export-format.test.ts +67 -0
  706. package/test/mcp/http-server.test.ts +80 -0
  707. package/test/middleware/field-aliases.test.ts +287 -0
  708. package/test/resources/schema.test.ts +28 -0
  709. package/test/schema/describe-contract.test.ts +24 -0
  710. package/test/schema/store.test.ts +45 -0
  711. package/test/server.test.ts +170 -0
  712. package/test/tools/analytics-filters.test.ts +35 -0
  713. package/test/tools/analytics.test.ts +419 -0
  714. package/test/tools/fetch-search-pages.test.ts +200 -0
  715. package/test/tools/functions.test.ts +153 -0
  716. package/test/tools/lookup.test.ts +296 -0
  717. package/test/tools/query.test.ts +100 -0
  718. package/test/tools/schema.test.ts +37 -0
  719. package/test/tools/search.test.ts +415 -0
  720. package/test/utils.test.ts +45 -0
  721. package/tsconfig.json +9 -0
  722. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Response parser for Dimensions API facet results.
3
+ * Transforms raw API responses into typed facet result structures.
4
+ * @module response-parser
5
+ */
6
+
7
+ import { z } from "zod";
8
+ import { ValidationError } from "../client/index.js";
9
+ import type { BaseBucket } from "./types/buckets.js";
10
+
11
+ /**
12
+ * Schema for validating bucket objects in facet results.
13
+ * Buckets must have an id (string or number) and a non-negative count.
14
+ */
15
+ const BaseBucketSchema = z
16
+ .object({
17
+ id: z.union([z.string(), z.number()]),
18
+ count: z.number().int().nonnegative(),
19
+ })
20
+ .passthrough();
21
+
22
+ /**
23
+ * Schema for validating _stats object in API responses.
24
+ */
25
+ const StatsSchema = z
26
+ .object({
27
+ total_count: z.number().int().nonnegative(),
28
+ })
29
+ .passthrough();
30
+
31
+ /**
32
+ * Configuration for a facet field, including optional aggregation indicators.
33
+ */
34
+ export interface FacetFieldConfig {
35
+ /** Optional array of aggregation indicator names to validate */
36
+ readonly indicators?: readonly string[];
37
+ }
38
+
39
+ /**
40
+ * Parses entity data from a Dimensions API response.
41
+ * Validates that the entity array is properly structured.
42
+ * Falls back to data.length if _stats.total_count is not available.
43
+ *
44
+ * @template T - The entity type
45
+ * @param response - Raw API response object
46
+ * @param entityKey - The entity type key (e.g., "publications")
47
+ * @returns Entity result with data array and totalCount
48
+ * @throws {ValidationError} If entity data is not an array
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const result = parseEntityResponse<Publication>(response, "publications");
53
+ * console.log(result.data.length, result.totalCount);
54
+ * ```
55
+ */
56
+ export function parseEntityResponse<T>(
57
+ response: Record<string, unknown>,
58
+ entityKey: string,
59
+ ): EntityResult<T> {
60
+ const entityData = response[entityKey];
61
+
62
+ // If entity key is missing, return empty result
63
+ if (entityData === undefined) {
64
+ return { data: [], totalCount: 0 };
65
+ }
66
+
67
+ // Validate entity data is an array
68
+ if (!Array.isArray(entityData)) {
69
+ throw new ValidationError(`Entity key "${entityKey}" must be an array`, {
70
+ entityKey,
71
+ actualType: typeof entityData,
72
+ });
73
+ }
74
+
75
+ const entityArray = entityData as T[];
76
+
77
+ // Try to get total_count from stats, fallback to data length
78
+ const statsResult = StatsSchema.safeParse(response._stats);
79
+ const totalCount = statsResult.success ? statsResult.data.total_count : entityArray.length;
80
+
81
+ return {
82
+ data: entityArray,
83
+ totalCount,
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Cache for bucket schemas keyed by sorted indicator combination.
89
+ * Avoids rebuilding the same ZodObject on every transformResponse call.
90
+ */
91
+ const bucketSchemaCache = new Map<string, z.ZodObject<z.ZodRawShape>>();
92
+
93
+ /**
94
+ * Creates a bucket schema that validates both base fields and aggregation indicators.
95
+ * Caches schemas by indicator combination to avoid repeated allocations.
96
+ * @param indicators - Array of indicator names that must be present as numbers
97
+ * @returns Zod schema for bucket validation
98
+ */
99
+ function createBucketSchema(indicators?: readonly string[]) {
100
+ if (!indicators || indicators.length === 0) {
101
+ return BaseBucketSchema;
102
+ }
103
+
104
+ const cacheKey = [...indicators].sort().join(",");
105
+ const cached = bucketSchemaCache.get(cacheKey);
106
+ if (cached) {
107
+ return cached;
108
+ }
109
+
110
+ // Build a schema that requires each indicator to be a number
111
+ const indicatorSchema: Record<string, z.ZodNumber> = {};
112
+ for (const indicator of indicators) {
113
+ indicatorSchema[indicator] = z.number();
114
+ }
115
+
116
+ const schema = BaseBucketSchema.extend(indicatorSchema);
117
+ bucketSchemaCache.set(cacheKey, schema);
118
+ return schema;
119
+ }
120
+
121
+ /**
122
+ * Typed facet result with bucket array.
123
+ * @template TBucket - The bucket type for this facet
124
+ */
125
+ export interface TypedFacetResult<TBucket extends BaseBucket = BaseBucket> {
126
+ readonly field: string;
127
+ readonly buckets: readonly TBucket[];
128
+ }
129
+
130
+ /**
131
+ * Entity data result with array and total count.
132
+ * @template T - The entity type
133
+ */
134
+ export interface EntityResult<T> {
135
+ readonly data: readonly T[];
136
+ readonly totalCount: number;
137
+ }
138
+
139
+ /**
140
+ * Combined result for queries with facets and/or entities.
141
+ * @template T - The entity type
142
+ * @template TFacets - Record of facet field names to their typed results
143
+ */
144
+ export interface FacetQueryResult<
145
+ T,
146
+ TFacets extends Record<string, TypedFacetResult> = Record<string, TypedFacetResult>,
147
+ > {
148
+ readonly entities?: EntityResult<T>;
149
+ readonly facets: TFacets;
150
+ /** Raw API response. Optional to avoid doubling memory for large responses. */
151
+ readonly _raw?: Record<string, unknown>;
152
+ }
153
+
154
+ /**
155
+ * Options for parsing facet responses.
156
+ */
157
+ export interface ParseFacetOptions {
158
+ /**
159
+ * Whether to include the raw API response in the result.
160
+ * Set to false to avoid doubling memory usage for large responses.
161
+ * @default true
162
+ */
163
+ readonly includeRaw?: boolean;
164
+ }
165
+
166
+ /**
167
+ * Parses a Dimensions API response into typed facet results.
168
+ * Extracts entity data and facet buckets from the response.
169
+ *
170
+ * @template T - The entity type
171
+ * @template TFacets - Record of facet field names to their typed results
172
+ * @param response - Raw API response object
173
+ * @param entityKey - The entity type key (e.g., "publications")
174
+ * @param facetFields - Array of facet field names or record of field configs
175
+ * @param options - Optional parsing configuration
176
+ * @returns Typed result with entities and facets
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Simple facets (field names only)
181
+ * const result = parseFacetResponse<Publication>(
182
+ * response,
183
+ * "publications",
184
+ * ["year", "type"]
185
+ * );
186
+ *
187
+ * // Aggregated facets (with indicator validation)
188
+ * const result = parseFacetResponse<Publication>(
189
+ * response,
190
+ * "publications",
191
+ * {
192
+ * year: {},
193
+ * funders: { indicators: ["rcr_avg", "citations_avg"] }
194
+ * }
195
+ * );
196
+ *
197
+ * // Exclude raw response to save memory
198
+ * const result = parseFacetResponse<Publication>(
199
+ * response,
200
+ * "publications",
201
+ * ["year"],
202
+ * { includeRaw: false }
203
+ * );
204
+ * ```
205
+ */
206
+ export function parseFacetResponse<
207
+ T,
208
+ TFacets extends Record<string, TypedFacetResult> = Record<string, TypedFacetResult>,
209
+ >(
210
+ response: Record<string, unknown>,
211
+ entityKey: string,
212
+ facetFields: readonly string[] | Record<string, FacetFieldConfig>,
213
+ options: ParseFacetOptions = {},
214
+ ): FacetQueryResult<T, TFacets> {
215
+ const { includeRaw = true } = options;
216
+ const facets: Record<string, TypedFacetResult> = {};
217
+
218
+ // Normalize facetFields to a record
219
+ const facetConfigs: Record<string, FacetFieldConfig> = Array.isArray(facetFields)
220
+ ? Object.fromEntries(facetFields.map((f) => [f, {}]))
221
+ : facetFields;
222
+
223
+ // Parse and validate entity data if present
224
+ let entities: EntityResult<T> | undefined;
225
+ if (response[entityKey] !== undefined) {
226
+ if (!Array.isArray(response[entityKey])) {
227
+ throw new ValidationError(`Entity key "${entityKey}" must be an array`, {
228
+ entityKey,
229
+ actualType: typeof response[entityKey],
230
+ });
231
+ }
232
+
233
+ const entityArray = response[entityKey] as T[];
234
+ if (entityArray.length > 0) {
235
+ const statsResult = StatsSchema.safeParse(response._stats);
236
+ if (!statsResult.success) {
237
+ throw new ValidationError("API response missing _stats.total_count for entity results", {
238
+ entityKey,
239
+ statsErrors: statsResult.error.issues,
240
+ });
241
+ }
242
+ entities = {
243
+ data: entityArray,
244
+ totalCount: statsResult.data.total_count,
245
+ };
246
+ } else {
247
+ // Empty array - use 0 as totalCount
248
+ entities = {
249
+ data: entityArray,
250
+ totalCount: 0,
251
+ };
252
+ }
253
+ }
254
+
255
+ // Parse and validate facet data
256
+ for (const [field, config] of Object.entries(facetConfigs)) {
257
+ const fieldData = response[field];
258
+
259
+ if (fieldData === undefined) {
260
+ throw new ValidationError(`Missing facet field "${field}" in API response`, {
261
+ requestedFields: Object.keys(facetConfigs),
262
+ });
263
+ }
264
+
265
+ if (!Array.isArray(fieldData)) {
266
+ throw new ValidationError(`Facet field "${field}" must be an array`, {
267
+ field,
268
+ actualType: typeof fieldData,
269
+ });
270
+ }
271
+
272
+ // Validate bucket structure (including indicators if specified)
273
+ const bucketSchema = createBucketSchema(config.indicators);
274
+ const parseResult = z.array(bucketSchema).safeParse(fieldData);
275
+ if (!parseResult.success) {
276
+ throw new ValidationError(`Invalid bucket data for facet "${field}"`, {
277
+ field,
278
+ indicators: config.indicators,
279
+ errors: parseResult.error.issues,
280
+ });
281
+ }
282
+
283
+ facets[field] = {
284
+ field,
285
+ buckets: parseResult.data as BaseBucket[],
286
+ };
287
+ }
288
+
289
+ const result: FacetQueryResult<T, TFacets> = {
290
+ entities,
291
+ facets: facets as TFacets,
292
+ };
293
+
294
+ if (includeRaw) {
295
+ return { ...result, _raw: response };
296
+ }
297
+
298
+ return result;
299
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Disk cache helpers for describe schema responses.
3
+ * @module schema/cache
4
+ */
5
+
6
+ import { readFile, writeFile } from "node:fs/promises";
7
+ import { extractDescribeSchema } from "./extract.js";
8
+ import type { DescribeSchemaResponse } from "./types.js";
9
+
10
+ /** Default cache TTL: 24 hours. */
11
+ export const DEFAULT_SCHEMA_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
12
+
13
+ /** On-disk cache envelope with metadata. */
14
+ export type SchemaCacheEnvelope = {
15
+ readonly cachedAt: string;
16
+ readonly version?: string;
17
+ readonly schema: DescribeSchemaResponse;
18
+ };
19
+
20
+ /** Parsed cache entry with normalized timestamps. */
21
+ export type SchemaCacheEntry = {
22
+ readonly response: DescribeSchemaResponse;
23
+ readonly cachedAt: Date | undefined;
24
+ readonly version: string | undefined;
25
+ };
26
+
27
+ /**
28
+ * Returns whether a cache entry is within the configured TTL.
29
+ * @param cachedAt - When the cache was written
30
+ * @param ttlMs - Maximum cache age in milliseconds
31
+ * @returns True when the entry is still fresh
32
+ */
33
+ export function isCacheFresh(cachedAt: Date | undefined, ttlMs: number): boolean {
34
+ if (cachedAt == null || !Number.isFinite(ttlMs) || ttlMs <= 0) {
35
+ return false;
36
+ }
37
+ return Date.now() - cachedAt.getTime() < ttlMs;
38
+ }
39
+
40
+ /**
41
+ * Reads a schema cache file (envelope or legacy bare describe payload).
42
+ * @param cachePath - Path to JSON cache file
43
+ * @returns Parsed cache entry or undefined when missing/invalid
44
+ */
45
+ export async function readSchemaCacheFile(
46
+ cachePath: string,
47
+ ): Promise<SchemaCacheEntry | undefined> {
48
+ try {
49
+ const text = await readFile(cachePath, "utf8");
50
+ const parsed = JSON.parse(text) as unknown;
51
+ return parseCachePayload(parsed);
52
+ } catch {
53
+ return undefined;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Parses cache JSON as an envelope or legacy describe response.
59
+ * @param parsed - Parsed JSON value
60
+ * @returns Normalized cache entry
61
+ */
62
+ export function parseCachePayload(parsed: unknown): SchemaCacheEntry | undefined {
63
+ if (typeof parsed !== "object" || parsed == null) {
64
+ return undefined;
65
+ }
66
+
67
+ const record = parsed as Record<string, unknown>;
68
+
69
+ if ("schema" in record) {
70
+ try {
71
+ const response = extractDescribeSchema(record.schema);
72
+ const cachedAt = typeof record.cachedAt === "string" ? new Date(record.cachedAt) : undefined;
73
+ const version = typeof record.version === "string" ? record.version : undefined;
74
+ return { response, cachedAt, version };
75
+ } catch {
76
+ return undefined;
77
+ }
78
+ }
79
+
80
+ try {
81
+ const response = extractDescribeSchema(parsed);
82
+ return { response, cachedAt: undefined, version: undefined };
83
+ } catch {
84
+ return undefined;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Writes describe schema to a cache file with metadata envelope.
90
+ * @param cachePath - Path to JSON cache file
91
+ * @param response - Schema response to persist
92
+ * @param version - Optional DSL version
93
+ */
94
+ export async function writeSchemaCacheFile(
95
+ cachePath: string,
96
+ response: DescribeSchemaResponse,
97
+ version?: string,
98
+ ): Promise<void> {
99
+ const envelope: SchemaCacheEnvelope = {
100
+ cachedAt: new Date().toISOString(),
101
+ ...(version != null ? { version } : {}),
102
+ schema: response,
103
+ };
104
+ await writeFile(cachePath, JSON.stringify(envelope), "utf8");
105
+ }
106
+
107
+ /**
108
+ * Resolves cache TTL from options or environment.
109
+ * @param overrideMs - Explicit TTL from caller
110
+ * @returns TTL in milliseconds
111
+ */
112
+ export function resolveCacheTtlMs(overrideMs?: number): number {
113
+ if (overrideMs != null && Number.isFinite(overrideMs) && overrideMs > 0) {
114
+ return overrideMs;
115
+ }
116
+ const raw = process.env.SCHEMA_CACHE_TTL_MS;
117
+ if (raw != null && raw.trim() !== "") {
118
+ const value = Number.parseInt(raw, 10);
119
+ if (Number.isFinite(value) && value > 0) {
120
+ return value;
121
+ }
122
+ }
123
+ return DEFAULT_SCHEMA_CACHE_TTL_MS;
124
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Normalizes raw `describe` API responses.
3
+ * @module schema/extract
4
+ */
5
+
6
+ import type { DescribeSchemaResponse, DescribeVersionResponse } from "./types.js";
7
+
8
+ /**
9
+ * Extracts describe schema payload from a raw API response.
10
+ * @param raw - Raw DSL API response
11
+ * @returns Normalized describe schema object
12
+ */
13
+ export function extractDescribeSchema(raw: unknown): DescribeSchemaResponse {
14
+ if (typeof raw !== "object" || raw === null) {
15
+ throw new Error("Invalid describe schema response: expected object");
16
+ }
17
+ const record = raw as Record<string, unknown>;
18
+ if ("sources" in record || "entities" in record) {
19
+ return {
20
+ sources: (record.sources as DescribeSchemaResponse["sources"]) ?? {},
21
+ entities: (record.entities as DescribeSchemaResponse["entities"]) ?? {},
22
+ };
23
+ }
24
+ throw new Error("Invalid describe schema response: missing sources/entities");
25
+ }
26
+
27
+ /**
28
+ * Extracts version string from `describe version` response.
29
+ * @param raw - Raw DSL API response
30
+ * @returns Version string or undefined
31
+ */
32
+ export function extractDescribeVersion(raw: unknown): string | undefined {
33
+ if (typeof raw !== "object" || raw === null) {
34
+ return undefined;
35
+ }
36
+ const record = raw as DescribeVersionResponse & Record<string, unknown>;
37
+ if (typeof record.version === "string") {
38
+ return record.version;
39
+ }
40
+ if (typeof record.release === "string") {
41
+ return record.release;
42
+ }
43
+ return undefined;
44
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Runtime schema from `describe schema` / `describe version`.
3
+ * @module schema
4
+ */
5
+
6
+ export {
7
+ DEFAULT_SCHEMA_CACHE_TTL_MS,
8
+ isCacheFresh,
9
+ parseCachePayload,
10
+ type SchemaCacheEntry,
11
+ type SchemaCacheEnvelope,
12
+ } from "./cache.js";
13
+ export { extractDescribeSchema, extractDescribeVersion } from "./extract.js";
14
+ export {
15
+ clearSchemaCache,
16
+ getCachedSchemaStore,
17
+ getOrLoadSchema,
18
+ type LoadSchemaOptions,
19
+ loadSchema,
20
+ } from "./load.js";
21
+ export {
22
+ createSchemaStoreFromResponse,
23
+ SCHEMA_LIMITS,
24
+ type SchemaLoadSource,
25
+ SchemaStore,
26
+ type SchemaStoreMetadata,
27
+ } from "./store.js";
28
+ export {
29
+ STRUCTURED_ENTITY_TYPES,
30
+ type StructuredEntityType,
31
+ searchResultKey,
32
+ searchToolName,
33
+ } from "./structured-entities.js";
34
+ export {
35
+ buildSchemaSummary,
36
+ SCHEMA_RESOURCE_URIS,
37
+ type SchemaSourceSummary,
38
+ type SchemaSummary,
39
+ } from "./summary.js";
40
+ export type {
41
+ DescribeField,
42
+ DescribeSchemaResponse,
43
+ DescribeVersionResponse,
44
+ EntityDescribe,
45
+ SourceDescribe,
46
+ } from "./types.js";
47
+ export {
48
+ assertValidEntity,
49
+ assertValidSearchIndex,
50
+ } from "./validation.js";
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Load schema from the Dimensions API or optional disk cache.
3
+ * @module schema/load
4
+ */
5
+
6
+ import type { DimensionsClient } from "../client.js";
7
+ import {
8
+ isCacheFresh,
9
+ readSchemaCacheFile,
10
+ resolveCacheTtlMs,
11
+ writeSchemaCacheFile,
12
+ } from "./cache.js";
13
+ import { extractDescribeSchema, extractDescribeVersion } from "./extract.js";
14
+ import { createSchemaStoreFromResponse, type SchemaStore } from "./store.js";
15
+
16
+ let moduleCache: SchemaStore | undefined;
17
+ let moduleLoadPromise: Promise<SchemaStore> | undefined;
18
+
19
+ /**
20
+ * Returns the module-level cached schema store, if loaded.
21
+ * @returns Cached store or undefined before first load
22
+ */
23
+ export function getCachedSchemaStore(): SchemaStore | undefined {
24
+ return moduleCache;
25
+ }
26
+
27
+ /**
28
+ * Clears the module-level schema cache (for tests and refresh).
29
+ */
30
+ export function clearSchemaCache(): void {
31
+ moduleCache = undefined;
32
+ moduleLoadPromise = undefined;
33
+ }
34
+
35
+ export type LoadSchemaOptions = {
36
+ /** Optional cache file path (defaults to `SCHEMA_CACHE_PATH` env) */
37
+ cachePath?: string;
38
+ /** Cache TTL in milliseconds (defaults to `SCHEMA_CACHE_TTL_MS` env or 24h) */
39
+ cacheTtlMs?: number;
40
+ /** Skip fresh cache and fetch from the API (stale fallback still applies on failure) */
41
+ forceRefresh?: boolean;
42
+ /** Log load stats to stderr (default true) */
43
+ log?: boolean;
44
+ };
45
+
46
+ /**
47
+ * Fetches schema from the Dimensions API, with TTL-aware cache and stale fallback.
48
+ * @param client - Authenticated Dimensions client
49
+ * @param options - Cache path, TTL, and logging options
50
+ * @returns Loaded schema store
51
+ */
52
+ export async function loadSchema(
53
+ client: DimensionsClient,
54
+ options?: LoadSchemaOptions | string,
55
+ ): Promise<SchemaStore> {
56
+ const resolved =
57
+ typeof options === "string" ? { cachePath: options, log: true as const } : (options ?? {});
58
+ const cachePath = resolved.cachePath ?? process.env.SCHEMA_CACHE_PATH;
59
+ const log = resolved.log ?? true;
60
+ const cacheTtlMs = resolveCacheTtlMs(resolved.cacheTtlMs);
61
+ const forceRefresh = resolved.forceRefresh ?? false;
62
+
63
+ const cached = cachePath ? await readSchemaCacheFile(cachePath) : undefined;
64
+ const cacheFresh = cached != null && isCacheFresh(cached.cachedAt, cacheTtlMs);
65
+
66
+ if (!forceRefresh && cacheFresh && cached) {
67
+ const store = createSchemaStoreFromResponse(cached.response, cached.version, new Date(), {
68
+ loadSource: "cache",
69
+ stale: false,
70
+ cachedAt: cached.cachedAt,
71
+ });
72
+ moduleCache = store;
73
+ if (log) {
74
+ logSchemaLoaded(store, "cache (fresh)");
75
+ }
76
+ return store;
77
+ }
78
+
79
+ try {
80
+ const started = performance.now();
81
+ const [schemaRaw, versionRaw] = await Promise.all([
82
+ client.rawQuery("describe schema"),
83
+ client.rawQuery("describe version").catch(() => undefined),
84
+ ]);
85
+
86
+ const response = extractDescribeSchema(schemaRaw);
87
+ const version = versionRaw ? extractDescribeVersion(versionRaw) : undefined;
88
+
89
+ if (cachePath) {
90
+ await writeSchemaCacheFile(cachePath, response, version);
91
+ }
92
+
93
+ const store = createSchemaStoreFromResponse(response, version, new Date(), {
94
+ loadSource: "api",
95
+ stale: false,
96
+ });
97
+ moduleCache = store;
98
+ if (log) {
99
+ const elapsed = Math.round(performance.now() - started);
100
+ logSchemaLoaded(store, `api (${elapsed}ms)`);
101
+ }
102
+ return store;
103
+ } catch (error) {
104
+ if (cached) {
105
+ const store = createSchemaStoreFromResponse(cached.response, cached.version, new Date(), {
106
+ loadSource: "cache",
107
+ stale: true,
108
+ cachedAt: cached.cachedAt,
109
+ });
110
+ moduleCache = store;
111
+ if (log) {
112
+ const age =
113
+ cached.cachedAt != null
114
+ ? `${Math.round((Date.now() - cached.cachedAt.getTime()) / 60_000)}m old`
115
+ : "legacy cache";
116
+ console.error(
117
+ `[schema] API unavailable; using stale cache (${age}). ` +
118
+ `Call refresh_schema when the API is reachable.`,
119
+ );
120
+ logSchemaLoaded(store, "cache (stale fallback)");
121
+ }
122
+ return store;
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Returns cached schema or loads once per process.
130
+ * @param client - Authenticated Dimensions client
131
+ * @param options - Cache path and logging options
132
+ * @returns Schema store
133
+ */
134
+ export async function getOrLoadSchema(
135
+ client: DimensionsClient,
136
+ options?: LoadSchemaOptions | string,
137
+ ): Promise<SchemaStore> {
138
+ if (moduleCache) {
139
+ return moduleCache;
140
+ }
141
+ if (!moduleLoadPromise) {
142
+ moduleLoadPromise = loadSchema(client, options).finally(() => {
143
+ moduleLoadPromise = undefined;
144
+ });
145
+ }
146
+ return moduleLoadPromise;
147
+ }
148
+
149
+ function logSchemaLoaded(store: SchemaStore, via: string): void {
150
+ const stats = store.stats();
151
+ const flags = [via, store.stale ? "stale" : undefined].filter(Boolean).join(", ");
152
+ console.error(
153
+ `[schema] loaded ${stats.sourceCount} sources, ${stats.entityCount} entities` +
154
+ (stats.dslVersion ? ` (DSL ${stats.dslVersion})` : "") +
155
+ ` [${flags}]`,
156
+ );
157
+ }
158
+
159
+ // Re-export extract helpers for backward compatibility
160
+ export { extractDescribeSchema, extractDescribeVersion } from "./extract.js";