@shortlink-org/portolan 0.1.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 (826) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +387 -0
  3. package/catalog/enum_test.go +46 -0
  4. package/catalog/model.go +932 -0
  5. package/catalog/roundtrip_test.go +185 -0
  6. package/catalog/via_test.go +38 -0
  7. package/cli/portolan.mjs +368 -0
  8. package/go.mod +14 -0
  9. package/go.sum +14 -0
  10. package/index.html +13 -0
  11. package/internal/commands/cargo.go +154 -0
  12. package/internal/commands/commands.go +143 -0
  13. package/internal/commands/commands_test.go +323 -0
  14. package/internal/commands/gradle.go +77 -0
  15. package/internal/commands/justfile.go +82 -0
  16. package/internal/commands/makefile.go +106 -0
  17. package/internal/commands/maven.go +93 -0
  18. package/internal/commands/packagejson.go +159 -0
  19. package/internal/commands/pyproject.go +169 -0
  20. package/internal/commands/taskfile.go +101 -0
  21. package/internal/commands/testdata/estate/.cargo/config.toml +7 -0
  22. package/internal/commands/testdata/estate/Makefile +33 -0
  23. package/internal/commands/testdata/estate/Taskfile.yml +21 -0
  24. package/internal/commands/testdata/estate/build.gradle.kts +21 -0
  25. package/internal/commands/testdata/estate/justfile +20 -0
  26. package/internal/commands/testdata/estate/package.json +13 -0
  27. package/internal/commands/testdata/estate/pom.xml +29 -0
  28. package/internal/commands/testdata/estate/pyproject.toml +27 -0
  29. package/internal/commands/testdata/estate/xtask/src/main.rs +27 -0
  30. package/internal/commands/testdata/golden/commands.json +305 -0
  31. package/internal/gohttp/analyze.go +2500 -0
  32. package/internal/gohttp/endpoints.go +1067 -0
  33. package/internal/gohttp/roots.go +320 -0
  34. package/internal/gohttp/typed.go +143 -0
  35. package/internal/goscan/constants.go +85 -0
  36. package/internal/goscan/goscan_test.go +227 -0
  37. package/internal/goscan/names.go +52 -0
  38. package/internal/goscan/parse_test.go +11 -0
  39. package/internal/goscan/source.go +36 -0
  40. package/internal/goscan/tree.go +155 -0
  41. package/internal/goscan/types.go +99 -0
  42. package/internal/wsdl/ids.go +127 -0
  43. package/internal/wsdl/ids_test.go +21 -0
  44. package/internal/wsdl/model.go +62 -0
  45. package/internal/wsdl/parse.go +920 -0
  46. package/internal/wsdl/parse_test.go +133 -0
  47. package/package.json +117 -0
  48. package/plugin/describe.go +107 -0
  49. package/plugin/describe_test.go +114 -0
  50. package/plugin/protocol.go +117 -0
  51. package/plugin/schematest/schematest.go +126 -0
  52. package/plugins/README.md +1160 -0
  53. package/plugins/extract-adr/describe.go +19 -0
  54. package/plugins/extract-adr/describe_test.go +11 -0
  55. package/plugins/extract-adr/extract.go +153 -0
  56. package/plugins/extract-adr/extract_test.go +350 -0
  57. package/plugins/extract-adr/history.go +99 -0
  58. package/plugins/extract-adr/main.go +65 -0
  59. package/plugins/extract-adr/options.schema.json +26 -0
  60. package/plugins/extract-adr/parse.go +642 -0
  61. package/plugins/extract-adr/parse_test.go +405 -0
  62. package/plugins/extract-asyncapi/describe.go +19 -0
  63. package/plugins/extract-asyncapi/describe_test.go +11 -0
  64. package/plugins/extract-asyncapi/extract.go +315 -0
  65. package/plugins/extract-asyncapi/extract_test.go +197 -0
  66. package/plugins/extract-asyncapi/main.go +48 -0
  67. package/plugins/extract-asyncapi/options.schema.json +26 -0
  68. package/plugins/extract-asyncapi/spec.go +151 -0
  69. package/plugins/extract-celery/README.md +169 -0
  70. package/plugins/extract-celery/extract.py +346 -0
  71. package/plugins/extract-celery/extract_test.py +192 -0
  72. package/plugins/extract-celery/main.py +66 -0
  73. package/plugins/extract-celery/options.py +31 -0
  74. package/plugins/extract-celery/options.schema.json +31 -0
  75. package/plugins/extract-celery/producers.py +156 -0
  76. package/plugins/extract-celery/routes_test.py +106 -0
  77. package/plugins/extract-commands/describe.go +19 -0
  78. package/plugins/extract-commands/describe_test.go +11 -0
  79. package/plugins/extract-commands/extract.go +79 -0
  80. package/plugins/extract-commands/extract_test.go +92 -0
  81. package/plugins/extract-commands/main.go +55 -0
  82. package/plugins/extract-commands/options.schema.json +20 -0
  83. package/plugins/extract-csr/avro.go +258 -0
  84. package/plugins/extract-csr/describe.go +19 -0
  85. package/plugins/extract-csr/describe_test.go +11 -0
  86. package/plugins/extract-csr/extract.go +338 -0
  87. package/plugins/extract-csr/extract_test.go +374 -0
  88. package/plugins/extract-csr/jsonschema.go +343 -0
  89. package/plugins/extract-csr/lock.go +25 -0
  90. package/plugins/extract-csr/main.go +84 -0
  91. package/plugins/extract-csr/options.schema.json +43 -0
  92. package/plugins/extract-csr/subject.go +102 -0
  93. package/plugins/extract-django/README.md +386 -0
  94. package/plugins/extract-django/apps.py +100 -0
  95. package/plugins/extract-django/auth.py +302 -0
  96. package/plugins/extract-django/auth_test.py +188 -0
  97. package/plugins/extract-django/clients.py +121 -0
  98. package/plugins/extract-django/contracts.py +458 -0
  99. package/plugins/extract-django/database.py +119 -0
  100. package/plugins/extract-django/domain.py +318 -0
  101. package/plugins/extract-django/events.py +86 -0
  102. package/plugins/extract-django/extract.py +601 -0
  103. package/plugins/extract-django/extract_test.py +397 -0
  104. package/plugins/extract-django/flows.py +1278 -0
  105. package/plugins/extract-django/flows_test.py +338 -0
  106. package/plugins/extract-django/ids.py +42 -0
  107. package/plugins/extract-django/ids_test.py +30 -0
  108. package/plugins/extract-django/lifecycle.py +222 -0
  109. package/plugins/extract-django/lifecycle_test.py +76 -0
  110. package/plugins/extract-django/main.py +66 -0
  111. package/plugins/extract-django/openapi.py +229 -0
  112. package/plugins/extract-django/openapi_test.py +60 -0
  113. package/plugins/extract-django/operations.py +96 -0
  114. package/plugins/extract-django/options.py +61 -0
  115. package/plugins/extract-django/options.schema.json +126 -0
  116. package/plugins/extract-django/routing.py +214 -0
  117. package/plugins/extract-django/routing_test.py +198 -0
  118. package/plugins/extract-django/serializers.py +558 -0
  119. package/plugins/extract-django/store.py +434 -0
  120. package/plugins/extract-django/transport.py +242 -0
  121. package/plugins/extract-flows/describe.go +19 -0
  122. package/plugins/extract-flows/describe_test.go +11 -0
  123. package/plugins/extract-flows/extract.go +91 -0
  124. package/plugins/extract-flows/main.go +45 -0
  125. package/plugins/extract-flows/options.schema.json +16 -0
  126. package/plugins/extract-flows/parse.go +593 -0
  127. package/plugins/extract-flows/parse_test.go +204 -0
  128. package/plugins/extract-glossary/describe.go +19 -0
  129. package/plugins/extract-glossary/describe_test.go +11 -0
  130. package/plugins/extract-glossary/extract.go +115 -0
  131. package/plugins/extract-glossary/extract_test.go +220 -0
  132. package/plugins/extract-glossary/main.go +59 -0
  133. package/plugins/extract-glossary/options.schema.json +21 -0
  134. package/plugins/extract-glossary/parse.go +214 -0
  135. package/plugins/extract-glossary/parse_test.go +203 -0
  136. package/plugins/extract-go/aggregate.go +214 -0
  137. package/plugins/extract-go/client.go +409 -0
  138. package/plugins/extract-go/client_test.go +266 -0
  139. package/plugins/extract-go/describe.go +19 -0
  140. package/plugins/extract-go/describe_test.go +11 -0
  141. package/plugins/extract-go/enum.go +195 -0
  142. package/plugins/extract-go/enum_test.go +82 -0
  143. package/plugins/extract-go/event.go +99 -0
  144. package/plugins/extract-go/extract.go +191 -0
  145. package/plugins/extract-go/extract_test.go +261 -0
  146. package/plugins/extract-go/flow.go +1441 -0
  147. package/plugins/extract-go/flow_test.go +609 -0
  148. package/plugins/extract-go/httpclient.go +174 -0
  149. package/plugins/extract-go/httpclient_test.go +296 -0
  150. package/plugins/extract-go/ids.go +92 -0
  151. package/plugins/extract-go/layout.go +225 -0
  152. package/plugins/extract-go/layout_test.go +125 -0
  153. package/plugins/extract-go/lifecycle.go +324 -0
  154. package/plugins/extract-go/lifecycle_test.go +108 -0
  155. package/plugins/extract-go/main.go +79 -0
  156. package/plugins/extract-go/operation.go +157 -0
  157. package/plugins/extract-go/options.schema.json +66 -0
  158. package/plugins/extract-go/source.go +316 -0
  159. package/plugins/extract-go/transport.go +321 -0
  160. package/plugins/extract-go/transport_test.go +145 -0
  161. package/plugins/extract-go/wiring.go +434 -0
  162. package/plugins/extract-go-nats/describe.go +19 -0
  163. package/plugins/extract-go-nats/describe_test.go +11 -0
  164. package/plugins/extract-go-nats/extract.go +177 -0
  165. package/plugins/extract-go-nats/extract_test.go +389 -0
  166. package/plugins/extract-go-nats/index.go +379 -0
  167. package/plugins/extract-go-nats/main.go +42 -0
  168. package/plugins/extract-go-nats/options.schema.json +21 -0
  169. package/plugins/extract-go-nats/resolve.go +161 -0
  170. package/plugins/extract-go-nats/sites.go +224 -0
  171. package/plugins/extract-graphql/describe.go +19 -0
  172. package/plugins/extract-graphql/describe_test.go +11 -0
  173. package/plugins/extract-graphql/extract.go +433 -0
  174. package/plugins/extract-graphql/extract_test.go +256 -0
  175. package/plugins/extract-graphql/ids.go +49 -0
  176. package/plugins/extract-graphql/lex.go +237 -0
  177. package/plugins/extract-graphql/main.go +51 -0
  178. package/plugins/extract-graphql/options.schema.json +31 -0
  179. package/plugins/extract-graphql/parse.go +621 -0
  180. package/plugins/extract-graphql/parse_test.go +122 -0
  181. package/plugins/extract-http-clients/describe.go +19 -0
  182. package/plugins/extract-http-clients/describe_test.go +11 -0
  183. package/plugins/extract-http-clients/extract.go +705 -0
  184. package/plugins/extract-http-clients/extract_test.go +1263 -0
  185. package/plugins/extract-http-clients/main.go +42 -0
  186. package/plugins/extract-http-clients/options.schema.json +33 -0
  187. package/plugins/extract-java/README.md +190 -0
  188. package/plugins/extract-java/build/org/portolan/extract/Catalog.class +0 -0
  189. package/plugins/extract-java/build/org/portolan/extract/Clients$1.class +0 -0
  190. package/plugins/extract-java/build/org/portolan/extract/Clients$2.class +0 -0
  191. package/plugins/extract-java/build/org/portolan/extract/Clients$Call.class +0 -0
  192. package/plugins/extract-java/build/org/portolan/extract/Clients$Client.class +0 -0
  193. package/plugins/extract-java/build/org/portolan/extract/Clients$Route.class +0 -0
  194. package/plugins/extract-java/build/org/portolan/extract/Clients.class +0 -0
  195. package/plugins/extract-java/build/org/portolan/extract/Domain$Aggregate.class +0 -0
  196. package/plugins/extract-java/build/org/portolan/extract/Domain.class +0 -0
  197. package/plugins/extract-java/build/org/portolan/extract/Events$Found.class +0 -0
  198. package/plugins/extract-java/build/org/portolan/extract/Events.class +0 -0
  199. package/plugins/extract-java/build/org/portolan/extract/Extract.class +0 -0
  200. package/plugins/extract-java/build/org/portolan/extract/Flows$1.class +0 -0
  201. package/plugins/extract-java/build/org/portolan/extract/Flows$Binding.class +0 -0
  202. package/plugins/extract-java/build/org/portolan/extract/Flows$Draft.class +0 -0
  203. package/plugins/extract-java/build/org/portolan/extract/Flows$Frame.class +0 -0
  204. package/plugins/extract-java/build/org/portolan/extract/Flows$Options.class +0 -0
  205. package/plugins/extract-java/build/org/portolan/extract/Flows.class +0 -0
  206. package/plugins/extract-java/build/org/portolan/extract/Ids.class +0 -0
  207. package/plugins/extract-java/build/org/portolan/extract/Json$Reader.class +0 -0
  208. package/plugins/extract-java/build/org/portolan/extract/Json.class +0 -0
  209. package/plugins/extract-java/build/org/portolan/extract/Lifecycle$1.class +0 -0
  210. package/plugins/extract-java/build/org/portolan/extract/Lifecycle$Move.class +0 -0
  211. package/plugins/extract-java/build/org/portolan/extract/Lifecycle.class +0 -0
  212. package/plugins/extract-java/build/org/portolan/extract/Main.class +0 -0
  213. package/plugins/extract-java/build/org/portolan/extract/OpenApi$Operation.class +0 -0
  214. package/plugins/extract-java/build/org/portolan/extract/OpenApi$Spec.class +0 -0
  215. package/plugins/extract-java/build/org/portolan/extract/OpenApi.class +0 -0
  216. package/plugins/extract-java/build/org/portolan/extract/Operations$1.class +0 -0
  217. package/plugins/extract-java/build/org/portolan/extract/Operations$UseCase.class +0 -0
  218. package/plugins/extract-java/build/org/portolan/extract/Operations.class +0 -0
  219. package/plugins/extract-java/build/org/portolan/extract/Proto$Rpc.class +0 -0
  220. package/plugins/extract-java/build/org/portolan/extract/Proto$Service.class +0 -0
  221. package/plugins/extract-java/build/org/portolan/extract/Proto.class +0 -0
  222. package/plugins/extract-java/build/org/portolan/extract/Protocol$Builder.class +0 -0
  223. package/plugins/extract-java/build/org/portolan/extract/Protocol$Input.class +0 -0
  224. package/plugins/extract-java/build/org/portolan/extract/Protocol$Options.class +0 -0
  225. package/plugins/extract-java/build/org/portolan/extract/Protocol.class +0 -0
  226. package/plugins/extract-java/build/org/portolan/extract/Source$Project.class +0 -0
  227. package/plugins/extract-java/build/org/portolan/extract/Source$Unit.class +0 -0
  228. package/plugins/extract-java/build/org/portolan/extract/Source.class +0 -0
  229. package/plugins/extract-java/build/org/portolan/extract/Transport$Endpoint.class +0 -0
  230. package/plugins/extract-java/build/org/portolan/extract/Transport.class +0 -0
  231. package/plugins/extract-java/build/org/portolan/extract/Yaml$Line.class +0 -0
  232. package/plugins/extract-java/build/org/portolan/extract/Yaml$Reader.class +0 -0
  233. package/plugins/extract-java/build/org/portolan/extract/Yaml.class +0 -0
  234. package/plugins/extract-java/options.schema.json +70 -0
  235. package/plugins/extract-openapi/describe.go +19 -0
  236. package/plugins/extract-openapi/describe_test.go +11 -0
  237. package/plugins/extract-openapi/discover.go +243 -0
  238. package/plugins/extract-openapi/extract.go +526 -0
  239. package/plugins/extract-openapi/extract_test.go +545 -0
  240. package/plugins/extract-openapi/main.go +75 -0
  241. package/plugins/extract-openapi/options.schema.json +62 -0
  242. package/plugins/extract-openapi/spec.go +350 -0
  243. package/plugins/extract-project/README.md +22 -0
  244. package/plugins/extract-project/describe.go +19 -0
  245. package/plugins/extract-project/describe_test.go +11 -0
  246. package/plugins/extract-project/extract.go +221 -0
  247. package/plugins/extract-project/extract_test.go +109 -0
  248. package/plugins/extract-project/main.go +41 -0
  249. package/plugins/extract-project/options.schema.json +48 -0
  250. package/plugins/extract-proto/ast.go +125 -0
  251. package/plugins/extract-proto/consumes.go +77 -0
  252. package/plugins/extract-proto/describe.go +19 -0
  253. package/plugins/extract-proto/extract.go +293 -0
  254. package/plugins/extract-proto/extract_test.go +459 -0
  255. package/plugins/extract-proto/ids.go +89 -0
  256. package/plugins/extract-proto/ids_test.go +57 -0
  257. package/plugins/extract-proto/lex.go +285 -0
  258. package/plugins/extract-proto/main.go +100 -0
  259. package/plugins/extract-proto/module.go +120 -0
  260. package/plugins/extract-proto/options.schema.json +51 -0
  261. package/plugins/extract-proto/parse.go +720 -0
  262. package/plugins/extract-proto/parse_test.go +307 -0
  263. package/plugins/extract-proto/provides.go +236 -0
  264. package/plugins/extract-proto/resolve.go +222 -0
  265. package/plugins/extract-proto/resolve_test.go +119 -0
  266. package/plugins/extract-python-kafka/README.md +36 -0
  267. package/plugins/extract-python-kafka/extract.py +211 -0
  268. package/plugins/extract-python-kafka/extract_test.py +68 -0
  269. package/plugins/extract-python-kafka/main.py +59 -0
  270. package/plugins/extract-python-kafka/options.py +29 -0
  271. package/plugins/extract-python-kafka/options.schema.json +31 -0
  272. package/plugins/extract-redis/README.md +11 -0
  273. package/plugins/extract-redis/describe.go +19 -0
  274. package/plugins/extract-redis/describe_test.go +11 -0
  275. package/plugins/extract-redis/extract.go +183 -0
  276. package/plugins/extract-redis/extract_test.go +168 -0
  277. package/plugins/extract-redis/keyspaces.go +469 -0
  278. package/plugins/extract-redis/main.go +44 -0
  279. package/plugins/extract-redis/options.schema.json +30 -0
  280. package/plugins/extract-river/describe.go +19 -0
  281. package/plugins/extract-river/describe_test.go +11 -0
  282. package/plugins/extract-river/extract.go +507 -0
  283. package/plugins/extract-river/extract_test.go +132 -0
  284. package/plugins/extract-river/main.go +42 -0
  285. package/plugins/extract-river/options.schema.json +21 -0
  286. package/plugins/extract-rust/Cargo.lock +133 -0
  287. package/plugins/extract-rust/Cargo.toml +23 -0
  288. package/plugins/extract-rust/README.md +204 -0
  289. package/plugins/extract-rust/options.schema.json +65 -0
  290. package/plugins/extract-rust/rustfmt.toml +1 -0
  291. package/plugins/extract-sql/ddl.go +893 -0
  292. package/plugins/extract-sql/ddl_test.go +401 -0
  293. package/plugins/extract-sql/describe.go +19 -0
  294. package/plugins/extract-sql/describe_test.go +11 -0
  295. package/plugins/extract-sql/layout.go +221 -0
  296. package/plugins/extract-sql/layout_test.go +55 -0
  297. package/plugins/extract-sql/lineage.go +107 -0
  298. package/plugins/extract-sql/main.go +141 -0
  299. package/plugins/extract-sql/maps.go +564 -0
  300. package/plugins/extract-sql/maps_java.go +117 -0
  301. package/plugins/extract-sql/maps_rust.go +333 -0
  302. package/plugins/extract-sql/maps_rust_test.go +70 -0
  303. package/plugins/extract-sql/maps_test.go +204 -0
  304. package/plugins/extract-sql/maps_ts.go +398 -0
  305. package/plugins/extract-sql/maps_ts_test.go +136 -0
  306. package/plugins/extract-sql/options.schema.json +53 -0
  307. package/plugins/extract-sql/projection.go +70 -0
  308. package/plugins/extract-sql/projection_test.go +50 -0
  309. package/plugins/extract-sql/store.go +420 -0
  310. package/plugins/extract-sql/store_test.go +233 -0
  311. package/plugins/extract-sql/view.go +295 -0
  312. package/plugins/extract-ts/README.md +306 -0
  313. package/plugins/extract-ts/ast.test.ts +178 -0
  314. package/plugins/extract-ts/ast.ts +648 -0
  315. package/plugins/extract-ts/clients.ts +185 -0
  316. package/plugins/extract-ts/domain.ts +164 -0
  317. package/plugins/extract-ts/extract.test.ts +208 -0
  318. package/plugins/extract-ts/extract.ts +200 -0
  319. package/plugins/extract-ts/flows.ts +783 -0
  320. package/plugins/extract-ts/graphql.test.ts +73 -0
  321. package/plugins/extract-ts/graphql.ts +181 -0
  322. package/plugins/extract-ts/ids.test.ts +21 -0
  323. package/plugins/extract-ts/ids.ts +52 -0
  324. package/plugins/extract-ts/lifecycle.ts +138 -0
  325. package/plugins/extract-ts/main.ts +48 -0
  326. package/plugins/extract-ts/openapi.test.ts +64 -0
  327. package/plugins/extract-ts/openapi.ts +99 -0
  328. package/plugins/extract-ts/operations.ts +93 -0
  329. package/plugins/extract-ts/options.schema.json +96 -0
  330. package/plugins/extract-ts/source.test.ts +174 -0
  331. package/plugins/extract-ts/source.ts +465 -0
  332. package/plugins/extract-ts/transport.ts +147 -0
  333. package/plugins/extract-ts/tsconfig.json +13 -0
  334. package/plugins/extract-ts/wiring.ts +190 -0
  335. package/plugins/extract-watermill/describe.go +19 -0
  336. package/plugins/extract-watermill/describe_test.go +11 -0
  337. package/plugins/extract-watermill/extract.go +1228 -0
  338. package/plugins/extract-watermill/extract_test.go +234 -0
  339. package/plugins/extract-watermill/main.go +41 -0
  340. package/plugins/extract-watermill/options.schema.json +21 -0
  341. package/plugins/extract-wsdl/describe.go +19 -0
  342. package/plugins/extract-wsdl/describe_test.go +11 -0
  343. package/plugins/extract-wsdl/extract.go +148 -0
  344. package/plugins/extract-wsdl/extract_test.go +45 -0
  345. package/plugins/extract-wsdl/main.go +53 -0
  346. package/plugins/extract-wsdl/options.schema.json +59 -0
  347. package/plugins/fetch-bsr/auth.go +114 -0
  348. package/plugins/fetch-bsr/bsr.go +240 -0
  349. package/plugins/fetch-bsr/cache.go +66 -0
  350. package/plugins/fetch-bsr/describe.go +19 -0
  351. package/plugins/fetch-bsr/fetch.go +192 -0
  352. package/plugins/fetch-bsr/fetch_test.go +465 -0
  353. package/plugins/fetch-bsr/lock.go +71 -0
  354. package/plugins/fetch-bsr/main.go +117 -0
  355. package/plugins/fetch-bsr/options.schema.json +42 -0
  356. package/plugins/fetch-csr/auth.go +95 -0
  357. package/plugins/fetch-csr/cache.go +69 -0
  358. package/plugins/fetch-csr/describe.go +19 -0
  359. package/plugins/fetch-csr/describe_test.go +11 -0
  360. package/plugins/fetch-csr/fetch.go +254 -0
  361. package/plugins/fetch-csr/fetch_test.go +494 -0
  362. package/plugins/fetch-csr/lock.go +95 -0
  363. package/plugins/fetch-csr/main.go +122 -0
  364. package/plugins/fetch-csr/options.schema.json +42 -0
  365. package/plugins/fetch-csr/registry.go +209 -0
  366. package/plugins/fetch-git/cache.go +65 -0
  367. package/plugins/fetch-git/describe.go +19 -0
  368. package/plugins/fetch-git/describe_test.go +11 -0
  369. package/plugins/fetch-git/fetch.go +181 -0
  370. package/plugins/fetch-git/fetch_test.go +332 -0
  371. package/plugins/fetch-git/git.go +169 -0
  372. package/plugins/fetch-git/lock.go +72 -0
  373. package/plugins/fetch-git/main.go +127 -0
  374. package/plugins/fetch-git/offline.go +39 -0
  375. package/plugins/fetch-git/options.schema.json +42 -0
  376. package/plugins/fetch-git/pin.go +90 -0
  377. package/plugins/fetch-git/pin_test.go +74 -0
  378. package/plugins/gen-backstage/describe.go +17 -0
  379. package/plugins/gen-backstage/main.go +22 -0
  380. package/plugins/gen-backstage/options.schema.json +30 -0
  381. package/plugins/gen-backstage/plugin.go +473 -0
  382. package/plugins/gen-backstage/plugin_test.go +145 -0
  383. package/plugins/gen-backstage.wasm +0 -0
  384. package/plugins/gen-markdown/adr.go +162 -0
  385. package/plugins/gen-markdown/aggregate.go +362 -0
  386. package/plugins/gen-markdown/canonical.go +93 -0
  387. package/plugins/gen-markdown/context.go +90 -0
  388. package/plugins/gen-markdown/coverage_test.go +89 -0
  389. package/plugins/gen-markdown/describe.go +19 -0
  390. package/plugins/gen-markdown/describe_test.go +11 -0
  391. package/plugins/gen-markdown/external.go +71 -0
  392. package/plugins/gen-markdown/flow.go +277 -0
  393. package/plugins/gen-markdown/glossary.go +76 -0
  394. package/plugins/gen-markdown/glossary_test.go +148 -0
  395. package/plugins/gen-markdown/llms.go +302 -0
  396. package/plugins/gen-markdown/main.go +22 -0
  397. package/plugins/gen-markdown/markdown.go +254 -0
  398. package/plugins/gen-markdown/markdown_test.go +100 -0
  399. package/plugins/gen-markdown/module.go +107 -0
  400. package/plugins/gen-markdown/options.schema.json +16 -0
  401. package/plugins/gen-markdown/plugin.go +39 -0
  402. package/plugins/gen-markdown/quality_test.go +176 -0
  403. package/plugins/gen-markdown/redis_test.go +38 -0
  404. package/plugins/gen-markdown/render.go +344 -0
  405. package/plugins/gen-markdown/render_test.go +186 -0
  406. package/plugins/gen-markdown/service.go +456 -0
  407. package/plugins/gen-markdown/source.go +177 -0
  408. package/plugins/gen-markdown/store.go +201 -0
  409. package/plugins/gen-markdown.wasm +0 -0
  410. package/plugins/gen-mermaid/describe.go +17 -0
  411. package/plugins/gen-mermaid/main.go +22 -0
  412. package/plugins/gen-mermaid/options.schema.json +10 -0
  413. package/plugins/gen-mermaid/plugin.go +104 -0
  414. package/plugins/gen-mermaid/plugin_test.go +33 -0
  415. package/plugins/gen-mermaid.wasm +0 -0
  416. package/plugins/openapi/ids.go +261 -0
  417. package/plugins/openapi/ids_test.go +98 -0
  418. package/plugins/pyplugin/catalog.py +209 -0
  419. package/plugins/pyplugin/celery_conf.py +436 -0
  420. package/plugins/pyplugin/celery_tasks.py +76 -0
  421. package/plugins/pyplugin/kafka.py +570 -0
  422. package/plugins/pyplugin/names.py +38 -0
  423. package/plugins/pyplugin/protocol.py +79 -0
  424. package/plugins/pyplugin/source.py +285 -0
  425. package/plugins/verify-codeowners/describe.go +19 -0
  426. package/plugins/verify-codeowners/describe_test.go +11 -0
  427. package/plugins/verify-codeowners/main.go +75 -0
  428. package/plugins/verify-codeowners/match.go +85 -0
  429. package/plugins/verify-codeowners/match_test.go +47 -0
  430. package/plugins/verify-codeowners/options.schema.json +15 -0
  431. package/plugins/verify-codeowners/owners.go +164 -0
  432. package/plugins/verify-codeowners/owners_test.go +225 -0
  433. package/plugins/verify-codeowners/parse.go +90 -0
  434. package/plugins/verify-codeowners/parse_test.go +62 -0
  435. package/plugins/verify-otel/describe.go +19 -0
  436. package/plugins/verify-otel/describe_test.go +11 -0
  437. package/plugins/verify-otel/main.go +53 -0
  438. package/plugins/verify-otel/match.go +336 -0
  439. package/plugins/verify-otel/options.schema.json +30 -0
  440. package/plugins/verify-otel/otlp.go +200 -0
  441. package/plugins/verify-otel/verify.go +734 -0
  442. package/plugins/verify-otel/verify_test.go +460 -0
  443. package/portolan.json +1073 -0
  444. package/public/favicon.svg +12 -0
  445. package/schema/portolan.schema.json +2558 -0
  446. package/scripts/README.md +53 -0
  447. package/scripts/build-report.mjs +60 -0
  448. package/scripts/build-report.test.mjs +44 -0
  449. package/scripts/builtin-plugins.mjs +49 -0
  450. package/scripts/catalog-sources.mjs +67 -0
  451. package/scripts/diff.mjs +315 -0
  452. package/scripts/diff.test.mjs +151 -0
  453. package/scripts/forge-comment.mjs +144 -0
  454. package/scripts/forge-comment.test.mjs +151 -0
  455. package/scripts/forge-release.mjs +138 -0
  456. package/scripts/forge-release.test.mjs +106 -0
  457. package/scripts/forge.mjs +61 -0
  458. package/scripts/gen-likec4.mjs +854 -0
  459. package/scripts/gen-likec4.test.mjs +258 -0
  460. package/scripts/gen.mjs +603 -0
  461. package/scripts/generated-docs.test.mjs +66 -0
  462. package/scripts/local-api.mjs +1192 -0
  463. package/scripts/local-api.test.mjs +387 -0
  464. package/scripts/manifest.mjs +214 -0
  465. package/scripts/manifest.test.mjs +148 -0
  466. package/scripts/output-path.mjs +79 -0
  467. package/scripts/output-path.test.mjs +45 -0
  468. package/scripts/package-smoke.mjs +37 -0
  469. package/scripts/plugin-host.mjs +419 -0
  470. package/scripts/plugin-host.test.mjs +109 -0
  471. package/scripts/plugin-wasm-worker.mjs +34 -0
  472. package/scripts/run-builtin.mjs +81 -0
  473. package/scripts/schema.mjs +357 -0
  474. package/scripts/site-docs.mjs +295 -0
  475. package/scripts/site-docs.test.mjs +181 -0
  476. package/scripts/vendor-lock.mjs +58 -0
  477. package/scripts/vendor-lock.test.mjs +69 -0
  478. package/src/README.md +38 -0
  479. package/src/app/App.tsx +448 -0
  480. package/src/app/BranchPicker.test.ts +46 -0
  481. package/src/app/BranchPicker.tsx +153 -0
  482. package/src/app/Breadcrumbs.test.ts +38 -0
  483. package/src/app/Breadcrumbs.tsx +223 -0
  484. package/src/app/BuildStamp.tsx +146 -0
  485. package/src/app/CommandPalette.tsx +292 -0
  486. package/src/app/HashScroll.tsx +45 -0
  487. package/src/app/Sidebar.tsx +1742 -0
  488. package/src/app/TopBar.tsx +393 -0
  489. package/src/app/density.tsx +64 -0
  490. package/src/app/forge-access.test.ts +27 -0
  491. package/src/app/forge-access.tsx +80 -0
  492. package/src/app/panels.tsx +141 -0
  493. package/src/app/pins.tsx +242 -0
  494. package/src/app/query-client.ts +24 -0
  495. package/src/app/responsive.ts +55 -0
  496. package/src/app/shortcuts.test.ts +39 -0
  497. package/src/app/shortcuts.tsx +282 -0
  498. package/src/app/theme.tsx +51 -0
  499. package/src/app/title.test.ts +14 -0
  500. package/src/app/title.ts +30 -0
  501. package/src/app/toast.tsx +59 -0
  502. package/src/app/tree-keys.test.ts +80 -0
  503. package/src/app/tree-keys.ts +87 -0
  504. package/src/app/ui-store.ts +52 -0
  505. package/src/catalog-error.test.ts +105 -0
  506. package/src/catalog-profile.test.ts +59 -0
  507. package/src/catalog-profile.ts +101 -0
  508. package/src/catalog-stores.test.ts +431 -0
  509. package/src/catalog.test.ts +1215 -0
  510. package/src/catalog.ts +3125 -0
  511. package/src/chat/Cards.tsx +408 -0
  512. package/src/chat/ChatPanel.tsx +79 -0
  513. package/src/chat/ChatSettings.tsx +219 -0
  514. package/src/chat/Composer.tsx +99 -0
  515. package/src/chat/Conversation.tsx +281 -0
  516. package/src/chat/Header.tsx +46 -0
  517. package/src/chat/Message.tsx +49 -0
  518. package/src/chat/Notice.tsx +195 -0
  519. package/src/chat/Starter.tsx +67 -0
  520. package/src/chat/Steps.tsx +45 -0
  521. package/src/chat/Waiting.tsx +87 -0
  522. package/src/chat/flags.test.ts +59 -0
  523. package/src/chat/flags.ts +155 -0
  524. package/src/chat/linkify.test.ts +30 -0
  525. package/src/chat/linkify.ts +45 -0
  526. package/src/chat/prefs.ts +56 -0
  527. package/src/chat/prompt.test.ts +43 -0
  528. package/src/chat/prompt.ts +157 -0
  529. package/src/chat/store.ts +35 -0
  530. package/src/chat/tools.ts +58 -0
  531. package/src/chat/transport.ts +70 -0
  532. package/src/components/AdrRow.tsx +29 -0
  533. package/src/components/AnchorLink.tsx +67 -0
  534. package/src/components/ApiReference.tsx +134 -0
  535. package/src/components/AsyncApiReference.tsx +120 -0
  536. package/src/components/CatalogStamp.tsx +155 -0
  537. package/src/components/ChannelRows.tsx +132 -0
  538. package/src/components/CommandRows.tsx +139 -0
  539. package/src/components/DiagramSkeleton.tsx +71 -0
  540. package/src/components/EditorLink.tsx +85 -0
  541. package/src/components/FieldTree.tsx +305 -0
  542. package/src/components/FlowTrigger.tsx +34 -0
  543. package/src/components/Ident.tsx +89 -0
  544. package/src/components/Integrations.tsx +243 -0
  545. package/src/components/LifecycleDiagram.tsx +110 -0
  546. package/src/components/MachineDocs.tsx +42 -0
  547. package/src/components/Markdown.tsx +173 -0
  548. package/src/components/MarkdownTable.tsx +206 -0
  549. package/src/components/Mermaid.tsx +211 -0
  550. package/src/components/MethodRows.tsx +309 -0
  551. package/src/components/Overlay.tsx +125 -0
  552. package/src/components/PageHeader.tsx +189 -0
  553. package/src/components/RowActions.tsx +97 -0
  554. package/src/components/SchemaDocument.tsx +89 -0
  555. package/src/components/Select.tsx +126 -0
  556. package/src/components/ShapeRows.tsx +118 -0
  557. package/src/components/SourceDoc.tsx +82 -0
  558. package/src/components/SourcePreview.tsx +441 -0
  559. package/src/components/TabRow.tsx +182 -0
  560. package/src/components/TechIcon.tsx +34 -0
  561. package/src/components/Toc.tsx +132 -0
  562. package/src/components/WhatLinksHere.tsx +273 -0
  563. package/src/components/WsdlReference.tsx +84 -0
  564. package/src/components/ddd-icons.tsx +107 -0
  565. package/src/components/kind.tsx +157 -0
  566. package/src/components/logo.tsx +61 -0
  567. package/src/components/primitives.tsx +264 -0
  568. package/src/data.test.ts +18 -0
  569. package/src/data.ts +202 -0
  570. package/src/enrich.test.ts +1150 -0
  571. package/src/enrich.ts +672 -0
  572. package/src/er/ErCanvas.tsx +533 -0
  573. package/src/er/RedisSchema.tsx +74 -0
  574. package/src/er/RelationCard.tsx +267 -0
  575. package/src/er/StoreHeader.tsx +155 -0
  576. package/src/er/TableNode.tsx +84 -0
  577. package/src/er/ViewNode.tsx +83 -0
  578. package/src/er/layout.test.ts +115 -0
  579. package/src/er/layout.ts +77 -0
  580. package/src/er/lineage.test.ts +140 -0
  581. package/src/er/lineage.ts +107 -0
  582. package/src/er/markers.tsx +79 -0
  583. package/src/er/spec.test.ts +344 -0
  584. package/src/er/spec.ts +426 -0
  585. package/src/flow/ChainList.tsx +162 -0
  586. package/src/flow/FlowTable.tsx +123 -0
  587. package/src/flow/FlowToolbar.tsx +372 -0
  588. package/src/flow/StepDetail.tsx +380 -0
  589. package/src/flow/StepRail.tsx +428 -0
  590. package/src/flow/answers.test.ts +50 -0
  591. package/src/flow/answers.ts +58 -0
  592. package/src/flow/chain.test.ts +383 -0
  593. package/src/flow/chain.ts +353 -0
  594. package/src/flow/chapters.test.ts +185 -0
  595. package/src/flow/chapters.ts +225 -0
  596. package/src/flow/continues.test.ts +102 -0
  597. package/src/flow/continues.ts +65 -0
  598. package/src/flow/cross-context.test.ts +97 -0
  599. package/src/flow/cross-context.ts +35 -0
  600. package/src/flow/mermaid.test.ts +22 -0
  601. package/src/flow/mermaid.ts +141 -0
  602. package/src/flow/outline.test.ts +212 -0
  603. package/src/flow/outline.ts +170 -0
  604. package/src/flow/paths.test.ts +129 -0
  605. package/src/flow/paths.ts +147 -0
  606. package/src/flow/prefs.test.ts +80 -0
  607. package/src/flow/prefs.ts +104 -0
  608. package/src/graph/DependencyGraph.tsx +283 -0
  609. package/src/graph/DependencyNodes.tsx +162 -0
  610. package/src/graph/EdgeLabel.tsx +61 -0
  611. package/src/graph/FocusedEventGraph.tsx +211 -0
  612. package/src/graph/GraphToolbar.tsx +187 -0
  613. package/src/graph/RoutedEdge.tsx +80 -0
  614. package/src/graph/dependency-layout.test.ts +360 -0
  615. package/src/graph/dependency-layout.ts +444 -0
  616. package/src/graph/elk.test.ts +70 -0
  617. package/src/graph/elk.ts +287 -0
  618. package/src/graph/nodes.tsx +97 -0
  619. package/src/graph/theme.ts +81 -0
  620. package/src/graph/useElkFlow.ts +125 -0
  621. package/src/index.css +1547 -0
  622. package/src/language/InLanguage.tsx +40 -0
  623. package/src/language/TermCard.tsx +132 -0
  624. package/src/language/cards.test.ts +114 -0
  625. package/src/language/cards.ts +111 -0
  626. package/src/lib/admonition.test.ts +49 -0
  627. package/src/lib/admonition.ts +48 -0
  628. package/src/lib/adr.test.ts +131 -0
  629. package/src/lib/adr.ts +68 -0
  630. package/src/lib/api.test.ts +122 -0
  631. package/src/lib/api.ts +135 -0
  632. package/src/lib/backlinks.test.ts +330 -0
  633. package/src/lib/backlinks.ts +567 -0
  634. package/src/lib/branch-compare.ts +16 -0
  635. package/src/lib/build-info.test.ts +76 -0
  636. package/src/lib/build-info.ts +80 -0
  637. package/src/lib/catalog-diff.test.ts +275 -0
  638. package/src/lib/catalog-diff.ts +655 -0
  639. package/src/lib/clipboard.ts +43 -0
  640. package/src/lib/comparison-memory.test.ts +40 -0
  641. package/src/lib/comparison-memory.ts +39 -0
  642. package/src/lib/context-color.ts +27 -0
  643. package/src/lib/context-map.test.ts +148 -0
  644. package/src/lib/context-map.ts +399 -0
  645. package/src/lib/data-model.test.ts +245 -0
  646. package/src/lib/data-model.ts +399 -0
  647. package/src/lib/data-problems.test.ts +178 -0
  648. package/src/lib/data-problems.ts +314 -0
  649. package/src/lib/derive.test.ts +251 -0
  650. package/src/lib/derive.ts +515 -0
  651. package/src/lib/editor-link.test.ts +125 -0
  652. package/src/lib/editor-link.ts +96 -0
  653. package/src/lib/editor-prefs.ts +27 -0
  654. package/src/lib/event-graph.test.ts +237 -0
  655. package/src/lib/event-graph.ts +327 -0
  656. package/src/lib/export-canvas.ts +37 -0
  657. package/src/lib/export-file.test.ts +30 -0
  658. package/src/lib/export-file.ts +20 -0
  659. package/src/lib/flow-tree.test.ts +177 -0
  660. package/src/lib/flow-tree.ts +160 -0
  661. package/src/lib/forge-refs.test.ts +50 -0
  662. package/src/lib/forge-refs.ts +60 -0
  663. package/src/lib/format.test.ts +35 -0
  664. package/src/lib/format.ts +64 -0
  665. package/src/lib/github-catalog.test.ts +301 -0
  666. package/src/lib/github-catalog.ts +610 -0
  667. package/src/lib/integrations.test.ts +119 -0
  668. package/src/lib/integrations.ts +133 -0
  669. package/src/lib/kinds.test.ts +91 -0
  670. package/src/lib/kinds.ts +204 -0
  671. package/src/lib/lifecycle.test.ts +93 -0
  672. package/src/lib/lifecycle.ts +165 -0
  673. package/src/lib/local-api.ts +194 -0
  674. package/src/lib/motion-features.ts +11 -0
  675. package/src/lib/motion.test.ts +120 -0
  676. package/src/lib/motion.tsx +269 -0
  677. package/src/lib/palette-recent.test.ts +80 -0
  678. package/src/lib/palette-recent.ts +90 -0
  679. package/src/lib/palette.test.ts +365 -0
  680. package/src/lib/palette.ts +593 -0
  681. package/src/lib/pins.test.ts +139 -0
  682. package/src/lib/pins.ts +130 -0
  683. package/src/lib/problems.test.ts +112 -0
  684. package/src/lib/project-preview.ts +5 -0
  685. package/src/lib/proto-problems.test.ts +121 -0
  686. package/src/lib/proto-problems.ts +65 -0
  687. package/src/lib/queries.test.ts +113 -0
  688. package/src/lib/queries.ts +131 -0
  689. package/src/lib/registry.test.ts +219 -0
  690. package/src/lib/registry.ts +208 -0
  691. package/src/lib/scenarios.ts +547 -0
  692. package/src/lib/setup-info.test.ts +199 -0
  693. package/src/lib/setup-info.ts +415 -0
  694. package/src/lib/shape.test.ts +289 -0
  695. package/src/lib/shape.ts +454 -0
  696. package/src/lib/sidebar-prefs.test.ts +32 -0
  697. package/src/lib/sidebar-prefs.ts +75 -0
  698. package/src/lib/source-code.test.ts +159 -0
  699. package/src/lib/source-code.ts +286 -0
  700. package/src/lib/source-doc.test.ts +131 -0
  701. package/src/lib/source-doc.ts +103 -0
  702. package/src/lib/source-highlight.test.ts +29 -0
  703. package/src/lib/source-highlight.ts +24 -0
  704. package/src/lib/source-link.test.ts +153 -0
  705. package/src/lib/source-link.ts +201 -0
  706. package/src/lib/spec-files.test.ts +24 -0
  707. package/src/lib/spec-files.ts +23 -0
  708. package/src/lib/table-directive.test.ts +139 -0
  709. package/src/lib/table-directive.ts +106 -0
  710. package/src/lib/tech.test.ts +120 -0
  711. package/src/lib/tech.ts +421 -0
  712. package/src/lib/terms.test.ts +67 -0
  713. package/src/lib/terms.ts +179 -0
  714. package/src/lib/wire-problems.test.ts +263 -0
  715. package/src/lib/wire-problems.ts +281 -0
  716. package/src/likec4/C4View.tsx +55 -0
  717. package/src/likec4/CanvasBridge.tsx +187 -0
  718. package/src/likec4/FlowView.tsx +235 -0
  719. package/src/likec4/InteractiveView.tsx +144 -0
  720. package/src/likec4/canvas-viewport.test.ts +149 -0
  721. package/src/likec4/canvas-viewport.ts +135 -0
  722. package/src/likec4/flow-edges.test.ts +51 -0
  723. package/src/likec4/flow-edges.ts +89 -0
  724. package/src/likec4/frame-theme.test.ts +76 -0
  725. package/src/likec4/frame-theme.ts +101 -0
  726. package/src/likec4/highlight-css.test.ts +49 -0
  727. package/src/likec4/highlight-css.ts +52 -0
  728. package/src/likec4/ids.test.ts +151 -0
  729. package/src/likec4/ids.ts +115 -0
  730. package/src/likec4/levels.tsx +70 -0
  731. package/src/likec4/mapping.test.ts +66 -0
  732. package/src/likec4/mapping.ts +54 -0
  733. package/src/likec4/reserved.json +141 -0
  734. package/src/likec4/view-index.ts +78 -0
  735. package/src/main.tsx +13 -0
  736. package/src/map/ContextMapGraph.tsx +274 -0
  737. package/src/map/ContextNode.tsx +70 -0
  738. package/src/map/FloatingEdge.tsx +86 -0
  739. package/src/merge.test.ts +1038 -0
  740. package/src/merge.ts +1004 -0
  741. package/src/pages/AdrDetail.tsx +242 -0
  742. package/src/pages/AdrIndex.tsx +114 -0
  743. package/src/pages/AggregatePage.tsx +727 -0
  744. package/src/pages/BlockPage.tsx +478 -0
  745. package/src/pages/CatalogFailure.tsx +111 -0
  746. package/src/pages/Changes.tsx +313 -0
  747. package/src/pages/ContextMap.tsx +534 -0
  748. package/src/pages/ContextPage.tsx +346 -0
  749. package/src/pages/EnumPage.tsx +282 -0
  750. package/src/pages/EventPage.tsx +686 -0
  751. package/src/pages/ExternalPage.tsx +204 -0
  752. package/src/pages/FlowDetail.tsx +663 -0
  753. package/src/pages/FlowIndex.tsx +303 -0
  754. package/src/pages/GraphPage.tsx +217 -0
  755. package/src/pages/Language.tsx +257 -0
  756. package/src/pages/ModulePage.tsx +366 -0
  757. package/src/pages/NotFound.tsx +54 -0
  758. package/src/pages/Overview.tsx +344 -0
  759. package/src/pages/Problems.tsx +360 -0
  760. package/src/pages/RegistryIndex.tsx +118 -0
  761. package/src/pages/ServicePage.tsx +746 -0
  762. package/src/pages/Settings.tsx +975 -0
  763. package/src/pages/StorePage.tsx +114 -0
  764. package/src/peek/PeekCard.test.ts +35 -0
  765. package/src/peek/PeekCard.tsx +118 -0
  766. package/src/peek/PeekLayer.tsx +147 -0
  767. package/src/peek/model.test.ts +156 -0
  768. package/src/peek/model.ts +253 -0
  769. package/src/routes.test.ts +222 -0
  770. package/src/routes.ts +449 -0
  771. package/src/selection/DetailPanel.tsx +1407 -0
  772. package/src/selection/hash.test.ts +73 -0
  773. package/src/selection/hash.ts +58 -0
  774. package/src/selection/model.test.ts +199 -0
  775. package/src/selection/model.ts +473 -0
  776. package/src/selection/pages.test.ts +115 -0
  777. package/src/selection/pages.ts +268 -0
  778. package/src/selection/store.test.ts +62 -0
  779. package/src/selection/store.ts +46 -0
  780. package/src/selection/sync.tsx +99 -0
  781. package/src/table/ColumnsMenu.tsx +72 -0
  782. package/src/table/DataTable.tsx +780 -0
  783. package/src/table/Facets.tsx +54 -0
  784. package/src/table/GroupMenu.tsx +69 -0
  785. package/src/table/Toolbar.tsx +190 -0
  786. package/src/table/cells.tsx +117 -0
  787. package/src/table/compare.test.ts +117 -0
  788. package/src/table/compare.ts +196 -0
  789. package/src/table/export.test.ts +88 -0
  790. package/src/table/export.ts +66 -0
  791. package/src/table/facet-groups.test.ts +74 -0
  792. package/src/table/facet-groups.ts +56 -0
  793. package/src/table/grouping.test.ts +84 -0
  794. package/src/table/grouping.ts +82 -0
  795. package/src/table/infer.test.ts +57 -0
  796. package/src/table/infer.ts +50 -0
  797. package/src/table/persist.test.ts +76 -0
  798. package/src/table/persist.ts +112 -0
  799. package/src/table/sort-url.test.ts +75 -0
  800. package/src/table/sort-url.ts +52 -0
  801. package/src/table/types.ts +80 -0
  802. package/src/table/useTableState.ts +220 -0
  803. package/src/test-catalog.ts +7 -0
  804. package/src/testing/estate/data__catalog.json +2847 -0
  805. package/src/testing/estate/data__flows.json +1724 -0
  806. package/src/testing/estate/examples__auth__portolan__api.json +212 -0
  807. package/src/testing/estate/examples__auth__portolan__domain.json +1204 -0
  808. package/src/testing/estate/examples__auth__portolan__glossary.json +226 -0
  809. package/src/testing/estate/examples__auth__portolan__observed.json +757 -0
  810. package/src/testing/estate/examples__auth__portolan__stores.json +195 -0
  811. package/src/testing/estate/examples__shop__cart__portolan__api.json +234 -0
  812. package/src/testing/estate/examples__shop__cart__portolan__commands.json +86 -0
  813. package/src/testing/estate/examples__shop__cart__portolan__domain.json +966 -0
  814. package/src/testing/estate/examples__shop__cart__portolan__observed.json +498 -0
  815. package/src/testing/estate/examples__shop__cart__portolan__stores.json +208 -0
  816. package/src/testing/estate/examples__shop__oms__portolan__glossary.json +98 -0
  817. package/src/testing/estate/examples__shop__oms__portolan__proto.json +186 -0
  818. package/src/testing/estate.ts +49 -0
  819. package/src/trail/Trail.tsx +81 -0
  820. package/src/trail/model.test.ts +157 -0
  821. package/src/trail/model.ts +189 -0
  822. package/src/trail/record.tsx +32 -0
  823. package/src/trail/store.test.ts +66 -0
  824. package/src/trail/store.ts +102 -0
  825. package/tsconfig.json +35 -0
  826. package/vite.config.ts +171 -0
