@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,269 @@
|
|
|
1
|
+
// Motion, in two halves.
|
|
2
|
+
//
|
|
3
|
+
// CSS owns what appears and what changes colour: a card rising on mount, a
|
|
4
|
+
// row hovered, a stagger of cards. That is `stagger-in`, `t-micro`
|
|
5
|
+
// in index.css, driven by the tokens declared there.
|
|
6
|
+
//
|
|
7
|
+
// Motion (motion.dev) owns the three things CSS cannot say on its own: an
|
|
8
|
+
// element that leaves (an exit needs the node to stay mounted while it goes),
|
|
9
|
+
// an element that changes place or size (layout), and an element that is the
|
|
10
|
+
// same thing in two places (a tab indicator that slides, `layoutId`).
|
|
11
|
+
//
|
|
12
|
+
// The two halves share one clock. The durations and easings below are the CSS
|
|
13
|
+
// tokens spelled as numbers; motion.test.ts holds them to index.css so the
|
|
14
|
+
// two cannot drift.
|
|
15
|
+
|
|
16
|
+
import { useEffect, useState } from "react";
|
|
17
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
18
|
+
import {
|
|
19
|
+
AnimatePresence,
|
|
20
|
+
LayoutGroup,
|
|
21
|
+
LazyMotion,
|
|
22
|
+
MotionConfig,
|
|
23
|
+
m,
|
|
24
|
+
} from "motion/react";
|
|
25
|
+
import type { TargetAndTransition, Transition } from "motion/react";
|
|
26
|
+
|
|
27
|
+
export { AnimatePresence, LayoutGroup, m };
|
|
28
|
+
|
|
29
|
+
/* ---------------------------------------------------------------------------
|
|
30
|
+
The clock: index.css --dur-* and --ease-*, as Motion reads them.
|
|
31
|
+
--------------------------------------------------------------------------- */
|
|
32
|
+
|
|
33
|
+
/** Seconds. `--dur-micro` and friends in index.css, divided by a thousand. */
|
|
34
|
+
export const DURATION = {
|
|
35
|
+
micro: 0.15,
|
|
36
|
+
panel: 0.25,
|
|
37
|
+
page: 0.25,
|
|
38
|
+
narrative: 0.4,
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
/** `--ease-out`: fast out, long settle. Anything that arrives or leaves. */
|
|
42
|
+
export const EASE_OUT = [0.2, 0, 0, 1] as const;
|
|
43
|
+
/** `--ease-in-out`: symmetric. Anything that changes in place. */
|
|
44
|
+
export const EASE_IN_OUT = [0.4, 0, 0.2, 1] as const;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* One transition per token, plus the one spring.
|
|
48
|
+
*
|
|
49
|
+
* `settle` is for a thing that moves to a new place and is still the same
|
|
50
|
+
* thing when it gets there: the active-tab indicator, a chevron turning, a
|
|
51
|
+
* highlight following the current step. A spring reads as weight; a duration
|
|
52
|
+
* reads as a cut. Its numbers are chosen to land in about the panel duration
|
|
53
|
+
* with no visible overshoot.
|
|
54
|
+
*/
|
|
55
|
+
export const transitions = {
|
|
56
|
+
micro: { duration: DURATION.micro, ease: EASE_OUT },
|
|
57
|
+
panel: { duration: DURATION.panel, ease: EASE_OUT },
|
|
58
|
+
page: { duration: DURATION.page, ease: EASE_OUT },
|
|
59
|
+
narrative: { duration: DURATION.narrative, ease: EASE_IN_OUT },
|
|
60
|
+
settle: { type: "spring", stiffness: 520, damping: 42, mass: 1 },
|
|
61
|
+
} as const satisfies Record<string, Transition>;
|
|
62
|
+
|
|
63
|
+
/* ---------------------------------------------------------------------------
|
|
64
|
+
Presence: how a thing arrives and how it leaves. Spread onto an `m.*`
|
|
65
|
+
element inside an <AnimatePresence>.
|
|
66
|
+
--------------------------------------------------------------------------- */
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The transition rides inside the targets, not as a prop of its own: Headless
|
|
70
|
+
* UI's DialogPanel has a boolean `transition` of its own, and a preset that
|
|
71
|
+
* carried one could not be spread onto it.
|
|
72
|
+
*/
|
|
73
|
+
interface Presence {
|
|
74
|
+
initial: TargetAndTransition;
|
|
75
|
+
animate: TargetAndTransition;
|
|
76
|
+
exit: TargetAndTransition;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** A backdrop, a toast body: opacity only. */
|
|
80
|
+
export const fade: Presence = {
|
|
81
|
+
initial: { opacity: 0 },
|
|
82
|
+
animate: { opacity: 1, transition: transitions.panel },
|
|
83
|
+
exit: { opacity: 0, transition: transitions.panel },
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** A modal: it grows into place by two percent, and shrinks the same on exit. */
|
|
87
|
+
export const scaleIn: Presence = {
|
|
88
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
89
|
+
animate: { opacity: 1, scale: 1, transition: transitions.panel },
|
|
90
|
+
exit: { opacity: 0, scale: 0.98, transition: transitions.panel },
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A route: rises the eight pixels on the page duration, and leaves on the
|
|
95
|
+
* micro duration, opacity only. The reader has already asked for the next
|
|
96
|
+
* page; the old one should be out of the way, not making an exit.
|
|
97
|
+
*/
|
|
98
|
+
export const page: Presence = {
|
|
99
|
+
initial: { opacity: 0, y: 8 },
|
|
100
|
+
animate: { opacity: 1, y: 0, transition: transitions.page },
|
|
101
|
+
exit: { opacity: 0, transition: transitions.micro },
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/** A row, a toast: rises the same eight pixels a page rises. */
|
|
105
|
+
export const rise: Presence = {
|
|
106
|
+
initial: { opacity: 0, y: 8 },
|
|
107
|
+
animate: { opacity: 1, y: 0, transition: transitions.panel },
|
|
108
|
+
exit: { opacity: 0, y: 8, transition: transitions.panel },
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A panel that arrives from an edge and leaves the way it came: the catalog
|
|
113
|
+
* drawer from the left (`-100%`), the detail sheet from the right (`100%`).
|
|
114
|
+
* A string is a percentage of the element's own width, so the sheet need not
|
|
115
|
+
* know how wide it is.
|
|
116
|
+
*/
|
|
117
|
+
export function slideFrom(x: number | string): Presence {
|
|
118
|
+
return {
|
|
119
|
+
initial: { x },
|
|
120
|
+
animate: { x: 0, transition: transitions.panel },
|
|
121
|
+
exit: { x, transition: transitions.panel },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* A branch that opens: height from nothing to whatever its children need, and
|
|
127
|
+
* back. Overflow is the component's, below: hidden while the height moves,
|
|
128
|
+
* visible once it has landed.
|
|
129
|
+
*/
|
|
130
|
+
export const unfold: Presence = {
|
|
131
|
+
initial: { height: 0, opacity: 0 },
|
|
132
|
+
animate: { height: "auto", opacity: 1, transition: transitions.panel },
|
|
133
|
+
exit: { height: 0, opacity: 0, transition: transitions.panel },
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* `unfold`, as a component: the children are there while `open`, and arrive
|
|
138
|
+
* and leave on the preset. `initial={false}` because a tree restored from the
|
|
139
|
+
* last session must not open every branch on the way in.
|
|
140
|
+
*/
|
|
141
|
+
export function Unfold({
|
|
142
|
+
open,
|
|
143
|
+
children,
|
|
144
|
+
}: {
|
|
145
|
+
open: boolean;
|
|
146
|
+
children: ReactNode;
|
|
147
|
+
}) {
|
|
148
|
+
return (
|
|
149
|
+
<AnimatePresence initial={false}>
|
|
150
|
+
{open ? <UnfoldBox>{children}</UnfoldBox> : null}
|
|
151
|
+
</AnimatePresence>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Overflow is hidden only while the box is moving. Open and at rest it is
|
|
157
|
+
* visible, so the focus ring on the first or last row inside is not clipped
|
|
158
|
+
* by the box that grew to hold it. (`transitionEnd` on the target would say
|
|
159
|
+
* the same, but Motion 13 applies it only to a static render, not after the
|
|
160
|
+
* animation it was meant to end.)
|
|
161
|
+
*/
|
|
162
|
+
function UnfoldBox({ children }: { children: ReactNode }) {
|
|
163
|
+
const [moving, setMoving] = useState(false);
|
|
164
|
+
return (
|
|
165
|
+
<m.div
|
|
166
|
+
{...unfold}
|
|
167
|
+
style={{ overflow: moving ? "hidden" : "visible" }}
|
|
168
|
+
onAnimationStart={() => setMoving(true)}
|
|
169
|
+
onAnimationComplete={() => setMoving(false)}
|
|
170
|
+
>
|
|
171
|
+
{children}
|
|
172
|
+
</m.div>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* ---------------------------------------------------------------------------
|
|
177
|
+
The provider. Once, at the root.
|
|
178
|
+
--------------------------------------------------------------------------- */
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* The feature bundle arrives after first paint; until then an `m.*` element
|
|
182
|
+
* renders as its plain tag, at its `animate` values. That is the correct
|
|
183
|
+
* first frame anyway: nothing on the first screen leaves or moves.
|
|
184
|
+
*/
|
|
185
|
+
const loadFeatures = () => import("./motion-features").then((mod) => mod.default);
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* `reducedMotion="user"` makes every `m.*` element read the same media query
|
|
189
|
+
* `useReducedMotion` below reads: transforms and layout stop moving, opacity
|
|
190
|
+
* still crossfades, so a reader who asked for less motion still sees things
|
|
191
|
+
* arrive and leave, just without travelling.
|
|
192
|
+
*
|
|
193
|
+
* `strict` throws on a `motion.*` element under this tree - the full one,
|
|
194
|
+
* with every feature bundled in. Only `m.*` belongs here.
|
|
195
|
+
*/
|
|
196
|
+
export function MotionProvider({ children }: { children: ReactNode }) {
|
|
197
|
+
return (
|
|
198
|
+
<LazyMotion features={loadFeatures} strict>
|
|
199
|
+
<MotionConfig reducedMotion="user" transition={transitions.panel}>
|
|
200
|
+
{children}
|
|
201
|
+
</MotionConfig>
|
|
202
|
+
</LazyMotion>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* ---------------------------------------------------------------------------
|
|
207
|
+
The pieces that predate Motion and stay: a count that ticks up, and the
|
|
208
|
+
media query for code that animates by hand.
|
|
209
|
+
--------------------------------------------------------------------------- */
|
|
210
|
+
|
|
211
|
+
const QUERY = "(prefers-reduced-motion: reduce)";
|
|
212
|
+
|
|
213
|
+
export function prefersReducedMotion(): boolean {
|
|
214
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
215
|
+
return window.matchMedia(QUERY).matches;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function useReducedMotion(): boolean {
|
|
219
|
+
const [reduced, setReduced] = useState(prefersReducedMotion);
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
222
|
+
const mq = window.matchMedia(QUERY);
|
|
223
|
+
const onChange = () => setReduced(mq.matches);
|
|
224
|
+
mq.addEventListener("change", onChange);
|
|
225
|
+
return () => mq.removeEventListener("change", onChange);
|
|
226
|
+
}, []);
|
|
227
|
+
return reduced;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Ticks a count up to `value` on first mount. Linear over 200ms - a spring on
|
|
232
|
+
* a number reads as a slot machine, and these are measurements.
|
|
233
|
+
*
|
|
234
|
+
* It animates once, on mount. A later change to `value` lands immediately,
|
|
235
|
+
* because a re-render is not an arrival.
|
|
236
|
+
*/
|
|
237
|
+
export function useCountUp(value: number, duration = 200): number {
|
|
238
|
+
const reduced = useReducedMotion();
|
|
239
|
+
const [shown, setShown] = useState(() => (reduced ? value : 0));
|
|
240
|
+
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (reduced || duration <= 0 || value === 0) {
|
|
243
|
+
setShown(value);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
let frame = 0;
|
|
247
|
+
const start = performance.now();
|
|
248
|
+
const tick = (now: number) => {
|
|
249
|
+
const t = Math.min(1, (now - start) / duration);
|
|
250
|
+
setShown(Math.round(value * t));
|
|
251
|
+
if (t < 1) frame = requestAnimationFrame(tick);
|
|
252
|
+
};
|
|
253
|
+
frame = requestAnimationFrame(tick);
|
|
254
|
+
return () => cancelAnimationFrame(frame);
|
|
255
|
+
// Mount-only on purpose: see above.
|
|
256
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
257
|
+
}, []);
|
|
258
|
+
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
if (reduced) setShown(value);
|
|
261
|
+
}, [reduced, value]);
|
|
262
|
+
|
|
263
|
+
return shown;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Caps a list index at the stagger ceiling: ten rows, 20ms apart, then flat. */
|
|
267
|
+
export function staggerStyle(index: number, cap = 10): CSSProperties {
|
|
268
|
+
return { "--i": Math.min(index, cap - 1) } as CSSProperties;
|
|
269
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { catalog } from "../testing/estate";
|
|
3
|
+
import { paletteItems } from "./palette";
|
|
4
|
+
import { itemsById, recentSections } from "./palette-recent";
|
|
5
|
+
import type { Visit } from "../trail/model";
|
|
6
|
+
|
|
7
|
+
const items = paletteItems(catalog);
|
|
8
|
+
const event = items.find((i) => i.kind === "event" && i.selectId && i.path)!;
|
|
9
|
+
const service = items.find((i) => i.kind === "service" && i.path)!;
|
|
10
|
+
const flow = items.find((i) => i.kind === "flow" && i.path)!;
|
|
11
|
+
const adr = items.find((i) => i.kind === "adr" && i.path)!;
|
|
12
|
+
|
|
13
|
+
const visit = (path: string, id?: string): Visit => ({
|
|
14
|
+
path,
|
|
15
|
+
selection: id ? { kind: "unknown", id } : null,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("itemsById", () => {
|
|
19
|
+
it("finds a selectable row by what it selects, and any row by its id", () => {
|
|
20
|
+
const byId = itemsById(items);
|
|
21
|
+
expect(byId.get(event.selectId!)).toBe(event);
|
|
22
|
+
expect(byId.get(flow.id)).toBe(flow);
|
|
23
|
+
expect(byId.get(adr.id)).toBe(adr);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("recentSections", () => {
|
|
28
|
+
it("is empty for a reader with no trail and no pins", () => {
|
|
29
|
+
expect(recentSections([], [], items, "/")).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("turns visits into rows, newest first, by selection or by page", () => {
|
|
33
|
+
const visits = [
|
|
34
|
+
visit(service.path!, event.selectId),
|
|
35
|
+
visit(flow.path!),
|
|
36
|
+
visit(adr.path!),
|
|
37
|
+
];
|
|
38
|
+
const [recent] = recentSections(visits, [], items, "/");
|
|
39
|
+
expect(recent?.title).toBe("recent");
|
|
40
|
+
expect(recent?.hits.map((h) => h.item)).toEqual([event, flow, adr]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("leaves out the page the reader is standing on", () => {
|
|
44
|
+
const visits = [visit(flow.path!), visit(service.path!)];
|
|
45
|
+
const [recent] = recentSections(visits, [], items, flow.path!);
|
|
46
|
+
expect(recent?.hits.map((h) => h.item)).toEqual([service]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("keeps a visit to the current page when something was selected on it", () => {
|
|
50
|
+
const visits = [visit(service.path!, event.selectId)];
|
|
51
|
+
const [recent] = recentSections(visits, [], items, service.path!);
|
|
52
|
+
expect(recent?.hits.map((h) => h.item)).toEqual([event]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("drops a visit to something the catalog no longer has", () => {
|
|
56
|
+
const visits = [visit("/c/nope/gone"), visit(flow.path!, "nope.gone.Event")];
|
|
57
|
+
expect(recentSections(visits, [], items, "/")).toEqual([
|
|
58
|
+
{ title: "recent", hits: [{ item: flow }] },
|
|
59
|
+
]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("lists pins after the trail, minus what the trail already shows", () => {
|
|
63
|
+
const visits = [visit(service.path!, event.selectId)];
|
|
64
|
+
const pins = [
|
|
65
|
+
{ kind: "event" as const, id: event.selectId! },
|
|
66
|
+
{ kind: "service" as const, id: service.selectId ?? service.id },
|
|
67
|
+
];
|
|
68
|
+
const sections = recentSections(visits, pins, items, "/");
|
|
69
|
+
expect(sections.map((s) => s.title)).toEqual(["recent", "pinned"]);
|
|
70
|
+
expect(sections[0]?.hits.map((h) => h.item)).toEqual([event]);
|
|
71
|
+
expect(sections[1]?.hits.map((h) => h.item)).toEqual([service]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("offers only the pins when there is no trail", () => {
|
|
75
|
+
const pins = [{ kind: "flow" as const, id: flow.id }];
|
|
76
|
+
expect(recentSections([], pins, items, "/")).toEqual([
|
|
77
|
+
{ title: "pinned", hits: [{ item: flow }] },
|
|
78
|
+
]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// What ⌘K offers before anything is typed: where the reader has been, and
|
|
2
|
+
// what they have kept.
|
|
3
|
+
//
|
|
4
|
+
// The trail and the pins already answer both questions, in the chrome. The
|
|
5
|
+
// palette is where a reader's hands already are, though, and "back to the
|
|
6
|
+
// event I was on" as two keystrokes from anywhere is a different thing from
|
|
7
|
+
// the same chip in a strip they would have to find with the mouse.
|
|
8
|
+
//
|
|
9
|
+
// Both stores hold ids, and the rows here are the palette's own rows found
|
|
10
|
+
// by those ids - so a visit to a renamed event shows the new name, and one to
|
|
11
|
+
// a deleted event shows nothing, exactly as the trail and the pin list do.
|
|
12
|
+
|
|
13
|
+
import type { Pin } from "./pins";
|
|
14
|
+
import type { PaletteHit, PaletteItem } from "./palette";
|
|
15
|
+
import type { Visit } from "../trail/model";
|
|
16
|
+
|
|
17
|
+
export interface PaletteSection {
|
|
18
|
+
title: "recent" | "pinned";
|
|
19
|
+
hits: PaletteHit[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Rows by the id a visit or a pin would name them with. */
|
|
23
|
+
export function itemsById(items: readonly PaletteItem[]): Map<string, PaletteItem> {
|
|
24
|
+
const byId = new Map<string, PaletteItem>();
|
|
25
|
+
for (const item of items) {
|
|
26
|
+
// Selectable rows are named by what they select; the rest by their own
|
|
27
|
+
// id. A row's own id goes in too when nothing has claimed it, so a pin
|
|
28
|
+
// on an ADR and a visit to a flow both find their row.
|
|
29
|
+
if (item.selectId && !byId.has(item.selectId)) byId.set(item.selectId, item);
|
|
30
|
+
if (!byId.has(item.id)) byId.set(item.id, item);
|
|
31
|
+
}
|
|
32
|
+
return byId;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The row a visit stands for: its selection when it had one, else its page. */
|
|
36
|
+
function itemOfVisit(
|
|
37
|
+
visit: Visit,
|
|
38
|
+
byId: Map<string, PaletteItem>,
|
|
39
|
+
byPath: Map<string, PaletteItem>,
|
|
40
|
+
): PaletteItem | null {
|
|
41
|
+
if (visit.selection) {
|
|
42
|
+
const item = byId.get(visit.selection.id);
|
|
43
|
+
if (item) return item;
|
|
44
|
+
}
|
|
45
|
+
return byPath.get(visit.path) ?? null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The sections for an empty query. Recent first, newest at the top; then the
|
|
50
|
+
* pins, minus any row already in the recent list. A section with nothing in
|
|
51
|
+
* it is left out, and a reader with neither gets an empty list - the palette
|
|
52
|
+
* falls back to its full index for them.
|
|
53
|
+
*/
|
|
54
|
+
export function recentSections(
|
|
55
|
+
visits: readonly Visit[],
|
|
56
|
+
pins: readonly Pin[],
|
|
57
|
+
items: readonly PaletteItem[],
|
|
58
|
+
currentPath: string,
|
|
59
|
+
): PaletteSection[] {
|
|
60
|
+
const byId = itemsById(items);
|
|
61
|
+
const byPath = new Map<string, PaletteItem>();
|
|
62
|
+
for (const item of items) {
|
|
63
|
+
if (item.path && !byPath.has(item.path)) byPath.set(item.path, item);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const seen = new Set<PaletteItem>();
|
|
67
|
+
const recent: PaletteHit[] = [];
|
|
68
|
+
for (const visit of visits) {
|
|
69
|
+
// The page the reader is on is not somewhere to go back to - unless the
|
|
70
|
+
// visit is to something selected on it, which they may have cleared.
|
|
71
|
+
if (visit.path === currentPath && !visit.selection) continue;
|
|
72
|
+
const item = itemOfVisit(visit, byId, byPath);
|
|
73
|
+
if (!item || seen.has(item)) continue;
|
|
74
|
+
seen.add(item);
|
|
75
|
+
recent.push({ item });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const pinned: PaletteHit[] = [];
|
|
79
|
+
for (const pin of pins) {
|
|
80
|
+
const item = byId.get(pin.id);
|
|
81
|
+
if (!item || seen.has(item)) continue;
|
|
82
|
+
seen.add(item);
|
|
83
|
+
pinned.push({ item });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const sections: PaletteSection[] = [];
|
|
87
|
+
if (recent.length > 0) sections.push({ title: "recent", hits: recent });
|
|
88
|
+
if (pinned.length > 0) sections.push({ title: "pinned", hits: pinned });
|
|
89
|
+
return sections;
|
|
90
|
+
}
|