@shortlink-org/portolan 0.1.0 → 0.2.1
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 +27 -10
- package/scripts/local-api.test.mjs +85 -2
- package/scripts/manifest.mjs +3 -2
- package/scripts/package-smoke.mjs +24 -3
- 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 +17 -9
- 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,621 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
// The definitions of a schema, read straight out of the SDL.
|
|
4
|
-
//
|
|
5
|
-
// A GraphQL server has a runtime schema and can print it, but printing needs
|
|
6
|
-
// the server, and the whole point of reading source is that nothing has to be
|
|
7
|
-
// running. So this is a parser for the type system language only - no
|
|
8
|
-
// executable documents, no fragments, no queries - which is a much smaller
|
|
9
|
-
// grammar than it looks: a handful of definition keywords, fields with
|
|
10
|
-
// arguments, and the wrappers `!` and `[]`.
|
|
11
|
-
//
|
|
12
|
-
// The same type may be declared in several files. A modular schema says
|
|
13
|
-
// `type Query { basket(...): Basket }` in one module and `type Query { order(...)
|
|
14
|
-
// : Order }` in the next, and both of them mean the one Query the server
|
|
15
|
-
// serves. Declarations merge; the file each field came from is kept, because
|
|
16
|
-
// that is what says which module owns it.
|
|
17
|
-
|
|
18
|
-
import (
|
|
19
|
-
"fmt"
|
|
20
|
-
"sort"
|
|
21
|
-
"strings"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
type typeKind string
|
|
25
|
-
|
|
26
|
-
const (
|
|
27
|
-
kindObject typeKind = "type"
|
|
28
|
-
kindInterface typeKind = "interface"
|
|
29
|
-
kindInput typeKind = "input"
|
|
30
|
-
kindUnion typeKind = "union"
|
|
31
|
-
kindEnum typeKind = "enum"
|
|
32
|
-
kindScalar typeKind = "scalar"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
// typeRef is a type as a field writes it: a name at the bottom, and the
|
|
36
|
-
// wrappers around it. Nested lists collapse into one - a catalog that spelled
|
|
37
|
-
// `[][]Line` would be describing a shape no reader of this estate has.
|
|
38
|
-
type typeRef struct {
|
|
39
|
-
name string
|
|
40
|
-
list bool
|
|
41
|
-
nonNull bool
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// spell renders a type the way every other extractor here spells one: `[]Item`
|
|
45
|
-
// for a list, the bare name otherwise. Nullability is not spelled, it is said
|
|
46
|
-
// in the prose, the same way an optional OpenAPI property is.
|
|
47
|
-
func (t typeRef) spell() string {
|
|
48
|
-
if t.list {
|
|
49
|
-
return "[]" + t.name
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return t.name
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
type argDef struct {
|
|
56
|
-
name string
|
|
57
|
-
doc string
|
|
58
|
-
typ typeRef
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
type fieldDef struct {
|
|
62
|
-
name string
|
|
63
|
-
doc string
|
|
64
|
-
args []argDef
|
|
65
|
-
typ typeRef
|
|
66
|
-
|
|
67
|
-
deprecated bool
|
|
68
|
-
reason string
|
|
69
|
-
|
|
70
|
-
// file is the document this field was declared in, and module is what that
|
|
71
|
-
// document is called for the purpose of grouping. A root field's module
|
|
72
|
-
// decides which interface it lands in.
|
|
73
|
-
file string
|
|
74
|
-
module string
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
type typeDef struct {
|
|
78
|
-
kind typeKind
|
|
79
|
-
name string
|
|
80
|
-
doc string
|
|
81
|
-
fields []fieldDef
|
|
82
|
-
|
|
83
|
-
// values are an enum's members, members a union's, and implements the
|
|
84
|
-
// interfaces an object declares - which is the other way a schema says
|
|
85
|
-
// "this shape stands for several".
|
|
86
|
-
values []string
|
|
87
|
-
members []string
|
|
88
|
-
implements []string
|
|
89
|
-
|
|
90
|
-
file string
|
|
91
|
-
module string
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
type document struct {
|
|
95
|
-
types map[string]*typeDef
|
|
96
|
-
order []string
|
|
97
|
-
|
|
98
|
-
// roots are the operation types the schema declares, by operation. A
|
|
99
|
-
// schema that says nothing has the three the spec names by default.
|
|
100
|
-
roots map[string]string
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
func newDocument() *document {
|
|
104
|
-
return &document{
|
|
105
|
-
types: map[string]*typeDef{},
|
|
106
|
-
roots: map[string]string{},
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
func (d *document) root(operation string) string {
|
|
111
|
-
if named, ok := d.roots[operation]; ok {
|
|
112
|
-
return named
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return strings.ToUpper(operation[:1]) + operation[1:]
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
func (d *document) define(t *typeDef) {
|
|
119
|
-
existing, ok := d.types[t.name]
|
|
120
|
-
if !ok {
|
|
121
|
-
d.types[t.name] = t
|
|
122
|
-
d.order = append(d.order, t.name)
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// The second declaration of a type extends the first, whether or not it
|
|
127
|
-
// said `extend`. A field declared twice is the schema's problem, not this
|
|
128
|
-
// reader's; the first spelling wins so the output does not depend on which
|
|
129
|
-
// file happened to sort first.
|
|
130
|
-
if existing.doc == "" {
|
|
131
|
-
existing.doc = t.doc
|
|
132
|
-
}
|
|
133
|
-
for _, f := range t.fields {
|
|
134
|
-
if existing.field(f.name) == nil {
|
|
135
|
-
existing.fields = append(existing.fields, f)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
existing.values = append(existing.values, t.values...)
|
|
139
|
-
existing.members = append(existing.members, t.members...)
|
|
140
|
-
existing.implements = append(existing.implements, t.implements...)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
func (t *typeDef) field(name string) *fieldDef {
|
|
144
|
-
for i := range t.fields {
|
|
145
|
-
if t.fields[i].name == name {
|
|
146
|
-
return &t.fields[i]
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return nil
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
type parser struct {
|
|
154
|
-
toks []token
|
|
155
|
-
pos int
|
|
156
|
-
file string
|
|
157
|
-
module string
|
|
158
|
-
doc *document
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// parseInto reads one SDL file into a document that may already hold others.
|
|
162
|
-
func parseInto(d *document, src, file, module string) error {
|
|
163
|
-
toks, err := lex(src)
|
|
164
|
-
if err != nil {
|
|
165
|
-
return fmt.Errorf("%s: %w", file, err)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
p := &parser{toks: toks, file: file, module: module, doc: d}
|
|
169
|
-
if err := p.document(); err != nil {
|
|
170
|
-
return fmt.Errorf("%s: %w", file, err)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return nil
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
func (p *parser) peek() token { return p.toks[p.pos] }
|
|
177
|
-
func (p *parser) next() token { t := p.toks[p.pos]; p.pos++; return t }
|
|
178
|
-
func (p *parser) done() bool { return p.peek().kind == tokEOF }
|
|
179
|
-
func (p *parser) at(s string) bool { return p.peek().is(s) }
|
|
180
|
-
|
|
181
|
-
func (p *parser) accept(s string) bool {
|
|
182
|
-
if p.at(s) {
|
|
183
|
-
p.pos++
|
|
184
|
-
return true
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return false
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
func (p *parser) expect(s string) error {
|
|
191
|
-
if p.accept(s) {
|
|
192
|
-
return nil
|
|
193
|
-
}
|
|
194
|
-
tok := p.peek()
|
|
195
|
-
|
|
196
|
-
return fmt.Errorf("line %d: expected %q, found %q", tok.line, s, tok.text)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
func (p *parser) name() (string, error) {
|
|
200
|
-
tok := p.peek()
|
|
201
|
-
if tok.kind != tokName {
|
|
202
|
-
return "", fmt.Errorf("line %d: expected a name, found %q", tok.line, tok.text)
|
|
203
|
-
}
|
|
204
|
-
p.pos++
|
|
205
|
-
|
|
206
|
-
return tok.text, nil
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
func (p *parser) document() error {
|
|
210
|
-
for !p.done() {
|
|
211
|
-
doc := ""
|
|
212
|
-
if p.peek().kind == tokString {
|
|
213
|
-
doc = p.next().text
|
|
214
|
-
}
|
|
215
|
-
if err := p.definition(doc); err != nil {
|
|
216
|
-
return err
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return nil
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
func (p *parser) definition(doc string) error {
|
|
224
|
-
// `extend` says the definition adds to one that already exists, which is
|
|
225
|
-
// what merging does anyway.
|
|
226
|
-
p.accept("extend")
|
|
227
|
-
|
|
228
|
-
keyword := p.peek()
|
|
229
|
-
if keyword.kind != tokName {
|
|
230
|
-
return fmt.Errorf("line %d: expected a definition, found %q", keyword.line, keyword.text)
|
|
231
|
-
}
|
|
232
|
-
p.pos++
|
|
233
|
-
|
|
234
|
-
switch keyword.text {
|
|
235
|
-
case "schema":
|
|
236
|
-
return p.schema()
|
|
237
|
-
case "type", "interface", "input":
|
|
238
|
-
return p.object(typeKind(keyword.text), doc)
|
|
239
|
-
case "union":
|
|
240
|
-
return p.union(doc)
|
|
241
|
-
case "enum":
|
|
242
|
-
return p.enum(doc)
|
|
243
|
-
case "scalar":
|
|
244
|
-
return p.scalar(doc)
|
|
245
|
-
case "directive":
|
|
246
|
-
return p.directiveDefinition()
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return fmt.Errorf("line %d: %q is not a type system definition", keyword.line, keyword.text)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
func (p *parser) schema() error {
|
|
253
|
-
if err := p.directives(nil); err != nil {
|
|
254
|
-
return err
|
|
255
|
-
}
|
|
256
|
-
if err := p.expect("{"); err != nil {
|
|
257
|
-
return err
|
|
258
|
-
}
|
|
259
|
-
for !p.accept("}") {
|
|
260
|
-
operation, err := p.name()
|
|
261
|
-
if err != nil {
|
|
262
|
-
return err
|
|
263
|
-
}
|
|
264
|
-
if err := p.expect(":"); err != nil {
|
|
265
|
-
return err
|
|
266
|
-
}
|
|
267
|
-
named, err := p.name()
|
|
268
|
-
if err != nil {
|
|
269
|
-
return err
|
|
270
|
-
}
|
|
271
|
-
p.doc.roots[operation] = named
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return nil
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
func (p *parser) object(kind typeKind, doc string) error {
|
|
278
|
-
name, err := p.name()
|
|
279
|
-
if err != nil {
|
|
280
|
-
return err
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
var implements []string
|
|
284
|
-
if p.accept("implements") {
|
|
285
|
-
p.accept("&")
|
|
286
|
-
for {
|
|
287
|
-
iface, err := p.name()
|
|
288
|
-
if err != nil {
|
|
289
|
-
return err
|
|
290
|
-
}
|
|
291
|
-
implements = append(implements, iface)
|
|
292
|
-
if !p.accept("&") {
|
|
293
|
-
break
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if err := p.directives(nil); err != nil {
|
|
298
|
-
return err
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
t := &typeDef{kind: kind, name: name, doc: doc, implements: implements, file: p.file, module: p.module}
|
|
302
|
-
if p.accept("{") {
|
|
303
|
-
for !p.accept("}") {
|
|
304
|
-
field, err := p.field()
|
|
305
|
-
if err != nil {
|
|
306
|
-
return err
|
|
307
|
-
}
|
|
308
|
-
t.fields = append(t.fields, field)
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
p.doc.define(t)
|
|
312
|
-
|
|
313
|
-
return nil
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
func (p *parser) field() (fieldDef, error) {
|
|
317
|
-
f := fieldDef{file: p.file, module: p.module}
|
|
318
|
-
if p.peek().kind == tokString {
|
|
319
|
-
f.doc = p.next().text
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
name, err := p.name()
|
|
323
|
-
if err != nil {
|
|
324
|
-
return f, err
|
|
325
|
-
}
|
|
326
|
-
f.name = name
|
|
327
|
-
|
|
328
|
-
if p.accept("(") {
|
|
329
|
-
for !p.accept(")") {
|
|
330
|
-
arg, err := p.argument()
|
|
331
|
-
if err != nil {
|
|
332
|
-
return f, err
|
|
333
|
-
}
|
|
334
|
-
f.args = append(f.args, arg)
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
if err := p.expect(":"); err != nil {
|
|
339
|
-
return f, err
|
|
340
|
-
}
|
|
341
|
-
if f.typ, err = p.typeRef(); err != nil {
|
|
342
|
-
return f, err
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// An input field may carry a default; an output field may not, and a
|
|
346
|
-
// document that gives one is wrong in a way this reader does not need to
|
|
347
|
-
// care about.
|
|
348
|
-
if p.accept("=") {
|
|
349
|
-
if err := p.value(); err != nil {
|
|
350
|
-
return f, err
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
deprecated := &f
|
|
355
|
-
if err := p.directives(deprecated); err != nil {
|
|
356
|
-
return f, err
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return f, nil
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
func (p *parser) argument() (argDef, error) {
|
|
363
|
-
a := argDef{}
|
|
364
|
-
if p.peek().kind == tokString {
|
|
365
|
-
a.doc = p.next().text
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
name, err := p.name()
|
|
369
|
-
if err != nil {
|
|
370
|
-
return a, err
|
|
371
|
-
}
|
|
372
|
-
a.name = name
|
|
373
|
-
|
|
374
|
-
if err := p.expect(":"); err != nil {
|
|
375
|
-
return a, err
|
|
376
|
-
}
|
|
377
|
-
if a.typ, err = p.typeRef(); err != nil {
|
|
378
|
-
return a, err
|
|
379
|
-
}
|
|
380
|
-
if p.accept("=") {
|
|
381
|
-
if err := p.value(); err != nil {
|
|
382
|
-
return a, err
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return a, p.directives(nil)
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
func (p *parser) typeRef() (typeRef, error) {
|
|
390
|
-
var t typeRef
|
|
391
|
-
if p.accept("[") {
|
|
392
|
-
inner, err := p.typeRef()
|
|
393
|
-
if err != nil {
|
|
394
|
-
return t, err
|
|
395
|
-
}
|
|
396
|
-
if err := p.expect("]"); err != nil {
|
|
397
|
-
return t, err
|
|
398
|
-
}
|
|
399
|
-
t = typeRef{name: inner.name, list: true}
|
|
400
|
-
} else {
|
|
401
|
-
name, err := p.name()
|
|
402
|
-
if err != nil {
|
|
403
|
-
return t, err
|
|
404
|
-
}
|
|
405
|
-
t = typeRef{name: name}
|
|
406
|
-
}
|
|
407
|
-
t.nonNull = p.accept("!")
|
|
408
|
-
|
|
409
|
-
return t, nil
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
func (p *parser) union(doc string) error {
|
|
413
|
-
name, err := p.name()
|
|
414
|
-
if err != nil {
|
|
415
|
-
return err
|
|
416
|
-
}
|
|
417
|
-
if err := p.directives(nil); err != nil {
|
|
418
|
-
return err
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
t := &typeDef{kind: kindUnion, name: name, doc: doc, file: p.file, module: p.module}
|
|
422
|
-
if p.accept("=") {
|
|
423
|
-
p.accept("|")
|
|
424
|
-
for {
|
|
425
|
-
member, err := p.name()
|
|
426
|
-
if err != nil {
|
|
427
|
-
return err
|
|
428
|
-
}
|
|
429
|
-
t.members = append(t.members, member)
|
|
430
|
-
if !p.accept("|") {
|
|
431
|
-
break
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
p.doc.define(t)
|
|
436
|
-
|
|
437
|
-
return nil
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
func (p *parser) enum(doc string) error {
|
|
441
|
-
name, err := p.name()
|
|
442
|
-
if err != nil {
|
|
443
|
-
return err
|
|
444
|
-
}
|
|
445
|
-
if err := p.directives(nil); err != nil {
|
|
446
|
-
return err
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
t := &typeDef{kind: kindEnum, name: name, doc: doc, file: p.file, module: p.module}
|
|
450
|
-
if p.accept("{") {
|
|
451
|
-
for !p.accept("}") {
|
|
452
|
-
if p.peek().kind == tokString {
|
|
453
|
-
p.pos++
|
|
454
|
-
}
|
|
455
|
-
value, err := p.name()
|
|
456
|
-
if err != nil {
|
|
457
|
-
return err
|
|
458
|
-
}
|
|
459
|
-
if err := p.directives(nil); err != nil {
|
|
460
|
-
return err
|
|
461
|
-
}
|
|
462
|
-
t.values = append(t.values, value)
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
p.doc.define(t)
|
|
466
|
-
|
|
467
|
-
return nil
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
func (p *parser) scalar(doc string) error {
|
|
471
|
-
name, err := p.name()
|
|
472
|
-
if err != nil {
|
|
473
|
-
return err
|
|
474
|
-
}
|
|
475
|
-
if err := p.directives(nil); err != nil {
|
|
476
|
-
return err
|
|
477
|
-
}
|
|
478
|
-
p.doc.define(&typeDef{kind: kindScalar, name: name, doc: doc, file: p.file, module: p.module})
|
|
479
|
-
|
|
480
|
-
return nil
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// directiveDefinition is stepped over. A schema may define its own directives;
|
|
484
|
-
// none of them are facts about the estate.
|
|
485
|
-
func (p *parser) directiveDefinition() error {
|
|
486
|
-
if err := p.expect("@"); err != nil {
|
|
487
|
-
return err
|
|
488
|
-
}
|
|
489
|
-
if _, err := p.name(); err != nil {
|
|
490
|
-
return err
|
|
491
|
-
}
|
|
492
|
-
if p.accept("(") {
|
|
493
|
-
for !p.accept(")") {
|
|
494
|
-
if _, err := p.argument(); err != nil {
|
|
495
|
-
return err
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
p.accept("repeatable")
|
|
500
|
-
if err := p.expect("on"); err != nil {
|
|
501
|
-
return err
|
|
502
|
-
}
|
|
503
|
-
p.accept("|")
|
|
504
|
-
for {
|
|
505
|
-
if _, err := p.name(); err != nil {
|
|
506
|
-
return err
|
|
507
|
-
}
|
|
508
|
-
if !p.accept("|") {
|
|
509
|
-
break
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
return nil
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// directives reads the directives on a declaration. Only one of them says
|
|
517
|
-
// something the catalog holds - `@deprecated`, which every other extractor
|
|
518
|
-
// here also reports - so only that one is kept, and onto the field that
|
|
519
|
-
// carries it.
|
|
520
|
-
func (p *parser) directives(f *fieldDef) error {
|
|
521
|
-
for p.accept("@") {
|
|
522
|
-
name, err := p.name()
|
|
523
|
-
if err != nil {
|
|
524
|
-
return err
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
reason := ""
|
|
528
|
-
if p.accept("(") {
|
|
529
|
-
for !p.accept(")") {
|
|
530
|
-
argName, err := p.name()
|
|
531
|
-
if err != nil {
|
|
532
|
-
return err
|
|
533
|
-
}
|
|
534
|
-
if err := p.expect(":"); err != nil {
|
|
535
|
-
return err
|
|
536
|
-
}
|
|
537
|
-
start := p.pos
|
|
538
|
-
if err := p.value(); err != nil {
|
|
539
|
-
return err
|
|
540
|
-
}
|
|
541
|
-
if argName == "reason" && p.toks[start].kind == tokString {
|
|
542
|
-
reason = p.toks[start].text
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
if name == "deprecated" && f != nil {
|
|
548
|
-
f.deprecated = true
|
|
549
|
-
f.reason = reason
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
return nil
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// value steps over a literal. Defaults and directive arguments are read only
|
|
557
|
-
// far enough to get past them, apart from a deprecation reason.
|
|
558
|
-
func (p *parser) value() error {
|
|
559
|
-
tok := p.peek()
|
|
560
|
-
switch {
|
|
561
|
-
case tok.is("["):
|
|
562
|
-
p.pos++
|
|
563
|
-
for !p.accept("]") {
|
|
564
|
-
if p.done() {
|
|
565
|
-
return fmt.Errorf("line %d: a list value is never closed", tok.line)
|
|
566
|
-
}
|
|
567
|
-
if err := p.value(); err != nil {
|
|
568
|
-
return err
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
return nil
|
|
572
|
-
case tok.is("{"):
|
|
573
|
-
p.pos++
|
|
574
|
-
for !p.accept("}") {
|
|
575
|
-
if p.done() {
|
|
576
|
-
return fmt.Errorf("line %d: an object value is never closed", tok.line)
|
|
577
|
-
}
|
|
578
|
-
if _, err := p.name(); err != nil {
|
|
579
|
-
return err
|
|
580
|
-
}
|
|
581
|
-
if err := p.expect(":"); err != nil {
|
|
582
|
-
return err
|
|
583
|
-
}
|
|
584
|
-
if err := p.value(); err != nil {
|
|
585
|
-
return err
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
return nil
|
|
589
|
-
case tok.is("$"):
|
|
590
|
-
p.pos++
|
|
591
|
-
_, err := p.name()
|
|
592
|
-
return err
|
|
593
|
-
case tok.kind == tokName, tok.kind == tokString, tok.kind == tokNumber:
|
|
594
|
-
p.pos++
|
|
595
|
-
return nil
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return fmt.Errorf("line %d: %q is not a value", tok.line, tok.text)
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// modules are every module that declared something, in a stable order.
|
|
602
|
-
func (d *document) modules() []string {
|
|
603
|
-
seen := map[string]bool{}
|
|
604
|
-
var out []string
|
|
605
|
-
for _, name := range d.order {
|
|
606
|
-
t := d.types[name]
|
|
607
|
-
if !seen[t.module] {
|
|
608
|
-
seen[t.module] = true
|
|
609
|
-
out = append(out, t.module)
|
|
610
|
-
}
|
|
611
|
-
for _, f := range t.fields {
|
|
612
|
-
if !seen[f.module] {
|
|
613
|
-
seen[f.module] = true
|
|
614
|
-
out = append(out, f.module)
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
sort.Strings(out)
|
|
619
|
-
|
|
620
|
-
return out
|
|
621
|
-
}
|