@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,648 @@
1
+ // The syntax tree, as much of it as the extractor looks at.
2
+ //
3
+ // The parser is oxc-parser: native, fast, and with no TypeScript inside it,
4
+ // which is the point - the project's TypeScript is the 7 series, a compiler
5
+ // with no syntax tree to offer, and pinning a second copy of 5 beside it for
6
+ // the parser alone was a workaround, not a design. oxc hands back an ESTree
7
+ // with the TypeScript nodes typescript-eslint would give, and everything the
8
+ // modules above need is a handful of node shapes, a way to walk, and the
9
+ // text and line of a node. Those are declared here, by hand and minimal, so
10
+ // the reading does not move when the parser's own typings do.
11
+ import { parseSync, visitorKeys } from "oxc-parser";
12
+ import type { ParseResult } from "oxc-parser";
13
+
14
+ export interface Node {
15
+ type: string;
16
+ start: number;
17
+ end: number;
18
+ }
19
+ export interface Identifier extends Node {
20
+ type: "Identifier";
21
+ name: string;
22
+ typeAnnotation?: TypeAnnotation | null;
23
+ decorators?: Decorator[];
24
+ }
25
+ export interface Literal extends Node {
26
+ type: "Literal";
27
+ value: unknown;
28
+ }
29
+ export interface TemplateLiteral extends Node {
30
+ type: "TemplateLiteral";
31
+ quasis: { value: { cooked: string | null; raw: string } }[];
32
+ expressions: Node[];
33
+ }
34
+ export interface MemberExpression extends Node {
35
+ type: "MemberExpression";
36
+ object: Node;
37
+ property: Node;
38
+ computed: boolean;
39
+ }
40
+ export interface CallExpression extends Node {
41
+ type: "CallExpression";
42
+ callee: Node;
43
+ arguments: Node[];
44
+ typeArguments?: { params: Node[] } | null;
45
+ }
46
+ export interface NewExpression extends Node {
47
+ type: "NewExpression";
48
+ callee: Node;
49
+ arguments: Node[];
50
+ }
51
+ export interface Wrapped extends Node {
52
+ type: "AwaitExpression" | "ParenthesizedExpression" | "TSAsExpression" | "TSNonNullExpression" | "TSSatisfiesExpression" | "TSTypeAssertion" | "SpreadElement";
53
+ expression?: Node;
54
+ argument?: Node;
55
+ }
56
+ export interface AssignmentExpression extends Node {
57
+ type: "AssignmentExpression";
58
+ operator: string;
59
+ left: Node;
60
+ right: Node;
61
+ }
62
+ export interface BinaryExpression extends Node {
63
+ type: "BinaryExpression";
64
+ operator: string;
65
+ left: Node;
66
+ right: Node;
67
+ }
68
+ export interface ObjectExpression extends Node {
69
+ type: "ObjectExpression";
70
+ properties: Node[];
71
+ }
72
+ export interface Property extends Node {
73
+ type: "Property";
74
+ key: Node;
75
+ value: Node;
76
+ computed: boolean;
77
+ }
78
+ export interface ArrayExpression extends Node {
79
+ type: "ArrayExpression";
80
+ elements: (Node | null)[];
81
+ }
82
+ export interface ArrayPattern extends Node {
83
+ type: "ArrayPattern";
84
+ elements: (Node | null)[];
85
+ }
86
+ export interface VariableDeclaration extends Node {
87
+ type: "VariableDeclaration";
88
+ declarations: VariableDeclarator[];
89
+ }
90
+ export interface VariableDeclarator extends Node {
91
+ type: "VariableDeclarator";
92
+ id: Node;
93
+ init: Node | null;
94
+ }
95
+ export interface ExpressionStatement extends Node {
96
+ type: "ExpressionStatement";
97
+ expression: Node;
98
+ }
99
+ export interface ReturnStatement extends Node {
100
+ type: "ReturnStatement";
101
+ argument: Node | null;
102
+ }
103
+ export interface BlockStatement extends Node {
104
+ type: "BlockStatement";
105
+ body: Node[];
106
+ }
107
+ export interface IfStatement extends Node {
108
+ type: "IfStatement";
109
+ test: Node;
110
+ consequent: Node;
111
+ alternate: Node | null;
112
+ }
113
+ export interface SwitchStatement extends Node {
114
+ type: "SwitchStatement";
115
+ discriminant: Node;
116
+ cases: SwitchCase[];
117
+ }
118
+ export interface SwitchCase extends Node {
119
+ type: "SwitchCase";
120
+ test: Node | null;
121
+ consequent: Node[];
122
+ }
123
+ export interface ForEachStatement extends Node {
124
+ type: "ForOfStatement" | "ForInStatement";
125
+ left: Node;
126
+ right: Node;
127
+ body: Node;
128
+ }
129
+ export interface ForStatement extends Node {
130
+ type: "ForStatement";
131
+ init: Node | null;
132
+ test: Node | null;
133
+ body: Node;
134
+ }
135
+ export interface WhileStatement extends Node {
136
+ type: "WhileStatement" | "DoWhileStatement";
137
+ test: Node;
138
+ body: Node;
139
+ }
140
+ export interface TryStatement extends Node {
141
+ type: "TryStatement";
142
+ block: BlockStatement;
143
+ handler: { body: BlockStatement } | null;
144
+ finalizer: BlockStatement | null;
145
+ }
146
+ export interface TypeAnnotation extends Node {
147
+ type: "TSTypeAnnotation";
148
+ typeAnnotation: Node;
149
+ }
150
+ export interface TypeReference extends Node {
151
+ type: "TSTypeReference";
152
+ typeName: Node;
153
+ }
154
+ export interface FunctionNode extends Node {
155
+ type: "FunctionExpression" | "FunctionDeclaration";
156
+ id: Identifier | null;
157
+ params: Node[];
158
+ body: BlockStatement | null;
159
+ returnType: TypeAnnotation | null;
160
+ }
161
+ export interface MethodDefinition extends Node {
162
+ type: "MethodDefinition";
163
+ key: Node;
164
+ value: FunctionNode;
165
+ kind: "constructor" | "method" | "get" | "set";
166
+ static: boolean;
167
+ computed: boolean;
168
+ }
169
+ export interface PropertyDefinition extends Node {
170
+ type: "PropertyDefinition";
171
+ key: Node;
172
+ value: Node | null;
173
+ typeAnnotation: TypeAnnotation | null;
174
+ static: boolean;
175
+ computed: boolean;
176
+ }
177
+ export interface ParameterProperty extends Node {
178
+ type: "TSParameterProperty";
179
+ parameter: Node;
180
+ decorators?: Decorator[];
181
+ }
182
+ export interface Decorator extends Node {
183
+ type: "Decorator";
184
+ expression: Node;
185
+ }
186
+ export interface ClassDeclaration extends Node {
187
+ type: "ClassDeclaration" | "ClassExpression";
188
+ id: Identifier | null;
189
+ body: { body: Node[] };
190
+ decorators: Decorator[];
191
+ }
192
+ export interface ImportDeclaration extends Node {
193
+ type: "ImportDeclaration";
194
+ source: Literal;
195
+ specifiers: ImportSpecifier[];
196
+ importKind: "type" | "value";
197
+ }
198
+ export interface ImportSpecifier extends Node {
199
+ type: "ImportSpecifier" | "ImportDefaultSpecifier" | "ImportNamespaceSpecifier";
200
+ local: Identifier;
201
+ imported?: Node;
202
+ importKind?: "type" | "value";
203
+ }
204
+ export interface ExportNamedDeclaration extends Node {
205
+ type: "ExportNamedDeclaration";
206
+ declaration: Node | null;
207
+ }
208
+ export interface InterfaceDeclaration extends Node {
209
+ type: "TSInterfaceDeclaration";
210
+ id: Identifier;
211
+ body: { body: Node[] };
212
+ }
213
+ export interface MethodSignature extends Node {
214
+ type: "TSMethodSignature";
215
+ key: Node;
216
+ returnType: TypeAnnotation | null;
217
+ }
218
+ export interface PropertySignature extends Node {
219
+ type: "TSPropertySignature";
220
+ key: Node;
221
+ typeAnnotation: TypeAnnotation | null;
222
+ }
223
+ export interface FunctionType extends Node {
224
+ type: "TSFunctionType";
225
+ returnType: TypeAnnotation | null;
226
+ }
227
+ export interface Program extends Node {
228
+ type: "Program";
229
+ body: Node[];
230
+ }
231
+ export interface Comment {
232
+ type: "Block" | "Line";
233
+ value: string;
234
+ start: number;
235
+ end: number;
236
+ }
237
+
238
+ /** One parsed file: its tree, its comments, and the text both point into. */
239
+ export interface Parsed {
240
+ path: string;
241
+ text: string;
242
+ program: Program;
243
+ comments: Comment[];
244
+ /** Offsets at which each line starts, for turning a position into a line. */
245
+ lines: number[];
246
+ /** JavaScript rather than TypeScript: the types are in the doc comments. */
247
+ js: boolean;
248
+ /** What the file imports and exports, as the parser records it: names, requests and whether an import is type-only, without walking the tree. */
249
+ module: ParseResult["module"];
250
+ /** Syntax errors. The tree is still handed back, but what follows an error in the file may be missing from it. */
251
+ errors: ParseResult["errors"];
252
+ }
253
+
254
+ /** `.ts`, `.tsx`, `.js`, `.mjs`, `.cjs`, `.jsx`: what the tree is written in, and so where its types are. */
255
+ export const SOURCE_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs", ".cjs", ".jsx"] as const;
256
+
257
+ /** A file the extractor reads: one of the source extensions, and not a test or a declaration file. */
258
+ export function isSourceFile(name: string): boolean {
259
+ if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(name) || name.endsWith(".d.ts")) return false;
260
+ return SOURCE_EXTENSIONS.some((ext) => name.endsWith(ext));
261
+ }
262
+
263
+ /** Whether a file is JavaScript, where the types are in the doc comments rather than the syntax. */
264
+ export function isJavaScript(path: string): boolean {
265
+ return /\.([cm]?js|jsx)$/.test(path);
266
+ }
267
+
268
+ export function parse(path: string, text: string): Parsed {
269
+ const lang = path.endsWith(".tsx") ? "tsx" : path.endsWith(".jsx") ? "jsx" : isJavaScript(path) ? "js" : "ts";
270
+ const result = parseSync(path, text, { lang, sourceType: "module" });
271
+ const lines = [0];
272
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) lines.push(i + 1);
273
+ return { path, text, program: result.program as unknown as Program, comments: result.comments as Comment[], lines, js: lang === "js" || lang === "jsx", module: result.module, errors: result.errors };
274
+ }
275
+
276
+ /**
277
+ * A type annotation with the text its offsets point into: the two travel
278
+ * together because `typeText` slices the text by the node. A type read from
279
+ * a doc comment has no place in the file, so it is parsed on its own and
280
+ * carries its own text; a type written in the syntax carries the file's.
281
+ */
282
+ export interface Typed {
283
+ p: Parsed;
284
+ ann: TypeAnnotation;
285
+ }
286
+
287
+ const docTypes = new Map<string, Typed | undefined>();
288
+
289
+ /**
290
+ * A JSDoc type expression - `{Promise<Basket>}` without its braces - as the
291
+ * node a TypeScript annotation would have been. The expressions a `checkJs`
292
+ * project writes are TypeScript's own, so `let _: <expr>;` is a program and
293
+ * its one annotation is the type; `typeText`, `bareType` and `isFunctionType`
294
+ * then read it exactly as they read one written in the syntax. Closure's
295
+ * `?T` and `Array.<T>` are not TypeScript and read as nothing.
296
+ */
297
+ export function typeFromDoc(expr: string): Typed | undefined {
298
+ const key = expr.trim();
299
+ if (!key) return undefined;
300
+ if (docTypes.has(key)) return docTypes.get(key);
301
+ let out: Typed | undefined;
302
+ try {
303
+ const p = parse("doc-type.ts", `let _: ${key};`);
304
+ const stmt = p.program.body[0];
305
+ const decl = isVarDecl(stmt) ? stmt.declarations[0]?.id : undefined;
306
+ const ann = isIdent(decl) ? decl.typeAnnotation : undefined;
307
+ // A parse that errored still hands back a tree; the text of the type must
308
+ // be the whole expression or something was left unread.
309
+ if (ann && text(p, ann.typeAnnotation) === key) out = { p, ann };
310
+ } catch {
311
+ out = undefined;
312
+ }
313
+ docTypes.set(key, out);
314
+ return out;
315
+ }
316
+
317
+ /** An interface declared in a doc comment - a `@typedef` - as the node an `interface` would have been, with its own text. */
318
+ export function interfaceFromDoc(name: string, body: string): { p: Parsed; node: InterfaceDeclaration } | undefined {
319
+ try {
320
+ const p = parse("doc-typedef.ts", `interface ${name} {${body}}`);
321
+ const node = p.program.body[0];
322
+ return isInterface(node) && node.id.name === name ? { p, node } : undefined;
323
+ } catch {
324
+ return undefined;
325
+ }
326
+ }
327
+
328
+ /** The source of a node, as written. */
329
+ export function text(p: Parsed, node: Node): string {
330
+ return p.text.slice(node.start, node.end);
331
+ }
332
+
333
+ /** The 1-based line a position falls on. */
334
+ export function lineOf(p: Parsed, offset: number): number {
335
+ let lo = 0;
336
+ let hi = p.lines.length - 1;
337
+ while (lo < hi) {
338
+ const mid = (lo + hi + 1) >> 1;
339
+ if (p.lines[mid]! <= offset) lo = mid;
340
+ else hi = mid - 1;
341
+ }
342
+ return lo + 1;
343
+ }
344
+
345
+ /**
346
+ * A `/** … *\/` comment read the way JSDoc says to: the prose above the first
347
+ * tag, then the block tags. Only the tags that say something about the thing
348
+ * itself are kept - a `@param` or a `@returns` is for a type checker, and the
349
+ * layout already says what a `@fires` would.
350
+ */
351
+ export interface DocBlock {
352
+ /**
353
+ * The prose, with `@remarks` folded in as the paragraphs after it, because
354
+ * TSDoc puts the long description there and a reader wants it in the same
355
+ * place. An inline `{@link X}` is flattened to what it names, or to its
356
+ * label when it has one.
357
+ */
358
+ text: string;
359
+ /** Each `@example`, as written, without its frame. */
360
+ examples: string[];
361
+ /**
362
+ * What followed `@deprecated`, "" when nothing did, and undefined when the
363
+ * tag is absent - so the reason is kept without a second field to say
364
+ * whether there was a tag at all.
365
+ */
366
+ deprecated?: string;
367
+ /**
368
+ * Every block tag, in order, with what followed it - the raw material the
369
+ * type readers below work from. `@param`, `@returns` and `@type` are where
370
+ * a JavaScript file keeps what a TypeScript file writes in the syntax.
371
+ */
372
+ tags: DocTag[];
373
+ }
374
+
375
+ export interface DocTag {
376
+ /** Lower case, without the `@`. */
377
+ tag: string;
378
+ /** Everything after the tag name, joined and trimmed. */
379
+ text: string;
380
+ }
381
+
382
+ const EMPTY_DOC: DocBlock = { text: "", examples: [], tags: [] };
383
+
384
+ /** `{T} rest` → `["T", "rest"]`, braces balanced so `{{ a: string }}` and `{Record<string, {x: number}>}` read whole; no braces → `["", text]`. */
385
+ export function splitDocType(text: string): [string, string] {
386
+ const s = text.trim();
387
+ if (!s.startsWith("{")) return ["", s];
388
+ let depth = 0;
389
+ for (let i = 0; i < s.length; i++) {
390
+ if (s[i] === "{") depth++;
391
+ else if (s[i] === "}" && --depth === 0) return [s.slice(1, i).trim(), s.slice(i + 1).trim()];
392
+ }
393
+ return ["", s];
394
+ }
395
+
396
+ /** The `@type {T}` of a doc block, or "". */
397
+ export function docType(block: DocBlock): string {
398
+ const tag = block.tags.find((t) => t.tag === "type");
399
+ return tag ? splitDocType(tag.text)[0] : "";
400
+ }
401
+
402
+ /** The `@returns {T}` (or `@return`) of a doc block, or "". */
403
+ export function docReturns(block: DocBlock): string {
404
+ const tag = block.tags.find((t) => t.tag === "returns" || t.tag === "return");
405
+ return tag ? splitDocType(tag.text)[0] : "";
406
+ }
407
+
408
+ /** Each `@param {T} name` of a doc block, by name; `[name]` and `[name=x]` are the optional spellings of the same. */
409
+ export function docParams(block: DocBlock): Map<string, string> {
410
+ const out = new Map<string, string>();
411
+ for (const t of block.tags) {
412
+ if (t.tag !== "param" && t.tag !== "arg" && t.tag !== "argument") continue;
413
+ const [type, rest] = splitDocType(t.text);
414
+ const m = /^\[?([\w$]+)/.exec(rest);
415
+ if (m && type) out.set(m[1]!, type);
416
+ }
417
+ return out;
418
+ }
419
+
420
+ /** A `@typedef {T} Name`, with the `@property {T} name` lines that followed it when `T` was `Object`. */
421
+ export interface DocTypedef {
422
+ name: string;
423
+ type: string;
424
+ properties: { name: string; type: string }[];
425
+ }
426
+
427
+ export function docTypedefs(block: DocBlock): DocTypedef[] {
428
+ const out: DocTypedef[] = [];
429
+ for (const t of block.tags) {
430
+ if (t.tag === "typedef") {
431
+ const [type, rest] = splitDocType(t.text);
432
+ const name = /^[\w$]+/.exec(rest)?.[0];
433
+ if (name) out.push({ name, type, properties: [] });
434
+ } else if ((t.tag === "property" || t.tag === "prop") && out.length) {
435
+ const [type, rest] = splitDocType(t.text);
436
+ const name = /^\[?([\w$]+)/.exec(rest)?.[1];
437
+ if (name && type) out[out.length - 1]!.properties.push({ name, type });
438
+ }
439
+ }
440
+ return out;
441
+ }
442
+
443
+ /**
444
+ * The doc comment that sits right above a node, cleaned the way a reader would
445
+ * read it: the frame and the leading stars gone, and split at the tags. `from`
446
+ * is where the node's first token is when something precedes the node itself -
447
+ * a decorator, `export` - and the comment sits above that.
448
+ */
449
+ export function docBlock(p: Parsed, node: Node, from = node.start): DocBlock {
450
+ let found: Comment | undefined;
451
+ for (const c of p.comments) {
452
+ if (c.end > from) break;
453
+ if (c.type !== "Block" || !c.value.startsWith("*")) continue;
454
+ if (p.text.slice(c.end, from).trim() === "") found = c;
455
+ }
456
+ if (!found) return EMPTY_DOC;
457
+ return parseDoc(found.value.slice(1));
458
+ }
459
+
460
+ /** The prose of the doc comment above a node: `docBlock(...).text`. */
461
+ export function jsdoc(p: Parsed, node: Node, from = node.start): string {
462
+ return docBlock(p, node, from).text;
463
+ }
464
+
465
+ /**
466
+ * Splits a cleaned comment body into the text above the first tag and one
467
+ * section per block tag. A tag opens at a line starting with `@name` and runs
468
+ * to the next such line; inline `{@link}` never starts a line, so it stays
469
+ * inside whichever section it sits in.
470
+ */
471
+ export function parseDoc(body: string): DocBlock {
472
+ const lines = body.split("\n").map((l) => l.replace(/^\s*\*? ?/, ""));
473
+ const sections: { tag: string; lines: string[] }[] = [{ tag: "", lines: [] }];
474
+ for (const line of lines) {
475
+ const m = /^\s*@(\w+)(?:\s+(.*))?$/.exec(line);
476
+ if (m) sections.push({ tag: m[1]!.toLowerCase(), lines: m[2] !== undefined ? [m[2]] : [] });
477
+ else sections[sections.length - 1]!.lines.push(line);
478
+ }
479
+ const prose = [sections[0]!.lines.join("\n").trim()];
480
+ const examples: string[] = [];
481
+ const tags: DocTag[] = [];
482
+ let deprecated: string | undefined;
483
+ for (const s of sections.slice(1)) {
484
+ const text = s.lines.join("\n").trim();
485
+ tags.push({ tag: s.tag, text });
486
+ if (s.tag === "remarks" && text) prose.push(text);
487
+ else if (s.tag === "example" && text) examples.push(text);
488
+ else if (s.tag === "deprecated") deprecated = flattenLinks(text.replace(/\s+/g, " "));
489
+ }
490
+ const out: DocBlock = { text: flattenLinks(prose.filter(Boolean).join("\n\n")), examples, tags };
491
+ if (deprecated !== undefined) out.deprecated = deprecated;
492
+ return out;
493
+ }
494
+
495
+ /**
496
+ * `{@link X}` → `X`, `{@link X|label}` and `{@link X label}` → `label`,
497
+ * `[label]{@link X}` → `label`; `@linkcode` and `@linkplain` the same. The
498
+ * catalog has no way to say "this name is that page" from inside prose, so
499
+ * the name is kept as words rather than dropped or left as a tag nobody
500
+ * renders.
501
+ */
502
+ export function flattenLinks(text: string): string {
503
+ return text
504
+ .replace(/\[([^\]]+)\]\{@link(?:code|plain)?\s+[^}]+\}/g, "$1")
505
+ .replace(/\{@link(?:code|plain)?\s+([^}\s|]+)(?:\s*\|\s*|\s+)([^}]+)\}/g, (_, _target, label: string) => label.trim())
506
+ .replace(/\{@link(?:code|plain)?\s+([^}]+)\}/g, (_, target: string) => target.trim());
507
+ }
508
+
509
+ /** Where a declaration's first token is: its decorator, its `export`, or itself. */
510
+ export function firstTokenOf(node: Node, exportNode?: Node): number {
511
+ let start = exportNode ? Math.min(exportNode.start, node.start) : node.start;
512
+ const decorators = (node as { decorators?: Decorator[] }).decorators ?? [];
513
+ for (const d of decorators) start = Math.min(start, d.start);
514
+ return start;
515
+ }
516
+
517
+ /** Every node under one, depth first, the parent before its children. */
518
+ export function walk(node: Node, f: (n: Node) => void): void {
519
+ f(node);
520
+ for (const child of children(node)) walk(child, f);
521
+ }
522
+
523
+ /**
524
+ * A node's children, in source order, by the parser's own table of which
525
+ * fields hold nodes. A type the table does not know - there is none in a tree
526
+ * oxc built, but a test may make one - falls back to reading every field.
527
+ */
528
+ export function* children(node: Node): Iterable<Node> {
529
+ const keys = (visitorKeys as Record<string, readonly string[] | undefined>)[node.type];
530
+ const fields = keys ? keys.map((k) => [k, (node as unknown as Record<string, unknown>)[k]] as const) : Object.entries(node);
531
+ for (const [key, value] of fields) {
532
+ if (key === "type" || key === "start" || key === "end" || value === null || typeof value !== "object") continue;
533
+ if (Array.isArray(value)) {
534
+ for (const el of value) if (isNode(el)) yield el;
535
+ } else if (isNode(value)) {
536
+ yield value;
537
+ }
538
+ }
539
+ }
540
+
541
+ function isNode(v: unknown): v is Node {
542
+ return typeof v === "object" && v !== null && typeof (v as Node).type === "string" && typeof (v as Node).start === "number";
543
+ }
544
+
545
+ /** The expression under `await`, parentheses, `as`, `satisfies`, `!` and `<T>`. */
546
+ export function unwrap(node: Node): Node {
547
+ let n = node;
548
+ for (;;) {
549
+ switch (n.type) {
550
+ case "AwaitExpression":
551
+ n = (n as Wrapped).argument!;
552
+ continue;
553
+ case "ParenthesizedExpression":
554
+ case "TSAsExpression":
555
+ case "TSNonNullExpression":
556
+ case "TSSatisfiesExpression":
557
+ case "TSTypeAssertion":
558
+ n = (n as Wrapped).expression!;
559
+ continue;
560
+ default:
561
+ return n;
562
+ }
563
+ }
564
+ }
565
+
566
+ export const isIdent = (n: Node | null | undefined): n is Identifier => n?.type === "Identifier";
567
+ export const isString = (n: Node | null | undefined): n is Literal & { value: string } => n?.type === "Literal" && typeof (n as Literal).value === "string";
568
+ export const isNumber = (n: Node | null | undefined): n is Literal & { value: number } => n?.type === "Literal" && typeof (n as Literal).value === "number";
569
+ export const isBoolean = (n: Node | null | undefined): n is Literal & { value: boolean } => n?.type === "Literal" && typeof (n as Literal).value === "boolean";
570
+ export const isTemplate = (n: Node | null | undefined): n is TemplateLiteral => n?.type === "TemplateLiteral";
571
+ export const isMember = (n: Node | null | undefined): n is MemberExpression => n?.type === "MemberExpression";
572
+ export const isCall = (n: Node | null | undefined): n is CallExpression => n?.type === "CallExpression";
573
+ export const isNew = (n: Node | null | undefined): n is NewExpression => n?.type === "NewExpression";
574
+ export const isThis = (n: Node | null | undefined): boolean => n?.type === "ThisExpression";
575
+ export const isSpread = (n: Node | null | undefined): n is Wrapped => n?.type === "SpreadElement";
576
+ export const isAssign = (n: Node | null | undefined): n is AssignmentExpression => n?.type === "AssignmentExpression";
577
+ export const isBinary = (n: Node | null | undefined): n is BinaryExpression => n?.type === "BinaryExpression";
578
+ export const isObject = (n: Node | null | undefined): n is ObjectExpression => n?.type === "ObjectExpression";
579
+ export const isProp = (n: Node | null | undefined): n is Property => n?.type === "Property";
580
+ export const isArray = (n: Node | null | undefined): n is ArrayExpression => n?.type === "ArrayExpression";
581
+ export const isArrayPattern = (n: Node | null | undefined): n is ArrayPattern => n?.type === "ArrayPattern";
582
+ export const isVarDecl = (n: Node | null | undefined): n is VariableDeclaration => n?.type === "VariableDeclaration";
583
+ export const isExprStmt = (n: Node | null | undefined): n is ExpressionStatement => n?.type === "ExpressionStatement";
584
+ export const isReturn = (n: Node | null | undefined): n is ReturnStatement => n?.type === "ReturnStatement";
585
+ export const isThrow = (n: Node | null | undefined): boolean => n?.type === "ThrowStatement";
586
+ export const isBlock = (n: Node | null | undefined): n is BlockStatement => n?.type === "BlockStatement";
587
+ export const isIf = (n: Node | null | undefined): n is IfStatement => n?.type === "IfStatement";
588
+ export const isSwitch = (n: Node | null | undefined): n is SwitchStatement => n?.type === "SwitchStatement";
589
+ export const isSwitchCase = (n: Node | null | undefined): n is SwitchCase => n?.type === "SwitchCase";
590
+ export const isForEach = (n: Node | null | undefined): n is ForEachStatement => n?.type === "ForOfStatement" || n?.type === "ForInStatement";
591
+ export const isFor = (n: Node | null | undefined): n is ForStatement => n?.type === "ForStatement";
592
+ export const isWhile = (n: Node | null | undefined): n is WhileStatement => n?.type === "WhileStatement" || n?.type === "DoWhileStatement";
593
+ export const isTry = (n: Node | null | undefined): n is TryStatement => n?.type === "TryStatement";
594
+ export const isClassDecl = (n: Node | null | undefined): n is ClassDeclaration => n?.type === "ClassDeclaration";
595
+ export const isFunctionDecl = (n: Node | null | undefined): n is FunctionNode => n?.type === "FunctionDeclaration";
596
+ export const isArrow = (n: Node | null | undefined): n is FunctionNode => n?.type === "ArrowFunctionExpression";
597
+ export const isMethod = (n: Node | null | undefined): n is MethodDefinition => n?.type === "MethodDefinition";
598
+ export const isPropertyDef = (n: Node | null | undefined): n is PropertyDefinition => n?.type === "PropertyDefinition";
599
+ export const isParamProperty = (n: Node | null | undefined): n is ParameterProperty => n?.type === "TSParameterProperty";
600
+ export const isInterface = (n: Node | null | undefined): n is InterfaceDeclaration => n?.type === "TSInterfaceDeclaration";
601
+ export const isImport = (n: Node | null | undefined): n is ImportDeclaration => n?.type === "ImportDeclaration";
602
+ export const isExportNamed = (n: Node | null | undefined): n is ExportNamedDeclaration => n?.type === "ExportNamedDeclaration";
603
+ export const isTypeRef = (n: Node | null | undefined): n is TypeReference => n?.type === "TSTypeReference";
604
+ export const isMethodSig = (n: Node | null | undefined): n is MethodSignature => n?.type === "TSMethodSignature";
605
+ export const isPropertySig = (n: Node | null | undefined): n is PropertySignature => n?.type === "TSPropertySignature";
606
+ export const isFunctionType = (n: Node | null | undefined): n is FunctionType => n?.type === "TSFunctionType";
607
+
608
+ /** The name a non-computed key or member property carries. */
609
+ export function keyName(n: Node): string | undefined {
610
+ if (isIdent(n)) return n.name;
611
+ if (isString(n)) return n.value;
612
+ return undefined;
613
+ }
614
+
615
+ /** `x.name` → "name", when the property is a plain name. */
616
+ export function memberName(n: MemberExpression): string | undefined {
617
+ return n.computed ? undefined : keyName(n.property);
618
+ }
619
+
620
+ /** `this.<name>` → name. */
621
+ export function thisMember(n: Node): string | undefined {
622
+ return isMember(n) && isThis(n.object) ? memberName(n) : undefined;
623
+ }
624
+
625
+ /** A string literal, or a template with no holes, as its text. */
626
+ export function stringOf(n: Node | null | undefined): string | undefined {
627
+ if (isString(n)) return n.value;
628
+ if (isTemplate(n) && n.expressions.length === 0) return n.quasis[0]?.value.cooked ?? undefined;
629
+ return undefined;
630
+ }
631
+
632
+ /** `/v1/users/${id}` → `/v1/users/${x}`: a template's holes are parameters. */
633
+ export function templateShape(t: TemplateLiteral): string {
634
+ return t.quasis.map((q) => q.value.cooked ?? q.value.raw).join("${x}");
635
+ }
636
+
637
+ /** The binding a parameter declares, through a parameter property, a default or a rest. */
638
+ export function paramIdent(param: Node): Identifier | undefined {
639
+ if (isParamProperty(param)) return paramIdent(param.parameter);
640
+ if (param.type === "AssignmentPattern") return paramIdent((param as unknown as { left: Node }).left);
641
+ if (param.type === "RestElement") return paramIdent((param as unknown as { argument: Node }).argument);
642
+ return isIdent(param) ? param : undefined;
643
+ }
644
+
645
+ /** The type a parameter or a property is annotated with, as written, or "". */
646
+ export function typeText(p: Parsed, ann: TypeAnnotation | null | undefined): string {
647
+ return ann ? text(p, ann.typeAnnotation) : "";
648
+ }