@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,95 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// The only file that reads the environment.
|
|
4
|
+
//
|
|
5
|
+
// The plugin protocol says a plugin has "no ambient state to read, no
|
|
6
|
+
// environment". That is about FACTS: nothing about the estate may come from
|
|
7
|
+
// anywhere but the request, or a fragment stops being reproducible from the
|
|
8
|
+
// tree it describes.
|
|
9
|
+
//
|
|
10
|
+
// A credential is not a fact about the estate. It is how the transport is
|
|
11
|
+
// allowed to open a socket - it changes whether the fetch succeeds, never what
|
|
12
|
+
// the fetch says. Isolating it in one file that nothing else calls is what
|
|
13
|
+
// keeps that claim checkable.
|
|
14
|
+
//
|
|
15
|
+
// It is also why this plugin can never be wasm. It needs a socket and a
|
|
16
|
+
// secret, and `process` exists for exactly that trade.
|
|
17
|
+
|
|
18
|
+
import (
|
|
19
|
+
"encoding/base64"
|
|
20
|
+
"os"
|
|
21
|
+
"strings"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
// The names Confluent's own tools use, longest first so the specific one wins
|
|
25
|
+
// over a shell that exports both.
|
|
26
|
+
const (
|
|
27
|
+
KeyEnv = "CONFLUENT_SCHEMA_REGISTRY_API_KEY"
|
|
28
|
+
SecretEnv = "CONFLUENT_SCHEMA_REGISTRY_API_SECRET"
|
|
29
|
+
|
|
30
|
+
// Short aliases, for a self-hosted registry nobody would call Confluent.
|
|
31
|
+
ShortKeyEnv = "CSR_API_KEY"
|
|
32
|
+
ShortSecretEnv = "CSR_API_SECRET"
|
|
33
|
+
|
|
34
|
+
// TokenEnv is a whole Authorization value, for a registry fronted by
|
|
35
|
+
// something that wants a bearer token rather than an API key pair.
|
|
36
|
+
TokenEnv = "CSR_TOKEN"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
// authorization is the header value to send, or "" for none.
|
|
40
|
+
//
|
|
41
|
+
// None is a normal outcome, not a failure: a registry inside a private network
|
|
42
|
+
// is commonly open to it, and the local one the tests run against certainly is.
|
|
43
|
+
func authorization() string {
|
|
44
|
+
if raw := env(TokenEnv); raw != "" {
|
|
45
|
+
// Passed through when it already names its scheme, so the same
|
|
46
|
+
// variable serves "Bearer ..." and an opaque token a proxy expects
|
|
47
|
+
// bare. Guessing on the caller's behalf is how a working token starts
|
|
48
|
+
// failing after somebody adds a prefix.
|
|
49
|
+
if strings.Contains(raw, " ") {
|
|
50
|
+
return raw
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return "Bearer " + raw
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
key := first(env(KeyEnv), env(ShortKeyEnv))
|
|
57
|
+
secret := first(env(SecretEnv), env(ShortSecretEnv))
|
|
58
|
+
if key == "" || secret == "" {
|
|
59
|
+
return ""
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return "Basic " + base64.StdEncoding.EncodeToString([]byte(key+":"+secret))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func env(name string) string { return strings.TrimSpace(os.Getenv(name)) }
|
|
66
|
+
|
|
67
|
+
func first(values ...string) string {
|
|
68
|
+
for _, value := range values {
|
|
69
|
+
if value != "" {
|
|
70
|
+
return value
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return ""
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// OfflineEnv turns the fetch off. Explicit, rather than inferred from a socket
|
|
78
|
+
// timeout: CI sets it in one line, and a build that would otherwise depend on
|
|
79
|
+
// the registry being up cannot silently start doing so again.
|
|
80
|
+
const OfflineEnv = "PORTOLAN_OFFLINE"
|
|
81
|
+
|
|
82
|
+
func offline() bool {
|
|
83
|
+
if env(OfflineEnv) != "" {
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// CI verifies what was committed. It never needs to reach the registry, and
|
|
88
|
+
// a fork's pull request has no secret to reach it with.
|
|
89
|
+
switch strings.ToLower(env("CI")) {
|
|
90
|
+
case "", "0", "false":
|
|
91
|
+
return false
|
|
92
|
+
default:
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// Replaying a fetch from what is already on disk.
|
|
4
|
+
//
|
|
5
|
+
// The cache is not a second copy of anything: it IS the tree. The schemas this
|
|
6
|
+
// plugin fetched were written by the host through the ordinary Response.Files
|
|
7
|
+
// path, so they are committed, reviewable, and GC'd when the step stops naming
|
|
8
|
+
// them. Reading them back and checking them against the lock is what lets a
|
|
9
|
+
// build that never opens a socket produce byte-identical output.
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"encoding/json"
|
|
13
|
+
"fmt"
|
|
14
|
+
"os"
|
|
15
|
+
"path/filepath"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
// cached is one subject's files, read back from the tree.
|
|
19
|
+
type cached struct {
|
|
20
|
+
registry string
|
|
21
|
+
lock LockSubject
|
|
22
|
+
files map[string][]byte
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// replay reads a subject's committed copy and checks it against its lock.
|
|
26
|
+
//
|
|
27
|
+
// An incomplete or edited cache is reported rather than patched over. The two
|
|
28
|
+
// failures it distinguishes matter: nothing on disk means there is nothing to
|
|
29
|
+
// fall back to, and bytes that no longer match their digest mean somebody
|
|
30
|
+
// edited a vendored copy - the drift docs/adr/org.0001.md wants visible.
|
|
31
|
+
func replay(dir string) (*cached, error) {
|
|
32
|
+
at := filepath.Join(dir, LockName)
|
|
33
|
+
|
|
34
|
+
raw, err := os.ReadFile(at)
|
|
35
|
+
if os.IsNotExist(err) {
|
|
36
|
+
return nil, fmt.Errorf("no %s in %s", LockName, filepath.ToSlash(dir))
|
|
37
|
+
}
|
|
38
|
+
if err != nil {
|
|
39
|
+
return nil, err
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var lock Lock
|
|
43
|
+
if err := json.Unmarshal(raw, &lock); err != nil {
|
|
44
|
+
return nil, fmt.Errorf("%s: %w", filepath.ToSlash(at), err)
|
|
45
|
+
}
|
|
46
|
+
if len(lock.Subjects) != 1 {
|
|
47
|
+
return nil, fmt.Errorf("%s names %d subjects; expected exactly one",
|
|
48
|
+
filepath.ToSlash(at), len(lock.Subjects))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
entry := lock.Subjects[0]
|
|
52
|
+
files := make(map[string][]byte, len(entry.Files))
|
|
53
|
+
|
|
54
|
+
for _, want := range entry.Files {
|
|
55
|
+
content, err := os.ReadFile(filepath.Join(dir, filepath.FromSlash(want.Path)))
|
|
56
|
+
if os.IsNotExist(err) {
|
|
57
|
+
return nil, fmt.Errorf("%s is in the lock but not on disk", want.Path)
|
|
58
|
+
}
|
|
59
|
+
if err != nil {
|
|
60
|
+
return nil, err
|
|
61
|
+
}
|
|
62
|
+
if got := digestOf(content); got != want.SHA256 {
|
|
63
|
+
return nil, fmt.Errorf("%s does not match its digest; the vendored copy was edited by hand", want.Path)
|
|
64
|
+
}
|
|
65
|
+
files[want.Path] = content
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return &cached{registry: lock.Registry, lock: entry, files: files}, nil
|
|
69
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
_ "embed"
|
|
5
|
+
|
|
6
|
+
"github.com/shortlink-org/portolan/plugin"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
//go:embed options.schema.json
|
|
10
|
+
var optionsSchema []byte
|
|
11
|
+
|
|
12
|
+
func descriptor() plugin.Descriptor {
|
|
13
|
+
return plugin.Descriptor{
|
|
14
|
+
Name: "fetch-csr",
|
|
15
|
+
Summary: "Fetches pinned subject versions from a Confluent Schema Registry into the tree, with a lock beside each, so a schema published to a registry can be read without talking to it.",
|
|
16
|
+
Phases: []string{plugin.PhaseExtract},
|
|
17
|
+
Options: optionsSchema,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// Deciding whether to fetch, and what to do when the fetch cannot happen.
|
|
4
|
+
//
|
|
5
|
+
// The rules below are the design, not error handling. The one that matters
|
|
6
|
+
// most is the third: a failed fetch with no cache is a NON-ZERO EXIT, never a
|
|
7
|
+
// short file list. The host deletes files a step stops naming, and dropping a
|
|
8
|
+
// repository's vendored schemas because a laptop went offline is worse than a
|
|
9
|
+
// red build.
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"fmt"
|
|
13
|
+
"path"
|
|
14
|
+
"path/filepath"
|
|
15
|
+
"sort"
|
|
16
|
+
"strconv"
|
|
17
|
+
"strings"
|
|
18
|
+
|
|
19
|
+
"github.com/shortlink-org/portolan/plugin"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
// fetch takes no plugin.Input: it reads nothing out of the tree being
|
|
23
|
+
// described. Its `cache` is repo-relative, like every other path in the
|
|
24
|
+
// manifest, and everything else it needs is in the options.
|
|
25
|
+
func fetch(opts Options) (plugin.Response, error) {
|
|
26
|
+
b := &plugin.Builder{}
|
|
27
|
+
|
|
28
|
+
if strings.TrimSpace(opts.Registry) == "" {
|
|
29
|
+
return plugin.Response{}, fmt.Errorf("no registry: name the schema registry's base URL in the manifest")
|
|
30
|
+
}
|
|
31
|
+
if len(opts.Subjects) == 0 {
|
|
32
|
+
return plugin.Response{}, fmt.Errorf("no subjects to fetch: name at least one in the manifest")
|
|
33
|
+
}
|
|
34
|
+
if opts.Cache == "" {
|
|
35
|
+
return plugin.Response{}, fmt.Errorf(
|
|
36
|
+
"no cache directory: set `cache` to the same path as the step's `out`, " +
|
|
37
|
+
"so an offline run can replay what the last online one wrote")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Sorted, so the file list and the diagnostics come out the same way every
|
|
41
|
+
// run whatever order the manifest happens to list them in.
|
|
42
|
+
queue := append([]Subject(nil), opts.Subjects...)
|
|
43
|
+
sort.Slice(queue, func(i, j int) bool { return queue[i].Subject < queue[j].Subject })
|
|
44
|
+
|
|
45
|
+
c := newClient(opts.Registry, authorization())
|
|
46
|
+
skip := offline()
|
|
47
|
+
|
|
48
|
+
// Two subjects that slug to the same directory would overwrite each other
|
|
49
|
+
// silently, and one subject wanted at two versions cannot be held in a
|
|
50
|
+
// tree that keeps one version per subject. Both are refused by name rather
|
|
51
|
+
// than resolved: the manifest is what has to change.
|
|
52
|
+
claimed := map[string]Subject{}
|
|
53
|
+
done := map[string]bool{}
|
|
54
|
+
|
|
55
|
+
for len(queue) > 0 {
|
|
56
|
+
want := queue[0]
|
|
57
|
+
queue = queue[1:]
|
|
58
|
+
|
|
59
|
+
if want.Subject == "" {
|
|
60
|
+
return plugin.Response{}, fmt.Errorf("a subject entry names no subject")
|
|
61
|
+
}
|
|
62
|
+
if held, taken := claimed[want.Subject]; taken {
|
|
63
|
+
if held.Version != want.Version {
|
|
64
|
+
return plugin.Response{}, fmt.Errorf(
|
|
65
|
+
"%s is wanted at version %s and at version %s; the tree keeps one version per subject, so pin one",
|
|
66
|
+
want.Subject, pin(held.Version), pin(want.Version))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
dir := slugOf(want.Subject)
|
|
73
|
+
if done[dir] {
|
|
74
|
+
// Not caught by `claimed`, which is keyed by subject: two
|
|
75
|
+
// different subjects can slug into one directory.
|
|
76
|
+
return plugin.Response{}, fmt.Errorf(
|
|
77
|
+
"%s and another subject both vendor into %s; the tree cannot hold both",
|
|
78
|
+
want.Subject, dir)
|
|
79
|
+
}
|
|
80
|
+
claimed[want.Subject] = want
|
|
81
|
+
done[dir] = true
|
|
82
|
+
|
|
83
|
+
at := filepath.Join(filepath.FromSlash(opts.Cache), filepath.FromSlash(dir))
|
|
84
|
+
|
|
85
|
+
var (
|
|
86
|
+
refs []Reference
|
|
87
|
+
err error
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if skip {
|
|
91
|
+
refs, err = emitCached(b, opts.Registry, dir, at, want, "offline")
|
|
92
|
+
if err != nil {
|
|
93
|
+
return plugin.Response{}, err
|
|
94
|
+
}
|
|
95
|
+
} else if refs, err = live(c, b, opts.Registry, dir, want); err != nil {
|
|
96
|
+
// Rule 2: the tree still holds a good copy, so the output is
|
|
97
|
+
// unchanged and `--check` stays clean.
|
|
98
|
+
cachedRefs, cacheErr := emitCached(b, opts.Registry, dir, at, want, err.Error())
|
|
99
|
+
if cacheErr != nil {
|
|
100
|
+
// Rule 3: nothing to fall back to.
|
|
101
|
+
return plugin.Response{}, fmt.Errorf(
|
|
102
|
+
"%s could not be fetched (%w) and there is no usable copy in the tree (%v)",
|
|
103
|
+
want.Subject, err, cacheErr)
|
|
104
|
+
}
|
|
105
|
+
refs = cachedRefs
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// A referenced subject is pinned by the schema that references it, so
|
|
109
|
+
// following one needs no permission from the manifest and adds no
|
|
110
|
+
// lottery: the version is part of the bytes we already have.
|
|
111
|
+
following := make([]Subject, 0, len(refs))
|
|
112
|
+
for _, ref := range refs {
|
|
113
|
+
if ref.Subject == "" || claimed[ref.Subject].Subject != "" {
|
|
114
|
+
continue
|
|
115
|
+
}
|
|
116
|
+
following = append(following, Subject{Subject: ref.Subject, Version: ref.Version})
|
|
117
|
+
}
|
|
118
|
+
sort.Slice(following, func(i, j int) bool { return following[i].Subject < following[j].Subject })
|
|
119
|
+
queue = append(queue, following...)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return b.Response(), nil
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// live fetches one subject, pinning it first if the manifest did not.
|
|
126
|
+
func live(c *client, b *plugin.Builder, registry, dir string, want Subject) ([]Reference, error) {
|
|
127
|
+
got, err := c.version(want.Subject, want.Version)
|
|
128
|
+
if err != nil {
|
|
129
|
+
return nil, err
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if want.Version == 0 {
|
|
133
|
+
// Rule: pin, or every run is a lottery. Resolving `latest` still
|
|
134
|
+
// works, but it is said out loud, because two runs a day apart would
|
|
135
|
+
// then produce two different trees from one manifest.
|
|
136
|
+
b.Warn(want.Subject, fmt.Sprintf(
|
|
137
|
+
"is not pinned; \"latest\" resolved to version %d. Pin it in portolan.json or every run is a lottery.",
|
|
138
|
+
got.Version))
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
extension, err := extensionFor(got.SchemaType)
|
|
142
|
+
if err != nil {
|
|
143
|
+
return nil, fmt.Errorf("%s at version %d: %w", want.Subject, got.Version, err)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
name := "v" + strconv.Itoa(got.Version) + extension
|
|
147
|
+
content := body(got.SchemaType, got.Schema)
|
|
148
|
+
|
|
149
|
+
entry := LockSubject{
|
|
150
|
+
Subject: want.Subject,
|
|
151
|
+
Version: got.Version,
|
|
152
|
+
ID: got.ID,
|
|
153
|
+
GUID: got.GUID,
|
|
154
|
+
SchemaType: schemaType(got.SchemaType),
|
|
155
|
+
References: got.References,
|
|
156
|
+
Files: []LockEntry{{
|
|
157
|
+
Path: name,
|
|
158
|
+
SHA256: digestOf([]byte(content)),
|
|
159
|
+
Size: len(content),
|
|
160
|
+
}},
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
b.File(path.Join(dir, name), content)
|
|
164
|
+
if err := emitLock(b, registry, dir, entry); err != nil {
|
|
165
|
+
return nil, err
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return entry.References, nil
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// emitCached re-emits the committed copy unchanged.
|
|
172
|
+
//
|
|
173
|
+
// Byte-identical to what the last online run wrote, which is the whole point:
|
|
174
|
+
// `gen:check` sees no drift, so CI can verify an estate whose schemas live in a
|
|
175
|
+
// registry it never talks to.
|
|
176
|
+
func emitCached(b *plugin.Builder, registry, dir, at string, want Subject, why string) ([]Reference, error) {
|
|
177
|
+
if want.Version == 0 {
|
|
178
|
+
return nil, fmt.Errorf("%s is not pinned to a version, so there is nothing to replay", want.Subject)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
held, err := replay(at)
|
|
182
|
+
if err != nil {
|
|
183
|
+
return nil, err
|
|
184
|
+
}
|
|
185
|
+
if held.lock.Version != want.Version {
|
|
186
|
+
return nil, fmt.Errorf("%s holds version %d but the manifest pins %d; fetch it",
|
|
187
|
+
want.Subject, held.lock.Version, want.Version)
|
|
188
|
+
}
|
|
189
|
+
if held.lock.Subject != want.Subject {
|
|
190
|
+
return nil, fmt.Errorf("%s vendors into %s, which holds %s",
|
|
191
|
+
want.Subject, filepath.ToSlash(at), held.lock.Subject)
|
|
192
|
+
}
|
|
193
|
+
if held.registry != "" && held.registry != registry {
|
|
194
|
+
return nil, fmt.Errorf("%s was fetched from %s but the manifest names %s; fetch it again",
|
|
195
|
+
want.Subject, held.registry, registry)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for _, entry := range held.lock.Files {
|
|
199
|
+
b.File(path.Join(dir, entry.Path), string(held.files[entry.Path]))
|
|
200
|
+
}
|
|
201
|
+
if err := emitLock(b, registry, dir, held.lock); err != nil {
|
|
202
|
+
return nil, err
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
b.Warn(want.Subject, "not fetched ("+why+"); the copy committed in this repository is used unchanged")
|
|
206
|
+
|
|
207
|
+
return held.lock.References, nil
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
func emitLock(b *plugin.Builder, registry, dir string, entry LockSubject) error {
|
|
211
|
+
lock, err := Lock{Registry: registry, Subjects: []LockSubject{entry}}.encode()
|
|
212
|
+
if err != nil {
|
|
213
|
+
return err
|
|
214
|
+
}
|
|
215
|
+
b.File(path.Join(dir, LockName), lock)
|
|
216
|
+
|
|
217
|
+
return nil
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// slugOf is the directory a subject vendors into.
|
|
221
|
+
//
|
|
222
|
+
// A subject name is whatever the producer registered, and under
|
|
223
|
+
// RecordNameStrategy that is a language's full name; a directory is not. So
|
|
224
|
+
// everything outside a safe set becomes an underscore, and the true subject is
|
|
225
|
+
// written in the lock beside the file rather than inferred back from the path.
|
|
226
|
+
func slugOf(subject string) string {
|
|
227
|
+
var out strings.Builder
|
|
228
|
+
|
|
229
|
+
for _, r := range subject {
|
|
230
|
+
switch {
|
|
231
|
+
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9':
|
|
232
|
+
out.WriteRune(r)
|
|
233
|
+
case r == '.' || r == '-' || r == '_':
|
|
234
|
+
out.WriteRune(r)
|
|
235
|
+
default:
|
|
236
|
+
out.WriteByte('_')
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
slug := strings.Trim(out.String(), ".")
|
|
241
|
+
if slug == "" {
|
|
242
|
+
return "_"
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return slug
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
func pin(version int) string {
|
|
249
|
+
if version == 0 {
|
|
250
|
+
return "latest"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return strconv.Itoa(version)
|
|
254
|
+
}
|