@shortlink-org/portolan 0.1.0 → 0.2.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/README.md +69 -205
- package/cli/init.mjs +285 -0
- package/cli/init.test.mjs +158 -0
- package/cli/portolan.mjs +37 -73
- package/index.html +19 -0
- package/package.json +5 -10
- package/plugins/README.md +66 -27
- package/plugins/portolan-go.wasm +0 -0
- package/portolan.json +52 -73
- package/public/landing/cats/bug-hunter.webp +0 -0
- package/public/landing/cats/compass-nap.webp +0 -0
- package/public/landing/cats/diagrammer.webp +0 -0
- package/public/landing/cats/docs-reader.webp +0 -0
- package/public/landing/cats/laptop.webp +0 -0
- package/public/landing/cats/map-inspector.webp +0 -0
- package/public/landing/cats/server-break.webp +0 -0
- package/public/landing/cats/star-mapper.webp +0 -0
- package/public/landing/cats/system-builder.webp +0 -0
- package/public/landing/cats/thread-tangle.webp +0 -0
- package/public/og.png +0 -0
- package/public/readme-header.webp +0 -0
- package/schema/portolan.schema.json +180 -0
- package/scripts/builtin-plugins.mjs +14 -0
- package/scripts/delivery-presets.mjs +353 -0
- package/scripts/gen.mjs +37 -4
- package/scripts/history.mjs +126 -0
- package/scripts/history.test.mjs +110 -0
- package/scripts/host-plugins/fetch-bsr.mjs +351 -0
- package/{plugins/fetch-bsr/options.schema.json → scripts/host-plugins/fetch-bsr.options.json} +4 -0
- package/scripts/host-plugins/fetch-bsr.test.mjs +212 -0
- package/scripts/host-plugins/fetch-csr.mjs +386 -0
- package/scripts/host-plugins/fetch-csr.test.mjs +178 -0
- package/scripts/host-plugins/fetch-git.mjs +379 -0
- package/scripts/host-plugins/fetch-git.test.mjs +210 -0
- package/scripts/local-api.mjs +22 -4
- package/scripts/local-api.test.mjs +84 -2
- package/scripts/manifest.mjs +3 -2
- package/scripts/package-smoke.mjs +6 -2
- package/scripts/plugin-host.mjs +77 -18
- package/scripts/plugin-host.test.mjs +50 -1
- package/scripts/plugin-wasm-worker.mjs +6 -3
- package/scripts/run-builtin.mjs +6 -26
- package/scripts/schema.mjs +6 -1
- package/src/app/App.tsx +24 -429
- package/src/app/Breadcrumbs.test.ts +7 -0
- package/src/app/Breadcrumbs.tsx +15 -2
- package/src/app/CatalogApp.tsx +436 -0
- package/src/app/Sidebar.tsx +0 -1
- package/src/chat/ChatPanel.tsx +98 -41
- package/src/chat/Composer.tsx +4 -2
- package/src/chat/Conversation.tsx +79 -15
- package/src/chat/Header.tsx +43 -9
- package/src/chat/Starter.tsx +64 -3
- package/src/chat/Steps.tsx +1 -1
- package/src/chat/flags.test.ts +51 -14
- package/src/chat/flags.ts +8 -2
- package/src/chat/page-context.test.ts +51 -0
- package/src/chat/page-context.ts +128 -0
- package/src/chat/prompt.test.ts +49 -1
- package/src/chat/prompt.ts +42 -1
- package/src/chat/tools.ts +7 -2
- package/src/chat/transport.ts +16 -4
- package/src/components/ProblemRow.tsx +182 -0
- package/src/data.ts +20 -5
- package/src/er/ErCanvas.tsx +1 -1
- package/src/graph/DependencyGraph.tsx +10 -1
- package/src/graph/FocusedEventGraph.tsx +1 -1
- package/src/graph/GraphToolbar.tsx +2 -4
- package/src/index.css +220 -2
- package/src/landing/DraggableReveal.tsx +168 -0
- package/src/landing/EstateGraph.tsx +28 -0
- package/src/landing/FlowPlayback.tsx +282 -0
- package/src/landing/HeroMap.tsx +128 -0
- package/src/landing/LandingPage.tsx +757 -0
- package/src/landing/ProductFrame.tsx +68 -0
- package/src/landing/ProductTour.tsx +371 -0
- package/src/landing/catalog.ts +25 -0
- package/src/landing/motion.tsx +52 -0
- package/src/lib/all-problems.ts +28 -0
- package/src/lib/local-api.ts +35 -1
- package/src/lib/setup-info.test.ts +8 -0
- package/src/lib/setup-info.ts +3 -2
- package/src/lib/source-code.ts +2 -1
- package/src/likec4/C4View.tsx +5 -0
- package/src/likec4/InteractiveView.tsx +5 -1
- package/src/map/ContextMapGraph.tsx +47 -20
- package/src/pages/ContextMap.tsx +5 -1
- package/src/pages/FlowDetail.tsx +24 -7
- package/src/pages/Overview.tsx +68 -12
- package/src/pages/Problems.tsx +6 -193
- package/src/pages/Settings.tsx +133 -108
- package/src/pages/settings/DeliverySettings.tsx +229 -0
- package/src/pages/settings/PreferencesSettings.tsx +101 -0
- package/src/routes.test.ts +20 -0
- package/src/routes.ts +13 -1
- package/vite.config.ts +12 -8
- package/catalog/enum_test.go +0 -46
- package/catalog/model.go +0 -932
- package/catalog/roundtrip_test.go +0 -185
- package/catalog/via_test.go +0 -38
- package/go.mod +0 -14
- package/go.sum +0 -14
- package/internal/commands/cargo.go +0 -154
- package/internal/commands/commands.go +0 -143
- package/internal/commands/commands_test.go +0 -323
- package/internal/commands/gradle.go +0 -77
- package/internal/commands/justfile.go +0 -82
- package/internal/commands/makefile.go +0 -106
- package/internal/commands/maven.go +0 -93
- package/internal/commands/packagejson.go +0 -159
- package/internal/commands/pyproject.go +0 -169
- package/internal/commands/taskfile.go +0 -101
- package/internal/commands/testdata/estate/.cargo/config.toml +0 -7
- package/internal/commands/testdata/estate/Makefile +0 -33
- package/internal/commands/testdata/estate/Taskfile.yml +0 -21
- package/internal/commands/testdata/estate/build.gradle.kts +0 -21
- package/internal/commands/testdata/estate/justfile +0 -20
- package/internal/commands/testdata/estate/package.json +0 -13
- package/internal/commands/testdata/estate/pom.xml +0 -29
- package/internal/commands/testdata/estate/pyproject.toml +0 -27
- package/internal/commands/testdata/estate/xtask/src/main.rs +0 -27
- package/internal/commands/testdata/golden/commands.json +0 -305
- package/internal/gohttp/analyze.go +0 -2500
- package/internal/gohttp/endpoints.go +0 -1067
- package/internal/gohttp/roots.go +0 -320
- package/internal/gohttp/typed.go +0 -143
- package/internal/goscan/constants.go +0 -85
- package/internal/goscan/goscan_test.go +0 -227
- package/internal/goscan/names.go +0 -52
- package/internal/goscan/parse_test.go +0 -11
- package/internal/goscan/source.go +0 -36
- package/internal/goscan/tree.go +0 -155
- package/internal/goscan/types.go +0 -99
- package/internal/wsdl/ids.go +0 -127
- package/internal/wsdl/ids_test.go +0 -21
- package/internal/wsdl/model.go +0 -62
- package/internal/wsdl/parse.go +0 -920
- package/internal/wsdl/parse_test.go +0 -133
- package/plugin/describe.go +0 -107
- package/plugin/describe_test.go +0 -114
- package/plugin/protocol.go +0 -117
- package/plugin/schematest/schematest.go +0 -126
- package/plugins/extract-adr/describe.go +0 -19
- package/plugins/extract-adr/describe_test.go +0 -11
- package/plugins/extract-adr/extract.go +0 -153
- package/plugins/extract-adr/extract_test.go +0 -350
- package/plugins/extract-adr/history.go +0 -99
- package/plugins/extract-adr/main.go +0 -65
- package/plugins/extract-adr/parse.go +0 -642
- package/plugins/extract-adr/parse_test.go +0 -405
- package/plugins/extract-asyncapi/describe.go +0 -19
- package/plugins/extract-asyncapi/describe_test.go +0 -11
- package/plugins/extract-asyncapi/extract.go +0 -315
- package/plugins/extract-asyncapi/extract_test.go +0 -197
- package/plugins/extract-asyncapi/main.go +0 -48
- package/plugins/extract-asyncapi/spec.go +0 -151
- package/plugins/extract-commands/describe.go +0 -19
- package/plugins/extract-commands/describe_test.go +0 -11
- package/plugins/extract-commands/extract.go +0 -79
- package/plugins/extract-commands/extract_test.go +0 -92
- package/plugins/extract-commands/main.go +0 -55
- package/plugins/extract-csr/avro.go +0 -258
- package/plugins/extract-csr/describe.go +0 -19
- package/plugins/extract-csr/describe_test.go +0 -11
- package/plugins/extract-csr/extract.go +0 -338
- package/plugins/extract-csr/extract_test.go +0 -374
- package/plugins/extract-csr/jsonschema.go +0 -343
- package/plugins/extract-csr/lock.go +0 -25
- package/plugins/extract-csr/main.go +0 -84
- package/plugins/extract-csr/subject.go +0 -102
- package/plugins/extract-flows/describe.go +0 -19
- package/plugins/extract-flows/describe_test.go +0 -11
- package/plugins/extract-flows/extract.go +0 -91
- package/plugins/extract-flows/main.go +0 -45
- package/plugins/extract-flows/parse.go +0 -593
- package/plugins/extract-flows/parse_test.go +0 -204
- package/plugins/extract-glossary/describe.go +0 -19
- package/plugins/extract-glossary/describe_test.go +0 -11
- package/plugins/extract-glossary/extract.go +0 -115
- package/plugins/extract-glossary/extract_test.go +0 -220
- package/plugins/extract-glossary/main.go +0 -59
- package/plugins/extract-glossary/parse.go +0 -214
- package/plugins/extract-glossary/parse_test.go +0 -203
- package/plugins/extract-go/aggregate.go +0 -214
- package/plugins/extract-go/client.go +0 -409
- package/plugins/extract-go/client_test.go +0 -266
- package/plugins/extract-go/describe.go +0 -19
- package/plugins/extract-go/describe_test.go +0 -11
- package/plugins/extract-go/enum.go +0 -195
- package/plugins/extract-go/enum_test.go +0 -82
- package/plugins/extract-go/event.go +0 -99
- package/plugins/extract-go/extract.go +0 -191
- package/plugins/extract-go/extract_test.go +0 -261
- package/plugins/extract-go/flow.go +0 -1441
- package/plugins/extract-go/flow_test.go +0 -609
- package/plugins/extract-go/httpclient.go +0 -174
- package/plugins/extract-go/httpclient_test.go +0 -296
- package/plugins/extract-go/ids.go +0 -92
- package/plugins/extract-go/layout.go +0 -225
- package/plugins/extract-go/layout_test.go +0 -125
- package/plugins/extract-go/lifecycle.go +0 -324
- package/plugins/extract-go/lifecycle_test.go +0 -108
- package/plugins/extract-go/main.go +0 -79
- package/plugins/extract-go/operation.go +0 -157
- package/plugins/extract-go/source.go +0 -316
- package/plugins/extract-go/transport.go +0 -321
- package/plugins/extract-go/transport_test.go +0 -145
- package/plugins/extract-go/wiring.go +0 -434
- package/plugins/extract-go-nats/describe.go +0 -19
- package/plugins/extract-go-nats/describe_test.go +0 -11
- package/plugins/extract-go-nats/extract.go +0 -177
- package/plugins/extract-go-nats/extract_test.go +0 -389
- package/plugins/extract-go-nats/index.go +0 -379
- package/plugins/extract-go-nats/main.go +0 -42
- package/plugins/extract-go-nats/resolve.go +0 -161
- package/plugins/extract-go-nats/sites.go +0 -224
- package/plugins/extract-graphql/describe.go +0 -19
- package/plugins/extract-graphql/describe_test.go +0 -11
- package/plugins/extract-graphql/extract.go +0 -433
- package/plugins/extract-graphql/extract_test.go +0 -256
- package/plugins/extract-graphql/ids.go +0 -49
- package/plugins/extract-graphql/lex.go +0 -237
- package/plugins/extract-graphql/main.go +0 -51
- package/plugins/extract-graphql/parse.go +0 -621
- package/plugins/extract-graphql/parse_test.go +0 -122
- package/plugins/extract-http-clients/describe.go +0 -19
- package/plugins/extract-http-clients/describe_test.go +0 -11
- package/plugins/extract-http-clients/extract.go +0 -705
- package/plugins/extract-http-clients/extract_test.go +0 -1263
- package/plugins/extract-http-clients/main.go +0 -42
- package/plugins/extract-openapi/describe.go +0 -19
- package/plugins/extract-openapi/describe_test.go +0 -11
- package/plugins/extract-openapi/discover.go +0 -243
- package/plugins/extract-openapi/extract.go +0 -526
- package/plugins/extract-openapi/extract_test.go +0 -545
- package/plugins/extract-openapi/main.go +0 -75
- package/plugins/extract-openapi/spec.go +0 -350
- package/plugins/extract-project/describe.go +0 -19
- package/plugins/extract-project/describe_test.go +0 -11
- package/plugins/extract-project/extract.go +0 -221
- package/plugins/extract-project/extract_test.go +0 -109
- package/plugins/extract-project/main.go +0 -41
- package/plugins/extract-proto/ast.go +0 -125
- package/plugins/extract-proto/consumes.go +0 -77
- package/plugins/extract-proto/describe.go +0 -19
- package/plugins/extract-proto/extract.go +0 -293
- package/plugins/extract-proto/extract_test.go +0 -459
- package/plugins/extract-proto/ids.go +0 -89
- package/plugins/extract-proto/ids_test.go +0 -57
- package/plugins/extract-proto/lex.go +0 -285
- package/plugins/extract-proto/main.go +0 -100
- package/plugins/extract-proto/module.go +0 -120
- package/plugins/extract-proto/parse.go +0 -720
- package/plugins/extract-proto/parse_test.go +0 -307
- package/plugins/extract-proto/provides.go +0 -236
- package/plugins/extract-proto/resolve.go +0 -222
- package/plugins/extract-proto/resolve_test.go +0 -119
- package/plugins/extract-redis/describe.go +0 -19
- package/plugins/extract-redis/describe_test.go +0 -11
- package/plugins/extract-redis/extract.go +0 -183
- package/plugins/extract-redis/extract_test.go +0 -168
- package/plugins/extract-redis/keyspaces.go +0 -469
- package/plugins/extract-redis/main.go +0 -44
- package/plugins/extract-river/describe.go +0 -19
- package/plugins/extract-river/describe_test.go +0 -11
- package/plugins/extract-river/extract.go +0 -507
- package/plugins/extract-river/extract_test.go +0 -132
- package/plugins/extract-river/main.go +0 -42
- package/plugins/extract-sql/ddl.go +0 -893
- package/plugins/extract-sql/ddl_test.go +0 -401
- package/plugins/extract-sql/describe.go +0 -19
- package/plugins/extract-sql/describe_test.go +0 -11
- package/plugins/extract-sql/layout.go +0 -221
- package/plugins/extract-sql/layout_test.go +0 -55
- package/plugins/extract-sql/lineage.go +0 -107
- package/plugins/extract-sql/main.go +0 -141
- package/plugins/extract-sql/maps.go +0 -564
- package/plugins/extract-sql/maps_java.go +0 -117
- package/plugins/extract-sql/maps_rust.go +0 -333
- package/plugins/extract-sql/maps_rust_test.go +0 -70
- package/plugins/extract-sql/maps_test.go +0 -204
- package/plugins/extract-sql/maps_ts.go +0 -398
- package/plugins/extract-sql/maps_ts_test.go +0 -136
- package/plugins/extract-sql/projection.go +0 -70
- package/plugins/extract-sql/projection_test.go +0 -50
- package/plugins/extract-sql/store.go +0 -420
- package/plugins/extract-sql/store_test.go +0 -233
- package/plugins/extract-sql/view.go +0 -295
- package/plugins/extract-watermill/describe.go +0 -19
- package/plugins/extract-watermill/describe_test.go +0 -11
- package/plugins/extract-watermill/extract.go +0 -1228
- package/plugins/extract-watermill/extract_test.go +0 -234
- package/plugins/extract-watermill/main.go +0 -41
- package/plugins/extract-wsdl/describe.go +0 -19
- package/plugins/extract-wsdl/describe_test.go +0 -11
- package/plugins/extract-wsdl/extract.go +0 -148
- package/plugins/extract-wsdl/extract_test.go +0 -45
- package/plugins/extract-wsdl/main.go +0 -53
- package/plugins/fetch-bsr/auth.go +0 -114
- package/plugins/fetch-bsr/bsr.go +0 -240
- package/plugins/fetch-bsr/cache.go +0 -66
- package/plugins/fetch-bsr/describe.go +0 -19
- package/plugins/fetch-bsr/fetch.go +0 -192
- package/plugins/fetch-bsr/fetch_test.go +0 -465
- package/plugins/fetch-bsr/lock.go +0 -71
- package/plugins/fetch-bsr/main.go +0 -117
- package/plugins/fetch-csr/auth.go +0 -95
- package/plugins/fetch-csr/cache.go +0 -69
- package/plugins/fetch-csr/describe.go +0 -19
- package/plugins/fetch-csr/describe_test.go +0 -11
- package/plugins/fetch-csr/fetch.go +0 -254
- package/plugins/fetch-csr/fetch_test.go +0 -494
- package/plugins/fetch-csr/lock.go +0 -95
- package/plugins/fetch-csr/main.go +0 -122
- package/plugins/fetch-csr/registry.go +0 -209
- package/plugins/fetch-git/cache.go +0 -65
- package/plugins/fetch-git/describe.go +0 -19
- package/plugins/fetch-git/describe_test.go +0 -11
- package/plugins/fetch-git/fetch.go +0 -181
- package/plugins/fetch-git/fetch_test.go +0 -332
- package/plugins/fetch-git/git.go +0 -169
- package/plugins/fetch-git/lock.go +0 -72
- package/plugins/fetch-git/main.go +0 -127
- package/plugins/fetch-git/offline.go +0 -39
- package/plugins/fetch-git/pin.go +0 -90
- package/plugins/fetch-git/pin_test.go +0 -74
- package/plugins/gen-backstage/describe.go +0 -17
- package/plugins/gen-backstage/main.go +0 -22
- package/plugins/gen-backstage/plugin.go +0 -473
- package/plugins/gen-backstage/plugin_test.go +0 -145
- package/plugins/gen-backstage.wasm +0 -0
- package/plugins/gen-markdown/adr.go +0 -162
- package/plugins/gen-markdown/aggregate.go +0 -362
- package/plugins/gen-markdown/canonical.go +0 -93
- package/plugins/gen-markdown/context.go +0 -90
- package/plugins/gen-markdown/coverage_test.go +0 -89
- package/plugins/gen-markdown/describe.go +0 -19
- package/plugins/gen-markdown/describe_test.go +0 -11
- package/plugins/gen-markdown/external.go +0 -71
- package/plugins/gen-markdown/flow.go +0 -277
- package/plugins/gen-markdown/glossary.go +0 -76
- package/plugins/gen-markdown/glossary_test.go +0 -148
- package/plugins/gen-markdown/llms.go +0 -302
- package/plugins/gen-markdown/main.go +0 -22
- package/plugins/gen-markdown/markdown.go +0 -254
- package/plugins/gen-markdown/markdown_test.go +0 -100
- package/plugins/gen-markdown/module.go +0 -107
- package/plugins/gen-markdown/plugin.go +0 -39
- package/plugins/gen-markdown/quality_test.go +0 -176
- package/plugins/gen-markdown/redis_test.go +0 -38
- package/plugins/gen-markdown/render.go +0 -344
- package/plugins/gen-markdown/render_test.go +0 -186
- package/plugins/gen-markdown/service.go +0 -456
- package/plugins/gen-markdown/source.go +0 -177
- package/plugins/gen-markdown/store.go +0 -201
- package/plugins/gen-markdown.wasm +0 -0
- package/plugins/gen-mermaid/describe.go +0 -17
- package/plugins/gen-mermaid/main.go +0 -22
- package/plugins/gen-mermaid/plugin.go +0 -104
- package/plugins/gen-mermaid/plugin_test.go +0 -33
- package/plugins/gen-mermaid.wasm +0 -0
- package/plugins/openapi/ids.go +0 -261
- package/plugins/openapi/ids_test.go +0 -98
- package/plugins/verify-codeowners/describe.go +0 -19
- package/plugins/verify-codeowners/describe_test.go +0 -11
- package/plugins/verify-codeowners/main.go +0 -75
- package/plugins/verify-codeowners/match.go +0 -85
- package/plugins/verify-codeowners/match_test.go +0 -47
- package/plugins/verify-codeowners/owners.go +0 -164
- package/plugins/verify-codeowners/owners_test.go +0 -225
- package/plugins/verify-codeowners/parse.go +0 -90
- package/plugins/verify-codeowners/parse_test.go +0 -62
- package/plugins/verify-otel/describe.go +0 -19
- package/plugins/verify-otel/describe_test.go +0 -11
- package/plugins/verify-otel/main.go +0 -53
- package/plugins/verify-otel/match.go +0 -336
- package/plugins/verify-otel/otlp.go +0 -200
- package/plugins/verify-otel/verify.go +0 -734
- package/plugins/verify-otel/verify_test.go +0 -460
- /package/{plugins/fetch-csr/options.schema.json → scripts/host-plugins/fetch-csr.options.json} +0 -0
- /package/{plugins/fetch-git/options.schema.json → scripts/host-plugins/fetch-git.options.json} +0 -0
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// Package main is portolan-extract-http-clients: outbound HTTP and SOAP calls
|
|
2
|
-
// in a Go repository in, source-backed dependencies and flows out.
|
|
3
|
-
package main
|
|
4
|
-
|
|
5
|
-
import (
|
|
6
|
-
"fmt"
|
|
7
|
-
"io"
|
|
8
|
-
"os"
|
|
9
|
-
"path/filepath"
|
|
10
|
-
|
|
11
|
-
"github.com/shortlink-org/portolan/plugin"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
type Options struct {
|
|
15
|
-
Context string `json:"context"`
|
|
16
|
-
Service string `json:"service"`
|
|
17
|
-
Peers map[string]string `json:"peers,omitempty"`
|
|
18
|
-
Externals map[string]string `json:"externals,omitempty"`
|
|
19
|
-
Out string `json:"out,omitempty"`
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
func main() {
|
|
23
|
-
if err := run(os.Stdin, os.Stdout); err != nil {
|
|
24
|
-
fmt.Fprintln(os.Stderr, "portolan-extract-http-clients:", err)
|
|
25
|
-
os.Exit(1)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
func run(stdin io.Reader, stdout io.Writer) error {
|
|
30
|
-
return plugin.Serve(stdin, stdout, descriptor(), func(req plugin.Request, opts Options) (plugin.Response, error) {
|
|
31
|
-
if req.Input.Root == "" {
|
|
32
|
-
return plugin.Response{}, fmt.Errorf("no input root: an extractor has nothing to read")
|
|
33
|
-
}
|
|
34
|
-
if opts.Context == "" {
|
|
35
|
-
opts.Context = slug(filepath.Base(req.Input.Root))
|
|
36
|
-
}
|
|
37
|
-
if opts.Service == "" {
|
|
38
|
-
opts.Service = slug(filepath.Base(req.Input.Root))
|
|
39
|
-
}
|
|
40
|
-
return extract(req.Input, opts)
|
|
41
|
-
})
|
|
42
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
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: "extract-openapi",
|
|
15
|
-
Summary: "Reads an OpenAPI document and answers with the rpc services a service provides, one per tag - or, for a copy vendored from outside the estate, what a third party answers on.",
|
|
16
|
-
Phases: []string{plugin.PhaseExtract},
|
|
17
|
-
Options: optionsSchema,
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"io/fs"
|
|
5
|
-
"os"
|
|
6
|
-
"path/filepath"
|
|
7
|
-
"sort"
|
|
8
|
-
"strings"
|
|
9
|
-
|
|
10
|
-
"github.com/shortlink-org/portolan/catalog"
|
|
11
|
-
"github.com/shortlink-org/portolan/plugin"
|
|
12
|
-
"github.com/shortlink-org/portolan/plugins/openapi"
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
// A document in a tree is one of two things, and what sits beside it says
|
|
16
|
-
// which. A server generated from it - oapi-codegen's ServerInterface, swag's
|
|
17
|
-
// docs package, a handler or controller written against it - means this
|
|
18
|
-
// service implements it, and the document is what the service provides. A
|
|
19
|
-
// client generated from it means this service calls it: a document vendored
|
|
20
|
-
// beside a client describes a system this tree does not implement, which is
|
|
21
|
-
// a system outside the estate unless the manifest says the api is one of
|
|
22
|
-
// ours. A document with neither beside it is reported and left alone, because
|
|
23
|
-
// reading it as either would be a guess.
|
|
24
|
-
|
|
25
|
-
// Directories nobody's documents live in: dependencies, build output, and the
|
|
26
|
-
// fixtures of tests.
|
|
27
|
-
var skippedDirs = map[string]bool{
|
|
28
|
-
".git": true, "vendor": true, "node_modules": true, "target": true,
|
|
29
|
-
"build": true, "dist": true, "testdata": true, ".claude": true,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// documentNames, in the order a directory holding two spellings of the same
|
|
33
|
-
// document is read: the yaml, and the json only when there is no yaml.
|
|
34
|
-
var documentNames = []string{"openapi.yaml", "openapi.yml", "swagger.yaml", "swagger.yml", "openapi.json", "swagger.json"}
|
|
35
|
-
|
|
36
|
-
type role int
|
|
37
|
-
|
|
38
|
-
const (
|
|
39
|
-
roleUnknown role = iota
|
|
40
|
-
roleServed
|
|
41
|
-
roleCalled
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
// discover walks the tree for documents and answers with what the service
|
|
45
|
-
// provides and the systems outside the estate it calls.
|
|
46
|
-
func discover(root, owner string, opts Options, b *plugin.Builder) ([]catalog.RpcService, []catalog.External) {
|
|
47
|
-
var provides []catalog.RpcService
|
|
48
|
-
var externals []catalog.External
|
|
49
|
-
byID := map[string]int{}
|
|
50
|
-
|
|
51
|
-
for _, path := range documents(root) {
|
|
52
|
-
source := filepath.ToSlash(path)
|
|
53
|
-
doc, err := load(path)
|
|
54
|
-
if err != nil {
|
|
55
|
-
b.Warn(owner, source+" could not be read: "+err.Error())
|
|
56
|
-
|
|
57
|
-
continue
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
switch roleOf(filepath.Dir(path)) {
|
|
61
|
-
case roleServed:
|
|
62
|
-
api := firstNonEmpty(opts.API, apiID(doc))
|
|
63
|
-
services := rpcServices(doc, api, source, b)
|
|
64
|
-
if len(services) == 0 {
|
|
65
|
-
b.Warn(owner, source+" declares no operations")
|
|
66
|
-
}
|
|
67
|
-
provides = append(provides, services...)
|
|
68
|
-
|
|
69
|
-
case roleCalled:
|
|
70
|
-
api := apiID(doc)
|
|
71
|
-
if _, ours := opts.Peers[api]; ours {
|
|
72
|
-
// One of ours: the service that implements it describes it.
|
|
73
|
-
continue
|
|
74
|
-
}
|
|
75
|
-
info := child(doc.root, "info")
|
|
76
|
-
title := text(child(info, "title"))
|
|
77
|
-
id := opts.Externals[api]
|
|
78
|
-
if id == "" {
|
|
79
|
-
id = openapi.ExternalID(title)
|
|
80
|
-
}
|
|
81
|
-
if id == "" {
|
|
82
|
-
b.Warn(owner, source+" is called from here and its document has no title, so the system it belongs to cannot be named; name it under `externals` as "+api+"")
|
|
83
|
-
|
|
84
|
-
continue
|
|
85
|
-
}
|
|
86
|
-
if strings.Contains(id, ".") {
|
|
87
|
-
b.Warn(owner, source+": external "+id+" has a dot in its id; an external sits at the root and is addressed by a bare name")
|
|
88
|
-
|
|
89
|
-
continue
|
|
90
|
-
}
|
|
91
|
-
services := rpcServices(doc, api, source, b)
|
|
92
|
-
if at, seen := byID[id]; seen {
|
|
93
|
-
externals[at].Provides = append(externals[at].Provides, services...)
|
|
94
|
-
|
|
95
|
-
continue
|
|
96
|
-
}
|
|
97
|
-
byID[id] = len(externals)
|
|
98
|
-
externals = append(externals, catalog.External{
|
|
99
|
-
ID: id,
|
|
100
|
-
Slug: id,
|
|
101
|
-
Name: firstNonEmpty(title, id),
|
|
102
|
-
Summary: text(child(info, "description")),
|
|
103
|
-
URL: text(child(doc.root, "externalDocs", "url")),
|
|
104
|
-
Provides: services,
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
default:
|
|
108
|
-
b.Warn(owner, "found "+source+", and nothing beside it says whether this service implements it or calls it; name it in `spec`, or generate a server or a client from it")
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if len(provides) == 0 {
|
|
113
|
-
b.Warn(owner, "no document this service implements was found under "+root+"; the service is described as providing no HTTP api")
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return provides, externals
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// documents lists every document under the root, one per directory, in path
|
|
120
|
-
// order so the fragment is the same however the tree was walked.
|
|
121
|
-
func documents(root string) []string {
|
|
122
|
-
perDir := map[string]string{}
|
|
123
|
-
_ = filepath.WalkDir(root, func(p string, entry fs.DirEntry, err error) error {
|
|
124
|
-
if err != nil {
|
|
125
|
-
return nil
|
|
126
|
-
}
|
|
127
|
-
if entry.IsDir() {
|
|
128
|
-
if p != root && skippedDirs[entry.Name()] {
|
|
129
|
-
return filepath.SkipDir
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return nil
|
|
133
|
-
}
|
|
134
|
-
rank := indexOf(documentNames, entry.Name())
|
|
135
|
-
if rank < 0 {
|
|
136
|
-
return nil
|
|
137
|
-
}
|
|
138
|
-
dir := filepath.Dir(p)
|
|
139
|
-
if held, ok := perDir[dir]; ok && indexOf(documentNames, filepath.Base(held)) <= rank {
|
|
140
|
-
return nil
|
|
141
|
-
}
|
|
142
|
-
perDir[dir] = p
|
|
143
|
-
|
|
144
|
-
return nil
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
out := make([]string, 0, len(perDir))
|
|
148
|
-
for _, p := range perDir {
|
|
149
|
-
out = append(out, p)
|
|
150
|
-
}
|
|
151
|
-
sort.Strings(out)
|
|
152
|
-
|
|
153
|
-
return out
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
func indexOf(names []string, name string) int {
|
|
157
|
-
for i, candidate := range names {
|
|
158
|
-
if candidate == name {
|
|
159
|
-
return i
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return -1
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// roleOf reads the files in the document's directory and the one above it,
|
|
167
|
-
// which is where generated code and the adapter written over it live.
|
|
168
|
-
// Implementing wins over calling: a service that publishes a client for its
|
|
169
|
-
// own api has both beside its document, and it still implements it.
|
|
170
|
-
func roleOf(dir string) role {
|
|
171
|
-
served, called := false, false
|
|
172
|
-
for _, d := range []string{dir, filepath.Dir(dir)} {
|
|
173
|
-
entries, err := os.ReadDir(d)
|
|
174
|
-
if err != nil {
|
|
175
|
-
continue
|
|
176
|
-
}
|
|
177
|
-
for _, entry := range entries {
|
|
178
|
-
if entry.IsDir() {
|
|
179
|
-
continue
|
|
180
|
-
}
|
|
181
|
-
name := strings.ToLower(entry.Name())
|
|
182
|
-
switch {
|
|
183
|
-
case strings.HasSuffix(name, ".go"):
|
|
184
|
-
switch goRole(filepath.Join(d, entry.Name())) {
|
|
185
|
-
case roleServed:
|
|
186
|
-
served = true
|
|
187
|
-
case roleCalled:
|
|
188
|
-
called = true
|
|
189
|
-
}
|
|
190
|
-
case isSourceFile(name):
|
|
191
|
-
if strings.Contains(name, "server") || strings.Contains(name, "handler") || strings.Contains(name, "controller") || strings.Contains(name, "router") || strings.Contains(name, "routes") {
|
|
192
|
-
served = true
|
|
193
|
-
} else if strings.Contains(name, "client") {
|
|
194
|
-
called = true
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
switch {
|
|
201
|
-
case served:
|
|
202
|
-
return roleServed
|
|
203
|
-
case called:
|
|
204
|
-
return roleCalled
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return roleUnknown
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// goRole reads what a Go file was generated as, by the names generators
|
|
211
|
-
// leave: oapi-codegen's ServerInterface and RegisterHandlers, swag's
|
|
212
|
-
// registration, and oapi-codegen's ClientInterface.
|
|
213
|
-
func goRole(path string) role {
|
|
214
|
-
contents, err := os.ReadFile(path)
|
|
215
|
-
if err != nil {
|
|
216
|
-
return roleUnknown
|
|
217
|
-
}
|
|
218
|
-
src := string(contents)
|
|
219
|
-
switch {
|
|
220
|
-
case strings.Contains(src, "ServerInterface interface"),
|
|
221
|
-
strings.Contains(src, "func RegisterHandlers("),
|
|
222
|
-
strings.Contains(src, "swag.Register("),
|
|
223
|
-
strings.Contains(src, "SwaggerInfo"):
|
|
224
|
-
return roleServed
|
|
225
|
-
case strings.Contains(src, "ClientInterface interface"),
|
|
226
|
-
strings.Contains(src, "ClientWithResponses"):
|
|
227
|
-
return roleCalled
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return roleUnknown
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// The source files a name-based reading applies to: anything a person writes
|
|
234
|
-
// an adapter in, and nothing a tool writes for other reasons.
|
|
235
|
-
func isSourceFile(name string) bool {
|
|
236
|
-
for _, ext := range []string{".ts", ".tsx", ".js", ".mjs", ".java", ".kt", ".rs", ".py", ".rb", ".cs", ".php"} {
|
|
237
|
-
if strings.HasSuffix(name, ext) {
|
|
238
|
-
return true
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return false
|
|
243
|
-
}
|