@canonical/pragma-cli 0.27.1-experimental.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +67 -15
  2. package/dist/pragma +0 -0
  3. package/package.json +16 -17
  4. package/src/config/defaultConfig.test.ts +33 -0
  5. package/src/config/defaultConfig.ts +59 -0
  6. package/src/config/defaults.json +17 -0
  7. package/src/config/findProjectConfigPath.test.ts +53 -0
  8. package/src/config/findProjectConfigPath.ts +36 -0
  9. package/src/config/index.ts +17 -2
  10. package/src/config/mergeConfigFileUpdate.ts +58 -0
  11. package/src/config/parseConfigValues.ts +215 -0
  12. package/src/config/readConfig.test.ts +104 -13
  13. package/src/config/readConfig.ts +12 -117
  14. package/src/config/readConfigLayers.test.ts +107 -0
  15. package/src/config/readConfigLayers.ts +115 -0
  16. package/src/config/resolveGlobalConfigPath.ts +13 -0
  17. package/src/config/resolveWriteConfigPath.test.ts +53 -0
  18. package/src/config/resolveWriteConfigPath.ts +31 -0
  19. package/src/config/types.ts +88 -2
  20. package/src/config/writeConfig.ts +25 -43
  21. package/src/constants.ts +12 -1
  22. package/src/domains/block/commands/index.ts +2 -1
  23. package/src/domains/block/commands/list.ts +5 -90
  24. package/src/domains/block/commands/lookup.ts +8 -167
  25. package/src/domains/block/commands/sample.ts +55 -0
  26. package/src/domains/block/formatters/index.ts +2 -1
  27. package/src/domains/block/formatters/sample.ts +21 -0
  28. package/src/domains/block/index.ts +3 -3
  29. package/src/domains/block/mcp/specs.ts +36 -168
  30. package/src/domains/block/operations/index.ts +2 -1
  31. package/src/domains/block/operations/lookup.ts +9 -0
  32. package/src/domains/block/operations/sample.ts +41 -0
  33. package/src/domains/block/orchestration/blockEmptyError.test.ts +26 -0
  34. package/src/domains/block/orchestration/resolveBlockLookup.ts +11 -3
  35. package/src/domains/block/stories.test.ts +28 -0
  36. package/src/domains/block/stories.ts +254 -0
  37. package/src/domains/config/commands/channel.test.ts +14 -3
  38. package/src/domains/config/commands/channel.ts +11 -7
  39. package/src/domains/config/commands/configScope.ts +46 -0
  40. package/src/domains/config/commands/framework.test.ts +105 -0
  41. package/src/domains/config/commands/framework.ts +91 -0
  42. package/src/domains/config/commands/index.ts +2 -0
  43. package/src/domains/config/commands/show.ts +5 -45
  44. package/src/domains/config/commands/tier.test.ts +13 -2
  45. package/src/domains/config/commands/tier.ts +11 -7
  46. package/src/domains/config/commands/trace.test.ts +165 -0
  47. package/src/domains/config/commands/trace.ts +83 -0
  48. package/src/domains/config/formatters/channel.test.ts +20 -6
  49. package/src/domains/config/formatters/channel.ts +14 -11
  50. package/src/domains/config/formatters/framework.ts +37 -0
  51. package/src/domains/config/formatters/index.ts +2 -0
  52. package/src/domains/config/formatters/show.test.ts +27 -0
  53. package/src/domains/config/formatters/show.ts +27 -4
  54. package/src/domains/config/formatters/tier.test.ts +26 -10
  55. package/src/domains/config/formatters/tier.ts +19 -11
  56. package/src/domains/config/formatters/trace.ts +28 -0
  57. package/src/domains/config/index.ts +15 -2
  58. package/src/domains/config/mcp/specs.ts +33 -53
  59. package/src/domains/config/operations/index.ts +1 -0
  60. package/src/domains/config/operations/show.test.ts +18 -0
  61. package/src/domains/config/operations/show.ts +7 -1
  62. package/src/domains/config/operations/types.ts +7 -0
  63. package/src/domains/config/operations/validateFramework.ts +24 -0
  64. package/src/domains/config/stories.ts +42 -0
  65. package/src/domains/config/tasks/index.ts +3 -0
  66. package/src/domains/config/tasks/setChannel.ts +13 -22
  67. package/src/domains/config/tasks/setFramework.ts +21 -0
  68. package/src/domains/config/tasks/setTier.ts +10 -23
  69. package/src/domains/config/tasks/setTrace.ts +20 -0
  70. package/src/domains/config/tasks/writeConfigField.ts +41 -0
  71. package/src/domains/create/commands/component.ts +5 -5
  72. package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -5
  73. package/src/domains/doctor/operations/checks/checkKeStore.ts +5 -5
  74. package/src/domains/doctor/operations/checks/checkMcpCommands.ts +130 -0
  75. package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +1 -1
  76. package/src/domains/doctor/operations/checks/checkPackageRefs.ts +30 -48
  77. package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +1 -1
  78. package/src/domains/doctor/operations/checks/index.ts +1 -0
  79. package/src/domains/doctor/operations/checks.test.ts +162 -8
  80. package/src/domains/doctor/operations/runChecks.test.ts +85 -4
  81. package/src/domains/doctor/operations/runChecks.ts +50 -12
  82. package/src/domains/graph/helpers/resolveUri.test.ts +50 -0
  83. package/src/domains/graph/helpers/resolveUri.ts +28 -21
  84. package/src/domains/graphql/commands/build.test.ts +196 -0
  85. package/src/domains/graphql/commands/build.ts +117 -0
  86. package/src/domains/graphql/commands/check.test.ts +141 -0
  87. package/src/domains/graphql/commands/check.ts +81 -0
  88. package/src/domains/graphql/commands/index.ts +5 -0
  89. package/src/domains/graphql/commands/serve.test.ts +40 -0
  90. package/src/domains/graphql/commands/serve.ts +131 -0
  91. package/src/domains/graphql/constants.ts +10 -0
  92. package/src/domains/graphql/formatters/index.ts +3 -0
  93. package/src/domains/graphql/formatters/report.ts +78 -0
  94. package/src/domains/graphql/helpers/gatherSources.test.ts +92 -0
  95. package/src/domains/graphql/helpers/gatherSources.ts +58 -0
  96. package/src/domains/graphql/helpers/index.ts +6 -0
  97. package/src/domains/graphql/helpers/parsePrefixes.test.ts +44 -0
  98. package/src/domains/graphql/helpers/parsePrefixes.ts +38 -0
  99. package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +56 -0
  100. package/src/domains/graphql/helpers/resolveSourceFiles.ts +45 -0
  101. package/src/domains/graphql/helpers/routeGraphql.test.ts +43 -0
  102. package/src/domains/graphql/helpers/routeGraphql.ts +28 -0
  103. package/src/domains/graphql/index.ts +24 -0
  104. package/src/domains/graphql/operations/compileSchema.test.ts +95 -0
  105. package/src/domains/graphql/operations/compileSchema.ts +107 -0
  106. package/src/domains/graphql/operations/createSchemaServer.test.ts +50 -0
  107. package/src/domains/graphql/operations/createSchemaServer.ts +75 -0
  108. package/src/domains/graphql/operations/index.ts +12 -0
  109. package/src/domains/graphql/types.ts +29 -0
  110. package/src/domains/info/operations/collectInfo.test.ts +16 -5
  111. package/src/domains/info/operations/collectInfo.ts +16 -19
  112. package/src/domains/llm/capabilities.test.ts +91 -0
  113. package/src/domains/llm/commands/capabilities.ts +28 -0
  114. package/src/domains/llm/commands/index.ts +1 -0
  115. package/src/domains/llm/data/commandReference.ts +90 -18
  116. package/src/domains/llm/data/decisionTrees.ts +15 -13
  117. package/src/domains/llm/data/index.ts +2 -0
  118. package/src/domains/llm/data/toolCatalog.ts +190 -0
  119. package/src/domains/llm/formatters/capabilities.ts +50 -0
  120. package/src/domains/llm/formatters/index.ts +1 -0
  121. package/src/domains/llm/index.ts +3 -2
  122. package/src/domains/llm/mcp/index.ts +1 -1
  123. package/src/domains/llm/mcp/specs.ts +59 -52
  124. package/src/domains/llm/types.ts +40 -0
  125. package/src/domains/modifier/commands/index.ts +2 -1
  126. package/src/domains/modifier/commands/list.ts +5 -38
  127. package/src/domains/modifier/commands/lookup.ts +8 -79
  128. package/src/domains/modifier/commands/sample.ts +53 -0
  129. package/src/domains/modifier/formatters/index.ts +2 -1
  130. package/src/domains/modifier/formatters/sample.ts +15 -0
  131. package/src/domains/modifier/index.ts +7 -3
  132. package/src/domains/modifier/mcp/specs.ts +38 -70
  133. package/src/domains/modifier/operations/index.ts +2 -1
  134. package/src/domains/modifier/operations/lookup.ts +9 -0
  135. package/src/domains/modifier/operations/sample.ts +32 -0
  136. package/src/domains/modifier/orchestration/modifierEmptyError.test.ts +26 -0
  137. package/src/domains/modifier/orchestration/modifierEmptyError.ts +7 -2
  138. package/src/domains/modifier/orchestration/resolveModifierLookup.ts +15 -2
  139. package/src/domains/modifier/stories.test.ts +20 -0
  140. package/src/domains/modifier/stories.ts +77 -0
  141. package/src/domains/ontology/commands/list.ts +5 -58
  142. package/src/domains/ontology/commands/show.ts +6 -58
  143. package/src/domains/ontology/formatters/show.ts +7 -1
  144. package/src/domains/ontology/mcp/specs.ts +7 -84
  145. package/src/domains/ontology/stories.test.ts +36 -0
  146. package/src/domains/ontology/stories.ts +108 -0
  147. package/src/domains/refs/operations/index.ts +1 -1
  148. package/src/domains/refs/operations/paths.ts +29 -1
  149. package/src/domains/refs/operations/updateRefs.test.ts +6 -3
  150. package/src/domains/refs/operations/updateRefs.ts +2 -36
  151. package/src/domains/setup/commands/skills.test.ts +6 -2
  152. package/src/domains/setup/commands/skills.ts +6 -2
  153. package/src/domains/setup/helpers/runSetupTask.test.ts +148 -150
  154. package/src/domains/setup/helpers/runSetupTask.ts +62 -70
  155. package/src/domains/setup/operations/setupMcp.test.ts +6 -1
  156. package/src/domains/shared/bootStore.ts +92 -50
  157. package/src/domains/shared/compactUri.test.ts +11 -0
  158. package/src/domains/shared/compactUri.ts +10 -5
  159. package/src/domains/shared/context.ts +2 -2
  160. package/src/domains/shared/contracts.ts +12 -0
  161. package/src/domains/shared/createInteractivePromptSession.test.ts +439 -0
  162. package/src/domains/shared/createInteractivePromptSession.ts +236 -0
  163. package/src/domains/shared/emptyErrorRecovery.test.ts +109 -0
  164. package/src/domains/shared/loaders/bundledLoader.test.ts +248 -0
  165. package/src/domains/shared/loaders/bundledLoader.ts +206 -0
  166. package/src/domains/shared/loaders/gitLoader.ts +31 -0
  167. package/src/domains/shared/loaders/index.ts +9 -0
  168. package/src/domains/shared/loaders/localLoader.ts +87 -0
  169. package/src/domains/shared/loaders/readPackageDir.ts +147 -0
  170. package/src/domains/shared/loaders/storyAssetsPlugin.test.ts +84 -0
  171. package/src/domains/shared/loaders/storyAssetsPlugin.ts +46 -0
  172. package/src/domains/shared/lookupMany.test.ts +120 -0
  173. package/src/domains/shared/lookupMany.ts +43 -3
  174. package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
  175. package/src/domains/shared/mergeAndParseRefs.ts +44 -0
  176. package/src/domains/shared/packages.ts +14 -120
  177. package/src/domains/shared/pickRandom.ts +22 -0
  178. package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
  179. package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
  180. package/src/domains/shared/runtime.ts +7 -63
  181. package/src/domains/shared/sampleFormatters.ts +47 -0
  182. package/src/domains/shared/semanticPackage.ts +112 -0
  183. package/src/domains/shared/stories/compileLookupCommand.test.ts +145 -0
  184. package/src/domains/shared/stories/compileLookupCommand.ts +100 -0
  185. package/src/domains/shared/stories/compileLookupTool.test.ts +105 -0
  186. package/src/domains/shared/stories/compileLookupTool.ts +96 -0
  187. package/src/domains/shared/stories/compileReadCommand.test.ts +121 -0
  188. package/src/domains/shared/stories/compileReadCommand.ts +48 -0
  189. package/src/domains/shared/stories/compileReadTool.test.ts +64 -0
  190. package/src/domains/shared/stories/compileReadTool.ts +38 -0
  191. package/src/domains/shared/stories/condense.test.ts +18 -0
  192. package/src/domains/shared/stories/condense.ts +15 -0
  193. package/src/domains/shared/stories/index.ts +20 -0
  194. package/src/domains/shared/stories/normalizeNames.test.ts +20 -0
  195. package/src/domains/shared/stories/normalizeNames.ts +22 -0
  196. package/src/domains/shared/stories/pack/applyPackFilters.test.ts +102 -0
  197. package/src/domains/shared/stories/pack/applyPackFilters.ts +76 -0
  198. package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +51 -0
  199. package/src/domains/shared/stories/pack/buildLookupQuery.ts +80 -0
  200. package/src/domains/shared/stories/pack/collectPackStories.test.ts +108 -0
  201. package/src/domains/shared/stories/pack/collectPackStories.ts +76 -0
  202. package/src/domains/shared/stories/pack/compilePackCommands.ts +40 -0
  203. package/src/domains/shared/stories/pack/compilePackStories.test.ts +146 -0
  204. package/src/domains/shared/stories/pack/compilePackStories.ts +253 -0
  205. package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +43 -0
  206. package/src/domains/shared/stories/pack/index.ts +28 -0
  207. package/src/domains/shared/stories/pack/runSelectQuery.ts +31 -0
  208. package/src/domains/shared/stories/pack/standardParity.test.ts +308 -0
  209. package/src/domains/shared/stories/pack/types.ts +104 -0
  210. package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +240 -0
  211. package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +408 -0
  212. package/src/domains/shared/stories/projectCliParameters.test.ts +59 -0
  213. package/src/domains/shared/stories/projectCliParameters.ts +57 -0
  214. package/src/domains/shared/stories/projectToolParams.test.ts +50 -0
  215. package/src/domains/shared/stories/projectToolParams.ts +32 -0
  216. package/src/domains/shared/stories/requirePragmaContext.test.ts +23 -0
  217. package/src/domains/shared/stories/requirePragmaContext.ts +23 -0
  218. package/src/domains/shared/stories/resolveLookupDetailed.test.ts +57 -0
  219. package/src/domains/shared/stories/resolveLookupDetailed.ts +27 -0
  220. package/src/domains/shared/stories/types.ts +171 -0
  221. package/src/domains/shared/suggestions/detectCrossDomain.test.ts +43 -0
  222. package/src/domains/shared/suggestions/detectCrossDomain.ts +116 -0
  223. package/src/domains/shared/suggestions/expandGlob.test.ts +92 -0
  224. package/src/domains/shared/suggestions/expandGlob.ts +52 -0
  225. package/src/domains/shared/suggestions/expandLookupQueries.ts +57 -0
  226. package/src/domains/shared/suggestions/index.ts +7 -0
  227. package/src/domains/shared/suggestions/listDomainNames.ts +61 -0
  228. package/src/domains/shared/suggestions/suggestNames.test.ts +70 -0
  229. package/src/domains/shared/suggestions/suggestNames.ts +130 -0
  230. package/src/domains/shared/types/index.ts +1 -0
  231. package/src/domains/shared/types/runtime.ts +4 -1
  232. package/src/domains/shared/types/sample.ts +17 -0
  233. package/src/domains/skill/commands/index.ts +3 -1
  234. package/src/domains/skill/commands/list.test.ts +6 -2
  235. package/src/domains/skill/commands/list.ts +5 -63
  236. package/src/domains/skill/commands/lookup.test.ts +118 -0
  237. package/src/domains/skill/commands/lookup.ts +14 -0
  238. package/src/domains/skill/formatters/index.ts +1 -0
  239. package/src/domains/skill/formatters/lookup.test.ts +46 -0
  240. package/src/domains/skill/formatters/lookup.ts +57 -0
  241. package/src/domains/skill/helpers/resolveSkillSources.ts +48 -16
  242. package/src/domains/skill/index.ts +7 -3
  243. package/src/domains/skill/mcp/specs.ts +10 -29
  244. package/src/domains/skill/operations/discover.test.ts +61 -30
  245. package/src/domains/skill/operations/discover.ts +28 -37
  246. package/src/domains/skill/operations/index.ts +2 -1
  247. package/src/domains/skill/operations/list.test.ts +15 -7
  248. package/src/domains/skill/operations/lookup.test.ts +91 -0
  249. package/src/domains/skill/operations/lookup.ts +70 -0
  250. package/src/domains/skill/stories.test.ts +43 -0
  251. package/src/domains/skill/stories.ts +103 -0
  252. package/src/domains/skill/types.ts +8 -0
  253. package/src/domains/standard/commands/index.ts +2 -1
  254. package/src/domains/standard/commands/list.ts +5 -84
  255. package/src/domains/standard/commands/lookup.ts +8 -93
  256. package/src/domains/standard/commands/sample.ts +57 -0
  257. package/src/domains/standard/formatters/index.ts +2 -1
  258. package/src/domains/standard/formatters/sample.ts +15 -0
  259. package/src/domains/standard/index.ts +8 -1
  260. package/src/domains/standard/mcp/specs.ts +44 -152
  261. package/src/domains/standard/operations/index.ts +2 -1
  262. package/src/domains/standard/operations/lookup.ts +9 -0
  263. package/src/domains/standard/operations/sample.ts +35 -0
  264. package/src/domains/standard/orchestration/resolveStandardLookup.ts +15 -2
  265. package/src/domains/standard/orchestration/standardEmptyError.test.ts +33 -0
  266. package/src/domains/standard/orchestration/standardEmptyError.ts +16 -6
  267. package/src/domains/standard/stories.test.ts +24 -0
  268. package/src/domains/standard/stories.ts +151 -0
  269. package/src/domains/tier/commands/list.ts +5 -55
  270. package/src/domains/tier/mcp/specs.ts +5 -31
  271. package/src/domains/tier/stories.test.ts +22 -0
  272. package/src/domains/tier/stories.ts +52 -0
  273. package/src/domains/token/commands/index.ts +2 -1
  274. package/src/domains/token/commands/sample.ts +53 -0
  275. package/src/domains/token/formatters/index.ts +2 -1
  276. package/src/domains/token/formatters/sample.ts +16 -0
  277. package/src/domains/token/index.ts +8 -1
  278. package/src/domains/token/mcp/specs.ts +52 -2
  279. package/src/domains/token/operations/index.ts +2 -1
  280. package/src/domains/token/operations/lookup.ts +9 -0
  281. package/src/domains/token/operations/sample.ts +32 -0
  282. package/src/domains/token/orchestration/resolveTokenLookup.ts +15 -2
  283. package/src/domains/token/orchestration/tokenEmptyError.test.ts +33 -0
  284. package/src/domains/token/orchestration/tokenEmptyError.ts +5 -2
  285. package/src/domains/trace/commands/clear.ts +71 -0
  286. package/src/domains/trace/commands/index.ts +5 -0
  287. package/src/domains/trace/commands/sessions.ts +32 -0
  288. package/src/domains/trace/commands/show.ts +145 -0
  289. package/src/domains/trace/formatters/index.ts +9 -0
  290. package/src/domains/trace/formatters/sessions.ts +80 -0
  291. package/src/domains/trace/formatters/show.ts +122 -0
  292. package/src/domains/trace/index.ts +17 -0
  293. package/src/domains/trace/operations/index.ts +8 -0
  294. package/src/domains/trace/operations/listSessions.test.ts +55 -0
  295. package/src/domains/trace/operations/listSessions.ts +52 -0
  296. package/src/domains/trace/operations/readTraceLog.test.ts +100 -0
  297. package/src/domains/trace/operations/readTraceLog.ts +104 -0
  298. package/src/domains/trace/tracePlugin.test.ts +171 -0
  299. package/src/domains/trace/tracePlugin.ts +159 -0
  300. package/src/domains/trace/types.ts +65 -0
  301. package/src/error/PragmaError.ts +15 -2
  302. package/src/error/types.ts +15 -1
  303. package/src/mcp/error/serializeErrorPayload.ts +7 -0
  304. package/src/mcp/error/types.ts +8 -0
  305. package/src/mcp/registerResources.test.ts +405 -75
  306. package/src/mcp/registerResources.ts +5 -299
  307. package/src/mcp/resources/buildGraphIndex.ts +167 -0
  308. package/src/mcp/resources/buildResourceList.test.ts +97 -0
  309. package/src/mcp/resources/buildResourceList.ts +176 -0
  310. package/src/mcp/resources/classifyEntity.test.ts +40 -0
  311. package/src/mcp/resources/classifyEntity.ts +27 -0
  312. package/src/mcp/resources/constants.ts +105 -0
  313. package/src/mcp/resources/displayPredicates.ts +62 -0
  314. package/src/mcp/resources/pickFirstValue.test.ts +29 -0
  315. package/src/mcp/resources/pickFirstValue.ts +26 -0
  316. package/src/mcp/resources/pickPrimaryType.test.ts +41 -0
  317. package/src/mcp/resources/pickPrimaryType.ts +26 -0
  318. package/src/mcp/resources/rankUriCompletions.test.ts +52 -0
  319. package/src/mcp/resources/rankUriCompletions.ts +64 -0
  320. package/src/mcp/resources/readEntity.ts +169 -0
  321. package/src/mcp/resources/registerResources.ts +126 -0
  322. package/src/mcp/resources/types.ts +128 -0
  323. package/src/mcp/tools/index.ts +9 -0
  324. package/src/mcp/tools/registerTools.test.ts +84 -12
  325. package/src/mcp/types.ts +4 -0
  326. package/src/mcp/utils/wrapTool.test.ts +1 -0
  327. package/src/pipeline/collectCommands.ts +15 -2
  328. package/src/pipeline/renderError.ts +15 -0
  329. package/src/pipeline/resolveCommandKind.ts +8 -1
  330. package/src/pipeline/runCli.ts +51 -6
  331. package/src/testing/createTestMcpClient.ts +5 -1
  332. package/src/testing/graphqlFixtures.ts +72 -0
  333. package/src/testing/index.ts +17 -0
  334. package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +1207 -0
  335. package/src/testing/integration/cross-binary-byte-equality.test.ts +129 -0
  336. package/src/testing/integration/executor-execution.test.ts +101 -0
  337. package/src/testing/integration/executor-golden.test.ts +145 -0
  338. package/src/testing/integration/mcp-surface.test.ts +11 -5
  339. package/src/testing/integration/parity.test.ts +17 -12
  340. package/src/testing/regression/0001-skill-discovery-granularity.test.ts +71 -0
  341. package/src/testing/setupXdgIsolation.ts +15 -0
  342. package/src/testing/standardParityFixtures.ts +92 -0
  343. package/src/testing/storyFixtures.ts +63 -0
  344. package/src/pipeline/runInteractiveCommand.ts +0 -198
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { PREFIX_MAP } from "../../shared/prefixes.js";
3
+ import parsePrefixes from "./parsePrefixes.js";
4
+
5
+ describe("parsePrefixes", () => {
6
+ it("returns the default prefix map for no entries", () => {
7
+ const prefixes = parsePrefixes([]);
8
+ expect(prefixes).toEqual(PREFIX_MAP);
9
+ });
10
+
11
+ it("merges entries on top of the defaults", () => {
12
+ const prefixes = parsePrefixes(["ex=http://example.org/"]);
13
+ expect(prefixes.ex).toBe("http://example.org/");
14
+ expect(prefixes.ds).toBe(PREFIX_MAP.ds);
15
+ });
16
+
17
+ it("lets entries override default prefixes", () => {
18
+ const prefixes = parsePrefixes(["ds=http://other.example/"]);
19
+ expect(prefixes.ds).toBe("http://other.example/");
20
+ });
21
+
22
+ it("splits on the first equals sign only", () => {
23
+ const prefixes = parsePrefixes(["ex=http://example.org/?q=1"]);
24
+ expect(prefixes.ex).toBe("http://example.org/?q=1");
25
+ });
26
+
27
+ it("throws structured error for an entry without equals sign", () => {
28
+ expect(() => parsePrefixes(["nonsense"])).toThrowError(
29
+ expect.objectContaining({ code: "INVALID_INPUT" }),
30
+ );
31
+ });
32
+
33
+ it("throws structured error for an entry without a name", () => {
34
+ expect(() => parsePrefixes(["=http://example.org/"])).toThrowError(
35
+ expect.objectContaining({ code: "INVALID_INPUT" }),
36
+ );
37
+ });
38
+
39
+ it("throws structured error for an entry without a namespace", () => {
40
+ expect(() => parsePrefixes(["ex="])).toThrowError(
41
+ expect.objectContaining({ code: "INVALID_INPUT" }),
42
+ );
43
+ });
44
+ });
@@ -0,0 +1,38 @@
1
+ import { PragmaError } from "#error";
2
+ import { PREFIX_MAP } from "../../shared/prefixes.js";
3
+
4
+ /**
5
+ * Parse repeated `--prefix name=namespace` entries into a prefix map.
6
+ *
7
+ * User-supplied prefixes are merged on top of pragma's default
8
+ * {@link PREFIX_MAP}, so `ds:` and the W3C vocabularies stay available
9
+ * unless explicitly overridden.
10
+ *
11
+ * @param entries - Raw `name=namespace` strings from the CLI.
12
+ * @returns The merged prefix map for store creation and compilation.
13
+ * @throws PragmaError with code `INVALID_INPUT` when an entry is malformed.
14
+ */
15
+ export default function parsePrefixes(
16
+ entries: readonly string[],
17
+ ): Record<string, string> {
18
+ const prefixes: Record<string, string> = { ...PREFIX_MAP };
19
+
20
+ for (const entry of entries) {
21
+ const separator = entry.indexOf("=");
22
+ const name = separator === -1 ? "" : entry.slice(0, separator).trim();
23
+ const namespace = separator === -1 ? "" : entry.slice(separator + 1).trim();
24
+
25
+ if (!name || !namespace) {
26
+ throw PragmaError.invalidInput("prefix", entry, {
27
+ recovery: {
28
+ message:
29
+ "Use name=namespace, e.g. --prefix ds=https://ds.canonical.com/.",
30
+ },
31
+ });
32
+ }
33
+
34
+ prefixes[name] = namespace;
35
+ }
36
+
37
+ return prefixes;
38
+ }
@@ -0,0 +1,56 @@
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import resolveSourceFiles from "./resolveSourceFiles.js";
6
+
7
+ describe("resolveSourceFiles", () => {
8
+ let dir: string;
9
+
10
+ beforeEach(() => {
11
+ dir = mkdtempSync(join(tmpdir(), "pragma-graphql-sources-"));
12
+ writeFileSync(join(dir, "a.ttl"), "# a");
13
+ writeFileSync(join(dir, "b.ttl"), "# b");
14
+ writeFileSync(join(dir, "notes.txt"), "ignore me");
15
+ mkdirSync(join(dir, "nested"));
16
+ writeFileSync(join(dir, "nested", "c.ttl"), "# c");
17
+ });
18
+
19
+ afterEach(() => {
20
+ rmSync(dir, { recursive: true, force: true });
21
+ });
22
+
23
+ it("resolves relative literal paths against cwd", () => {
24
+ const files = resolveSourceFiles(["a.ttl"], dir);
25
+ expect(files).toEqual([join(dir, "a.ttl")]);
26
+ });
27
+
28
+ it("keeps absolute literal paths", () => {
29
+ const files = resolveSourceFiles([join(dir, "b.ttl")], dir);
30
+ expect(files).toEqual([join(dir, "b.ttl")]);
31
+ });
32
+
33
+ it("skips missing literal paths", () => {
34
+ const files = resolveSourceFiles(["missing.ttl"], dir);
35
+ expect(files).toEqual([]);
36
+ });
37
+
38
+ it("expands glob patterns", () => {
39
+ const files = resolveSourceFiles(["*.ttl"], dir);
40
+ expect(files.sort()).toEqual([join(dir, "a.ttl"), join(dir, "b.ttl")]);
41
+ });
42
+
43
+ it("expands recursive glob patterns", () => {
44
+ const files = resolveSourceFiles(["**/*.ttl"], dir);
45
+ expect(files.sort()).toEqual([
46
+ join(dir, "a.ttl"),
47
+ join(dir, "b.ttl"),
48
+ join(dir, "nested", "c.ttl"),
49
+ ]);
50
+ });
51
+
52
+ it("combines multiple patterns in order", () => {
53
+ const files = resolveSourceFiles(["b.ttl", "nested/*.ttl"], dir);
54
+ expect(files).toEqual([join(dir, "b.ttl"), join(dir, "nested", "c.ttl")]);
55
+ });
56
+ });
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Resolve TTL source patterns to absolute file paths.
3
+ *
4
+ * Mirrors ke's own source resolution (wildcard detection + `globSync`,
5
+ * literal paths checked for existence) so the files the CLI reads and
6
+ * hashes are exactly the files `createStore` loads.
7
+ *
8
+ * @note Impure — reads filesystem to expand globs and check existence.
9
+ */
10
+
11
+ import { existsSync, globSync } from "node:fs";
12
+ import { resolve } from "node:path";
13
+
14
+ /**
15
+ * Expand file paths and glob patterns into absolute file paths.
16
+ *
17
+ * @param patterns - Literal paths or glob patterns (`*`, `?`, `[`).
18
+ * @param cwd - Base directory for resolving relative patterns.
19
+ * @returns Absolute paths of all matched, existing files.
20
+ */
21
+ export default function resolveSourceFiles(
22
+ patterns: readonly string[],
23
+ cwd: string,
24
+ ): string[] {
25
+ const files: string[] = [];
26
+
27
+ for (const pattern of patterns) {
28
+ if (
29
+ pattern.includes("*") ||
30
+ pattern.includes("?") ||
31
+ pattern.includes("[")
32
+ ) {
33
+ for (const file of globSync(pattern, { cwd })) {
34
+ files.push(resolve(cwd, file));
35
+ }
36
+ } else {
37
+ const absPath = resolve(cwd, pattern);
38
+ if (existsSync(absPath)) {
39
+ files.push(absPath);
40
+ }
41
+ }
42
+ }
43
+
44
+ return files;
45
+ }
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import routeGraphql from "./routeGraphql.js";
3
+
4
+ describe("routeGraphql", () => {
5
+ it("delegates /graphql to the handler", async () => {
6
+ const handler = vi.fn(() => new Response("handled"));
7
+ const request = new Request("http://localhost:4000/graphql");
8
+
9
+ const response = await routeGraphql(request, handler, 4000);
10
+
11
+ expect(handler).toHaveBeenCalledWith(request);
12
+ expect(await response.text()).toBe("handled");
13
+ });
14
+
15
+ it("redirects / to /graphql", async () => {
16
+ const handler = vi.fn();
17
+
18
+ const response = await routeGraphql(
19
+ new Request("http://localhost:4000/"),
20
+ handler,
21
+ 4000,
22
+ );
23
+
24
+ expect(response.status).toBe(302);
25
+ expect(response.headers.get("location")).toBe(
26
+ "http://localhost:4000/graphql",
27
+ );
28
+ expect(handler).not.toHaveBeenCalled();
29
+ });
30
+
31
+ it("404s any other path", async () => {
32
+ const handler = vi.fn();
33
+
34
+ const response = await routeGraphql(
35
+ new Request("http://localhost:4000/favicon.ico"),
36
+ handler,
37
+ 4000,
38
+ );
39
+
40
+ expect(response.status).toBe(404);
41
+ expect(handler).not.toHaveBeenCalled();
42
+ });
43
+ });
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Route an incoming request for the graphql dev server: `/graphql` to the
3
+ * GraphQL + GraphiQL handler, `/` to a redirect there, and everything else
4
+ * to 404. Mounting is intentionally the host's job, which keeps the handler
5
+ * itself path-agnostic.
6
+ *
7
+ * @param request - The incoming fetch Request.
8
+ * @param handler - The GraphQL fetch handler for `/graphql`.
9
+ * @param port - The listen port, used to build the root redirect target.
10
+ * @returns The response (or a promise of one) for the route.
11
+ */
12
+
13
+ type GraphQLHandler = (request: Request) => Response | Promise<Response>;
14
+
15
+ export default function routeGraphql(
16
+ request: Request,
17
+ handler: GraphQLHandler,
18
+ port: number,
19
+ ): Response | Promise<Response> {
20
+ const { pathname } = new URL(request.url);
21
+ if (pathname === "/graphql") {
22
+ return handler(request);
23
+ }
24
+ if (pathname === "/") {
25
+ return Response.redirect(`http://localhost:${port}/graphql`, 302);
26
+ }
27
+ return new Response(null, { status: 404 });
28
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @module GraphQL domain barrel.
3
+ *
4
+ * Compiles TTL ontologies into GraphQL schema artifacts via the ke-graphql
5
+ * pipeline, and serves them locally. Commands boot their own ke store —
6
+ * from explicit TTL sources or, when none are given, the semantic packages
7
+ * configured in `pragma.config.json` — so they run on the store-skip
8
+ * pipeline path.
9
+ */
10
+
11
+ import type { CommandDefinition } from "@canonical/cli-core";
12
+ import { buildCommand, checkCommand, serveCommand } from "./commands/index.js";
13
+
14
+ /**
15
+ * Returns all command definitions for the graphql domain.
16
+ *
17
+ * @returns The `graphql build`, `graphql check`, and `graphql serve`
18
+ * command definitions.
19
+ */
20
+ export function commands(): CommandDefinition[] {
21
+ return [buildCommand, checkCommand, serveCommand];
22
+ }
23
+
24
+ export { compileSchema } from "./operations/index.js";
@@ -0,0 +1,95 @@
1
+ import { hashSources } from "@canonical/ke-graphql";
2
+ import { describe, expect, it } from "vitest";
3
+ import {
4
+ EX_NAMESPACE,
5
+ GRAPHQL_CLEAN_TTL,
6
+ GRAPHQL_ERROR_TTL,
7
+ GRAPHQL_FATAL_TTL,
8
+ } from "#testing";
9
+ import { PREFIX_MAP } from "../../shared/prefixes.js";
10
+ import compileSchema from "./compileSchema.js";
11
+
12
+ const PREFIXES = { ...PREFIX_MAP, ex: EX_NAMESPACE };
13
+
14
+ const inline = (content: string, path: string) => ({
15
+ content,
16
+ format: "turtle" as const,
17
+ path,
18
+ });
19
+
20
+ describe("compileSchema", () => {
21
+ it("compiles a clean ontology into SDL", async () => {
22
+ const outcome = await compileSchema({
23
+ sources: [inline(GRAPHQL_CLEAN_TTL, "clean.ttl")],
24
+ prefixes: PREFIXES,
25
+ });
26
+
27
+ expect(outcome.status).toBe("ok");
28
+ expect(outcome.compiled?.sdl).toContain("type Thing");
29
+ expect(outcome.diagnostics).toEqual([]);
30
+ expect(outcome.files).toEqual(["clean.ttl"]);
31
+ });
32
+
33
+ it("hashes the exact raw source contents", async () => {
34
+ const outcome = await compileSchema({
35
+ sources: [inline(GRAPHQL_CLEAN_TTL, "clean.ttl")],
36
+ prefixes: PREFIXES,
37
+ });
38
+
39
+ expect(outcome.sourcesHash).toBe(hashSources([GRAPHQL_CLEAN_TTL]));
40
+ });
41
+
42
+ it("labels a source without a path as 'inline'", async () => {
43
+ const outcome = await compileSchema({
44
+ sources: [{ content: GRAPHQL_CLEAN_TTL, format: "turtle" }],
45
+ prefixes: PREFIXES,
46
+ });
47
+
48
+ expect(outcome.files).toEqual(["inline"]);
49
+ });
50
+
51
+ it("surfaces error diagnostics without failing the compile", async () => {
52
+ const outcome = await compileSchema({
53
+ sources: [inline(GRAPHQL_ERROR_TTL, "error.ttl")],
54
+ prefixes: PREFIXES,
55
+ });
56
+
57
+ expect(outcome.status).toBe("ok");
58
+ expect(outcome.compiled).toBeDefined();
59
+ expect(
60
+ outcome.diagnostics.some(
61
+ (d) => d.severity === "error" && d.code === "M001",
62
+ ),
63
+ ).toBe(true);
64
+ });
65
+
66
+ it("converts CompilationError into a failed result with diagnostics", async () => {
67
+ const outcome = await compileSchema({
68
+ sources: [inline(GRAPHQL_FATAL_TTL, "fatal.ttl")],
69
+ prefixes: PREFIXES,
70
+ });
71
+
72
+ expect(outcome.status).toBe("failed");
73
+ expect(outcome.compiled).toBeUndefined();
74
+ expect(
75
+ outcome.diagnostics.some(
76
+ (d) => d.severity === "error" && d.code === "C003",
77
+ ),
78
+ ).toBe(true);
79
+ });
80
+
81
+ it("throws a structured error when given no sources", async () => {
82
+ await expect(
83
+ compileSchema({ sources: [], prefixes: PREFIXES }),
84
+ ).rejects.toMatchObject({ code: "INVALID_INPUT" });
85
+ });
86
+
87
+ it("throws a structured error on invalid TTL syntax", async () => {
88
+ await expect(
89
+ compileSchema({
90
+ sources: [inline("this is not turtle .", "broken.ttl")],
91
+ prefixes: PREFIXES,
92
+ }),
93
+ ).rejects.toMatchObject({ code: "STORE_ERROR" });
94
+ });
95
+ });
@@ -0,0 +1,107 @@
1
+ import { createStore, type InlineSource } from "@canonical/ke";
2
+ import {
3
+ CompilationError,
4
+ type CompilerResult,
5
+ compile,
6
+ createStoreQueryFn,
7
+ type Diagnostic,
8
+ hashSources,
9
+ } from "@canonical/ke-graphql";
10
+ import { PragmaError } from "#error";
11
+
12
+ export interface CompileSchemaOptions {
13
+ /** In-memory TTL sources (content + provenance path) to compile. */
14
+ readonly sources: readonly InlineSource[];
15
+ /** Prefix map handed to both the ke store and the compiler. */
16
+ readonly prefixes: Readonly<Record<string, string>>;
17
+ /** Working directory, passed through to the store (unused for inline). */
18
+ readonly cwd?: string;
19
+ }
20
+
21
+ export interface CompileSchemaResult {
22
+ /** `"ok"` when a schema was produced, `"failed"` when composition aborted. */
23
+ readonly status: "ok" | "failed";
24
+ /** All compiler diagnostics, including those carried by a CompilationError. */
25
+ readonly diagnostics: readonly Diagnostic[];
26
+ /** Provenance paths of the sources that were loaded. */
27
+ readonly files: readonly string[];
28
+ /** Fingerprint of the raw source contents (matches ke's onLoad hashing). */
29
+ readonly sourcesHash: string;
30
+ /** Full compiler output; absent when compilation failed. */
31
+ readonly compiled?: CompilerResult;
32
+ }
33
+
34
+ /**
35
+ * Compile in-memory TTL sources into a GraphQL schema via the ke-graphql
36
+ * pipeline.
37
+ *
38
+ * Hashes the raw source contents (the exact bytes ke loads, so the
39
+ * artifact's `sourcesHash` matches what `createSchemaPlugin` computes from
40
+ * ke's onLoad), boots a throwaway ke store, and runs the compiler. A
41
+ * {@link CompilationError} (schema composition failed) is converted into a
42
+ * `"failed"` result carrying its diagnostics; the store is always disposed.
43
+ *
44
+ * @note Impure — boots a ke store (WASM + TTL).
45
+ *
46
+ * @param options - In-memory sources and prefixes.
47
+ * @returns The compile outcome with diagnostics, files, and sources hash.
48
+ * @throws PragmaError with code `INVALID_INPUT` when given no sources.
49
+ * @throws PragmaError with code `STORE_ERROR` when the store fails to load.
50
+ */
51
+ export default async function compileSchema(
52
+ options: CompileSchemaOptions,
53
+ ): Promise<CompileSchemaResult> {
54
+ const { sources } = options;
55
+
56
+ if (sources.length === 0) {
57
+ throw PragmaError.invalidInput("sources", "(empty)", {
58
+ recovery: {
59
+ message: "Provide at least one TTL source.",
60
+ },
61
+ });
62
+ }
63
+
64
+ const sourcesHash = hashSources(sources.map((source) => source.content));
65
+ const files = sources.map((source) => source.path ?? "inline");
66
+
67
+ let store: Awaited<ReturnType<typeof createStore>>;
68
+ try {
69
+ store = await createStore({
70
+ sources: [...sources],
71
+ prefixes: options.prefixes,
72
+ cwd: options.cwd,
73
+ });
74
+ } catch (error) {
75
+ throw PragmaError.storeError(
76
+ error instanceof Error ? error.message : String(error),
77
+ {
78
+ recovery: {
79
+ message: "Check the TTL syntax of the provided sources.",
80
+ },
81
+ },
82
+ );
83
+ }
84
+
85
+ try {
86
+ const compiled = await compile(createStoreQueryFn(store), options.prefixes);
87
+ return {
88
+ status: "ok",
89
+ diagnostics: compiled.diagnostics,
90
+ files,
91
+ sourcesHash,
92
+ compiled,
93
+ };
94
+ } catch (error) {
95
+ if (error instanceof CompilationError) {
96
+ return {
97
+ status: "failed",
98
+ diagnostics: error.diagnostics,
99
+ files,
100
+ sourcesHash,
101
+ };
102
+ }
103
+ throw error;
104
+ } finally {
105
+ store.dispose();
106
+ }
107
+ }
@@ -0,0 +1,50 @@
1
+ import { afterEach, describe, expect, it } from "vitest";
2
+ import { EX_NAMESPACE, GRAPHQL_CLEAN_TTL } from "#testing";
3
+ import { PREFIX_MAP } from "../../shared/prefixes.js";
4
+ import createSchemaServer, { type SchemaServer } from "./createSchemaServer.js";
5
+
6
+ const PREFIXES = { ...PREFIX_MAP, ex: EX_NAMESPACE };
7
+
8
+ describe("createSchemaServer", () => {
9
+ let server: SchemaServer | undefined;
10
+
11
+ afterEach(() => {
12
+ server?.dispose();
13
+ server = undefined;
14
+ });
15
+
16
+ it("compiles inline sources and serves an introspectable schema", async () => {
17
+ server = await createSchemaServer({
18
+ sources: [
19
+ { content: GRAPHQL_CLEAN_TTL, format: "turtle", path: "clean.ttl" },
20
+ ],
21
+ prefixes: PREFIXES,
22
+ });
23
+
24
+ const response = await server.handler(
25
+ new Request("http://localhost/graphql", {
26
+ method: "POST",
27
+ headers: { "content-type": "application/json" },
28
+ body: JSON.stringify({
29
+ query: "{ __schema { queryType { name } } }",
30
+ }),
31
+ }),
32
+ );
33
+
34
+ expect(response.status).toBe(200);
35
+ const body = (await response.json()) as {
36
+ data?: { __schema?: { queryType?: { name?: string } } };
37
+ };
38
+ expect(body.data?.__schema?.queryType?.name).toBe("Query");
39
+ expect(Array.isArray(server.diagnostics)).toBe(true);
40
+ });
41
+
42
+ it("throws a STORE_ERROR on invalid TTL", async () => {
43
+ await expect(
44
+ createSchemaServer({
45
+ sources: [{ content: "not turtle .", format: "turtle", path: "x.ttl" }],
46
+ prefixes: PREFIXES,
47
+ }),
48
+ ).rejects.toMatchObject({ code: "STORE_ERROR" });
49
+ });
50
+ });
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Boot a persistent ke store over in-memory TTL sources with the
3
+ * ke-graphql schema plugin attached, and build the `/http` fetch handler
4
+ * (GraphiQL + GraphQL, CORS, incremental delivery) over the compiled
5
+ * schema. The caller owns the returned `dispose`.
6
+ *
7
+ * @note Impure — boots a ke store (WASM + TTL) and compiles the schema.
8
+ */
9
+
10
+ import { createStore, type InlineSource, type Plugin } from "@canonical/ke";
11
+ import {
12
+ createSchemaPlugin,
13
+ type Diagnostic,
14
+ type SchemaPluginApi,
15
+ } from "@canonical/ke-graphql";
16
+ import { createGraphQLHandler } from "@canonical/ke-graphql/http";
17
+ import { PragmaError } from "#error";
18
+
19
+ export interface CreateSchemaServerOptions {
20
+ /** In-memory TTL sources to load into the store. */
21
+ readonly sources: readonly InlineSource[];
22
+ /** Prefix map handed to both the ke store and the compiler. */
23
+ readonly prefixes: Readonly<Record<string, string>>;
24
+ }
25
+
26
+ export interface SchemaServer {
27
+ /** Runtime-neutral fetch handler over the compiled schema. */
28
+ readonly handler: ReturnType<typeof createGraphQLHandler>;
29
+ /** Compiler diagnostics produced while building the schema. */
30
+ readonly diagnostics: readonly Diagnostic[];
31
+ /** Releases the underlying ke store. */
32
+ readonly dispose: () => void;
33
+ }
34
+
35
+ export default async function createSchemaServer(
36
+ options: CreateSchemaServerOptions,
37
+ ): Promise<SchemaServer> {
38
+ const plugin = createSchemaPlugin({ incremental: true });
39
+
40
+ let store: Awaited<ReturnType<typeof createStore>>;
41
+ try {
42
+ store = await createStore({
43
+ sources: [...options.sources],
44
+ prefixes: options.prefixes,
45
+ // biome-ignore lint/suspicious/noExplicitAny: Plugin generic variance
46
+ plugins: [plugin as Plugin<any>],
47
+ });
48
+ } catch (error) {
49
+ throw PragmaError.storeError(
50
+ error instanceof Error ? error.message : String(error),
51
+ { recovery: { message: "Check the TTL syntax of the sources." } },
52
+ );
53
+ }
54
+
55
+ const api = store.api<SchemaPluginApi>("ke-graphql");
56
+ if (!api) {
57
+ store.dispose();
58
+ throw PragmaError.storeError("ke-graphql plugin did not register its API", {
59
+ recovery: { message: "This is an internal error; please report it." },
60
+ });
61
+ }
62
+
63
+ const handler = createGraphQLHandler(api.schema, {
64
+ context: () => api.createContext(store),
65
+ graphiql: true,
66
+ cors: true,
67
+ incremental: true,
68
+ });
69
+
70
+ return {
71
+ handler,
72
+ diagnostics: api.diagnostics,
73
+ dispose: () => store.dispose(),
74
+ };
75
+ }
@@ -0,0 +1,12 @@
1
+ /** @module Barrel for graphql operations. */
2
+
3
+ export type {
4
+ CompileSchemaOptions,
5
+ CompileSchemaResult,
6
+ } from "./compileSchema.js";
7
+ export { default as compileSchema } from "./compileSchema.js";
8
+ export type {
9
+ CreateSchemaServerOptions,
10
+ SchemaServer,
11
+ } from "./createSchemaServer.js";
12
+ export { default as createSchemaServer } from "./createSchemaServer.js";
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Type definitions for the graphql domain.
3
+ *
4
+ * The compile report is the shared output shape for `graphql build` and
5
+ * `graphql check`: the full diagnostic list plus source and artifact
6
+ * metadata, rendered by the report formatters.
7
+ */
8
+
9
+ import type { Diagnostic } from "@canonical/ke-graphql";
10
+
11
+ /** Artifact paths written by `pragma graphql build`. */
12
+ export interface GraphqlArtifacts {
13
+ /** Absolute path of the written GraphQL SDL file. */
14
+ readonly sdl: string;
15
+ /** Absolute path of the written extraction artifact. */
16
+ readonly extraction: string;
17
+ }
18
+
19
+ /** Output shape rendered by `graphql build` and `graphql check`. */
20
+ export interface GraphqlCompileReport {
21
+ /** All compiler diagnostics (errors, warnings, info). */
22
+ readonly diagnostics: readonly Diagnostic[];
23
+ /** Resolved absolute TTL file paths that were compiled. */
24
+ readonly files: readonly string[];
25
+ /** Combined fingerprint of the raw TTL source contents. */
26
+ readonly sourcesHash: string;
27
+ /** Written artifact paths (present only for a successful `build`). */
28
+ readonly artifacts?: GraphqlArtifacts;
29
+ }