@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.
- package/LICENSE +21 -0
- package/README.md +387 -0
- package/catalog/enum_test.go +46 -0
- package/catalog/model.go +932 -0
- package/catalog/roundtrip_test.go +185 -0
- package/catalog/via_test.go +38 -0
- package/cli/portolan.mjs +368 -0
- package/go.mod +14 -0
- package/go.sum +14 -0
- package/index.html +13 -0
- package/internal/commands/cargo.go +154 -0
- package/internal/commands/commands.go +143 -0
- package/internal/commands/commands_test.go +323 -0
- package/internal/commands/gradle.go +77 -0
- package/internal/commands/justfile.go +82 -0
- package/internal/commands/makefile.go +106 -0
- package/internal/commands/maven.go +93 -0
- package/internal/commands/packagejson.go +159 -0
- package/internal/commands/pyproject.go +169 -0
- package/internal/commands/taskfile.go +101 -0
- package/internal/commands/testdata/estate/.cargo/config.toml +7 -0
- package/internal/commands/testdata/estate/Makefile +33 -0
- package/internal/commands/testdata/estate/Taskfile.yml +21 -0
- package/internal/commands/testdata/estate/build.gradle.kts +21 -0
- package/internal/commands/testdata/estate/justfile +20 -0
- package/internal/commands/testdata/estate/package.json +13 -0
- package/internal/commands/testdata/estate/pom.xml +29 -0
- package/internal/commands/testdata/estate/pyproject.toml +27 -0
- package/internal/commands/testdata/estate/xtask/src/main.rs +27 -0
- package/internal/commands/testdata/golden/commands.json +305 -0
- package/internal/gohttp/analyze.go +2500 -0
- package/internal/gohttp/endpoints.go +1067 -0
- package/internal/gohttp/roots.go +320 -0
- package/internal/gohttp/typed.go +143 -0
- package/internal/goscan/constants.go +85 -0
- package/internal/goscan/goscan_test.go +227 -0
- package/internal/goscan/names.go +52 -0
- package/internal/goscan/parse_test.go +11 -0
- package/internal/goscan/source.go +36 -0
- package/internal/goscan/tree.go +155 -0
- package/internal/goscan/types.go +99 -0
- package/internal/wsdl/ids.go +127 -0
- package/internal/wsdl/ids_test.go +21 -0
- package/internal/wsdl/model.go +62 -0
- package/internal/wsdl/parse.go +920 -0
- package/internal/wsdl/parse_test.go +133 -0
- package/package.json +117 -0
- package/plugin/describe.go +107 -0
- package/plugin/describe_test.go +114 -0
- package/plugin/protocol.go +117 -0
- package/plugin/schematest/schematest.go +126 -0
- package/plugins/README.md +1160 -0
- package/plugins/extract-adr/describe.go +19 -0
- package/plugins/extract-adr/describe_test.go +11 -0
- package/plugins/extract-adr/extract.go +153 -0
- package/plugins/extract-adr/extract_test.go +350 -0
- package/plugins/extract-adr/history.go +99 -0
- package/plugins/extract-adr/main.go +65 -0
- package/plugins/extract-adr/options.schema.json +26 -0
- package/plugins/extract-adr/parse.go +642 -0
- package/plugins/extract-adr/parse_test.go +405 -0
- package/plugins/extract-asyncapi/describe.go +19 -0
- package/plugins/extract-asyncapi/describe_test.go +11 -0
- package/plugins/extract-asyncapi/extract.go +315 -0
- package/plugins/extract-asyncapi/extract_test.go +197 -0
- package/plugins/extract-asyncapi/main.go +48 -0
- package/plugins/extract-asyncapi/options.schema.json +26 -0
- package/plugins/extract-asyncapi/spec.go +151 -0
- package/plugins/extract-celery/README.md +169 -0
- package/plugins/extract-celery/extract.py +346 -0
- package/plugins/extract-celery/extract_test.py +192 -0
- package/plugins/extract-celery/main.py +66 -0
- package/plugins/extract-celery/options.py +31 -0
- package/plugins/extract-celery/options.schema.json +31 -0
- package/plugins/extract-celery/producers.py +156 -0
- package/plugins/extract-celery/routes_test.py +106 -0
- package/plugins/extract-commands/describe.go +19 -0
- package/plugins/extract-commands/describe_test.go +11 -0
- package/plugins/extract-commands/extract.go +79 -0
- package/plugins/extract-commands/extract_test.go +92 -0
- package/plugins/extract-commands/main.go +55 -0
- package/plugins/extract-commands/options.schema.json +20 -0
- package/plugins/extract-csr/avro.go +258 -0
- package/plugins/extract-csr/describe.go +19 -0
- package/plugins/extract-csr/describe_test.go +11 -0
- package/plugins/extract-csr/extract.go +338 -0
- package/plugins/extract-csr/extract_test.go +374 -0
- package/plugins/extract-csr/jsonschema.go +343 -0
- package/plugins/extract-csr/lock.go +25 -0
- package/plugins/extract-csr/main.go +84 -0
- package/plugins/extract-csr/options.schema.json +43 -0
- package/plugins/extract-csr/subject.go +102 -0
- package/plugins/extract-django/README.md +386 -0
- package/plugins/extract-django/apps.py +100 -0
- package/plugins/extract-django/auth.py +302 -0
- package/plugins/extract-django/auth_test.py +188 -0
- package/plugins/extract-django/clients.py +121 -0
- package/plugins/extract-django/contracts.py +458 -0
- package/plugins/extract-django/database.py +119 -0
- package/plugins/extract-django/domain.py +318 -0
- package/plugins/extract-django/events.py +86 -0
- package/plugins/extract-django/extract.py +601 -0
- package/plugins/extract-django/extract_test.py +397 -0
- package/plugins/extract-django/flows.py +1278 -0
- package/plugins/extract-django/flows_test.py +338 -0
- package/plugins/extract-django/ids.py +42 -0
- package/plugins/extract-django/ids_test.py +30 -0
- package/plugins/extract-django/lifecycle.py +222 -0
- package/plugins/extract-django/lifecycle_test.py +76 -0
- package/plugins/extract-django/main.py +66 -0
- package/plugins/extract-django/openapi.py +229 -0
- package/plugins/extract-django/openapi_test.py +60 -0
- package/plugins/extract-django/operations.py +96 -0
- package/plugins/extract-django/options.py +61 -0
- package/plugins/extract-django/options.schema.json +126 -0
- package/plugins/extract-django/routing.py +214 -0
- package/plugins/extract-django/routing_test.py +198 -0
- package/plugins/extract-django/serializers.py +558 -0
- package/plugins/extract-django/store.py +434 -0
- package/plugins/extract-django/transport.py +242 -0
- package/plugins/extract-flows/describe.go +19 -0
- package/plugins/extract-flows/describe_test.go +11 -0
- package/plugins/extract-flows/extract.go +91 -0
- package/plugins/extract-flows/main.go +45 -0
- package/plugins/extract-flows/options.schema.json +16 -0
- package/plugins/extract-flows/parse.go +593 -0
- package/plugins/extract-flows/parse_test.go +204 -0
- package/plugins/extract-glossary/describe.go +19 -0
- package/plugins/extract-glossary/describe_test.go +11 -0
- package/plugins/extract-glossary/extract.go +115 -0
- package/plugins/extract-glossary/extract_test.go +220 -0
- package/plugins/extract-glossary/main.go +59 -0
- package/plugins/extract-glossary/options.schema.json +21 -0
- package/plugins/extract-glossary/parse.go +214 -0
- package/plugins/extract-glossary/parse_test.go +203 -0
- package/plugins/extract-go/aggregate.go +214 -0
- package/plugins/extract-go/client.go +409 -0
- package/plugins/extract-go/client_test.go +266 -0
- package/plugins/extract-go/describe.go +19 -0
- package/plugins/extract-go/describe_test.go +11 -0
- package/plugins/extract-go/enum.go +195 -0
- package/plugins/extract-go/enum_test.go +82 -0
- package/plugins/extract-go/event.go +99 -0
- package/plugins/extract-go/extract.go +191 -0
- package/plugins/extract-go/extract_test.go +261 -0
- package/plugins/extract-go/flow.go +1441 -0
- package/plugins/extract-go/flow_test.go +609 -0
- package/plugins/extract-go/httpclient.go +174 -0
- package/plugins/extract-go/httpclient_test.go +296 -0
- package/plugins/extract-go/ids.go +92 -0
- package/plugins/extract-go/layout.go +225 -0
- package/plugins/extract-go/layout_test.go +125 -0
- package/plugins/extract-go/lifecycle.go +324 -0
- package/plugins/extract-go/lifecycle_test.go +108 -0
- package/plugins/extract-go/main.go +79 -0
- package/plugins/extract-go/operation.go +157 -0
- package/plugins/extract-go/options.schema.json +66 -0
- package/plugins/extract-go/source.go +316 -0
- package/plugins/extract-go/transport.go +321 -0
- package/plugins/extract-go/transport_test.go +145 -0
- package/plugins/extract-go/wiring.go +434 -0
- package/plugins/extract-go-nats/describe.go +19 -0
- package/plugins/extract-go-nats/describe_test.go +11 -0
- package/plugins/extract-go-nats/extract.go +177 -0
- package/plugins/extract-go-nats/extract_test.go +389 -0
- package/plugins/extract-go-nats/index.go +379 -0
- package/plugins/extract-go-nats/main.go +42 -0
- package/plugins/extract-go-nats/options.schema.json +21 -0
- package/plugins/extract-go-nats/resolve.go +161 -0
- package/plugins/extract-go-nats/sites.go +224 -0
- package/plugins/extract-graphql/describe.go +19 -0
- package/plugins/extract-graphql/describe_test.go +11 -0
- package/plugins/extract-graphql/extract.go +433 -0
- package/plugins/extract-graphql/extract_test.go +256 -0
- package/plugins/extract-graphql/ids.go +49 -0
- package/plugins/extract-graphql/lex.go +237 -0
- package/plugins/extract-graphql/main.go +51 -0
- package/plugins/extract-graphql/options.schema.json +31 -0
- package/plugins/extract-graphql/parse.go +621 -0
- package/plugins/extract-graphql/parse_test.go +122 -0
- package/plugins/extract-http-clients/describe.go +19 -0
- package/plugins/extract-http-clients/describe_test.go +11 -0
- package/plugins/extract-http-clients/extract.go +705 -0
- package/plugins/extract-http-clients/extract_test.go +1263 -0
- package/plugins/extract-http-clients/main.go +42 -0
- package/plugins/extract-http-clients/options.schema.json +33 -0
- package/plugins/extract-java/README.md +190 -0
- package/plugins/extract-java/build/org/portolan/extract/Catalog.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$2.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Call.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Client.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Route.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Domain$Aggregate.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Domain.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Events$Found.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Events.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Extract.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Binding.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Draft.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Frame.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Options.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Ids.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Json$Reader.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Json.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle$Move.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Main.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi$Operation.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi$Spec.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations$UseCase.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto$Rpc.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto$Service.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Builder.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Input.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Options.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source$Project.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source$Unit.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Transport$Endpoint.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Transport.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml$Line.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml$Reader.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml.class +0 -0
- package/plugins/extract-java/options.schema.json +70 -0
- package/plugins/extract-openapi/describe.go +19 -0
- package/plugins/extract-openapi/describe_test.go +11 -0
- package/plugins/extract-openapi/discover.go +243 -0
- package/plugins/extract-openapi/extract.go +526 -0
- package/plugins/extract-openapi/extract_test.go +545 -0
- package/plugins/extract-openapi/main.go +75 -0
- package/plugins/extract-openapi/options.schema.json +62 -0
- package/plugins/extract-openapi/spec.go +350 -0
- package/plugins/extract-project/README.md +22 -0
- package/plugins/extract-project/describe.go +19 -0
- package/plugins/extract-project/describe_test.go +11 -0
- package/plugins/extract-project/extract.go +221 -0
- package/plugins/extract-project/extract_test.go +109 -0
- package/plugins/extract-project/main.go +41 -0
- package/plugins/extract-project/options.schema.json +48 -0
- package/plugins/extract-proto/ast.go +125 -0
- package/plugins/extract-proto/consumes.go +77 -0
- package/plugins/extract-proto/describe.go +19 -0
- package/plugins/extract-proto/extract.go +293 -0
- package/plugins/extract-proto/extract_test.go +459 -0
- package/plugins/extract-proto/ids.go +89 -0
- package/plugins/extract-proto/ids_test.go +57 -0
- package/plugins/extract-proto/lex.go +285 -0
- package/plugins/extract-proto/main.go +100 -0
- package/plugins/extract-proto/module.go +120 -0
- package/plugins/extract-proto/options.schema.json +51 -0
- package/plugins/extract-proto/parse.go +720 -0
- package/plugins/extract-proto/parse_test.go +307 -0
- package/plugins/extract-proto/provides.go +236 -0
- package/plugins/extract-proto/resolve.go +222 -0
- package/plugins/extract-proto/resolve_test.go +119 -0
- package/plugins/extract-python-kafka/README.md +36 -0
- package/plugins/extract-python-kafka/extract.py +211 -0
- package/plugins/extract-python-kafka/extract_test.py +68 -0
- package/plugins/extract-python-kafka/main.py +59 -0
- package/plugins/extract-python-kafka/options.py +29 -0
- package/plugins/extract-python-kafka/options.schema.json +31 -0
- package/plugins/extract-redis/README.md +11 -0
- package/plugins/extract-redis/describe.go +19 -0
- package/plugins/extract-redis/describe_test.go +11 -0
- package/plugins/extract-redis/extract.go +183 -0
- package/plugins/extract-redis/extract_test.go +168 -0
- package/plugins/extract-redis/keyspaces.go +469 -0
- package/plugins/extract-redis/main.go +44 -0
- package/plugins/extract-redis/options.schema.json +30 -0
- package/plugins/extract-river/describe.go +19 -0
- package/plugins/extract-river/describe_test.go +11 -0
- package/plugins/extract-river/extract.go +507 -0
- package/plugins/extract-river/extract_test.go +132 -0
- package/plugins/extract-river/main.go +42 -0
- package/plugins/extract-river/options.schema.json +21 -0
- package/plugins/extract-rust/Cargo.lock +133 -0
- package/plugins/extract-rust/Cargo.toml +23 -0
- package/plugins/extract-rust/README.md +204 -0
- package/plugins/extract-rust/options.schema.json +65 -0
- package/plugins/extract-rust/rustfmt.toml +1 -0
- package/plugins/extract-sql/ddl.go +893 -0
- package/plugins/extract-sql/ddl_test.go +401 -0
- package/plugins/extract-sql/describe.go +19 -0
- package/plugins/extract-sql/describe_test.go +11 -0
- package/plugins/extract-sql/layout.go +221 -0
- package/plugins/extract-sql/layout_test.go +55 -0
- package/plugins/extract-sql/lineage.go +107 -0
- package/plugins/extract-sql/main.go +141 -0
- package/plugins/extract-sql/maps.go +564 -0
- package/plugins/extract-sql/maps_java.go +117 -0
- package/plugins/extract-sql/maps_rust.go +333 -0
- package/plugins/extract-sql/maps_rust_test.go +70 -0
- package/plugins/extract-sql/maps_test.go +204 -0
- package/plugins/extract-sql/maps_ts.go +398 -0
- package/plugins/extract-sql/maps_ts_test.go +136 -0
- package/plugins/extract-sql/options.schema.json +53 -0
- package/plugins/extract-sql/projection.go +70 -0
- package/plugins/extract-sql/projection_test.go +50 -0
- package/plugins/extract-sql/store.go +420 -0
- package/plugins/extract-sql/store_test.go +233 -0
- package/plugins/extract-sql/view.go +295 -0
- package/plugins/extract-ts/README.md +306 -0
- package/plugins/extract-ts/ast.test.ts +178 -0
- package/plugins/extract-ts/ast.ts +648 -0
- package/plugins/extract-ts/clients.ts +185 -0
- package/plugins/extract-ts/domain.ts +164 -0
- package/plugins/extract-ts/extract.test.ts +208 -0
- package/plugins/extract-ts/extract.ts +200 -0
- package/plugins/extract-ts/flows.ts +783 -0
- package/plugins/extract-ts/graphql.test.ts +73 -0
- package/plugins/extract-ts/graphql.ts +181 -0
- package/plugins/extract-ts/ids.test.ts +21 -0
- package/plugins/extract-ts/ids.ts +52 -0
- package/plugins/extract-ts/lifecycle.ts +138 -0
- package/plugins/extract-ts/main.ts +48 -0
- package/plugins/extract-ts/openapi.test.ts +64 -0
- package/plugins/extract-ts/openapi.ts +99 -0
- package/plugins/extract-ts/operations.ts +93 -0
- package/plugins/extract-ts/options.schema.json +96 -0
- package/plugins/extract-ts/source.test.ts +174 -0
- package/plugins/extract-ts/source.ts +465 -0
- package/plugins/extract-ts/transport.ts +147 -0
- package/plugins/extract-ts/tsconfig.json +13 -0
- package/plugins/extract-ts/wiring.ts +190 -0
- package/plugins/extract-watermill/describe.go +19 -0
- package/plugins/extract-watermill/describe_test.go +11 -0
- package/plugins/extract-watermill/extract.go +1228 -0
- package/plugins/extract-watermill/extract_test.go +234 -0
- package/plugins/extract-watermill/main.go +41 -0
- package/plugins/extract-watermill/options.schema.json +21 -0
- package/plugins/extract-wsdl/describe.go +19 -0
- package/plugins/extract-wsdl/describe_test.go +11 -0
- package/plugins/extract-wsdl/extract.go +148 -0
- package/plugins/extract-wsdl/extract_test.go +45 -0
- package/plugins/extract-wsdl/main.go +53 -0
- package/plugins/extract-wsdl/options.schema.json +59 -0
- package/plugins/fetch-bsr/auth.go +114 -0
- package/plugins/fetch-bsr/bsr.go +240 -0
- package/plugins/fetch-bsr/cache.go +66 -0
- package/plugins/fetch-bsr/describe.go +19 -0
- package/plugins/fetch-bsr/fetch.go +192 -0
- package/plugins/fetch-bsr/fetch_test.go +465 -0
- package/plugins/fetch-bsr/lock.go +71 -0
- package/plugins/fetch-bsr/main.go +117 -0
- package/plugins/fetch-bsr/options.schema.json +42 -0
- package/plugins/fetch-csr/auth.go +95 -0
- package/plugins/fetch-csr/cache.go +69 -0
- package/plugins/fetch-csr/describe.go +19 -0
- package/plugins/fetch-csr/describe_test.go +11 -0
- package/plugins/fetch-csr/fetch.go +254 -0
- package/plugins/fetch-csr/fetch_test.go +494 -0
- package/plugins/fetch-csr/lock.go +95 -0
- package/plugins/fetch-csr/main.go +122 -0
- package/plugins/fetch-csr/options.schema.json +42 -0
- package/plugins/fetch-csr/registry.go +209 -0
- package/plugins/fetch-git/cache.go +65 -0
- package/plugins/fetch-git/describe.go +19 -0
- package/plugins/fetch-git/describe_test.go +11 -0
- package/plugins/fetch-git/fetch.go +181 -0
- package/plugins/fetch-git/fetch_test.go +332 -0
- package/plugins/fetch-git/git.go +169 -0
- package/plugins/fetch-git/lock.go +72 -0
- package/plugins/fetch-git/main.go +127 -0
- package/plugins/fetch-git/offline.go +39 -0
- package/plugins/fetch-git/options.schema.json +42 -0
- package/plugins/fetch-git/pin.go +90 -0
- package/plugins/fetch-git/pin_test.go +74 -0
- package/plugins/gen-backstage/describe.go +17 -0
- package/plugins/gen-backstage/main.go +22 -0
- package/plugins/gen-backstage/options.schema.json +30 -0
- package/plugins/gen-backstage/plugin.go +473 -0
- package/plugins/gen-backstage/plugin_test.go +145 -0
- package/plugins/gen-backstage.wasm +0 -0
- package/plugins/gen-markdown/adr.go +162 -0
- package/plugins/gen-markdown/aggregate.go +362 -0
- package/plugins/gen-markdown/canonical.go +93 -0
- package/plugins/gen-markdown/context.go +90 -0
- package/plugins/gen-markdown/coverage_test.go +89 -0
- package/plugins/gen-markdown/describe.go +19 -0
- package/plugins/gen-markdown/describe_test.go +11 -0
- package/plugins/gen-markdown/external.go +71 -0
- package/plugins/gen-markdown/flow.go +277 -0
- package/plugins/gen-markdown/glossary.go +76 -0
- package/plugins/gen-markdown/glossary_test.go +148 -0
- package/plugins/gen-markdown/llms.go +302 -0
- package/plugins/gen-markdown/main.go +22 -0
- package/plugins/gen-markdown/markdown.go +254 -0
- package/plugins/gen-markdown/markdown_test.go +100 -0
- package/plugins/gen-markdown/module.go +107 -0
- package/plugins/gen-markdown/options.schema.json +16 -0
- package/plugins/gen-markdown/plugin.go +39 -0
- package/plugins/gen-markdown/quality_test.go +176 -0
- package/plugins/gen-markdown/redis_test.go +38 -0
- package/plugins/gen-markdown/render.go +344 -0
- package/plugins/gen-markdown/render_test.go +186 -0
- package/plugins/gen-markdown/service.go +456 -0
- package/plugins/gen-markdown/source.go +177 -0
- package/plugins/gen-markdown/store.go +201 -0
- package/plugins/gen-markdown.wasm +0 -0
- package/plugins/gen-mermaid/describe.go +17 -0
- package/plugins/gen-mermaid/main.go +22 -0
- package/plugins/gen-mermaid/options.schema.json +10 -0
- package/plugins/gen-mermaid/plugin.go +104 -0
- package/plugins/gen-mermaid/plugin_test.go +33 -0
- package/plugins/gen-mermaid.wasm +0 -0
- package/plugins/openapi/ids.go +261 -0
- package/plugins/openapi/ids_test.go +98 -0
- package/plugins/pyplugin/catalog.py +209 -0
- package/plugins/pyplugin/celery_conf.py +436 -0
- package/plugins/pyplugin/celery_tasks.py +76 -0
- package/plugins/pyplugin/kafka.py +570 -0
- package/plugins/pyplugin/names.py +38 -0
- package/plugins/pyplugin/protocol.py +79 -0
- package/plugins/pyplugin/source.py +285 -0
- package/plugins/verify-codeowners/describe.go +19 -0
- package/plugins/verify-codeowners/describe_test.go +11 -0
- package/plugins/verify-codeowners/main.go +75 -0
- package/plugins/verify-codeowners/match.go +85 -0
- package/plugins/verify-codeowners/match_test.go +47 -0
- package/plugins/verify-codeowners/options.schema.json +15 -0
- package/plugins/verify-codeowners/owners.go +164 -0
- package/plugins/verify-codeowners/owners_test.go +225 -0
- package/plugins/verify-codeowners/parse.go +90 -0
- package/plugins/verify-codeowners/parse_test.go +62 -0
- package/plugins/verify-otel/describe.go +19 -0
- package/plugins/verify-otel/describe_test.go +11 -0
- package/plugins/verify-otel/main.go +53 -0
- package/plugins/verify-otel/match.go +336 -0
- package/plugins/verify-otel/options.schema.json +30 -0
- package/plugins/verify-otel/otlp.go +200 -0
- package/plugins/verify-otel/verify.go +734 -0
- package/plugins/verify-otel/verify_test.go +460 -0
- package/portolan.json +1073 -0
- package/public/favicon.svg +12 -0
- package/schema/portolan.schema.json +2558 -0
- package/scripts/README.md +53 -0
- package/scripts/build-report.mjs +60 -0
- package/scripts/build-report.test.mjs +44 -0
- package/scripts/builtin-plugins.mjs +49 -0
- package/scripts/catalog-sources.mjs +67 -0
- package/scripts/diff.mjs +315 -0
- package/scripts/diff.test.mjs +151 -0
- package/scripts/forge-comment.mjs +144 -0
- package/scripts/forge-comment.test.mjs +151 -0
- package/scripts/forge-release.mjs +138 -0
- package/scripts/forge-release.test.mjs +106 -0
- package/scripts/forge.mjs +61 -0
- package/scripts/gen-likec4.mjs +854 -0
- package/scripts/gen-likec4.test.mjs +258 -0
- package/scripts/gen.mjs +603 -0
- package/scripts/generated-docs.test.mjs +66 -0
- package/scripts/local-api.mjs +1192 -0
- package/scripts/local-api.test.mjs +387 -0
- package/scripts/manifest.mjs +214 -0
- package/scripts/manifest.test.mjs +148 -0
- package/scripts/output-path.mjs +79 -0
- package/scripts/output-path.test.mjs +45 -0
- package/scripts/package-smoke.mjs +37 -0
- package/scripts/plugin-host.mjs +419 -0
- package/scripts/plugin-host.test.mjs +109 -0
- package/scripts/plugin-wasm-worker.mjs +34 -0
- package/scripts/run-builtin.mjs +81 -0
- package/scripts/schema.mjs +357 -0
- package/scripts/site-docs.mjs +295 -0
- package/scripts/site-docs.test.mjs +181 -0
- package/scripts/vendor-lock.mjs +58 -0
- package/scripts/vendor-lock.test.mjs +69 -0
- package/src/README.md +38 -0
- package/src/app/App.tsx +448 -0
- package/src/app/BranchPicker.test.ts +46 -0
- package/src/app/BranchPicker.tsx +153 -0
- package/src/app/Breadcrumbs.test.ts +38 -0
- package/src/app/Breadcrumbs.tsx +223 -0
- package/src/app/BuildStamp.tsx +146 -0
- package/src/app/CommandPalette.tsx +292 -0
- package/src/app/HashScroll.tsx +45 -0
- package/src/app/Sidebar.tsx +1742 -0
- package/src/app/TopBar.tsx +393 -0
- package/src/app/density.tsx +64 -0
- package/src/app/forge-access.test.ts +27 -0
- package/src/app/forge-access.tsx +80 -0
- package/src/app/panels.tsx +141 -0
- package/src/app/pins.tsx +242 -0
- package/src/app/query-client.ts +24 -0
- package/src/app/responsive.ts +55 -0
- package/src/app/shortcuts.test.ts +39 -0
- package/src/app/shortcuts.tsx +282 -0
- package/src/app/theme.tsx +51 -0
- package/src/app/title.test.ts +14 -0
- package/src/app/title.ts +30 -0
- package/src/app/toast.tsx +59 -0
- package/src/app/tree-keys.test.ts +80 -0
- package/src/app/tree-keys.ts +87 -0
- package/src/app/ui-store.ts +52 -0
- package/src/catalog-error.test.ts +105 -0
- package/src/catalog-profile.test.ts +59 -0
- package/src/catalog-profile.ts +101 -0
- package/src/catalog-stores.test.ts +431 -0
- package/src/catalog.test.ts +1215 -0
- package/src/catalog.ts +3125 -0
- package/src/chat/Cards.tsx +408 -0
- package/src/chat/ChatPanel.tsx +79 -0
- package/src/chat/ChatSettings.tsx +219 -0
- package/src/chat/Composer.tsx +99 -0
- package/src/chat/Conversation.tsx +281 -0
- package/src/chat/Header.tsx +46 -0
- package/src/chat/Message.tsx +49 -0
- package/src/chat/Notice.tsx +195 -0
- package/src/chat/Starter.tsx +67 -0
- package/src/chat/Steps.tsx +45 -0
- package/src/chat/Waiting.tsx +87 -0
- package/src/chat/flags.test.ts +59 -0
- package/src/chat/flags.ts +155 -0
- package/src/chat/linkify.test.ts +30 -0
- package/src/chat/linkify.ts +45 -0
- package/src/chat/prefs.ts +56 -0
- package/src/chat/prompt.test.ts +43 -0
- package/src/chat/prompt.ts +157 -0
- package/src/chat/store.ts +35 -0
- package/src/chat/tools.ts +58 -0
- package/src/chat/transport.ts +70 -0
- package/src/components/AdrRow.tsx +29 -0
- package/src/components/AnchorLink.tsx +67 -0
- package/src/components/ApiReference.tsx +134 -0
- package/src/components/AsyncApiReference.tsx +120 -0
- package/src/components/CatalogStamp.tsx +155 -0
- package/src/components/ChannelRows.tsx +132 -0
- package/src/components/CommandRows.tsx +139 -0
- package/src/components/DiagramSkeleton.tsx +71 -0
- package/src/components/EditorLink.tsx +85 -0
- package/src/components/FieldTree.tsx +305 -0
- package/src/components/FlowTrigger.tsx +34 -0
- package/src/components/Ident.tsx +89 -0
- package/src/components/Integrations.tsx +243 -0
- package/src/components/LifecycleDiagram.tsx +110 -0
- package/src/components/MachineDocs.tsx +42 -0
- package/src/components/Markdown.tsx +173 -0
- package/src/components/MarkdownTable.tsx +206 -0
- package/src/components/Mermaid.tsx +211 -0
- package/src/components/MethodRows.tsx +309 -0
- package/src/components/Overlay.tsx +125 -0
- package/src/components/PageHeader.tsx +189 -0
- package/src/components/RowActions.tsx +97 -0
- package/src/components/SchemaDocument.tsx +89 -0
- package/src/components/Select.tsx +126 -0
- package/src/components/ShapeRows.tsx +118 -0
- package/src/components/SourceDoc.tsx +82 -0
- package/src/components/SourcePreview.tsx +441 -0
- package/src/components/TabRow.tsx +182 -0
- package/src/components/TechIcon.tsx +34 -0
- package/src/components/Toc.tsx +132 -0
- package/src/components/WhatLinksHere.tsx +273 -0
- package/src/components/WsdlReference.tsx +84 -0
- package/src/components/ddd-icons.tsx +107 -0
- package/src/components/kind.tsx +157 -0
- package/src/components/logo.tsx +61 -0
- package/src/components/primitives.tsx +264 -0
- package/src/data.test.ts +18 -0
- package/src/data.ts +202 -0
- package/src/enrich.test.ts +1150 -0
- package/src/enrich.ts +672 -0
- package/src/er/ErCanvas.tsx +533 -0
- package/src/er/RedisSchema.tsx +74 -0
- package/src/er/RelationCard.tsx +267 -0
- package/src/er/StoreHeader.tsx +155 -0
- package/src/er/TableNode.tsx +84 -0
- package/src/er/ViewNode.tsx +83 -0
- package/src/er/layout.test.ts +115 -0
- package/src/er/layout.ts +77 -0
- package/src/er/lineage.test.ts +140 -0
- package/src/er/lineage.ts +107 -0
- package/src/er/markers.tsx +79 -0
- package/src/er/spec.test.ts +344 -0
- package/src/er/spec.ts +426 -0
- package/src/flow/ChainList.tsx +162 -0
- package/src/flow/FlowTable.tsx +123 -0
- package/src/flow/FlowToolbar.tsx +372 -0
- package/src/flow/StepDetail.tsx +380 -0
- package/src/flow/StepRail.tsx +428 -0
- package/src/flow/answers.test.ts +50 -0
- package/src/flow/answers.ts +58 -0
- package/src/flow/chain.test.ts +383 -0
- package/src/flow/chain.ts +353 -0
- package/src/flow/chapters.test.ts +185 -0
- package/src/flow/chapters.ts +225 -0
- package/src/flow/continues.test.ts +102 -0
- package/src/flow/continues.ts +65 -0
- package/src/flow/cross-context.test.ts +97 -0
- package/src/flow/cross-context.ts +35 -0
- package/src/flow/mermaid.test.ts +22 -0
- package/src/flow/mermaid.ts +141 -0
- package/src/flow/outline.test.ts +212 -0
- package/src/flow/outline.ts +170 -0
- package/src/flow/paths.test.ts +129 -0
- package/src/flow/paths.ts +147 -0
- package/src/flow/prefs.test.ts +80 -0
- package/src/flow/prefs.ts +104 -0
- package/src/graph/DependencyGraph.tsx +283 -0
- package/src/graph/DependencyNodes.tsx +162 -0
- package/src/graph/EdgeLabel.tsx +61 -0
- package/src/graph/FocusedEventGraph.tsx +211 -0
- package/src/graph/GraphToolbar.tsx +187 -0
- package/src/graph/RoutedEdge.tsx +80 -0
- package/src/graph/dependency-layout.test.ts +360 -0
- package/src/graph/dependency-layout.ts +444 -0
- package/src/graph/elk.test.ts +70 -0
- package/src/graph/elk.ts +287 -0
- package/src/graph/nodes.tsx +97 -0
- package/src/graph/theme.ts +81 -0
- package/src/graph/useElkFlow.ts +125 -0
- package/src/index.css +1547 -0
- package/src/language/InLanguage.tsx +40 -0
- package/src/language/TermCard.tsx +132 -0
- package/src/language/cards.test.ts +114 -0
- package/src/language/cards.ts +111 -0
- package/src/lib/admonition.test.ts +49 -0
- package/src/lib/admonition.ts +48 -0
- package/src/lib/adr.test.ts +131 -0
- package/src/lib/adr.ts +68 -0
- package/src/lib/api.test.ts +122 -0
- package/src/lib/api.ts +135 -0
- package/src/lib/backlinks.test.ts +330 -0
- package/src/lib/backlinks.ts +567 -0
- package/src/lib/branch-compare.ts +16 -0
- package/src/lib/build-info.test.ts +76 -0
- package/src/lib/build-info.ts +80 -0
- package/src/lib/catalog-diff.test.ts +275 -0
- package/src/lib/catalog-diff.ts +655 -0
- package/src/lib/clipboard.ts +43 -0
- package/src/lib/comparison-memory.test.ts +40 -0
- package/src/lib/comparison-memory.ts +39 -0
- package/src/lib/context-color.ts +27 -0
- package/src/lib/context-map.test.ts +148 -0
- package/src/lib/context-map.ts +399 -0
- package/src/lib/data-model.test.ts +245 -0
- package/src/lib/data-model.ts +399 -0
- package/src/lib/data-problems.test.ts +178 -0
- package/src/lib/data-problems.ts +314 -0
- package/src/lib/derive.test.ts +251 -0
- package/src/lib/derive.ts +515 -0
- package/src/lib/editor-link.test.ts +125 -0
- package/src/lib/editor-link.ts +96 -0
- package/src/lib/editor-prefs.ts +27 -0
- package/src/lib/event-graph.test.ts +237 -0
- package/src/lib/event-graph.ts +327 -0
- package/src/lib/export-canvas.ts +37 -0
- package/src/lib/export-file.test.ts +30 -0
- package/src/lib/export-file.ts +20 -0
- package/src/lib/flow-tree.test.ts +177 -0
- package/src/lib/flow-tree.ts +160 -0
- package/src/lib/forge-refs.test.ts +50 -0
- package/src/lib/forge-refs.ts +60 -0
- package/src/lib/format.test.ts +35 -0
- package/src/lib/format.ts +64 -0
- package/src/lib/github-catalog.test.ts +301 -0
- package/src/lib/github-catalog.ts +610 -0
- package/src/lib/integrations.test.ts +119 -0
- package/src/lib/integrations.ts +133 -0
- package/src/lib/kinds.test.ts +91 -0
- package/src/lib/kinds.ts +204 -0
- package/src/lib/lifecycle.test.ts +93 -0
- package/src/lib/lifecycle.ts +165 -0
- package/src/lib/local-api.ts +194 -0
- package/src/lib/motion-features.ts +11 -0
- package/src/lib/motion.test.ts +120 -0
- package/src/lib/motion.tsx +269 -0
- package/src/lib/palette-recent.test.ts +80 -0
- package/src/lib/palette-recent.ts +90 -0
- package/src/lib/palette.test.ts +365 -0
- package/src/lib/palette.ts +593 -0
- package/src/lib/pins.test.ts +139 -0
- package/src/lib/pins.ts +130 -0
- package/src/lib/problems.test.ts +112 -0
- package/src/lib/project-preview.ts +5 -0
- package/src/lib/proto-problems.test.ts +121 -0
- package/src/lib/proto-problems.ts +65 -0
- package/src/lib/queries.test.ts +113 -0
- package/src/lib/queries.ts +131 -0
- package/src/lib/registry.test.ts +219 -0
- package/src/lib/registry.ts +208 -0
- package/src/lib/scenarios.ts +547 -0
- package/src/lib/setup-info.test.ts +199 -0
- package/src/lib/setup-info.ts +415 -0
- package/src/lib/shape.test.ts +289 -0
- package/src/lib/shape.ts +454 -0
- package/src/lib/sidebar-prefs.test.ts +32 -0
- package/src/lib/sidebar-prefs.ts +75 -0
- package/src/lib/source-code.test.ts +159 -0
- package/src/lib/source-code.ts +286 -0
- package/src/lib/source-doc.test.ts +131 -0
- package/src/lib/source-doc.ts +103 -0
- package/src/lib/source-highlight.test.ts +29 -0
- package/src/lib/source-highlight.ts +24 -0
- package/src/lib/source-link.test.ts +153 -0
- package/src/lib/source-link.ts +201 -0
- package/src/lib/spec-files.test.ts +24 -0
- package/src/lib/spec-files.ts +23 -0
- package/src/lib/table-directive.test.ts +139 -0
- package/src/lib/table-directive.ts +106 -0
- package/src/lib/tech.test.ts +120 -0
- package/src/lib/tech.ts +421 -0
- package/src/lib/terms.test.ts +67 -0
- package/src/lib/terms.ts +179 -0
- package/src/lib/wire-problems.test.ts +263 -0
- package/src/lib/wire-problems.ts +281 -0
- package/src/likec4/C4View.tsx +55 -0
- package/src/likec4/CanvasBridge.tsx +187 -0
- package/src/likec4/FlowView.tsx +235 -0
- package/src/likec4/InteractiveView.tsx +144 -0
- package/src/likec4/canvas-viewport.test.ts +149 -0
- package/src/likec4/canvas-viewport.ts +135 -0
- package/src/likec4/flow-edges.test.ts +51 -0
- package/src/likec4/flow-edges.ts +89 -0
- package/src/likec4/frame-theme.test.ts +76 -0
- package/src/likec4/frame-theme.ts +101 -0
- package/src/likec4/highlight-css.test.ts +49 -0
- package/src/likec4/highlight-css.ts +52 -0
- package/src/likec4/ids.test.ts +151 -0
- package/src/likec4/ids.ts +115 -0
- package/src/likec4/levels.tsx +70 -0
- package/src/likec4/mapping.test.ts +66 -0
- package/src/likec4/mapping.ts +54 -0
- package/src/likec4/reserved.json +141 -0
- package/src/likec4/view-index.ts +78 -0
- package/src/main.tsx +13 -0
- package/src/map/ContextMapGraph.tsx +274 -0
- package/src/map/ContextNode.tsx +70 -0
- package/src/map/FloatingEdge.tsx +86 -0
- package/src/merge.test.ts +1038 -0
- package/src/merge.ts +1004 -0
- package/src/pages/AdrDetail.tsx +242 -0
- package/src/pages/AdrIndex.tsx +114 -0
- package/src/pages/AggregatePage.tsx +727 -0
- package/src/pages/BlockPage.tsx +478 -0
- package/src/pages/CatalogFailure.tsx +111 -0
- package/src/pages/Changes.tsx +313 -0
- package/src/pages/ContextMap.tsx +534 -0
- package/src/pages/ContextPage.tsx +346 -0
- package/src/pages/EnumPage.tsx +282 -0
- package/src/pages/EventPage.tsx +686 -0
- package/src/pages/ExternalPage.tsx +204 -0
- package/src/pages/FlowDetail.tsx +663 -0
- package/src/pages/FlowIndex.tsx +303 -0
- package/src/pages/GraphPage.tsx +217 -0
- package/src/pages/Language.tsx +257 -0
- package/src/pages/ModulePage.tsx +366 -0
- package/src/pages/NotFound.tsx +54 -0
- package/src/pages/Overview.tsx +344 -0
- package/src/pages/Problems.tsx +360 -0
- package/src/pages/RegistryIndex.tsx +118 -0
- package/src/pages/ServicePage.tsx +746 -0
- package/src/pages/Settings.tsx +975 -0
- package/src/pages/StorePage.tsx +114 -0
- package/src/peek/PeekCard.test.ts +35 -0
- package/src/peek/PeekCard.tsx +118 -0
- package/src/peek/PeekLayer.tsx +147 -0
- package/src/peek/model.test.ts +156 -0
- package/src/peek/model.ts +253 -0
- package/src/routes.test.ts +222 -0
- package/src/routes.ts +449 -0
- package/src/selection/DetailPanel.tsx +1407 -0
- package/src/selection/hash.test.ts +73 -0
- package/src/selection/hash.ts +58 -0
- package/src/selection/model.test.ts +199 -0
- package/src/selection/model.ts +473 -0
- package/src/selection/pages.test.ts +115 -0
- package/src/selection/pages.ts +268 -0
- package/src/selection/store.test.ts +62 -0
- package/src/selection/store.ts +46 -0
- package/src/selection/sync.tsx +99 -0
- package/src/table/ColumnsMenu.tsx +72 -0
- package/src/table/DataTable.tsx +780 -0
- package/src/table/Facets.tsx +54 -0
- package/src/table/GroupMenu.tsx +69 -0
- package/src/table/Toolbar.tsx +190 -0
- package/src/table/cells.tsx +117 -0
- package/src/table/compare.test.ts +117 -0
- package/src/table/compare.ts +196 -0
- package/src/table/export.test.ts +88 -0
- package/src/table/export.ts +66 -0
- package/src/table/facet-groups.test.ts +74 -0
- package/src/table/facet-groups.ts +56 -0
- package/src/table/grouping.test.ts +84 -0
- package/src/table/grouping.ts +82 -0
- package/src/table/infer.test.ts +57 -0
- package/src/table/infer.ts +50 -0
- package/src/table/persist.test.ts +76 -0
- package/src/table/persist.ts +112 -0
- package/src/table/sort-url.test.ts +75 -0
- package/src/table/sort-url.ts +52 -0
- package/src/table/types.ts +80 -0
- package/src/table/useTableState.ts +220 -0
- package/src/test-catalog.ts +7 -0
- package/src/testing/estate/data__catalog.json +2847 -0
- package/src/testing/estate/data__flows.json +1724 -0
- package/src/testing/estate/examples__auth__portolan__api.json +212 -0
- package/src/testing/estate/examples__auth__portolan__domain.json +1204 -0
- package/src/testing/estate/examples__auth__portolan__glossary.json +226 -0
- package/src/testing/estate/examples__auth__portolan__observed.json +757 -0
- package/src/testing/estate/examples__auth__portolan__stores.json +195 -0
- package/src/testing/estate/examples__shop__cart__portolan__api.json +234 -0
- package/src/testing/estate/examples__shop__cart__portolan__commands.json +86 -0
- package/src/testing/estate/examples__shop__cart__portolan__domain.json +966 -0
- package/src/testing/estate/examples__shop__cart__portolan__observed.json +498 -0
- package/src/testing/estate/examples__shop__cart__portolan__stores.json +208 -0
- package/src/testing/estate/examples__shop__oms__portolan__glossary.json +98 -0
- package/src/testing/estate/examples__shop__oms__portolan__proto.json +186 -0
- package/src/testing/estate.ts +49 -0
- package/src/trail/Trail.tsx +81 -0
- package/src/trail/model.test.ts +157 -0
- package/src/trail/model.ts +189 -0
- package/src/trail/record.tsx +32 -0
- package/src/trail/store.test.ts +66 -0
- package/src/trail/store.ts +102 -0
- package/tsconfig.json +35 -0
- package/vite.config.ts +171 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Query definitions for everything the UI reads at runtime.
|
|
2
|
+
//
|
|
3
|
+
// The loaders in github-catalog, source-code and local-api stay plain async
|
|
4
|
+
// functions; this module only says how their results are keyed and shared.
|
|
5
|
+
// Two components asking for the same branches get one request, a token change
|
|
6
|
+
// is a different key and so a fresh request, and a reader's "Try again"
|
|
7
|
+
// resets one key prefix instead of a module-level Map.
|
|
8
|
+
//
|
|
9
|
+
// Access tokens are part of the keys. The query cache lives only in this tab's
|
|
10
|
+
// memory, which is the same promise the forge-access provider makes, and a
|
|
11
|
+
// key that did not include the token would hand an authenticated reader a
|
|
12
|
+
// public answer, or the other way round.
|
|
13
|
+
|
|
14
|
+
import { queryOptions } from "@tanstack/react-query";
|
|
15
|
+
import type { Catalog } from "../catalog";
|
|
16
|
+
import { diffCatalogs } from "./catalog-diff";
|
|
17
|
+
import type { Change } from "./catalog-diff";
|
|
18
|
+
import { findRef } from "./forge-refs";
|
|
19
|
+
import { listForgeRefs, loadForgeCatalog } from "./github-catalog";
|
|
20
|
+
import type { ForgeRef, ForgeRepo } from "./github-catalog";
|
|
21
|
+
import { localStatus } from "./local-api";
|
|
22
|
+
import { loadSourceCode } from "./source-code";
|
|
23
|
+
import type { SourceFile } from "./source-code";
|
|
24
|
+
import type { SourceLocation } from "./source-link";
|
|
25
|
+
|
|
26
|
+
export const forgeKeys = {
|
|
27
|
+
/** Prefix for every forge read; reset it to forget branches and catalogs. */
|
|
28
|
+
all: ["forge"] as const,
|
|
29
|
+
refs: (repo: ForgeRepo | null, token: string) =>
|
|
30
|
+
["forge", "refs", repo?.provider ?? "", repo?.webUrl ?? "", token] as const,
|
|
31
|
+
comparison: (repo: ForgeRepo | null, token: string, baseSha: string, headSha: string) =>
|
|
32
|
+
["forge", "comparison", repo?.provider ?? "", repo?.webUrl ?? "", baseSha, headSha, token] as const,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const sourceKeys = {
|
|
36
|
+
all: ["source"] as const,
|
|
37
|
+
file: (location: SourceLocation, token: string) =>
|
|
38
|
+
location.kind === "remote"
|
|
39
|
+
? (["source", "remote", location.provider, location.repositoryUrl, location.ref, location.path, token] as const)
|
|
40
|
+
: (["source", "local", location.path] as const),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const localKeys = {
|
|
44
|
+
status: ["local", "status"] as const,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Branches and tags of the configured forge repository. Disabled without one. */
|
|
48
|
+
export function forgeRefsQuery(repo: ForgeRepo | null, token: string) {
|
|
49
|
+
return queryOptions({
|
|
50
|
+
queryKey: forgeKeys.refs(repo, token),
|
|
51
|
+
queryFn: (): Promise<ForgeRef[]> => {
|
|
52
|
+
if (!repo) throw new Error("No forge repository is configured.");
|
|
53
|
+
return listForgeRefs(repo, { token });
|
|
54
|
+
},
|
|
55
|
+
enabled: repo !== null,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* One side of a comparison: the name a reader typed, the commit it resolves
|
|
61
|
+
* to, and the catalog itself when the side is the one this build was made
|
|
62
|
+
* from - that catalog is already in the bundle and is never fetched.
|
|
63
|
+
*/
|
|
64
|
+
export type ComparisonSide = {
|
|
65
|
+
name: string;
|
|
66
|
+
sha: string;
|
|
67
|
+
catalog: Catalog | null;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type Comparison = {
|
|
71
|
+
changes: Change[];
|
|
72
|
+
baseSha: string;
|
|
73
|
+
headSha: string;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Resolves a branch or tag name against the forge's refs. The current
|
|
78
|
+
* branch resolves to the bundled catalog; anything else must still exist on
|
|
79
|
+
* the forge, and null says it no longer does.
|
|
80
|
+
*/
|
|
81
|
+
export function comparisonSide(
|
|
82
|
+
name: string,
|
|
83
|
+
refs: ForgeRef[],
|
|
84
|
+
current: { name: string; sha: string; catalog: Catalog },
|
|
85
|
+
): ComparisonSide | null {
|
|
86
|
+
if (name === current.name) return { name, sha: current.sha, catalog: current.catalog };
|
|
87
|
+
const ref = findRef(refs, name);
|
|
88
|
+
if (!ref) return null;
|
|
89
|
+
return { name, sha: ref.commit, catalog: null };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** The architectural diff between two resolved sides. Disabled until both resolve. */
|
|
93
|
+
export function comparisonQuery(
|
|
94
|
+
repo: ForgeRepo | null,
|
|
95
|
+
token: string,
|
|
96
|
+
base: ComparisonSide | null,
|
|
97
|
+
head: ComparisonSide | null,
|
|
98
|
+
) {
|
|
99
|
+
return queryOptions({
|
|
100
|
+
queryKey: forgeKeys.comparison(repo, token, base?.sha ?? "", head?.sha ?? ""),
|
|
101
|
+
queryFn: async (): Promise<Comparison> => {
|
|
102
|
+
if (!repo || !base || !head) throw new Error("The comparison is not resolved yet.");
|
|
103
|
+
const load = (side: ComparisonSide) =>
|
|
104
|
+
side.catalog ? Promise.resolve(side.catalog) : loadForgeCatalog(repo, side.sha, { token });
|
|
105
|
+
const [before, after] = await Promise.all([load(base), load(head)]);
|
|
106
|
+
return { changes: diffCatalogs(before, after), baseSha: base.sha, headSha: head.sha };
|
|
107
|
+
},
|
|
108
|
+
enabled: repo !== null && base !== null && head !== null,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** One source file for the hover preview, at the catalog's commit or from the working tree. */
|
|
113
|
+
export function sourceCodeQuery(location: SourceLocation, token: string) {
|
|
114
|
+
return queryOptions({
|
|
115
|
+
queryKey: sourceKeys.file(location, token),
|
|
116
|
+
queryFn: (): Promise<SourceFile> => loadSourceCode(location, token),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Whether a local Portolan server answers, and what it knows about the last
|
|
122
|
+
* generator run. Asked again on every visit to Settings: the server can be
|
|
123
|
+
* started or stopped while the tab stays open.
|
|
124
|
+
*/
|
|
125
|
+
export function localStatusQuery() {
|
|
126
|
+
return queryOptions({
|
|
127
|
+
queryKey: localKeys.status,
|
|
128
|
+
queryFn: () => localStatus(),
|
|
129
|
+
staleTime: 0,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { buildIndex, validateCatalog, type Catalog } from "../catalog";
|
|
3
|
+
import { registryCatalog } from "./scenarios";
|
|
4
|
+
import {
|
|
5
|
+
callsThrough,
|
|
6
|
+
consumersOf,
|
|
7
|
+
countsOf,
|
|
8
|
+
dependenciesOf,
|
|
9
|
+
dependentsOf,
|
|
10
|
+
interfacesOf,
|
|
11
|
+
moduleBySlug,
|
|
12
|
+
modules,
|
|
13
|
+
packageOf,
|
|
14
|
+
packagesOf,
|
|
15
|
+
registryUrl,
|
|
16
|
+
servicesUsing,
|
|
17
|
+
} from "./registry";
|
|
18
|
+
|
|
19
|
+
const catalog = registryCatalog();
|
|
20
|
+
const index = buildIndex(catalog);
|
|
21
|
+
|
|
22
|
+
function shop() {
|
|
23
|
+
const module = modules(catalog).find((m) => m.id === "buf.build/acme/shop");
|
|
24
|
+
if (!module) throw new Error("no shop module");
|
|
25
|
+
|
|
26
|
+
return module;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function huge() {
|
|
30
|
+
const module = modules(catalog).find((m) => m.id === "buf.build/acme/huge");
|
|
31
|
+
if (!module) throw new Error("no huge module");
|
|
32
|
+
|
|
33
|
+
return module;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A catalog that never published a proto — the state the estate is in today. */
|
|
37
|
+
const bare: Catalog = {
|
|
38
|
+
generatedAt: "2026-01-01T00:00:00Z",
|
|
39
|
+
commit: "0000000",
|
|
40
|
+
contexts: [],
|
|
41
|
+
defs: {},
|
|
42
|
+
flows: [],
|
|
43
|
+
adrs: [],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
describe("the scenario itself", () => {
|
|
47
|
+
it("is a catalog the validator accepts", () => {
|
|
48
|
+
expect(() => validateCatalog(catalog)).not.toThrow();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("modules", () => {
|
|
53
|
+
it("finds a module by the slug the URL uses", () => {
|
|
54
|
+
expect(moduleBySlug(index, "acme-shop")?.id).toBe("buf.build/acme/shop");
|
|
55
|
+
expect(moduleBySlug(index, "nothing")).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("links a module to a registry, at the commit it was built from", () => {
|
|
59
|
+
expect(registryUrl(shop())).toBe(
|
|
60
|
+
"https://buf.build/acme/shop/tree/c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6",
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// A module never published to a registry has nowhere to link to, and a
|
|
65
|
+
// dead link would be worse than none.
|
|
66
|
+
it("has no link for a module that was never published", () => {
|
|
67
|
+
expect(
|
|
68
|
+
registryUrl({ ...shop(), registry: undefined, commit: undefined }),
|
|
69
|
+
).toBeNull();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("what a module holds", () => {
|
|
74
|
+
it("finds the interfaces declared in it, with the service answering on each", () => {
|
|
75
|
+
const declared = interfacesOf(index, shop());
|
|
76
|
+
|
|
77
|
+
expect(declared.map((d) => d.provided.id)).toEqual([
|
|
78
|
+
"shop.v1.Orders",
|
|
79
|
+
"shop.events.v1.Feed",
|
|
80
|
+
]);
|
|
81
|
+
expect(declared[0]?.service.id).toBe("shop.oms");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("groups interfaces by the proto package they sit in", () => {
|
|
85
|
+
const packages = packagesOf(index, shop());
|
|
86
|
+
|
|
87
|
+
expect(packages.map((p) => p.name)).toEqual(["shop.v1", "shop.events.v1"]);
|
|
88
|
+
expect(packages[0]?.interfaces.map((i) => i.provided.id)).toEqual([
|
|
89
|
+
"shop.v1.Orders",
|
|
90
|
+
]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// A module is not only the interfaces in it: a package holding nothing but
|
|
94
|
+
// messages is still part of what was published.
|
|
95
|
+
it("keeps a package the inventory lists but no interface sits in", () => {
|
|
96
|
+
const module = { ...shop(), packages: ["shop.v1", "shop.types.v1"] };
|
|
97
|
+
const packages = packagesOf(index, module);
|
|
98
|
+
|
|
99
|
+
expect(packages.map((p) => p.name)).toContain("shop.types.v1");
|
|
100
|
+
expect(
|
|
101
|
+
packages.find((p) => p.name === "shop.types.v1")?.interfaces,
|
|
102
|
+
).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("counts a message moved by two interfaces once", () => {
|
|
106
|
+
const counts = countsOf(index, shop());
|
|
107
|
+
|
|
108
|
+
// Both interfaces list Message1..N, so the union is smaller than the sum.
|
|
109
|
+
const declared = interfacesOf(index, shop());
|
|
110
|
+
const total = declared.reduce(
|
|
111
|
+
(n, d) => n + (d.provided.messages?.length ?? 0),
|
|
112
|
+
0,
|
|
113
|
+
);
|
|
114
|
+
expect(counts.messages).toBeLessThan(total);
|
|
115
|
+
expect(counts.interfaces).toBe(2);
|
|
116
|
+
expect(counts.methods).toBe(8);
|
|
117
|
+
expect(counts.packages).toBe(2);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("reads the package out of an interface id", () => {
|
|
121
|
+
expect(packageOf("shop.v1.Orders")).toBe("shop.v1");
|
|
122
|
+
expect(packageOf("Orders")).toBe("");
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("who uses a module", () => {
|
|
127
|
+
it("finds a service through what it publishes and what it calls", () => {
|
|
128
|
+
expect(servicesUsing(index, huge()).map((s) => s.id)).toEqual([
|
|
129
|
+
"shop.oms",
|
|
130
|
+
"shop.pricing",
|
|
131
|
+
]);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// A service that both publishes and calls is one user, not two.
|
|
135
|
+
it("does not count one service twice", () => {
|
|
136
|
+
const ids = servicesUsing(index, shop()).map((s) => s.id);
|
|
137
|
+
|
|
138
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// The interesting fact about a module is who ELSE reads it, so its own
|
|
142
|
+
// publisher is not listed among its consumers.
|
|
143
|
+
it("leaves the owner out of the consumers", () => {
|
|
144
|
+
expect(consumersOf(index, shop()).map((s) => s.id)).not.toContain(
|
|
145
|
+
"shop.oms",
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("finds the calls made through a module's vendored copies", () => {
|
|
150
|
+
const calls = callsThrough(catalog, huge());
|
|
151
|
+
|
|
152
|
+
expect(calls).toHaveLength(1);
|
|
153
|
+
expect(calls[0]?.call.id).toBe("huge.v1.Svc1/Method1");
|
|
154
|
+
expect(calls[0]?.service.id).toBe("shop.oms");
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe("dependencies", () => {
|
|
159
|
+
it("resolves a dep the catalog holds and names one it does not", () => {
|
|
160
|
+
const deps = dependenciesOf(index, shop());
|
|
161
|
+
|
|
162
|
+
expect(deps.map((d) => d.id)).toEqual([
|
|
163
|
+
"buf.build/acme/huge",
|
|
164
|
+
"buf.build/other/never-vendored",
|
|
165
|
+
]);
|
|
166
|
+
expect(deps[0]?.module?.slug).toBe("acme-huge");
|
|
167
|
+
// Dangling is normal: a module may depend on one the estate never vendored.
|
|
168
|
+
expect(deps[1]?.module).toBeUndefined();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("finds the modules that depend on this one", () => {
|
|
172
|
+
expect(dependentsOf(catalog, huge()).map((m) => m.id)).toEqual([
|
|
173
|
+
"buf.build/acme/shop",
|
|
174
|
+
]);
|
|
175
|
+
expect(dependentsOf(catalog, shop())).toEqual([]);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// THE REQUIREMENT THE WHOLE FEATURE HAS TO MEET BEFORE IT HAS ANY DATA.
|
|
180
|
+
//
|
|
181
|
+
// An estate that has never published a proto must render exactly as it did
|
|
182
|
+
// before, with no empty sections and no dead rows.
|
|
183
|
+
describe("a catalog with no modules at all", () => {
|
|
184
|
+
const empty = buildIndex(bare);
|
|
185
|
+
const nothing = {
|
|
186
|
+
id: "buf.build/acme/nothing",
|
|
187
|
+
slug: "nothing",
|
|
188
|
+
name: "acme/nothing",
|
|
189
|
+
packages: [],
|
|
190
|
+
files: [],
|
|
191
|
+
source: "",
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
it("has no modules to list", () => {
|
|
195
|
+
expect(modules(bare)).toEqual([]);
|
|
196
|
+
expect(moduleBySlug(empty, "anything")).toBeUndefined();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("answers empty for every lookup rather than throwing", () => {
|
|
200
|
+
expect(interfacesOf(empty, nothing)).toEqual([]);
|
|
201
|
+
expect(servicesUsing(empty, nothing)).toEqual([]);
|
|
202
|
+
expect(consumersOf(empty, nothing)).toEqual([]);
|
|
203
|
+
expect(dependenciesOf(empty, nothing)).toEqual([]);
|
|
204
|
+
expect(dependentsOf(bare, nothing)).toEqual([]);
|
|
205
|
+
expect(callsThrough(bare, nothing)).toEqual([]);
|
|
206
|
+
expect(packagesOf(empty, nothing)).toEqual([]);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("counts nothing", () => {
|
|
210
|
+
expect(countsOf(empty, nothing)).toEqual({
|
|
211
|
+
packages: 0,
|
|
212
|
+
interfaces: 0,
|
|
213
|
+
methods: 0,
|
|
214
|
+
messages: 0,
|
|
215
|
+
deps: 0,
|
|
216
|
+
consumers: 0,
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// The registry side of the catalog: schema modules, and who touches them.
|
|
2
|
+
//
|
|
3
|
+
// A module carries identity and inventory, not schema. Its interfaces are found
|
|
4
|
+
// through `RpcService.module` and their shapes live in `RpcService.messages` and
|
|
5
|
+
// `catalog.defs` — in ONE place, rather than two that can disagree. So almost
|
|
6
|
+
// everything here is a lookup through the index rather than a field read, and
|
|
7
|
+
// the module page is assembled from the catalog it already has.
|
|
8
|
+
//
|
|
9
|
+
// Every function answers empty for a catalog with no modules. That is the whole
|
|
10
|
+
// requirement the registry UI has to meet before it has any data: an estate that
|
|
11
|
+
// has never published a proto must render exactly as it did before.
|
|
12
|
+
|
|
13
|
+
import type {
|
|
14
|
+
Catalog,
|
|
15
|
+
CatalogIndex,
|
|
16
|
+
InterfaceOwner,
|
|
17
|
+
ProtoModule,
|
|
18
|
+
RpcCall,
|
|
19
|
+
Service,
|
|
20
|
+
} from "../catalog";
|
|
21
|
+
import { allModules } from "../catalog";
|
|
22
|
+
|
|
23
|
+
export function modules(catalog: Catalog): ProtoModule[] {
|
|
24
|
+
return allModules(catalog);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function moduleBySlug(
|
|
28
|
+
index: CatalogIndex,
|
|
29
|
+
slug: string,
|
|
30
|
+
): ProtoModule | undefined {
|
|
31
|
+
return index.moduleBySlug.get(slug);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The interfaces declared in a module, with the service that answers on each.
|
|
36
|
+
*
|
|
37
|
+
* This is the join the whole registry page hangs on, and it is one string
|
|
38
|
+
* comparison: an interface says which module it came from, and its id is the
|
|
39
|
+
* same `shop.v1.Orders` the estate already uses everywhere else.
|
|
40
|
+
*/
|
|
41
|
+
export function interfacesOf(
|
|
42
|
+
index: CatalogIndex,
|
|
43
|
+
module: ProtoModule,
|
|
44
|
+
): InterfaceOwner[] {
|
|
45
|
+
return index.interfacesByModule.get(module.id) ?? [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Every service that publishes the module, vendors it, or calls into it. */
|
|
49
|
+
export function servicesUsing(
|
|
50
|
+
index: CatalogIndex,
|
|
51
|
+
module: ProtoModule,
|
|
52
|
+
): Service[] {
|
|
53
|
+
return index.servicesUsingModule.get(module.id) ?? [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The services that read the module without publishing it.
|
|
58
|
+
*
|
|
59
|
+
* The interesting fact about a module is usually who ELSE reads it, so the
|
|
60
|
+
* owner is taken out rather than listed among its own consumers.
|
|
61
|
+
*/
|
|
62
|
+
export function consumersOf(
|
|
63
|
+
index: CatalogIndex,
|
|
64
|
+
module: ProtoModule,
|
|
65
|
+
): Service[] {
|
|
66
|
+
return servicesUsing(index, module).filter(
|
|
67
|
+
(service) => service.id !== module.owner,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The calls made through a module's vendored copies, across the estate. */
|
|
72
|
+
export function callsThrough(
|
|
73
|
+
catalog: Catalog,
|
|
74
|
+
module: ProtoModule,
|
|
75
|
+
): { service: Service; call: RpcCall }[] {
|
|
76
|
+
const out: { service: Service; call: RpcCall }[] = [];
|
|
77
|
+
|
|
78
|
+
for (const context of catalog.contexts) {
|
|
79
|
+
for (const service of context.services) {
|
|
80
|
+
for (const call of service.consumes) {
|
|
81
|
+
if (call.module === module.id) out.push({ service, call });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** A dependency, resolved when the catalog holds it and named when it does not. */
|
|
90
|
+
export interface Dependency {
|
|
91
|
+
id: string;
|
|
92
|
+
module: ProtoModule | undefined;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* What a module depends on.
|
|
97
|
+
*
|
|
98
|
+
* A dangling dep is normal rather than broken: a module may depend on one the
|
|
99
|
+
* estate never vendored, and the honest answer is to name it and say the
|
|
100
|
+
* catalog does not hold it.
|
|
101
|
+
*/
|
|
102
|
+
export function dependenciesOf(
|
|
103
|
+
index: CatalogIndex,
|
|
104
|
+
module: ProtoModule,
|
|
105
|
+
): Dependency[] {
|
|
106
|
+
return (module.deps ?? []).map((id) => ({
|
|
107
|
+
id,
|
|
108
|
+
module: index.moduleById.get(id),
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** The modules that depend on this one, in catalog order. */
|
|
113
|
+
export function dependentsOf(
|
|
114
|
+
catalog: Catalog,
|
|
115
|
+
module: ProtoModule,
|
|
116
|
+
): ProtoModule[] {
|
|
117
|
+
return allModules(catalog).filter((other) =>
|
|
118
|
+
(other.deps ?? []).includes(module.id),
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** What the module page counts, so the header and the tabs agree. */
|
|
123
|
+
export interface ModuleCounts {
|
|
124
|
+
packages: number;
|
|
125
|
+
interfaces: number;
|
|
126
|
+
methods: number;
|
|
127
|
+
messages: number;
|
|
128
|
+
deps: number;
|
|
129
|
+
consumers: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function countsOf(
|
|
133
|
+
index: CatalogIndex,
|
|
134
|
+
module: ProtoModule,
|
|
135
|
+
): ModuleCounts {
|
|
136
|
+
const declared = interfacesOf(index, module);
|
|
137
|
+
|
|
138
|
+
// Messages are counted by NAME across the module's interfaces: two
|
|
139
|
+
// interfaces both moving a `Money` are moving one type, and counting it
|
|
140
|
+
// twice would say the module holds more than it does.
|
|
141
|
+
const messages = new Set<string>();
|
|
142
|
+
for (const { provided } of declared) {
|
|
143
|
+
for (const message of provided.messages ?? []) messages.add(message.name);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
packages: module.packages.length,
|
|
148
|
+
interfaces: declared.length,
|
|
149
|
+
methods: declared.reduce(
|
|
150
|
+
(n, { provided }) => n + provided.methods.length,
|
|
151
|
+
0,
|
|
152
|
+
),
|
|
153
|
+
messages: messages.size,
|
|
154
|
+
deps: (module.deps ?? []).length,
|
|
155
|
+
consumers: consumersOf(index, module).length,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The interfaces of a module grouped by the proto package they sit in.
|
|
161
|
+
*
|
|
162
|
+
* Packages come from the module's own inventory, so a package holding only
|
|
163
|
+
* messages still appears — a module is not only the interfaces in it.
|
|
164
|
+
*/
|
|
165
|
+
export interface ModulePackage {
|
|
166
|
+
name: string;
|
|
167
|
+
interfaces: InterfaceOwner[];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function packagesOf(
|
|
171
|
+
index: CatalogIndex,
|
|
172
|
+
module: ProtoModule,
|
|
173
|
+
): ModulePackage[] {
|
|
174
|
+
const declared = interfacesOf(index, module);
|
|
175
|
+
const names = [...module.packages];
|
|
176
|
+
|
|
177
|
+
// An interface whose package the inventory does not list is still real: the
|
|
178
|
+
// module was described by one source and the interface by another, and the
|
|
179
|
+
// page should show what it has rather than hide the disagreement.
|
|
180
|
+
for (const { provided } of declared) {
|
|
181
|
+
const name = packageOf(provided.id);
|
|
182
|
+
if (name && !names.includes(name)) names.push(name);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return names.map((name) => ({
|
|
186
|
+
name,
|
|
187
|
+
interfaces: declared.filter(
|
|
188
|
+
({ provided }) => packageOf(provided.id) === name,
|
|
189
|
+
),
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** The proto package of `shop.v1.Orders`: everything before the last segment. */
|
|
194
|
+
export function packageOf(interfaceId: string): string {
|
|
195
|
+
const at = interfaceId.lastIndexOf(".");
|
|
196
|
+
|
|
197
|
+
return at < 0 ? "" : interfaceId.slice(0, at);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Where a module can be read on the web, when it was published somewhere. */
|
|
201
|
+
export function registryUrl(module: ProtoModule): string | null {
|
|
202
|
+
if (!module.registry) return null;
|
|
203
|
+
|
|
204
|
+
const at = module.commit ? `/tree/${module.commit}` : "";
|
|
205
|
+
|
|
206
|
+
return `https://${module.registry}/${module.name}${at}`;
|
|
207
|
+
}
|
|
208
|
+
|