@shortlink-org/portolan 0.1.0 → 0.2.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 (381) hide show
  1. package/README.md +69 -205
  2. package/cli/init.mjs +285 -0
  3. package/cli/init.test.mjs +158 -0
  4. package/cli/portolan.mjs +37 -73
  5. package/index.html +19 -0
  6. package/package.json +5 -10
  7. package/plugins/README.md +66 -27
  8. package/plugins/portolan-go.wasm +0 -0
  9. package/portolan.json +52 -73
  10. package/public/landing/cats/bug-hunter.webp +0 -0
  11. package/public/landing/cats/compass-nap.webp +0 -0
  12. package/public/landing/cats/diagrammer.webp +0 -0
  13. package/public/landing/cats/docs-reader.webp +0 -0
  14. package/public/landing/cats/laptop.webp +0 -0
  15. package/public/landing/cats/map-inspector.webp +0 -0
  16. package/public/landing/cats/server-break.webp +0 -0
  17. package/public/landing/cats/star-mapper.webp +0 -0
  18. package/public/landing/cats/system-builder.webp +0 -0
  19. package/public/landing/cats/thread-tangle.webp +0 -0
  20. package/public/og.png +0 -0
  21. package/public/readme-header.webp +0 -0
  22. package/schema/portolan.schema.json +180 -0
  23. package/scripts/builtin-plugins.mjs +14 -0
  24. package/scripts/delivery-presets.mjs +353 -0
  25. package/scripts/gen.mjs +37 -4
  26. package/scripts/history.mjs +126 -0
  27. package/scripts/history.test.mjs +110 -0
  28. package/scripts/host-plugins/fetch-bsr.mjs +351 -0
  29. package/{plugins/fetch-bsr/options.schema.json → scripts/host-plugins/fetch-bsr.options.json} +4 -0
  30. package/scripts/host-plugins/fetch-bsr.test.mjs +212 -0
  31. package/scripts/host-plugins/fetch-csr.mjs +386 -0
  32. package/scripts/host-plugins/fetch-csr.test.mjs +178 -0
  33. package/scripts/host-plugins/fetch-git.mjs +379 -0
  34. package/scripts/host-plugins/fetch-git.test.mjs +210 -0
  35. package/scripts/local-api.mjs +22 -4
  36. package/scripts/local-api.test.mjs +84 -2
  37. package/scripts/manifest.mjs +3 -2
  38. package/scripts/package-smoke.mjs +6 -2
  39. package/scripts/plugin-host.mjs +77 -18
  40. package/scripts/plugin-host.test.mjs +50 -1
  41. package/scripts/plugin-wasm-worker.mjs +6 -3
  42. package/scripts/run-builtin.mjs +6 -26
  43. package/scripts/schema.mjs +6 -1
  44. package/src/app/App.tsx +24 -429
  45. package/src/app/Breadcrumbs.test.ts +7 -0
  46. package/src/app/Breadcrumbs.tsx +15 -2
  47. package/src/app/CatalogApp.tsx +436 -0
  48. package/src/app/Sidebar.tsx +0 -1
  49. package/src/chat/ChatPanel.tsx +98 -41
  50. package/src/chat/Composer.tsx +4 -2
  51. package/src/chat/Conversation.tsx +79 -15
  52. package/src/chat/Header.tsx +43 -9
  53. package/src/chat/Starter.tsx +64 -3
  54. package/src/chat/Steps.tsx +1 -1
  55. package/src/chat/flags.test.ts +51 -14
  56. package/src/chat/flags.ts +8 -2
  57. package/src/chat/page-context.test.ts +51 -0
  58. package/src/chat/page-context.ts +128 -0
  59. package/src/chat/prompt.test.ts +49 -1
  60. package/src/chat/prompt.ts +42 -1
  61. package/src/chat/tools.ts +7 -2
  62. package/src/chat/transport.ts +16 -4
  63. package/src/components/ProblemRow.tsx +182 -0
  64. package/src/data.ts +20 -5
  65. package/src/er/ErCanvas.tsx +1 -1
  66. package/src/graph/DependencyGraph.tsx +10 -1
  67. package/src/graph/FocusedEventGraph.tsx +1 -1
  68. package/src/graph/GraphToolbar.tsx +2 -4
  69. package/src/index.css +220 -2
  70. package/src/landing/DraggableReveal.tsx +168 -0
  71. package/src/landing/EstateGraph.tsx +28 -0
  72. package/src/landing/FlowPlayback.tsx +282 -0
  73. package/src/landing/HeroMap.tsx +128 -0
  74. package/src/landing/LandingPage.tsx +757 -0
  75. package/src/landing/ProductFrame.tsx +68 -0
  76. package/src/landing/ProductTour.tsx +371 -0
  77. package/src/landing/catalog.ts +25 -0
  78. package/src/landing/motion.tsx +52 -0
  79. package/src/lib/all-problems.ts +28 -0
  80. package/src/lib/local-api.ts +35 -1
  81. package/src/lib/setup-info.test.ts +8 -0
  82. package/src/lib/setup-info.ts +3 -2
  83. package/src/lib/source-code.ts +2 -1
  84. package/src/likec4/C4View.tsx +5 -0
  85. package/src/likec4/InteractiveView.tsx +5 -1
  86. package/src/map/ContextMapGraph.tsx +47 -20
  87. package/src/pages/ContextMap.tsx +5 -1
  88. package/src/pages/FlowDetail.tsx +24 -7
  89. package/src/pages/Overview.tsx +68 -12
  90. package/src/pages/Problems.tsx +6 -193
  91. package/src/pages/Settings.tsx +133 -108
  92. package/src/pages/settings/DeliverySettings.tsx +229 -0
  93. package/src/pages/settings/PreferencesSettings.tsx +101 -0
  94. package/src/routes.test.ts +20 -0
  95. package/src/routes.ts +13 -1
  96. package/vite.config.ts +12 -8
  97. package/catalog/enum_test.go +0 -46
  98. package/catalog/model.go +0 -932
  99. package/catalog/roundtrip_test.go +0 -185
  100. package/catalog/via_test.go +0 -38
  101. package/go.mod +0 -14
  102. package/go.sum +0 -14
  103. package/internal/commands/cargo.go +0 -154
  104. package/internal/commands/commands.go +0 -143
  105. package/internal/commands/commands_test.go +0 -323
  106. package/internal/commands/gradle.go +0 -77
  107. package/internal/commands/justfile.go +0 -82
  108. package/internal/commands/makefile.go +0 -106
  109. package/internal/commands/maven.go +0 -93
  110. package/internal/commands/packagejson.go +0 -159
  111. package/internal/commands/pyproject.go +0 -169
  112. package/internal/commands/taskfile.go +0 -101
  113. package/internal/commands/testdata/estate/.cargo/config.toml +0 -7
  114. package/internal/commands/testdata/estate/Makefile +0 -33
  115. package/internal/commands/testdata/estate/Taskfile.yml +0 -21
  116. package/internal/commands/testdata/estate/build.gradle.kts +0 -21
  117. package/internal/commands/testdata/estate/justfile +0 -20
  118. package/internal/commands/testdata/estate/package.json +0 -13
  119. package/internal/commands/testdata/estate/pom.xml +0 -29
  120. package/internal/commands/testdata/estate/pyproject.toml +0 -27
  121. package/internal/commands/testdata/estate/xtask/src/main.rs +0 -27
  122. package/internal/commands/testdata/golden/commands.json +0 -305
  123. package/internal/gohttp/analyze.go +0 -2500
  124. package/internal/gohttp/endpoints.go +0 -1067
  125. package/internal/gohttp/roots.go +0 -320
  126. package/internal/gohttp/typed.go +0 -143
  127. package/internal/goscan/constants.go +0 -85
  128. package/internal/goscan/goscan_test.go +0 -227
  129. package/internal/goscan/names.go +0 -52
  130. package/internal/goscan/parse_test.go +0 -11
  131. package/internal/goscan/source.go +0 -36
  132. package/internal/goscan/tree.go +0 -155
  133. package/internal/goscan/types.go +0 -99
  134. package/internal/wsdl/ids.go +0 -127
  135. package/internal/wsdl/ids_test.go +0 -21
  136. package/internal/wsdl/model.go +0 -62
  137. package/internal/wsdl/parse.go +0 -920
  138. package/internal/wsdl/parse_test.go +0 -133
  139. package/plugin/describe.go +0 -107
  140. package/plugin/describe_test.go +0 -114
  141. package/plugin/protocol.go +0 -117
  142. package/plugin/schematest/schematest.go +0 -126
  143. package/plugins/extract-adr/describe.go +0 -19
  144. package/plugins/extract-adr/describe_test.go +0 -11
  145. package/plugins/extract-adr/extract.go +0 -153
  146. package/plugins/extract-adr/extract_test.go +0 -350
  147. package/plugins/extract-adr/history.go +0 -99
  148. package/plugins/extract-adr/main.go +0 -65
  149. package/plugins/extract-adr/parse.go +0 -642
  150. package/plugins/extract-adr/parse_test.go +0 -405
  151. package/plugins/extract-asyncapi/describe.go +0 -19
  152. package/plugins/extract-asyncapi/describe_test.go +0 -11
  153. package/plugins/extract-asyncapi/extract.go +0 -315
  154. package/plugins/extract-asyncapi/extract_test.go +0 -197
  155. package/plugins/extract-asyncapi/main.go +0 -48
  156. package/plugins/extract-asyncapi/spec.go +0 -151
  157. package/plugins/extract-commands/describe.go +0 -19
  158. package/plugins/extract-commands/describe_test.go +0 -11
  159. package/plugins/extract-commands/extract.go +0 -79
  160. package/plugins/extract-commands/extract_test.go +0 -92
  161. package/plugins/extract-commands/main.go +0 -55
  162. package/plugins/extract-csr/avro.go +0 -258
  163. package/plugins/extract-csr/describe.go +0 -19
  164. package/plugins/extract-csr/describe_test.go +0 -11
  165. package/plugins/extract-csr/extract.go +0 -338
  166. package/plugins/extract-csr/extract_test.go +0 -374
  167. package/plugins/extract-csr/jsonschema.go +0 -343
  168. package/plugins/extract-csr/lock.go +0 -25
  169. package/plugins/extract-csr/main.go +0 -84
  170. package/plugins/extract-csr/subject.go +0 -102
  171. package/plugins/extract-flows/describe.go +0 -19
  172. package/plugins/extract-flows/describe_test.go +0 -11
  173. package/plugins/extract-flows/extract.go +0 -91
  174. package/plugins/extract-flows/main.go +0 -45
  175. package/plugins/extract-flows/parse.go +0 -593
  176. package/plugins/extract-flows/parse_test.go +0 -204
  177. package/plugins/extract-glossary/describe.go +0 -19
  178. package/plugins/extract-glossary/describe_test.go +0 -11
  179. package/plugins/extract-glossary/extract.go +0 -115
  180. package/plugins/extract-glossary/extract_test.go +0 -220
  181. package/plugins/extract-glossary/main.go +0 -59
  182. package/plugins/extract-glossary/parse.go +0 -214
  183. package/plugins/extract-glossary/parse_test.go +0 -203
  184. package/plugins/extract-go/aggregate.go +0 -214
  185. package/plugins/extract-go/client.go +0 -409
  186. package/plugins/extract-go/client_test.go +0 -266
  187. package/plugins/extract-go/describe.go +0 -19
  188. package/plugins/extract-go/describe_test.go +0 -11
  189. package/plugins/extract-go/enum.go +0 -195
  190. package/plugins/extract-go/enum_test.go +0 -82
  191. package/plugins/extract-go/event.go +0 -99
  192. package/plugins/extract-go/extract.go +0 -191
  193. package/plugins/extract-go/extract_test.go +0 -261
  194. package/plugins/extract-go/flow.go +0 -1441
  195. package/plugins/extract-go/flow_test.go +0 -609
  196. package/plugins/extract-go/httpclient.go +0 -174
  197. package/plugins/extract-go/httpclient_test.go +0 -296
  198. package/plugins/extract-go/ids.go +0 -92
  199. package/plugins/extract-go/layout.go +0 -225
  200. package/plugins/extract-go/layout_test.go +0 -125
  201. package/plugins/extract-go/lifecycle.go +0 -324
  202. package/plugins/extract-go/lifecycle_test.go +0 -108
  203. package/plugins/extract-go/main.go +0 -79
  204. package/plugins/extract-go/operation.go +0 -157
  205. package/plugins/extract-go/source.go +0 -316
  206. package/plugins/extract-go/transport.go +0 -321
  207. package/plugins/extract-go/transport_test.go +0 -145
  208. package/plugins/extract-go/wiring.go +0 -434
  209. package/plugins/extract-go-nats/describe.go +0 -19
  210. package/plugins/extract-go-nats/describe_test.go +0 -11
  211. package/plugins/extract-go-nats/extract.go +0 -177
  212. package/plugins/extract-go-nats/extract_test.go +0 -389
  213. package/plugins/extract-go-nats/index.go +0 -379
  214. package/plugins/extract-go-nats/main.go +0 -42
  215. package/plugins/extract-go-nats/resolve.go +0 -161
  216. package/plugins/extract-go-nats/sites.go +0 -224
  217. package/plugins/extract-graphql/describe.go +0 -19
  218. package/plugins/extract-graphql/describe_test.go +0 -11
  219. package/plugins/extract-graphql/extract.go +0 -433
  220. package/plugins/extract-graphql/extract_test.go +0 -256
  221. package/plugins/extract-graphql/ids.go +0 -49
  222. package/plugins/extract-graphql/lex.go +0 -237
  223. package/plugins/extract-graphql/main.go +0 -51
  224. package/plugins/extract-graphql/parse.go +0 -621
  225. package/plugins/extract-graphql/parse_test.go +0 -122
  226. package/plugins/extract-http-clients/describe.go +0 -19
  227. package/plugins/extract-http-clients/describe_test.go +0 -11
  228. package/plugins/extract-http-clients/extract.go +0 -705
  229. package/plugins/extract-http-clients/extract_test.go +0 -1263
  230. package/plugins/extract-http-clients/main.go +0 -42
  231. package/plugins/extract-openapi/describe.go +0 -19
  232. package/plugins/extract-openapi/describe_test.go +0 -11
  233. package/plugins/extract-openapi/discover.go +0 -243
  234. package/plugins/extract-openapi/extract.go +0 -526
  235. package/plugins/extract-openapi/extract_test.go +0 -545
  236. package/plugins/extract-openapi/main.go +0 -75
  237. package/plugins/extract-openapi/spec.go +0 -350
  238. package/plugins/extract-project/describe.go +0 -19
  239. package/plugins/extract-project/describe_test.go +0 -11
  240. package/plugins/extract-project/extract.go +0 -221
  241. package/plugins/extract-project/extract_test.go +0 -109
  242. package/plugins/extract-project/main.go +0 -41
  243. package/plugins/extract-proto/ast.go +0 -125
  244. package/plugins/extract-proto/consumes.go +0 -77
  245. package/plugins/extract-proto/describe.go +0 -19
  246. package/plugins/extract-proto/extract.go +0 -293
  247. package/plugins/extract-proto/extract_test.go +0 -459
  248. package/plugins/extract-proto/ids.go +0 -89
  249. package/plugins/extract-proto/ids_test.go +0 -57
  250. package/plugins/extract-proto/lex.go +0 -285
  251. package/plugins/extract-proto/main.go +0 -100
  252. package/plugins/extract-proto/module.go +0 -120
  253. package/plugins/extract-proto/parse.go +0 -720
  254. package/plugins/extract-proto/parse_test.go +0 -307
  255. package/plugins/extract-proto/provides.go +0 -236
  256. package/plugins/extract-proto/resolve.go +0 -222
  257. package/plugins/extract-proto/resolve_test.go +0 -119
  258. package/plugins/extract-redis/describe.go +0 -19
  259. package/plugins/extract-redis/describe_test.go +0 -11
  260. package/plugins/extract-redis/extract.go +0 -183
  261. package/plugins/extract-redis/extract_test.go +0 -168
  262. package/plugins/extract-redis/keyspaces.go +0 -469
  263. package/plugins/extract-redis/main.go +0 -44
  264. package/plugins/extract-river/describe.go +0 -19
  265. package/plugins/extract-river/describe_test.go +0 -11
  266. package/plugins/extract-river/extract.go +0 -507
  267. package/plugins/extract-river/extract_test.go +0 -132
  268. package/plugins/extract-river/main.go +0 -42
  269. package/plugins/extract-sql/ddl.go +0 -893
  270. package/plugins/extract-sql/ddl_test.go +0 -401
  271. package/plugins/extract-sql/describe.go +0 -19
  272. package/plugins/extract-sql/describe_test.go +0 -11
  273. package/plugins/extract-sql/layout.go +0 -221
  274. package/plugins/extract-sql/layout_test.go +0 -55
  275. package/plugins/extract-sql/lineage.go +0 -107
  276. package/plugins/extract-sql/main.go +0 -141
  277. package/plugins/extract-sql/maps.go +0 -564
  278. package/plugins/extract-sql/maps_java.go +0 -117
  279. package/plugins/extract-sql/maps_rust.go +0 -333
  280. package/plugins/extract-sql/maps_rust_test.go +0 -70
  281. package/plugins/extract-sql/maps_test.go +0 -204
  282. package/plugins/extract-sql/maps_ts.go +0 -398
  283. package/plugins/extract-sql/maps_ts_test.go +0 -136
  284. package/plugins/extract-sql/projection.go +0 -70
  285. package/plugins/extract-sql/projection_test.go +0 -50
  286. package/plugins/extract-sql/store.go +0 -420
  287. package/plugins/extract-sql/store_test.go +0 -233
  288. package/plugins/extract-sql/view.go +0 -295
  289. package/plugins/extract-watermill/describe.go +0 -19
  290. package/plugins/extract-watermill/describe_test.go +0 -11
  291. package/plugins/extract-watermill/extract.go +0 -1228
  292. package/plugins/extract-watermill/extract_test.go +0 -234
  293. package/plugins/extract-watermill/main.go +0 -41
  294. package/plugins/extract-wsdl/describe.go +0 -19
  295. package/plugins/extract-wsdl/describe_test.go +0 -11
  296. package/plugins/extract-wsdl/extract.go +0 -148
  297. package/plugins/extract-wsdl/extract_test.go +0 -45
  298. package/plugins/extract-wsdl/main.go +0 -53
  299. package/plugins/fetch-bsr/auth.go +0 -114
  300. package/plugins/fetch-bsr/bsr.go +0 -240
  301. package/plugins/fetch-bsr/cache.go +0 -66
  302. package/plugins/fetch-bsr/describe.go +0 -19
  303. package/plugins/fetch-bsr/fetch.go +0 -192
  304. package/plugins/fetch-bsr/fetch_test.go +0 -465
  305. package/plugins/fetch-bsr/lock.go +0 -71
  306. package/plugins/fetch-bsr/main.go +0 -117
  307. package/plugins/fetch-csr/auth.go +0 -95
  308. package/plugins/fetch-csr/cache.go +0 -69
  309. package/plugins/fetch-csr/describe.go +0 -19
  310. package/plugins/fetch-csr/describe_test.go +0 -11
  311. package/plugins/fetch-csr/fetch.go +0 -254
  312. package/plugins/fetch-csr/fetch_test.go +0 -494
  313. package/plugins/fetch-csr/lock.go +0 -95
  314. package/plugins/fetch-csr/main.go +0 -122
  315. package/plugins/fetch-csr/registry.go +0 -209
  316. package/plugins/fetch-git/cache.go +0 -65
  317. package/plugins/fetch-git/describe.go +0 -19
  318. package/plugins/fetch-git/describe_test.go +0 -11
  319. package/plugins/fetch-git/fetch.go +0 -181
  320. package/plugins/fetch-git/fetch_test.go +0 -332
  321. package/plugins/fetch-git/git.go +0 -169
  322. package/plugins/fetch-git/lock.go +0 -72
  323. package/plugins/fetch-git/main.go +0 -127
  324. package/plugins/fetch-git/offline.go +0 -39
  325. package/plugins/fetch-git/pin.go +0 -90
  326. package/plugins/fetch-git/pin_test.go +0 -74
  327. package/plugins/gen-backstage/describe.go +0 -17
  328. package/plugins/gen-backstage/main.go +0 -22
  329. package/plugins/gen-backstage/plugin.go +0 -473
  330. package/plugins/gen-backstage/plugin_test.go +0 -145
  331. package/plugins/gen-backstage.wasm +0 -0
  332. package/plugins/gen-markdown/adr.go +0 -162
  333. package/plugins/gen-markdown/aggregate.go +0 -362
  334. package/plugins/gen-markdown/canonical.go +0 -93
  335. package/plugins/gen-markdown/context.go +0 -90
  336. package/plugins/gen-markdown/coverage_test.go +0 -89
  337. package/plugins/gen-markdown/describe.go +0 -19
  338. package/plugins/gen-markdown/describe_test.go +0 -11
  339. package/plugins/gen-markdown/external.go +0 -71
  340. package/plugins/gen-markdown/flow.go +0 -277
  341. package/plugins/gen-markdown/glossary.go +0 -76
  342. package/plugins/gen-markdown/glossary_test.go +0 -148
  343. package/plugins/gen-markdown/llms.go +0 -302
  344. package/plugins/gen-markdown/main.go +0 -22
  345. package/plugins/gen-markdown/markdown.go +0 -254
  346. package/plugins/gen-markdown/markdown_test.go +0 -100
  347. package/plugins/gen-markdown/module.go +0 -107
  348. package/plugins/gen-markdown/plugin.go +0 -39
  349. package/plugins/gen-markdown/quality_test.go +0 -176
  350. package/plugins/gen-markdown/redis_test.go +0 -38
  351. package/plugins/gen-markdown/render.go +0 -344
  352. package/plugins/gen-markdown/render_test.go +0 -186
  353. package/plugins/gen-markdown/service.go +0 -456
  354. package/plugins/gen-markdown/source.go +0 -177
  355. package/plugins/gen-markdown/store.go +0 -201
  356. package/plugins/gen-markdown.wasm +0 -0
  357. package/plugins/gen-mermaid/describe.go +0 -17
  358. package/plugins/gen-mermaid/main.go +0 -22
  359. package/plugins/gen-mermaid/plugin.go +0 -104
  360. package/plugins/gen-mermaid/plugin_test.go +0 -33
  361. package/plugins/gen-mermaid.wasm +0 -0
  362. package/plugins/openapi/ids.go +0 -261
  363. package/plugins/openapi/ids_test.go +0 -98
  364. package/plugins/verify-codeowners/describe.go +0 -19
  365. package/plugins/verify-codeowners/describe_test.go +0 -11
  366. package/plugins/verify-codeowners/main.go +0 -75
  367. package/plugins/verify-codeowners/match.go +0 -85
  368. package/plugins/verify-codeowners/match_test.go +0 -47
  369. package/plugins/verify-codeowners/owners.go +0 -164
  370. package/plugins/verify-codeowners/owners_test.go +0 -225
  371. package/plugins/verify-codeowners/parse.go +0 -90
  372. package/plugins/verify-codeowners/parse_test.go +0 -62
  373. package/plugins/verify-otel/describe.go +0 -19
  374. package/plugins/verify-otel/describe_test.go +0 -11
  375. package/plugins/verify-otel/main.go +0 -53
  376. package/plugins/verify-otel/match.go +0 -336
  377. package/plugins/verify-otel/otlp.go +0 -200
  378. package/plugins/verify-otel/verify.go +0 -734
  379. package/plugins/verify-otel/verify_test.go +0 -460
  380. /package/{plugins/fetch-csr/options.schema.json → scripts/host-plugins/fetch-csr.options.json} +0 -0
  381. /package/{plugins/fetch-git/options.schema.json → scripts/host-plugins/fetch-git.options.json} +0 -0