@@ -0,0 +1,34 @@
1
+ // A brand's mark, drawn so it sits in a row with lucide.
2
+ //
3
+ // simple-icons fills its 24x24 box edge to edge; lucide leaves a 2px margin
4
+ // inside its own. Shown at the same pixel size the brand mark would read a
5
+ // step heavier than the database glyph beside it, so the viewBox is opened by
6
+ // two units on every side and the two families weigh the same.
7
+
8
+ import type { TechGlyph } from "../lib/tech";
9
+
10
+ export function TechIcon({
11
+ glyph,
12
+ size = 14,
13
+ className = "",
14
+ }: {
15
+ glyph: TechGlyph;
16
+ size?: number;
17
+ className?: string;
18
+ }) {
19
+ return (
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ width={size}
23
+ height={size}
24
+ viewBox="-2 -2 28 28"
25
+ fill="currentColor"
26
+ aria-hidden
27
+ /* `block` for the same reason KindIcon is: no inline baseline gap, so
28
+ the mark centres on the text beside it. */
29
+ className={`block shrink-0 ${className}`}
30
+ >
31
+ <path d={glyph.path} />
32
+ </svg>
33
+ );
34
+ }
@@ -0,0 +1,132 @@
1
+ // The right-edge table of contents, with scroll-spy.
2
+ //
3
+ // It began as the readme outline on the aggregate page and is now the one
4
+ // component every long page uses, because two implementations of "where am I"
5
+ // is exactly how the two start disagreeing.
6
+ //
7
+ // It costs 24px of the page, not 208.
8
+ //
9
+ // At rest it is a column of ticks - one per section, the one you are in lit -
10
+ // which is the whole of what a table of contents is for while you are reading:
11
+ // how many sections, and which. The names are what you want only when you have
12
+ // decided to leave, so they arrive on hover or focus, in a panel that opens
13
+ // leftwards OVER the page rather than pushing it. Nothing reflows: the dock
14
+ // keeps its 24px whether the panel is open or not.
15
+ //
16
+ // Spy notes: the observer's root is the page's own scroll container, not the
17
+ // window - this shell never scrolls the document - and the bottom margin is
18
+ // pulled up to 65% so a section counts as "here" once its heading reaches the
19
+ // upper third, which is where a reader actually thinks they are.
20
+
21
+ import { useEffect, useMemo, useState } from "react";
22
+
23
+ export interface TocItem {
24
+ /** The id of the element on the page. */
25
+ id: string;
26
+ label: string;
27
+ /** 1 is flush left; each level indents 10px. */
28
+ depth?: number;
29
+ }
30
+
31
+ /** Nearest scrollable ancestor, or null when the page scrolls in the window. */
32
+ function scrollParent(el: Element | null): Element | null {
33
+ let node = el?.parentElement ?? null;
34
+ while (node) {
35
+ const overflow = getComputedStyle(node).overflowY;
36
+ if (overflow === "auto" || overflow === "scroll") return node;
37
+ node = node.parentElement;
38
+ }
39
+ return null;
40
+ }
41
+
42
+ export function useScrollSpy(ids: readonly string[]): string | null {
43
+ const [active, setActive] = useState<string | null>(ids[0] ?? null);
44
+ const key = ids.join(" ");
45
+
46
+ useEffect(() => {
47
+ const list = key ? key.split(" ") : [];
48
+ const elements = list
49
+ .map((id) => document.getElementById(id))
50
+ .filter((el): el is HTMLElement => el !== null);
51
+ if (elements.length === 0) return;
52
+
53
+ const seen = new Set<string>();
54
+ const observer = new IntersectionObserver(
55
+ (entries) => {
56
+ for (const entry of entries) {
57
+ if (entry.isIntersecting) seen.add(entry.target.id);
58
+ else seen.delete(entry.target.id);
59
+ }
60
+ // First in document order wins, so scrolling down moves the marker
61
+ // down one section at a time rather than jumping to whatever fired.
62
+ const first = list.find((id) => seen.has(id));
63
+ // Nothing intersecting means the reader is between two sections;
64
+ // holding the last answer beats blanking the rail.
65
+ if (first) setActive(first);
66
+ },
67
+ {
68
+ root: scrollParent(elements[0] ?? null),
69
+ rootMargin: "0px 0px -65% 0px",
70
+ threshold: 0,
71
+ },
72
+ );
73
+ for (const el of elements) observer.observe(el);
74
+ return () => observer.disconnect();
75
+ }, [key]);
76
+
77
+ return active;
78
+ }
79
+
80
+ export function Toc({
81
+ items,
82
+ label = "On this page",
83
+ title = "On this page",
84
+ }: {
85
+ items: readonly TocItem[];
86
+ /** Accessible name for the nav landmark. */
87
+ label?: string;
88
+ /** The heading printed above the list, once the panel is open. */
89
+ title?: string;
90
+ }) {
91
+ const ids = useMemo(() => items.map((i) => i.id), [items]);
92
+ const active = useScrollSpy(ids);
93
+
94
+ if (items.length === 0) return null;
95
+
96
+ return (
97
+ <nav
98
+ /* Hidden below the two-column breakpoint, where the page has no right
99
+ edge to spare at all. */
100
+ className="toc-dock sticky hidden h-fit shrink-0 self-start lg:block"
101
+ aria-label={label}
102
+ >
103
+ <div className="toc-panel">
104
+ <div className="label toc-name mb-1 px-3 pt-1">{title}</div>
105
+ <ul>
106
+ {items.map((item) => {
107
+ const on = item.id === active;
108
+ return (
109
+ <li key={item.id}>
110
+ <a
111
+ href={`#${item.id}`}
112
+ aria-current={on ? "location" : undefined}
113
+ /* The tick is the marker AND the hairline: 2px, always
114
+ drawn, transparent when idle, so nothing shifts as the
115
+ spy moves down the page. */
116
+ className={`toc-item ${on ? "text-ink" : "text-muted"}`}
117
+ style={{
118
+ borderColor: on ? "var(--accent)" : "var(--border)",
119
+ marginLeft: ((item.depth ?? 1) - 1) * 10,
120
+ }}
121
+ title={item.label}
122
+ >
123
+ <span className="toc-name">{item.label}</span>
124
+ </a>
125
+ </li>
126
+ );
127
+ })}
128
+ </ul>
129
+ </div>
130
+ </nav>
131
+ );
132
+ }
@@ -0,0 +1,273 @@
1
+ // The incoming half of the graph, drawn the same way on every entity page.
2
+ //
3
+ // A page's own body says what a thing depends on. This says what depends on
4
+ // it — the question a reader actually arrives with, and the one no single
5
+ // entity can answer about itself. It sits last on every page and answers under
6
+ // the same heading, at the same anchor, in the same row shape, so "who breaks
7
+ // if I change this" is one place to look rather than five different ones.
8
+ //
9
+ // Every row says WHY it is here. A name with no reason attached would send the
10
+ // reader to open the page just to find out, which is the trip this section
11
+ // exists to save.
12
+
13
+ import { useMemo } from "react";
14
+ import type { ReactNode } from "react";
15
+ import { Link } from "react-router";
16
+ import { catalog, index } from "../data";
17
+ import { backlinkCount, backlinksFor } from "../lib/backlinks";
18
+ import type { Backlink, BacklinkGroup, BacklinkTarget } from "../lib/backlinks";
19
+ import { plural } from "../lib/format";
20
+ import { KIND_LABEL, KIND_PLURAL } from "../lib/kinds";
21
+ import type { Kind } from "../lib/kinds";
22
+ import { LINKS_HERE, backlinkPath } from "../routes";
23
+ import { KIND_COLOR, KindIcon } from "./kind";
24
+ import { Empty, SectionTitle } from "./PageHeader";
25
+ import { RowActions } from "./RowActions";
26
+ import { StatusChip } from "./primitives";
27
+
28
+ /** A section on this same page that already lists one kind of link, in full. */
29
+ export interface Elsewhere {
30
+ /** Where it is: a fragment, or a tab's query string. */
31
+ href: string;
32
+ /** What it is called there, so the pointer names the thing it points at. */
33
+ label: string;
34
+ }
35
+
36
+ /** Kinds the tree draws a row for, and so the ones "reveal" can find. */
37
+ const REVEALABLE: readonly Kind[] = [
38
+ "context",
39
+ "service",
40
+ "aggregate",
41
+ "event",
42
+ ] as const;
43
+
44
+ /**
45
+ * The same answer this section draws, for a page that also wants to count it
46
+ * in its header. Derived twice rather than threaded through props, because it
47
+ * is a pure walk over a catalog that does not change while the page is open.
48
+ */
49
+ export function useBacklinks(target: BacklinkTarget): BacklinkGroup[] {
50
+ return useMemo(
51
+ () => backlinksFor(catalog, index, target),
52
+ [target.kind, target.id],
53
+ );
54
+ }
55
+
56
+ function Row({ link }: { link: Backlink }) {
57
+ const to = backlinkPath(link);
58
+ // What a reader takes to a grep: the flow's slug is not enough to find the
59
+ // step inside it, so a link that points through one carries both.
60
+ const id = link.at ? `${link.id}/${link.at}` : link.id;
61
+ const reveal = to && REVEALABLE.includes(link.kind) ? link.id : undefined;
62
+ return (
63
+ /* A div holding a link, not a link holding buttons: the row actions are
64
+ interactive too, and interactive content does not nest. */
65
+ <div className="row gap-2">
66
+ <KindIcon kind={link.kind} contextId={link.context ?? undefined} />
67
+ {to ? (
68
+ /* Only events are painted by kind. Everything else keeps the ink of a
69
+ link in a row, because eight muted names in a column would read as
70
+ eight pieces of text rather than eight places to go. */
71
+ <Link
72
+ to={to}
73
+ data-nav-item
74
+ data-peek={link.id}
75
+ className="mono shrink-0 rounded-control"
76
+ style={
77
+ link.kind === "event" ? { color: KIND_COLOR.event } : undefined
78
+ }
79
+ title={id}
80
+ >
81
+ {link.name}
82
+ </Link>
83
+ ) : (
84
+ <span
85
+ className={`mono shrink-0 ${
86
+ link.status === "unresolved" ? "text-unresolved" : "text-muted"
87
+ }`}
88
+ title={id}
89
+ >
90
+ {link.name}
91
+ </span>
92
+ )}
93
+ {/* One cell per column, empty ones included: the rows share a subgrid,
94
+ and a row that skips a field would slide every field after it into
95
+ the wrong column. */}
96
+ {link.owner ? (
97
+ <span className="min-w-0 truncate text-muted" title={link.owner}>
98
+ {link.owner}
99
+ </span>
100
+ ) : (
101
+ <span />
102
+ )}
103
+ <span className="mono shrink-0 text-muted" title="how it points here">
104
+ {link.via}
105
+ </span>
106
+ {link.versions && link.versions.length > 0 ? (
107
+ <span
108
+ className="mono justify-self-start rounded-[4px] border px-1 border-line text-muted"
109
+ title="event versions carrying it"
110
+ >
111
+ {link.versions.join(" ")}
112
+ </span>
113
+ ) : (
114
+ <span />
115
+ )}
116
+ {link.status ? <StatusChip status={link.status} /> : <span />}
117
+ <RowActions copy={id} {...(reveal ? { reveal } : {})} label={link.name} />
118
+ </div>
119
+ );
120
+ }
121
+
122
+ export function WhatLinksHere({
123
+ target,
124
+ variant = "section",
125
+ className = "",
126
+ elsewhere,
127
+ empty,
128
+ }: {
129
+ target: BacklinkTarget;
130
+ /** `line` only: what the row it is folded into wants of its spacing. */
131
+ className?: string;
132
+ /**
133
+ * `section` is the block every scrolling page ends with. `line` is the same
134
+ * facts as one row of chips, for a page with no bottom to put a section on -
135
+ * the flow, whose rail and canvas take the whole height.
136
+ */
137
+ variant?: "section" | "line";
138
+ /**
139
+ * Kinds this page already lists in a section of their own, mapped to where
140
+ * that section is. Those rows are not repeated here; the count and a pointer
141
+ * to them are, so the whole answer is still readable in one place.
142
+ */
143
+ elsewhere?: Partial<Record<Kind, Elsewhere>>;
144
+ /** What to say when nothing points here, when the reason is worth saying. */
145
+ empty?: ReactNode;
146
+ }) {
147
+ const groups = useBacklinks(target);
148
+
149
+ const total = backlinkCount(groups);
150
+ const shown = groups.filter((g) => !elsewhere?.[g.kind]);
151
+ const pointers = groups
152
+ .map((g) => ({ group: g, at: elsewhere?.[g.kind] }))
153
+ .filter((p): p is { group: (typeof groups)[number]; at: Elsewhere } =>
154
+ Boolean(p.at),
155
+ );
156
+
157
+ if (variant === "line") {
158
+ // Nothing to say, so nothing is said: a hero row is not the place for an
159
+ // empty state, and "linked from —" is worse than silence.
160
+ if (total === 0) return null;
161
+ return (
162
+ <span
163
+ className={`mono flex flex-wrap items-center gap-1.5 text-muted ${className || "mt-2"}`}
164
+ >
165
+ linked from
166
+ {groups
167
+ .flatMap((g) => g.links)
168
+ .map((link) => {
169
+ const to = backlinkPath(link);
170
+ const body = (
171
+ <>
172
+ <KindIcon
173
+ kind={link.kind}
174
+ contextId={link.context ?? undefined}
175
+ />
176
+ {link.name}
177
+ </>
178
+ );
179
+ const title = `${link.owner ?? link.id} — ${link.via}`;
180
+ return to ? (
181
+ <Link
182
+ key={`${link.kind}:${link.id}:${link.name}`}
183
+ to={to}
184
+ data-peek={link.id}
185
+ className="chip border-line-strong hover:text-ink"
186
+ title={title}
187
+ >
188
+ {body}
189
+ </Link>
190
+ ) : (
191
+ <span
192
+ key={`${link.kind}:${link.id}:${link.name}`}
193
+ className="chip border-line"
194
+ title={title}
195
+ >
196
+ {body}
197
+ </span>
198
+ );
199
+ })}
200
+ </span>
201
+ );
202
+ }
203
+
204
+ return (
205
+ <section id={LINKS_HERE} className="mt-section max-w-table">
206
+ <SectionTitle
207
+ anchor={LINKS_HERE}
208
+ right={
209
+ <span>
210
+ <span className="tnum">{total}</span> incoming
211
+ </span>
212
+ }
213
+ >
214
+ What links here
215
+ </SectionTitle>
216
+
217
+ {total === 0 ? (
218
+ <Empty>{empty ?? "nothing in the catalog points here"}</Empty>
219
+ ) : null}
220
+
221
+ {shown.map((group) => (
222
+ <div key={group.kind} className="mt-3 first:mt-0">
223
+ <div className="label mb-1.5">
224
+ {KIND_PLURAL[group.kind]}{" "}
225
+ <span className="tnum">{group.links.length}</span>
226
+ </div>
227
+ {/* icon, name, owner, why it points here, the versions carrying
228
+ it, status, actions. The owner takes the slack, so the reason
229
+ and everything after it hold the same column down the group. */}
230
+ <div
231
+ className="rows grid-cols-[auto_auto_1fr_auto_auto_auto_auto]"
232
+ data-nav-list
233
+ >
234
+ {group.links.map((link, i) => (
235
+ <Row
236
+ key={`${link.kind}:${link.id}:${link.at ?? i}`}
237
+ link={link}
238
+ />
239
+ ))}
240
+ </div>
241
+ </div>
242
+ ))}
243
+
244
+ {pointers.map(({ group, at }) => {
245
+ const body = (
246
+ <>
247
+ <KindIcon kind={group.kind} />
248
+ <span className="tnum">{group.links.length}</span>
249
+ {plural(
250
+ group.links.length,
251
+ KIND_LABEL[group.kind],
252
+ KIND_PLURAL[group.kind],
253
+ )}
254
+ <span className="ml-auto">listed under {at.label}</span>
255
+ </>
256
+ );
257
+ const className = "row mono mt-3 gap-2 text-muted hover:text-ink";
258
+ // A section on this page is a fragment and the browser can jump to it
259
+ // on its own; a tab is a route, and routing it through <a> would
260
+ // reload the whole app to change one panel.
261
+ return at.href.startsWith("#") ? (
262
+ <a key={group.kind} href={at.href} className={className}>
263
+ {body}
264
+ </a>
265
+ ) : (
266
+ <Link key={group.kind} to={at.href} className={className}>
267
+ {body}
268
+ </Link>
269
+ );
270
+ })}
271
+ </section>
272
+ );
273
+ }
@@ -0,0 +1,84 @@
1
+ // A WSDL contract drawn from the structured facts extract-wsdl recorded.
2
+ // Unlike OpenAPI, the catalog already carries the operation binding and the
3
+ // reachable message shapes, so this remains useful when the source repository
4
+ // is not bundled into the generated site.
5
+
6
+ import { useState } from "react";
7
+ import type { RpcMethod, RpcService } from "../catalog";
8
+ import { Empty, SectionTitle } from "./PageHeader";
9
+ import { Ident } from "./Ident";
10
+ import { MessageList, MethodRows } from "./MethodRows";
11
+
12
+ export function WsdlReference({
13
+ source,
14
+ provided,
15
+ }: {
16
+ source: string;
17
+ provided: RpcService[];
18
+ }) {
19
+ const [open, setOpen] = useState<ReadonlySet<string>>(new Set());
20
+ const interfaces = provided.filter((item) => item.source === source);
21
+ const toggle = (id: string) =>
22
+ setOpen((shown) => {
23
+ const next = new Set(shown);
24
+ if (!next.delete(id)) next.add(id);
25
+ return next;
26
+ });
27
+
28
+ if (interfaces.length === 0) {
29
+ return <Empty>the WSDL source names no interface in this catalog</Empty>;
30
+ }
31
+
32
+ return (
33
+ <div className="max-w-table">
34
+ <p className="mono text-muted">{source}</p>
35
+ {interfaces.map((iface) => {
36
+ const soap = iface.methods.find((method) => method.soap)?.soap;
37
+ return (
38
+ <section key={iface.id} className="mt-section">
39
+ <SectionTitle>{iface.id}</SectionTitle>
40
+ <div className="rounded-card border border-line">
41
+ <div className="flex flex-wrap items-center gap-x-2 border-b border-line bg-surface px-3 py-1.5">
42
+ <Ident value={iface.id} className="text-ink" />
43
+ {soap?.version ? <span className="chip">SOAP {soap.version}</span> : null}
44
+ {soap?.style ? <span className="chip">{soap.style}</span> : null}
45
+ {soap?.binding ? <span className="chip mono">{soap.binding}</span> : null}
46
+ {soap?.endpoint ? (
47
+ <span className="mono min-w-0 truncate text-muted" title={soap.endpoint}>
48
+ {soap.endpoint}
49
+ </span>
50
+ ) : null}
51
+ </div>
52
+ <MethodRows provided={iface} open={open} onToggle={toggle} />
53
+ <MessageList provided={iface} open={open} onToggle={toggle} />
54
+ </div>
55
+ </section>
56
+ );
57
+ })}
58
+ </div>
59
+ );
60
+ }
61
+
62
+ /** The one external SOAP operation a consumer card points at. */
63
+ export function SoapCallContract({
64
+ provided,
65
+ method,
66
+ }: {
67
+ provided: RpcService;
68
+ method: RpcMethod;
69
+ }) {
70
+ const [open, setOpen] = useState<ReadonlySet<string>>(new Set());
71
+ const toggle = (id: string) =>
72
+ setOpen((shown) => {
73
+ const next = new Set(shown);
74
+ if (!next.delete(id)) next.add(id);
75
+ return next;
76
+ });
77
+ const one = { ...provided, methods: [method] };
78
+
79
+ return (
80
+ <div className="mt-1 w-full rounded-control border border-line bg-surface">
81
+ <MethodRows provided={one} open={open} onToggle={toggle} />
82
+ </div>
83
+ );
84
+ }
@@ -0,0 +1,107 @@
1
+ // The five DDD building blocks, drawn rather than borrowed.
2
+ //
3
+ // Lucide has no vocabulary for a domain event or a value object, so what it
4
+ // lends instead is a metaphor: Zap for an event, Diamond for a value object,
5
+ // Square for an entity. Each of those says "roughly this shape" and nothing
6
+ // about what the thing IS. These five say what the thing is.
7
+ //
8
+ // They are drawn on lucide's own grid - 24x24, 1.5px stroke, round caps and
9
+ // joins, no fill - so a value object standing next to a lucide chevron in the
10
+ // tree reads as one family and not as an imported sticker.
11
+ //
12
+ // The semantics, one line each:
13
+ //
14
+ // event a fact, announced: a point that already happened, and the pulse
15
+ // leaving it. Every other context hears about it after the fact.
16
+ // vo a shape with no identity: a diamond holding an equals sign -
17
+ // two equal values ARE the same value.
18
+ // entity a shape with identity: the same square, and the one dot that
19
+ // says this instance is not that one.
20
+ // command a directive arriving at the aggregate: an arrow that lands on
21
+ // the boundary and changes what is behind it.
22
+ // query the same boundary, answering: rows leaving it, changing nothing.
23
+
24
+ import type { SVGProps } from "react";
25
+
26
+ export interface DddIconProps extends Omit<SVGProps<SVGSVGElement>, "ref"> {
27
+ size?: number;
28
+ }
29
+
30
+ /**
31
+ * Shared frame. Every attribute lucide sets on its own icons is set here, so
32
+ * the two families size, colour and align identically.
33
+ */
34
+ function Icon({ size = 16, children, ...rest }: DddIconProps) {
35
+ return (
36
+ <svg
37
+ xmlns="http://www.w3.org/2000/svg"
38
+ width={size}
39
+ height={size}
40
+ viewBox="0 0 24 24"
41
+ fill="none"
42
+ stroke="currentColor"
43
+ strokeWidth={1.5}
44
+ strokeLinecap="round"
45
+ strokeLinejoin="round"
46
+ {...rest}
47
+ >
48
+ {children}
49
+ </svg>
50
+ );
51
+ }
52
+
53
+ /** A fact that happened, and the pulse that carried it outward. */
54
+ export function EventIcon(props: DddIconProps) {
55
+ return (
56
+ <Icon {...props}>
57
+ <circle cx={7} cy={12} r={1.6} />
58
+ <path d="M9.9 8.4a4.6 4.6 0 0 1 0 7.2" />
59
+ <path d="M12.2 5.4a8.4 8.4 0 0 1 0 13.2" />
60
+ </Icon>
61
+ );
62
+ }
63
+
64
+ /** No identity: equal values are the same value. */
65
+ export function ValueObjectIcon(props: DddIconProps) {
66
+ return (
67
+ <Icon {...props}>
68
+ <path d="M12 3.5 20.5 12 12 20.5 3.5 12Z" />
69
+ <path d="M9 10.5h6" />
70
+ <path d="M9 13.5h6" />
71
+ </Icon>
72
+ );
73
+ }
74
+
75
+ /** Identity: this one, tracked over time, and not that one. */
76
+ export function EntityIcon(props: DddIconProps) {
77
+ return (
78
+ <Icon {...props}>
79
+ <rect x={4} y={4} width={16} height={16} rx={3} />
80
+ <circle cx={12} cy={12} r={1.6} />
81
+ </Icon>
82
+ );
83
+ }
84
+
85
+ /** A directive landing on the aggregate boundary. */
86
+ export function CommandIcon(props: DddIconProps) {
87
+ return (
88
+ <Icon {...props}>
89
+ <path d="M19 4.5v15" />
90
+ <path d="M4 12h11" />
91
+ <path d="m11.5 8.5 3.5 3.5-3.5 3.5" />
92
+ </Icon>
93
+ );
94
+ }
95
+
96
+ /** The same boundary, answering. Rows out, nothing changed. */
97
+ export function QueryIcon(props: DddIconProps) {
98
+ return (
99
+ <Icon {...props}>
100
+ <path d="M19 4.5v15" />
101
+ <path d="M19 9H7" />
102
+ <path d="m10.5 5.5-3.5 3.5 3.5 3.5" />
103
+ <path d="M19 15h-8" />
104
+ <path d="m14.5 11.5-3.5 3.5 3.5 3.5" />
105
+ </Icon>
106
+ );
107
+ }