@@ -1,621 +0,0 @@
1
- package main
2
-
3
- // The definitions of a schema, read straight out of the SDL.
4
- //
5
- // A GraphQL server has a runtime schema and can print it, but printing needs
6
- // the server, and the whole point of reading source is that nothing has to be
7
- // running. So this is a parser for the type system language only - no
8
- // executable documents, no fragments, no queries - which is a much smaller
9
- // grammar than it looks: a handful of definition keywords, fields with
10
- // arguments, and the wrappers `!` and `[]`.
11
- //
12
- // The same type may be declared in several files. A modular schema says
13
- // `type Query { basket(...): Basket }` in one module and `type Query { order(...)
14
- // : Order }` in the next, and both of them mean the one Query the server
15
- // serves. Declarations merge; the file each field came from is kept, because
16
- // that is what says which module owns it.
17
-
18
- import (
19
- "fmt"
20
- "sort"
21
- "strings"
22
- )
23
-
24
- type typeKind string
25
-
26
- const (
27
- kindObject typeKind = "type"
28
- kindInterface typeKind = "interface"
29
- kindInput typeKind = "input"
30
- kindUnion typeKind = "union"
31
- kindEnum typeKind = "enum"
32
- kindScalar typeKind = "scalar"
33
- )
34
-
35
- // typeRef is a type as a field writes it: a name at the bottom, and the
36
- // wrappers around it. Nested lists collapse into one - a catalog that spelled
37
- // `[][]Line` would be describing a shape no reader of this estate has.
38
- type typeRef struct {
39
- name string
40
- list bool
41
- nonNull bool
42
- }
43
-
44
- // spell renders a type the way every other extractor here spells one: `[]Item`
45
- // for a list, the bare name otherwise. Nullability is not spelled, it is said
46
- // in the prose, the same way an optional OpenAPI property is.
47
- func (t typeRef) spell() string {
48
- if t.list {
49
- return "[]" + t.name
50
- }
51
-
52
- return t.name
53
- }
54
-
55
- type argDef struct {
56
- name string
57
- doc string
58
- typ typeRef
59
- }
60
-
61
- type fieldDef struct {
62
- name string
63
- doc string
64
- args []argDef
65
- typ typeRef
66
-
67
- deprecated bool
68
- reason string
69
-
70
- // file is the document this field was declared in, and module is what that
71
- // document is called for the purpose of grouping. A root field's module
72
- // decides which interface it lands in.
73
- file string
74
- module string
75
- }
76
-
77
- type typeDef struct {
78
- kind typeKind
79
- name string
80
- doc string
81
- fields []fieldDef
82
-
83
- // values are an enum's members, members a union's, and implements the
84
- // interfaces an object declares - which is the other way a schema says
85
- // "this shape stands for several".
86
- values []string
87
- members []string
88
- implements []string
89
-
90
- file string
91
- module string
92
- }
93
-
94
- type document struct {
95
- types map[string]*typeDef
96
- order []string
97
-
98
- // roots are the operation types the schema declares, by operation. A
99
- // schema that says nothing has the three the spec names by default.
100
- roots map[string]string
101
- }
102
-
103
- func newDocument() *document {
104
- return &document{
105
- types: map[string]*typeDef{},
106
- roots: map[string]string{},
107
- }
108
- }
109
-
110
- func (d *document) root(operation string) string {
111
- if named, ok := d.roots[operation]; ok {
112
- return named
113
- }
114
-
115
- return strings.ToUpper(operation[:1]) + operation[1:]
116
- }
117
-
118
- func (d *document) define(t *typeDef) {
119
- existing, ok := d.types[t.name]
120
- if !ok {
121
- d.types[t.name] = t
122
- d.order = append(d.order, t.name)
123
- return
124
- }
125
-
126
- // The second declaration of a type extends the first, whether or not it
127
- // said `extend`. A field declared twice is the schema's problem, not this
128
- // reader's; the first spelling wins so the output does not depend on which
129
- // file happened to sort first.
130
- if existing.doc == "" {
131
- existing.doc = t.doc
132
- }
133
- for _, f := range t.fields {
134
- if existing.field(f.name) == nil {
135
- existing.fields = append(existing.fields, f)
136
- }
137
- }
138
- existing.values = append(existing.values, t.values...)
139
- existing.members = append(existing.members, t.members...)
140
- existing.implements = append(existing.implements, t.implements...)
141
- }
142
-
143
- func (t *typeDef) field(name string) *fieldDef {
144
- for i := range t.fields {
145
- if t.fields[i].name == name {
146
- return &t.fields[i]
147
- }
148
- }
149
-
150
- return nil
151
- }
152
-
153
- type parser struct {
154
- toks []token
155
- pos int
156
- file string
157
- module string
158
- doc *document
159
- }
160
-
161
- // parseInto reads one SDL file into a document that may already hold others.
162
- func parseInto(d *document, src, file, module string) error {
163
- toks, err := lex(src)
164
- if err != nil {
165
- return fmt.Errorf("%s: %w", file, err)
166
- }
167
-
168
- p := &parser{toks: toks, file: file, module: module, doc: d}
169
- if err := p.document(); err != nil {
170
- return fmt.Errorf("%s: %w", file, err)
171
- }
172
-
173
- return nil
174
- }
175
-
176
- func (p *parser) peek() token { return p.toks[p.pos] }
177
- func (p *parser) next() token { t := p.toks[p.pos]; p.pos++; return t }
178
- func (p *parser) done() bool { return p.peek().kind == tokEOF }
179
- func (p *parser) at(s string) bool { return p.peek().is(s) }
180
-
181
- func (p *parser) accept(s string) bool {
182
- if p.at(s) {
183
- p.pos++
184
- return true
185
- }
186
-
187
- return false
188
- }
189
-
190
- func (p *parser) expect(s string) error {
191
- if p.accept(s) {
192
- return nil
193
- }
194
- tok := p.peek()
195
-
196
- return fmt.Errorf("line %d: expected %q, found %q", tok.line, s, tok.text)
197
- }
198
-
199
- func (p *parser) name() (string, error) {
200
- tok := p.peek()
201
- if tok.kind != tokName {
202
- return "", fmt.Errorf("line %d: expected a name, found %q", tok.line, tok.text)
203
- }
204
- p.pos++
205
-
206
- return tok.text, nil
207
- }
208
-
209
- func (p *parser) document() error {
210
- for !p.done() {
211
- doc := ""
212
- if p.peek().kind == tokString {
213
- doc = p.next().text
214
- }
215
- if err := p.definition(doc); err != nil {
216
- return err
217
- }
218
- }
219
-
220
- return nil
221
- }
222
-
223
- func (p *parser) definition(doc string) error {
224
- // `extend` says the definition adds to one that already exists, which is
225
- // what merging does anyway.
226
- p.accept("extend")
227
-
228
- keyword := p.peek()
229
- if keyword.kind != tokName {
230
- return fmt.Errorf("line %d: expected a definition, found %q", keyword.line, keyword.text)
231
- }
232
- p.pos++
233
-
234
- switch keyword.text {
235
- case "schema":
236
- return p.schema()
237
- case "type", "interface", "input":
238
- return p.object(typeKind(keyword.text), doc)
239
- case "union":
240
- return p.union(doc)
241
- case "enum":
242
- return p.enum(doc)
243
- case "scalar":
244
- return p.scalar(doc)
245
- case "directive":
246
- return p.directiveDefinition()
247
- }
248
-
249
- return fmt.Errorf("line %d: %q is not a type system definition", keyword.line, keyword.text)
250
- }
251
-
252
- func (p *parser) schema() error {
253
- if err := p.directives(nil); err != nil {
254
- return err
255
- }
256
- if err := p.expect("{"); err != nil {
257
- return err
258
- }
259
- for !p.accept("}") {
260
- operation, err := p.name()
261
- if err != nil {
262
- return err
263
- }
264
- if err := p.expect(":"); err != nil {
265
- return err
266
- }
267
- named, err := p.name()
268
- if err != nil {
269
- return err
270
- }
271
- p.doc.roots[operation] = named
272
- }
273
-
274
- return nil
275
- }
276
-
277
- func (p *parser) object(kind typeKind, doc string) error {
278
- name, err := p.name()
279
- if err != nil {
280
- return err
281
- }
282
-
283
- var implements []string
284
- if p.accept("implements") {
285
- p.accept("&")
286
- for {
287
- iface, err := p.name()
288
- if err != nil {
289
- return err
290
- }
291
- implements = append(implements, iface)
292
- if !p.accept("&") {
293
- break
294
- }
295
- }
296
- }
297
- if err := p.directives(nil); err != nil {
298
- return err
299
- }
300
-
301
- t := &typeDef{kind: kind, name: name, doc: doc, implements: implements, file: p.file, module: p.module}
302
- if p.accept("{") {
303
- for !p.accept("}") {
304
- field, err := p.field()
305
- if err != nil {
306
- return err
307
- }
308
- t.fields = append(t.fields, field)
309
- }
310
- }
311
- p.doc.define(t)
312
-
313
- return nil
314
- }
315
-
316
- func (p *parser) field() (fieldDef, error) {
317
- f := fieldDef{file: p.file, module: p.module}
318
- if p.peek().kind == tokString {
319
- f.doc = p.next().text
320
- }
321
-
322
- name, err := p.name()
323
- if err != nil {
324
- return f, err
325
- }
326
- f.name = name
327
-
328
- if p.accept("(") {
329
- for !p.accept(")") {
330
- arg, err := p.argument()
331
- if err != nil {
332
- return f, err
333
- }
334
- f.args = append(f.args, arg)
335
- }
336
- }
337
-
338
- if err := p.expect(":"); err != nil {
339
- return f, err
340
- }
341
- if f.typ, err = p.typeRef(); err != nil {
342
- return f, err
343
- }
344
-
345
- // An input field may carry a default; an output field may not, and a
346
- // document that gives one is wrong in a way this reader does not need to
347
- // care about.
348
- if p.accept("=") {
349
- if err := p.value(); err != nil {
350
- return f, err
351
- }
352
- }
353
-
354
- deprecated := &f
355
- if err := p.directives(deprecated); err != nil {
356
- return f, err
357
- }
358
-
359
- return f, nil
360
- }
361
-
362
- func (p *parser) argument() (argDef, error) {
363
- a := argDef{}
364
- if p.peek().kind == tokString {
365
- a.doc = p.next().text
366
- }
367
-
368
- name, err := p.name()
369
- if err != nil {
370
- return a, err
371
- }
372
- a.name = name
373
-
374
- if err := p.expect(":"); err != nil {
375
- return a, err
376
- }
377
- if a.typ, err = p.typeRef(); err != nil {
378
- return a, err
379
- }
380
- if p.accept("=") {
381
- if err := p.value(); err != nil {
382
- return a, err
383
- }
384
- }
385
-
386
- return a, p.directives(nil)
387
- }
388
-
389
- func (p *parser) typeRef() (typeRef, error) {
390
- var t typeRef
391
- if p.accept("[") {
392
- inner, err := p.typeRef()
393
- if err != nil {
394
- return t, err
395
- }
396
- if err := p.expect("]"); err != nil {
397
- return t, err
398
- }
399
- t = typeRef{name: inner.name, list: true}
400
- } else {
401
- name, err := p.name()
402
- if err != nil {
403
- return t, err
404
- }
405
- t = typeRef{name: name}
406
- }
407
- t.nonNull = p.accept("!")
408
-
409
- return t, nil
410
- }
411
-
412
- func (p *parser) union(doc string) error {
413
- name, err := p.name()
414
- if err != nil {
415
- return err
416
- }
417
- if err := p.directives(nil); err != nil {
418
- return err
419
- }
420
-
421
- t := &typeDef{kind: kindUnion, name: name, doc: doc, file: p.file, module: p.module}
422
- if p.accept("=") {
423
- p.accept("|")
424
- for {
425
- member, err := p.name()
426
- if err != nil {
427
- return err
428
- }
429
- t.members = append(t.members, member)
430
- if !p.accept("|") {
431
- break
432
- }
433
- }
434
- }
435
- p.doc.define(t)
436
-
437
- return nil
438
- }
439
-
440
- func (p *parser) enum(doc string) error {
441
- name, err := p.name()
442
- if err != nil {
443
- return err
444
- }
445
- if err := p.directives(nil); err != nil {
446
- return err
447
- }
448
-
449
- t := &typeDef{kind: kindEnum, name: name, doc: doc, file: p.file, module: p.module}
450
- if p.accept("{") {
451
- for !p.accept("}") {
452
- if p.peek().kind == tokString {
453
- p.pos++
454
- }
455
- value, err := p.name()
456
- if err != nil {
457
- return err
458
- }
459
- if err := p.directives(nil); err != nil {
460
- return err
461
- }
462
- t.values = append(t.values, value)
463
- }
464
- }
465
- p.doc.define(t)
466
-
467
- return nil
468
- }
469
-
470
- func (p *parser) scalar(doc string) error {
471
- name, err := p.name()
472
- if err != nil {
473
- return err
474
- }
475
- if err := p.directives(nil); err != nil {
476
- return err
477
- }
478
- p.doc.define(&typeDef{kind: kindScalar, name: name, doc: doc, file: p.file, module: p.module})
479
-
480
- return nil
481
- }
482
-
483
- // directiveDefinition is stepped over. A schema may define its own directives;
484
- // none of them are facts about the estate.
485
- func (p *parser) directiveDefinition() error {
486
- if err := p.expect("@"); err != nil {
487
- return err
488
- }
489
- if _, err := p.name(); err != nil {
490
- return err
491
- }
492
- if p.accept("(") {
493
- for !p.accept(")") {
494
- if _, err := p.argument(); err != nil {
495
- return err
496
- }
497
- }
498
- }
499
- p.accept("repeatable")
500
- if err := p.expect("on"); err != nil {
501
- return err
502
- }
503
- p.accept("|")
504
- for {
505
- if _, err := p.name(); err != nil {
506
- return err
507
- }
508
- if !p.accept("|") {
509
- break
510
- }
511
- }
512
-
513
- return nil
514
- }
515
-
516
- // directives reads the directives on a declaration. Only one of them says
517
- // something the catalog holds - `@deprecated`, which every other extractor
518
- // here also reports - so only that one is kept, and onto the field that
519
- // carries it.
520
- func (p *parser) directives(f *fieldDef) error {
521
- for p.accept("@") {
522
- name, err := p.name()
523
- if err != nil {
524
- return err
525
- }
526
-
527
- reason := ""
528
- if p.accept("(") {
529
- for !p.accept(")") {
530
- argName, err := p.name()
531
- if err != nil {
532
- return err
533
- }
534
- if err := p.expect(":"); err != nil {
535
- return err
536
- }
537
- start := p.pos
538
- if err := p.value(); err != nil {
539
- return err
540
- }
541
- if argName == "reason" && p.toks[start].kind == tokString {
542
- reason = p.toks[start].text
543
- }
544
- }
545
- }
546
-
547
- if name == "deprecated" && f != nil {
548
- f.deprecated = true
549
- f.reason = reason
550
- }
551
- }
552
-
553
- return nil
554
- }
555
-
556
- // value steps over a literal. Defaults and directive arguments are read only
557
- // far enough to get past them, apart from a deprecation reason.
558
- func (p *parser) value() error {
559
- tok := p.peek()
560
- switch {
561
- case tok.is("["):
562
- p.pos++
563
- for !p.accept("]") {
564
- if p.done() {
565
- return fmt.Errorf("line %d: a list value is never closed", tok.line)
566
- }
567
- if err := p.value(); err != nil {
568
- return err
569
- }
570
- }
571
- return nil
572
- case tok.is("{"):
573
- p.pos++
574
- for !p.accept("}") {
575
- if p.done() {
576
- return fmt.Errorf("line %d: an object value is never closed", tok.line)
577
- }
578
- if _, err := p.name(); err != nil {
579
- return err
580
- }
581
- if err := p.expect(":"); err != nil {
582
- return err
583
- }
584
- if err := p.value(); err != nil {
585
- return err
586
- }
587
- }
588
- return nil
589
- case tok.is("$"):
590
- p.pos++
591
- _, err := p.name()
592
- return err
593
- case tok.kind == tokName, tok.kind == tokString, tok.kind == tokNumber:
594
- p.pos++
595
- return nil
596
- }
597
-
598
- return fmt.Errorf("line %d: %q is not a value", tok.line, tok.text)
599
- }
600
-
601
- // modules are every module that declared something, in a stable order.
602
- func (d *document) modules() []string {
603
- seen := map[string]bool{}
604
- var out []string
605
- for _, name := range d.order {
606
- t := d.types[name]
607
- if !seen[t.module] {
608
- seen[t.module] = true
609
- out = append(out, t.module)
610
- }
611
- for _, f := range t.fields {
612
- if !seen[f.module] {
613
- seen[f.module] = true
614
- out = append(out, f.module)
615
- }
616
- }
617
- }
618
- sort.Strings(out)
619
-
620
- return out
621
- }