@crvouga/atlas 0.3.0 → 0.5.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/CHANGELOG.md +12 -0
- package/README.md +178 -604
- package/dist/bun/src/driver.d.ts +41 -7
- package/dist/bun/src/driver.js +47 -6
- package/dist/bun/src/index.d.ts +8 -0
- package/dist/bun/src/index.js +8 -0
- package/dist/core/src/cli.d.ts +14 -1
- package/dist/core/src/cli.js +30 -1
- package/dist/core/src/config.d.ts +70 -4
- package/dist/core/src/config.js +62 -3
- package/dist/core/src/events/cloudevents.d.ts +54 -9
- package/dist/core/src/events/cloudevents.js +60 -9
- package/dist/core/src/graph.d.ts +21 -0
- package/dist/core/src/graph.js +26 -0
- package/dist/core/src/index.d.ts +11 -0
- package/dist/core/src/index.js +11 -0
- package/dist/core/src/lint.d.ts +30 -0
- package/dist/core/src/lint.js +13 -0
- package/dist/core/src/plan.d.ts +39 -1
- package/dist/core/src/plan.js +28 -1
- package/dist/core/src/privacy.d.ts +29 -2
- package/dist/core/src/privacy.js +19 -2
- package/dist/core/src/report/formats.d.ts +34 -4
- package/dist/core/src/report/formats.js +24 -4
- package/dist/core/src/report/markdown.d.ts +15 -0
- package/dist/core/src/report/markdown.js +8 -0
- package/dist/core/src/run/clients.d.ts +44 -5
- package/dist/core/src/run/clients.js +46 -2
- package/dist/core/src/run/execute.d.ts +69 -16
- package/dist/core/src/run/execute.js +67 -16
- package/dist/core/src/run/frames.d.ts +13 -4
- package/dist/core/src/run/frames.js +19 -4
- package/dist/core/src/run/http.d.ts +34 -1
- package/dist/core/src/run/http.js +14 -1
- package/dist/core/src/run/types.d.ts +76 -3
- package/dist/core/src/run/types.js +19 -3
- package/dist/core/src/signals.d.ts +49 -5
- package/dist/core/src/signals.js +22 -5
- package/dist/core/src/spec/compose.d.ts +23 -1
- package/dist/core/src/spec/compose.js +10 -1
- package/dist/core/src/spec/index.d.ts +9 -1
- package/dist/core/src/spec/index.js +9 -1
- package/dist/core/src/spec/load.d.ts +22 -1
- package/dist/core/src/spec/load.js +31 -1
- package/dist/core/src/spec/parse.d.ts +16 -2
- package/dist/core/src/spec/parse.js +25 -2
- package/dist/core/src/spec/scxml.d.ts +25 -4
- package/dist/core/src/spec/scxml.js +36 -4
- package/dist/core/src/spec/types.d.ts +52 -1
- package/dist/core/src/spec/types.js +24 -0
- package/dist/detox/src/index.d.ts +54 -11
- package/dist/detox/src/index.js +45 -7
- package/dist/playwright/src/driver.d.ts +39 -3
- package/dist/playwright/src/driver.js +27 -3
- package/dist/playwright/src/index.d.ts +10 -0
- package/dist/playwright/src/index.js +10 -0
- package/dist/playwright/src/media.d.ts +50 -4
- package/dist/playwright/src/media.js +55 -4
- package/dist/playwright/src/signals.d.ts +44 -5
- package/dist/playwright/src/signals.js +29 -5
- package/dist/reports/src/attachment-files.d.ts +44 -0
- package/dist/reports/src/attachment-files.js +121 -0
- package/dist/reports/src/attachment-response.d.ts +31 -0
- package/dist/reports/src/attachment-response.js +55 -0
- package/dist/reports/src/aws-credentials.d.ts +48 -0
- package/dist/reports/src/aws-credentials.js +221 -0
- package/dist/reports/src/browser-navigation.d.ts +14 -0
- package/dist/reports/src/browser-navigation.js +7 -0
- package/dist/reports/src/bundle.d.ts +34 -2
- package/dist/reports/src/bundle.js +38 -2
- package/dist/reports/src/catalog.d.ts +34 -3
- package/dist/reports/src/catalog.js +17 -3
- package/dist/reports/src/cli-stores.d.ts +36 -0
- package/dist/reports/src/cli-stores.js +73 -0
- package/dist/reports/src/clock.d.ts +7 -2
- package/dist/reports/src/clock.js +5 -2
- package/dist/reports/src/completion-order.d.ts +18 -5
- package/dist/reports/src/completion-order.js +18 -5
- package/dist/reports/src/compose.d.ts +80 -0
- package/dist/reports/src/compose.js +117 -0
- package/dist/reports/src/copy-store.d.ts +29 -0
- package/dist/reports/src/copy-store.js +52 -0
- package/dist/reports/src/directory-outline.d.ts +38 -0
- package/dist/reports/src/directory-outline.js +103 -0
- package/dist/reports/src/directory-store.d.ts +20 -0
- package/dist/reports/src/directory-store.js +166 -0
- package/dist/reports/src/doctor.d.ts +29 -0
- package/dist/reports/src/doctor.js +83 -0
- package/dist/reports/src/effective-delta.d.ts +34 -0
- package/dist/reports/src/effective-delta.js +25 -0
- package/dist/reports/src/evidence-detail.d.ts +64 -0
- package/dist/reports/src/evidence-detail.js +92 -0
- package/dist/reports/src/evidence-live.d.ts +40 -4
- package/dist/reports/src/evidence-live.js +52 -4
- package/dist/reports/src/evidence-types.d.ts +70 -1
- package/dist/reports/src/evidence-types.js +5 -1
- package/dist/reports/src/evidence-view.d.ts +58 -6
- package/dist/reports/src/evidence-view.js +44 -5
- package/dist/reports/src/explorer-types.d.ts +40 -3
- package/dist/reports/src/explorer-types.js +8 -0
- package/dist/reports/src/explorer-versions.d.ts +9 -1
- package/dist/reports/src/explorer-versions.js +18 -1
- package/dist/reports/src/export-evidence.d.ts +16 -1
- package/dist/reports/src/export-evidence.js +52 -1
- package/dist/reports/src/fetcher.d.ts +27 -3
- package/dist/reports/src/fetcher.js +11 -3
- package/dist/reports/src/format-date.d.ts +6 -0
- package/dist/reports/src/format-date.js +6 -0
- package/dist/reports/src/format.d.ts +16 -0
- package/dist/reports/src/format.js +10 -0
- package/dist/reports/src/frames.d.ts +36 -3
- package/dist/reports/src/frames.js +22 -3
- package/dist/reports/src/hash.d.ts +18 -0
- package/dist/reports/src/hash.js +13 -0
- package/dist/reports/src/host.d.ts +29 -0
- package/dist/reports/src/host.js +64 -0
- package/dist/reports/src/html-frame.d.ts +5 -6
- package/dist/reports/src/html-frame.js +12 -1
- package/dist/reports/src/http-store.d.ts +52 -0
- package/dist/reports/src/http-store.js +145 -0
- package/dist/reports/src/http.d.ts +7 -0
- package/dist/reports/src/http.js +6 -0
- package/dist/reports/src/ingest.d.ts +54 -0
- package/dist/reports/src/ingest.js +210 -0
- package/dist/reports/src/init.d.ts +40 -0
- package/dist/reports/src/init.js +364 -0
- package/dist/reports/src/junit.d.ts +33 -6
- package/dist/reports/src/junit.js +87 -21
- package/dist/reports/src/keyboard.d.ts +20 -0
- package/dist/reports/src/keyboard.js +11 -0
- package/dist/reports/src/keys.d.ts +21 -3
- package/dist/reports/src/keys.js +21 -3
- package/dist/reports/src/layer-axes.d.ts +48 -0
- package/dist/reports/src/layer-axes.js +71 -0
- package/dist/reports/src/layer-catalog.d.ts +28 -1
- package/dist/reports/src/layer-catalog.js +19 -2
- package/dist/reports/src/layer-merge.d.ts +98 -9
- package/dist/reports/src/layer-merge.js +154 -33
- package/dist/reports/src/layer-source.d.ts +18 -0
- package/dist/reports/src/layer-source.js +14 -0
- package/dist/reports/src/layer-store.d.ts +42 -0
- package/dist/reports/src/layer-store.js +63 -5
- package/dist/reports/src/layer-types.d.ts +34 -1
- package/dist/reports/src/layers-route.d.ts +47 -4
- package/dist/reports/src/layers-route.js +88 -12
- package/dist/reports/src/media-types.d.ts +11 -0
- package/dist/reports/src/media-types.js +22 -0
- package/dist/reports/src/namespace-guard.d.ts +10 -1
- package/dist/reports/src/namespace-guard.js +10 -1
- package/dist/reports/src/navigation.d.ts +12 -0
- package/dist/reports/src/navigation.js +7 -0
- package/dist/reports/src/object-io.d.ts +11 -4
- package/dist/reports/src/object-io.js +4 -4
- package/dist/reports/src/object-store-conformance.d.ts +27 -0
- package/dist/reports/src/object-store-conformance.js +87 -0
- package/dist/reports/src/object-store.d.ts +33 -24
- package/dist/reports/src/object-store.js +17 -24
- package/dist/reports/src/parse-with.d.ts +16 -0
- package/dist/reports/src/parse-with.js +14 -0
- package/dist/reports/src/performance-part.d.ts +25 -1
- package/dist/reports/src/performance-part.js +15 -1
- package/dist/reports/src/performance.d.ts +22 -2
- package/dist/reports/src/performance.js +12 -2
- package/dist/reports/src/persist.d.ts +12 -3
- package/dist/reports/src/persist.js +12 -3
- package/dist/reports/src/phone.d.ts +18 -1
- package/dist/reports/src/phone.js +18 -1
- package/dist/reports/src/protocol.d.ts +30 -4
- package/dist/reports/src/protocol.js +15 -4
- package/dist/reports/src/publication.d.ts +21 -1
- package/dist/reports/src/publication.js +21 -1
- package/dist/reports/src/publish-checks.d.ts +35 -0
- package/dist/reports/src/publish-checks.js +122 -0
- package/dist/reports/src/publish.d.ts +44 -9
- package/dist/reports/src/publish.js +40 -7
- package/dist/reports/src/read.d.ts +46 -16
- package/dist/reports/src/read.js +38 -14
- package/dist/reports/src/recording-bundle.d.ts +13 -2
- package/dist/reports/src/recording-bundle.js +4 -2
- package/dist/reports/src/recording-keys.d.ts +15 -1
- package/dist/reports/src/recording-keys.js +15 -1
- package/dist/reports/src/remote-report.d.ts +28 -7
- package/dist/reports/src/remote-report.js +15 -7
- package/dist/reports/src/report-cli.d.ts +51 -0
- package/dist/reports/src/report-cli.js +485 -0
- package/dist/reports/src/report-index.d.ts +99 -0
- package/dist/reports/src/report-index.js +337 -0
- package/dist/reports/src/report-loader.d.ts +10 -0
- package/dist/reports/src/report-loader.js +6 -0
- package/dist/reports/src/report-parts.d.ts +29 -3
- package/dist/reports/src/report-parts.js +40 -3
- package/dist/reports/src/report-status.d.ts +48 -0
- package/dist/reports/src/report-status.js +156 -0
- package/dist/reports/src/report-types.d.ts +73 -0
- package/dist/reports/src/report-types.js +3 -0
- package/dist/reports/src/reporter.d.ts +67 -0
- package/dist/reports/src/reporter.js +128 -0
- package/dist/reports/src/reports-explorer-route.d.ts +541 -0
- package/dist/reports/src/reports-explorer-route.js +11 -0
- package/dist/reports/src/reports-list-route.d.ts +9 -0
- package/dist/reports/src/reports-list-route.js +9 -0
- package/dist/reports/src/reports-route.d.ts +561 -22
- package/dist/reports/src/reports-route.js +11 -3
- package/dist/reports/src/reports-store.d.ts +19 -2
- package/dist/reports/src/reports-store.js +10 -2
- package/dist/reports/src/resilient-cache.d.ts +14 -1
- package/dist/reports/src/resilient-cache.js +8 -1
- package/dist/reports/src/retention.d.ts +17 -1
- package/dist/reports/src/retention.js +5 -1
- package/dist/reports/src/run-bundle.d.ts +63 -0
- package/dist/reports/src/run-bundle.js +159 -0
- package/dist/reports/src/s3-store.d.ts +79 -0
- package/dist/reports/src/s3-store.js +295 -0
- package/dist/reports/src/scenario.d.ts +14 -4
- package/dist/reports/src/scenario.js +5 -4
- package/dist/reports/src/sigv4.d.ts +72 -0
- package/dist/reports/src/sigv4.js +96 -0
- package/dist/reports/src/snapshot-bundle.d.ts +24 -1
- package/dist/reports/src/snapshot-bundle.js +27 -2
- package/dist/reports/src/snapshot-surface.d.ts +20 -9
- package/dist/reports/src/snapshot-surface.js +32 -19
- package/dist/reports/src/source-content.d.ts +23 -0
- package/dist/reports/src/source-content.js +30 -1
- package/dist/reports/src/source-entries.d.ts +13 -0
- package/dist/reports/src/source-entries.js +6 -0
- package/dist/reports/src/source-part.d.ts +15 -0
- package/dist/reports/src/source-part.js +8 -0
- package/dist/reports/src/source-reader.d.ts +11 -0
- package/dist/reports/src/source-reader.js +5 -0
- package/dist/reports/src/spec-evidence.d.ts +12 -2
- package/dist/reports/src/spec-evidence.js +6 -2
- package/dist/reports/src/spec-inventory.d.ts +15 -1
- package/dist/reports/src/spec-inventory.js +22 -1
- package/dist/reports/src/spec-link.d.ts +28 -0
- package/dist/reports/src/spec-link.js +70 -0
- package/dist/reports/src/spec-set.d.ts +63 -0
- package/dist/reports/src/spec-set.js +177 -0
- package/dist/reports/src/status.d.ts +10 -0
- package/dist/reports/src/status.js +5 -0
- package/dist/reports/src/store-prefix.d.ts +28 -0
- package/dist/reports/src/store-prefix.js +22 -0
- package/dist/reports/src/store-url.d.ts +89 -0
- package/dist/reports/src/store-url.js +160 -0
- package/dist/reports/src/test-catalog-entity.d.ts +11 -0
- package/dist/reports/src/test-catalog-entity.js +6 -0
- package/dist/reports/src/types.d.ts +6 -1
- package/dist/reports/src/use-report-nav.d.ts +35 -0
- package/dist/reports/src/use-report-nav.js +12 -0
- package/dist/schema/src/api.d.ts +799 -0
- package/dist/schema/src/api.js +201 -0
- package/dist/schema/src/cli-results.d.ts +210 -0
- package/dist/schema/src/cli-results.js +124 -0
- package/dist/schema/src/common.d.ts +53 -0
- package/dist/schema/src/common.js +42 -0
- package/dist/schema/src/index.d.ts +14 -0
- package/dist/schema/src/index.js +14 -0
- package/dist/schema/src/layer.d.ts +2273 -0
- package/dist/schema/src/layer.js +462 -0
- package/dist/schema/src/manifest.d.ts +95 -0
- package/dist/schema/src/manifest.js +84 -0
- package/dist/schema/src/report-sources.d.ts +28 -0
- package/dist/schema/src/report-sources.js +25 -0
- package/dist/schema/src/runs-index.d.ts +16 -0
- package/dist/schema/src/runs-index.js +15 -0
- package/dist/schema/src/server-config.d.ts +93 -0
- package/dist/schema/src/server-config.js +73 -0
- package/dist/schema/src/spec.d.ts +69 -0
- package/dist/schema/src/spec.js +58 -0
- package/dist/server/src/app.d.ts +62 -0
- package/dist/server/src/app.js +419 -0
- package/dist/server/src/auth.d.ts +41 -0
- package/dist/server/src/auth.js +59 -0
- package/dist/server/src/config.d.ts +83 -0
- package/dist/server/src/config.js +187 -0
- package/dist/server/src/dev.d.ts +12 -0
- package/dist/server/src/dev.js +80 -0
- package/dist/server/src/events.d.ts +29 -0
- package/dist/server/src/events.js +101 -0
- package/dist/server/src/host.d.ts +30 -0
- package/dist/server/src/host.js +115 -0
- package/dist/server/src/index.d.ts +16 -0
- package/dist/server/src/index.js +16 -0
- package/dist/server/src/llms.d.ts +19 -0
- package/dist/server/src/llms.js +63 -0
- package/dist/server/src/main.d.ts +30 -0
- package/dist/server/src/main.js +112 -0
- package/dist/server/src/openapi.d.ts +59 -0
- package/dist/server/src/openapi.js +374 -0
- package/dist/server/src/problem.d.ts +8 -0
- package/dist/server/src/problem.js +39 -0
- package/dist/server/src/site.d.ts +13 -0
- package/dist/server/src/site.js +43 -0
- package/dist/server/src/store-api.d.ts +28 -0
- package/dist/server/src/store-api.js +159 -0
- package/dist/server/src/validate.d.ts +71 -0
- package/dist/server/src/validate.js +197 -0
- package/dist/vitest/src/index.d.ts +27 -5
- package/dist/vitest/src/index.js +18 -5
- package/dist/webdriver/src/driver.d.ts +63 -11
- package/dist/webdriver/src/driver.js +57 -6
- package/dist/webdriver/src/index.d.ts +8 -0
- package/dist/webdriver/src/index.js +1 -0
- package/dist/webdriver/src/protocol.d.ts +75 -6
- package/dist/webdriver/src/protocol.js +79 -6
- package/docs/agents.md +137 -0
- package/docs/deploying.md +345 -0
- package/docs/dogfooding.md +175 -0
- package/docs/extending.md +242 -0
- package/docs/integrating.md +485 -0
- package/docs/reference/bun.md +141 -0
- package/docs/reference/cli.md +146 -0
- package/docs/reference/core.md +2426 -0
- package/docs/reference/detox.md +150 -0
- package/docs/reference/http-api.md +303 -0
- package/docs/reference/playwright.md +303 -0
- package/docs/reference/reports.md +7098 -0
- package/docs/reference/schema.md +1651 -0
- package/docs/reference/server.md +685 -0
- package/docs/reference/vitest.md +45 -0
- package/docs/reference/webdriver.md +330 -0
- package/docs/report-backends.md +144 -0
- package/docs/report-contract.md +400 -0
- package/docs/reporting-issues.md +160 -0
- package/docs/server.md +285 -0
- package/docs/statecharts.md +641 -0
- package/llms-full.txt +3506 -0
- package/llms.txt +47 -0
- package/package.json +33 -5
- package/packages/core/README.md +2 -1
- package/packages/reports/README.md +69 -2
- package/packages/reports/STORAGE.md +5 -1
- package/packages/schema/README.md +14 -0
- package/packages/schema/schemas/check-detail.schema.json +1032 -0
- package/packages/schema/schemas/checks-result.schema.json +26 -0
- package/packages/schema/schemas/command-error.schema.json +35 -0
- package/packages/schema/schemas/doctor-result.schema.json +60 -0
- package/packages/schema/schemas/effective-delta.schema.json +490 -0
- package/packages/schema/schemas/effective-evidence.schema.json +471 -0
- package/packages/schema/schemas/evidence-page.schema.json +271 -0
- package/packages/schema/schemas/hello-event.schema.json +22 -0
- package/packages/schema/schemas/init-plan.schema.json +347 -0
- package/packages/schema/schemas/layer-rows.schema.json +199 -0
- package/packages/schema/schemas/layer.schema.json +2888 -0
- package/packages/schema/schemas/merge-result.schema.json +40 -0
- package/packages/schema/schemas/outline.schema.json +62 -0
- package/packages/schema/schemas/problem.schema.json +37 -0
- package/packages/schema/schemas/publish-checks.schema.json +1413 -0
- package/packages/schema/schemas/publish-result.schema.json +168 -0
- package/packages/schema/schemas/ready.schema.json +68 -0
- package/packages/schema/schemas/report-event.schema.json +100 -0
- package/packages/schema/schemas/report-status.schema.json +370 -0
- package/packages/schema/schemas/server-config.schema.json +194 -0
- package/packages/schema/schemas/server-info.schema.json +114 -0
- package/packages/schema/schemas/spec-set.schema.json +103 -0
- package/packages/schema/schemas/store-listing.schema.json +29 -0
- package/packages/schema/schemas/store-write-result.schema.json +28 -0
- package/packages/schema/schemas/stream-result.schema.json +59 -0
- package/packages/server/README.md +43 -0
- package/packages/server/openapi.json +6699 -0
- package/packages/visualizer/README.md +27 -5
- package/packages/visualizer/example/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/example/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/example/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/example/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/example/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/example/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/cart.qnt +7 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/checkout.openslo.yaml +10 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/drink-price.dmn +24 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/loyalty.feature +7 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/ordering.feature +36 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/payment.als +4 -0
- package/packages/visualizer/scripts/make-fixtures.ts +2 -0
- package/packages/visualizer/scripts/publish-data.ts +1 -2
- package/packages/visualizer/src/app/AppShell.tsx +9 -2
- package/packages/visualizer/src/app/report-sources.tsx +6 -4
- package/packages/visualizer/src/app/router.tsx +3 -3
- package/packages/visualizer/src/components/Header.module.css +35 -0
- package/packages/visualizer/src/components/Header.tsx +41 -4
- package/packages/visualizer/src/data/adapters/adapter.ts +5 -17
- package/packages/visualizer/src/data/adapters/index.ts +10 -1
- package/packages/visualizer/src/evidence/api.ts +14 -2
- package/packages/visualizer/src/evidence/artifacts.module.css +213 -0
- package/packages/visualizer/src/evidence/artifacts.tsx +272 -0
- package/packages/visualizer/src/evidence/check-detail.tsx +38 -4
- package/packages/visualizer/src/evidence/evidence-context.tsx +74 -12
- package/packages/visualizer/src/evidence/evidence.module.css +20 -0
- package/packages/visualizer/src/evidence/marks.tsx +2 -0
- package/packages/visualizer/src/evidence/overview.tsx +3 -3
- package/packages/visualizer/src/evidence/sources-panel.tsx +88 -34
- package/packages/visualizer/src/evidence/spec-page.tsx +23 -16
- package/packages/visualizer/src/find/Finder.tsx +1 -7
- package/packages/visualizer/src/find/open.ts +4 -0
- package/packages/visualizer/src/live/live-stream.ts +204 -0
- package/packages/visualizer/src/runtime.ts +19 -0
- package/packages/visualizer/src/state/ui-store.ts +6 -2
- package/packages/visualizer/vite/atlas-server-proxy.ts +36 -0
- package/packages/visualizer/vite/example-reports.ts +475 -0
- package/packages/visualizer/vite.config.ts +18 -2
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
# Reference: server
|
|
2
|
+
|
|
3
|
+
The Atlas server: the API results are uploaded to, the live report, and the viewer on one host. Import path `@crvouga/atlas/server`.
|
|
4
|
+
|
|
5
|
+
> Generated from the doc comments of `packages/server/src` by `bun run docs`. Do not edit: change the comment next to the code.
|
|
6
|
+
|
|
7
|
+
### The Atlas server application
|
|
8
|
+
|
|
9
|
+
Source: `packages/server/src/app.ts`
|
|
10
|
+
|
|
11
|
+
`createAtlasServer` is the whole of a project's Atlas as one `fetch` handler: the API results are uploaded to, the live
|
|
12
|
+
report every viewer is shown, the gate, the server-sent event stream, the specs and runs the viewer reads, the viewer
|
|
13
|
+
itself, and the server's own description (`/api/openapi.json`, `/llms.txt`). What it knows lives in its backends (by
|
|
14
|
+
default a folder on its own disk), so replacing it loses nothing. Every error leaves as an RFC 9457 problem document; every
|
|
15
|
+
route is described in `openapi.ts` (a test holds the two together).
|
|
16
|
+
|
|
17
|
+
See docs/server.md
|
|
18
|
+
|
|
19
|
+
#### `AtlasServerOptions`
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
export type AtlasServerOptions = {
|
|
23
|
+
/** Every backend, read together. */
|
|
24
|
+
readonly backends: readonly BackendInput[];
|
|
25
|
+
/** The id of the backend uploads go to. */
|
|
26
|
+
readonly write: string;
|
|
27
|
+
readonly tokens?: readonly ResolvedToken[];
|
|
28
|
+
readonly anonymousRead?: boolean;
|
|
29
|
+
/** The built viewer. Without it, only the API is served. */
|
|
30
|
+
readonly site?: string;
|
|
31
|
+
readonly outlineBranch?: string;
|
|
32
|
+
readonly include?: (layer: LayerHeader) => boolean;
|
|
33
|
+
readonly refreshMs?: number;
|
|
34
|
+
readonly limits?: { readonly maxObjectMiB?: number; readonly maxJsonMiB?: number; readonly maxStreams?: number };
|
|
35
|
+
readonly heartbeatMs?: number;
|
|
36
|
+
readonly log?: (line: Record<string, unknown>) => void;
|
|
37
|
+
readonly now?: () => number;
|
|
38
|
+
readonly version?: string;
|
|
39
|
+
/** Extra runtime configuration written into the page. */
|
|
40
|
+
readonly page?: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
What the server is built from: its `backends` (read together) and which one takes uploads (`write`), `tokens`, the built `site`, the report's filters (`include`, `outlineBranch`), `limits`, timings, `log`, and `now` for tests.
|
|
45
|
+
|
|
46
|
+
#### `AtlasServer`
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
export type AtlasServer = {
|
|
50
|
+
readonly fetch: (request: Request) => Promise<Response>;
|
|
51
|
+
readonly index: ReportIndex;
|
|
52
|
+
readonly events: EventHub;
|
|
53
|
+
/** The routes the server answers, as registered: what the OpenAPI document must describe (a test holds the two together). */
|
|
54
|
+
readonly routes: readonly { readonly method: string; readonly path: string }[];
|
|
55
|
+
/** Resolves when the first pass over the backends is done. */
|
|
56
|
+
readonly ready: Promise<void>;
|
|
57
|
+
/** Stop refreshing and end every live connection. */
|
|
58
|
+
close(): void;
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
A running server application: `fetch` (serve requests), `index` (the live report), `events` (the viewers), `routes` (what it answers), `ready` (the first pass over the backends is done) and `close`.
|
|
63
|
+
|
|
64
|
+
#### `createAtlasServer`
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
export function createAtlasServer(options: AtlasServerOptions): AtlasServer
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The whole of a project's Atlas on one process: the API that results are uploaded to, the live report every
|
|
71
|
+
viewer is shown, and the viewer itself. All of it is under one host, `/api` for the API and `/` for the page.
|
|
72
|
+
What it knows lives in its backends (by default a folder on its own disk), so replacing it loses nothing.
|
|
73
|
+
|
|
74
|
+
### Authentication and roles
|
|
75
|
+
|
|
76
|
+
Source: `packages/server/src/auth.ts`
|
|
77
|
+
|
|
78
|
+
Who is asking, and may they. Tokens have a role (`read` < `publish` < `admin`) and are compared in constant time. Reading
|
|
79
|
+
accepts a Bearer token or the browser's sign-in box (any user name, the token as the password); changing anything needs
|
|
80
|
+
the Bearer header, because a browser sends the sign-in box's credentials to any page that asks, which would let another
|
|
81
|
+
site upload with them. A server with no tokens is open, and refuses to listen beyond this machine unless told it may.
|
|
82
|
+
|
|
83
|
+
#### `Identity`
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
export type Identity = {
|
|
87
|
+
readonly name: string;
|
|
88
|
+
readonly role: ServerRole;
|
|
89
|
+
/** `bearer` for a token in a header, `basic` for the browser's sign-in box, `none` for a server with no tokens. */
|
|
90
|
+
readonly via: 'bearer' | 'basic' | 'none';
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Who a request is: the token's `name` (never the token), its `role`, and how it was presented (`bearer`, `basic`, or `none` for an open server or an anonymous reader).
|
|
95
|
+
|
|
96
|
+
#### `Verdict`
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
export type Verdict =
|
|
100
|
+
| { readonly ok: true; readonly identity: Identity }
|
|
101
|
+
| { readonly ok: false; readonly status: 401 | 403; readonly message: string };
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The answer to "may this request do that": allowed with the identity, or refused with the status to answer (`401` no or unknown token, `403` a known token that may not) and a message that says what to do.
|
|
105
|
+
|
|
106
|
+
#### `createAuth`
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
export function createAuth(tokens: readonly ResolvedToken[], anonymousRead: boolean)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Who is asking, and may they. A server with no tokens is open (and refuses to listen beyond this machine
|
|
113
|
+
unless told it may). With tokens, every request must carry one, except where `anonymousRead` lets anyone look.
|
|
114
|
+
|
|
115
|
+
Changing anything needs a token in an `Authorization: Bearer` header, never the browser's sign-in box: the
|
|
116
|
+
browser sends that box's credentials on its own to any page that asks, which would let another site upload
|
|
117
|
+
with them.
|
|
118
|
+
|
|
119
|
+
#### `Auth`
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
export type Auth = ReturnType<typeof createAuth>;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The authentication of one server: `identify` (who is this), `check` (may they, for a needed role) and `open` (the server has no tokens).
|
|
126
|
+
|
|
127
|
+
### Server configuration
|
|
128
|
+
|
|
129
|
+
Source: `packages/server/src/config.ts`
|
|
130
|
+
|
|
131
|
+
Loads how the server runs: `atlas.server.json`, then environment variables, then flags, each overriding the last, checked
|
|
132
|
+
against `ServerConfigSchema` and resolved (paths made absolute, backends named, tokens read). Every mistake is a
|
|
133
|
+
`ConfigError` that says what to change, and a server that would listen beyond this machine with no tokens refuses to
|
|
134
|
+
start. `SERVER_SETTINGS` documents every setting once; the table in docs/server.md is generated from it and a test proves
|
|
135
|
+
each row.
|
|
136
|
+
|
|
137
|
+
See docs/server.md#configuration
|
|
138
|
+
|
|
139
|
+
#### `ResolvedToken`
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
export type ResolvedToken = { readonly name: string; readonly role: ServerRole; readonly token: string };
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
A token as the server holds it: the `name` it is shown under in logs, its `role`, and the secret `token`.
|
|
146
|
+
|
|
147
|
+
#### `BackendSpec`
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
export type BackendSpec = { readonly id: string; readonly label: string; readonly url: string };
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
A backend as configured: its `id`, the `label` people see, and the `url` (a folder, `s3://…`, or another server) to open.
|
|
154
|
+
|
|
155
|
+
#### `ResolvedServerConfig`
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
export type ResolvedServerConfig = Omit<ServerConfig, 'backends' | 'auth' | 'write'> & {
|
|
159
|
+
/** The folder that is the default backend, absolute. */
|
|
160
|
+
readonly data: string;
|
|
161
|
+
/** Every backend, the data folder first. All are read; uploads go to `writeId`. */
|
|
162
|
+
readonly backends: readonly BackendSpec[];
|
|
163
|
+
readonly writeId: string;
|
|
164
|
+
readonly tokens: readonly ResolvedToken[];
|
|
165
|
+
readonly anonymousRead: boolean;
|
|
166
|
+
readonly insecure: boolean;
|
|
167
|
+
/** Where the config came from, for the first line of the log. */
|
|
168
|
+
readonly configFile: string | null;
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The configuration the server runs with: the file, then the environment, then the flags, checked and resolved.
|
|
173
|
+
|
|
174
|
+
#### `ConfigError`
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
export class ConfigError extends Error {}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
A configuration that cannot be used. The message says what to change; `atlas serve` prints it and exits 2.
|
|
181
|
+
|
|
182
|
+
#### `SERVER_FLAGS`
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export const SERVER_FLAGS: readonly string[]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Every flag `atlas serve` accepts, with its `--`.
|
|
189
|
+
|
|
190
|
+
#### `ServerSetting`
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
export type ServerSetting = {
|
|
194
|
+
/** What it sets, in words. */
|
|
195
|
+
readonly summary: string;
|
|
196
|
+
/** The key in `atlas.server.json` (dotted for nested keys). */
|
|
197
|
+
readonly key: string;
|
|
198
|
+
/** The command-line flag, with its value placeholder, or null when there is none. */
|
|
199
|
+
readonly flag: string | null;
|
|
200
|
+
/** The environment variables, the first that is set wins; empty when there are none. */
|
|
201
|
+
readonly env: readonly string[];
|
|
202
|
+
/** What it is when nothing sets it. */
|
|
203
|
+
readonly default: string;
|
|
204
|
+
/**
|
|
205
|
+
* How the documentation is held to the code: giving `value` through the environment variable (or the flag) must make
|
|
206
|
+
* `read` of the resolved configuration equal `expected`. A test runs every setting's example both ways.
|
|
207
|
+
*/
|
|
208
|
+
readonly example: { readonly value: string; readonly read: (config: ResolvedServerConfig) => unknown; readonly expected: unknown };
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
One setting of the server as an operator meets it: the config key, the flag, the environment variables, and what it does.
|
|
213
|
+
|
|
214
|
+
#### `SERVER_SETTINGS`
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
export const SERVER_SETTINGS: readonly ServerSetting[]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Every setting that can be given by flag or environment, documented once. `docs/server.md` renders its table from
|
|
221
|
+
this list, and a test proves each row: its example, through the flag and through the environment, changes the
|
|
222
|
+
configuration as the row says. A setting added to the loader without a row here is therefore not documented in the
|
|
223
|
+
table; one documented here that the loader ignores fails the test.
|
|
224
|
+
|
|
225
|
+
#### `SERVER_USAGE`
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
export const SERVER_USAGE = …
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The text `atlas serve --help` prints. Also the source of the `atlas serve` section of `docs/reference/cli.md`.
|
|
232
|
+
|
|
233
|
+
#### `loadServerConfig`
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
export function loadServerConfig(argv: readonly string[], env: Env, cwd: string, read: (file: string) => string = file => readFileSync(file, 'utf8')): ResolvedServerConfig
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Read the file named by `--config`/`ATLAS_CONFIG`, or `atlas.server.json` in the folder if there is one, lay the
|
|
240
|
+
environment and then the flags over it, and check the result. Every problem is a {@link ConfigError} that says
|
|
241
|
+
what to change.
|
|
242
|
+
|
|
243
|
+
#### `assertSafeToListen`
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
export function assertSafeToListen(config: Pick<ResolvedServerConfig, 'host' | 'tokens' | 'insecure'>): void
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
A server that anyone on the network can upload to must say who may.
|
|
250
|
+
|
|
251
|
+
### `atlas dev`
|
|
252
|
+
|
|
253
|
+
Source: `packages/server/src/dev.ts`
|
|
254
|
+
|
|
255
|
+
Runs the same server as `atlas serve` on a port of its own, with the viewer's Vite dev server in front of it. Vite proxies
|
|
256
|
+
`/api` (server-sent events included) to the server and writes the same address book into the page, so the browser, the
|
|
257
|
+
uploaders and the viewer all use one host, exactly as in production, and a change to the viewer shows at once.
|
|
258
|
+
|
|
259
|
+
#### `DEV_USAGE`
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
export const DEV_USAGE = …
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The text `atlas dev --help` prints. Also the source of the `atlas dev` section of `docs/reference/cli.md`.
|
|
266
|
+
|
|
267
|
+
#### `devMain`
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
export async function devMain(argv: readonly string[], io: ServeIo): Promise<number>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
`atlas dev`.
|
|
274
|
+
|
|
275
|
+
### Server-sent events
|
|
276
|
+
|
|
277
|
+
Source: `packages/server/src/events.ts`
|
|
278
|
+
|
|
279
|
+
What the server tells every connected viewer the moment it happens. A viewer that misses some (a dropped connection, a
|
|
280
|
+
laptop that slept) loses nothing: events say "something changed", the state is always fetched, and a viewer reads again
|
|
281
|
+
when it reconnects. `EventHub` encodes each event once for all viewers, sends a named `ping` every heartbeat so proxies
|
|
282
|
+
keep the connection and a quiet server is told apart from a dead one, refuses past a maximum number of viewers (they poll
|
|
283
|
+
instead), and lets go of a viewer that has stopped reading rather than hold its backlog.
|
|
284
|
+
|
|
285
|
+
See docs/server.md#streaming
|
|
286
|
+
|
|
287
|
+
#### `EventName`
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
export type EventName = 'hello' | 'report' | 'atlas:change';
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
The events the server publishes: `hello` (sent first to a new viewer), `report` (layers arrived) and `atlas:change` (specs or runs changed). `ping` is the heartbeat, sent by the hub itself.
|
|
294
|
+
|
|
295
|
+
#### `EventHub`
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
export class EventHub
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The viewers connected to `/api/events` and how to reach them all. One hub per server.
|
|
302
|
+
|
|
303
|
+
- `get count(): number { return this.#subscribers.size; }` — How many viewers are connected right now.
|
|
304
|
+
- `publish(name: EventName, data: unknown): void` — Tell every viewer. `data` is JSON.
|
|
305
|
+
- `stream(request: Request, greeting: () => unknown): Response` — A stream for one viewer, starting with `hello` (what `greeting` returns). It ends when the viewer goes.
|
|
306
|
+
- `close(): void` — End every stream, for shutting down.
|
|
307
|
+
|
|
308
|
+
### HTTP host for a fetch handler
|
|
309
|
+
|
|
310
|
+
Source: `packages/server/src/host.ts`
|
|
311
|
+
|
|
312
|
+
`listen` serves any `(Request) => Promise<Response>` over HTTP: with `Bun.serve` when running on Bun, with a `node:http`
|
|
313
|
+
bridge (streaming bodies in and out, so server-sent events work) everywhere else. The server's behaviour is the same on
|
|
314
|
+
both; `bun run release:smoke` proves it under each. Bodies over `maxBodyBytes` are refused by the runtime before the
|
|
315
|
+
handler sees them.
|
|
316
|
+
|
|
317
|
+
#### `RunningServer`
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
export type RunningServer = {
|
|
321
|
+
readonly port: number;
|
|
322
|
+
readonly url: string;
|
|
323
|
+
/** Stop accepting, let requests in flight finish for up to `graceMs`, then end what is left. */
|
|
324
|
+
close(graceMs?: number): Promise<void>;
|
|
325
|
+
};
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
A server that is listening: the `port` it got (useful when asked for `0`), its `url`, and `close`.
|
|
329
|
+
|
|
330
|
+
#### `ListenOptions`
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
export type ListenOptions = {
|
|
334
|
+
readonly port: number;
|
|
335
|
+
readonly host: string;
|
|
336
|
+
/** The largest request body to read, in bytes. */
|
|
337
|
+
readonly maxBodyBytes: number;
|
|
338
|
+
};
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Where to listen (`port`, `host`) and the largest request body the runtime will accept.
|
|
342
|
+
|
|
343
|
+
#### `listen`
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
export async function listen(handler: Handler, options: ListenOptions): Promise<RunningServer>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Serve a fetch handler. On Bun, which is what Atlas is made for, that is `Bun.serve`: one native server for the
|
|
350
|
+
API, the live streams and the page. On Node it is the same handler behind `node:http`, so the package still runs
|
|
351
|
+
where Bun is not installed.
|
|
352
|
+
|
|
353
|
+
### Server package entry point (`@crvouga/atlas/server`)
|
|
354
|
+
|
|
355
|
+
Source: `packages/server/src/index.ts`. Import: `@crvouga/atlas/server`
|
|
356
|
+
|
|
357
|
+
Everything needed to run the Atlas server from code: `createAtlasServer` (a `fetch` handler with the live report, uploads
|
|
358
|
+
and the viewer), `listen` (serve it over HTTP on Bun or Node), `loadServerConfig` (the file, the environment and the flags
|
|
359
|
+
as one checked configuration), `serveMain` (what `atlas serve` runs), `EventHub`, `createAuth`, and the upload checks.
|
|
360
|
+
|
|
361
|
+
See docs/server.md
|
|
362
|
+
|
|
363
|
+
### llms.txt of a running server
|
|
364
|
+
|
|
365
|
+
Source: `packages/server/src/llms.ts`
|
|
366
|
+
|
|
367
|
+
The plain-text guide ([llms.txt](https://llmstxt.org)) a server serves about itself at `GET /llms.txt`, for an AI
|
|
368
|
+
agent that was handed nothing but the server's address. It is written from this server's own settings (its
|
|
369
|
+
address, whether it needs a token), so what it says is true of the server that says it, and it points at the
|
|
370
|
+
machine-readable description (`/api/openapi.json`) rather than repeating it.
|
|
371
|
+
|
|
372
|
+
#### `LlmsContext`
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
export type LlmsContext = {
|
|
376
|
+
/** The address clients use, such as `https://atlas.example.com`, no trailing slash. */
|
|
377
|
+
readonly url: string;
|
|
378
|
+
/** True when the server has no tokens: anyone who can reach it may upload. */
|
|
379
|
+
readonly open: boolean;
|
|
380
|
+
/** The id of the backend uploads go to. */
|
|
381
|
+
readonly write: string;
|
|
382
|
+
};
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
What the guide says about the server that serves it.
|
|
386
|
+
|
|
387
|
+
#### `llmsTxt`
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
export function llmsTxt(context: LlmsContext): string
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
The guide for one server, Markdown. Stable in structure: an agent may read it by its headings.
|
|
394
|
+
|
|
395
|
+
### `atlas serve`
|
|
396
|
+
|
|
397
|
+
Source: `packages/server/src/main.ts`
|
|
398
|
+
|
|
399
|
+
Starts the Atlas server from its configuration: opens every backend (creating the data folder), proves the upload
|
|
400
|
+
backend can be written to before listening, finds or builds the viewer, listens at once (so a liveness probe finds the
|
|
401
|
+
process while a large backend is still being read), and stops cleanly on SIGTERM or SIGINT. `serverOptionsOf` is shared
|
|
402
|
+
with `atlas dev`, so the two run the same server.
|
|
403
|
+
|
|
404
|
+
See docs/server.md#run-it
|
|
405
|
+
|
|
406
|
+
#### `ServeIo`
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
export type ServeIo = { readonly out: (text: string) => void; readonly env?: Env; readonly cwd?: string; readonly signal?: AbortSignal };
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
What `serveMain` and `devMain` are given besides arguments: where output goes, and, for tests and embedding, the environment, working directory and an `AbortSignal` that stops the server (otherwise SIGTERM and SIGINT do).
|
|
413
|
+
|
|
414
|
+
#### `openConfiguredBackends`
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
export function openConfiguredBackends(config: ResolvedServerConfig, env: Env, cwd: string): (BackendInput & { readonly writable: boolean })[]
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Open every backend of a configuration. The data folder is made if it is not there.
|
|
421
|
+
|
|
422
|
+
#### `serverOptionsOf`
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
export function serverOptionsOf(config: ResolvedServerConfig, backends: ReturnType<typeof openConfiguredBackends>, log?: (line: Record<string, unknown>) => void): AtlasServerOptions
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
What `createAtlasServer` is given for a configuration: `atlas serve` and `atlas dev` run the same server.
|
|
429
|
+
|
|
430
|
+
#### `serveMain`
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
export async function serveMain(argv: readonly string[], io: ServeIo): Promise<number>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
`atlas serve`. Runs until it is told to stop; returns the exit code.
|
|
437
|
+
|
|
438
|
+
### OpenAPI document of the Atlas server
|
|
439
|
+
|
|
440
|
+
Source: `packages/server/src/openapi.ts`
|
|
441
|
+
|
|
442
|
+
The server's HTTP API described as an OpenAPI 3.1 document (JSON Schema 2020-12 inside), generated from the
|
|
443
|
+
operation table below and the Zod schemas of `packages/schema/src/api.ts`. It is served at `GET /api/openapi.json`,
|
|
444
|
+
shipped as `@crvouga/atlas/openapi.json`, and committed as `packages/server/openapi.json` (`bun run docs` rewrites
|
|
445
|
+
it; a test fails when it differs). Any OpenAPI tool can generate a client, a mock or a test suite from it.
|
|
446
|
+
|
|
447
|
+
The table is held to the code by a test: every route the server registers must have an operation here and every
|
|
448
|
+
operation here must be a route the server registers. Adding a route without describing it fails the build.
|
|
449
|
+
|
|
450
|
+
Stability: this API only grows within `API_VERSION`: optional parameters, optional response fields, new
|
|
451
|
+
operations and new events. See AGENTS.md ("The server is a living application").
|
|
452
|
+
|
|
453
|
+
#### `API_VERSION`
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
export const API_VERSION = …
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
The version of the API described, `major.minor.patch`: the minor grows when an operation or field is added, the major never within `/api`.
|
|
460
|
+
|
|
461
|
+
#### `Role`
|
|
462
|
+
|
|
463
|
+
```ts
|
|
464
|
+
export type Role = 'none' | 'read' | 'publish' | 'admin';
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Who may call an operation: `none` (anyone), or the least role that may (`read` < `publish` < `admin`).
|
|
468
|
+
|
|
469
|
+
#### `Operation`
|
|
470
|
+
|
|
471
|
+
```ts
|
|
472
|
+
export type Operation = {
|
|
473
|
+
/** The route as Hono registers it, `METHOD /path` (`:name` for a parameter, `*` for the rest of the path). */
|
|
474
|
+
readonly route: string;
|
|
475
|
+
/** The same route as OpenAPI writes it, `/path/{name}`. */
|
|
476
|
+
readonly path: string;
|
|
477
|
+
readonly operationId: string;
|
|
478
|
+
readonly tag: string;
|
|
479
|
+
readonly summary: string;
|
|
480
|
+
/** What it does and how to use it, written for a client that has read nothing else (Markdown). */
|
|
481
|
+
readonly description: string;
|
|
482
|
+
readonly role: Role;
|
|
483
|
+
readonly parameters?: readonly Param[];
|
|
484
|
+
readonly body?: Body;
|
|
485
|
+
readonly responses: Readonly<Record<string, Response>>;
|
|
486
|
+
};
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
One operation of the API, and the route the server registers for it.
|
|
490
|
+
|
|
491
|
+
#### `OPERATIONS`
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
export const OPERATIONS: readonly Operation[]
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Every operation of the API. The order is the order of the document. The descriptions are the documentation an
|
|
498
|
+
agent reads, so they say what to send, what comes back, and what to do when it does not work.
|
|
499
|
+
|
|
500
|
+
#### `NOT_OPERATIONS`
|
|
501
|
+
|
|
502
|
+
```ts
|
|
503
|
+
export const NOT_OPERATIONS: ReadonlyMap<string, string>
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Routes the server registers that are not operations of this API, each with the reason. The coverage test skips
|
|
507
|
+
these and only these.
|
|
508
|
+
|
|
509
|
+
#### `openApiDocument`
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
export function openApiDocument(options: { readonly serverUrl?: string } = {}): Record<string, unknown>
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
The OpenAPI 3.1 document of the API. `serverUrl` (such as `https://atlas.example.com`) is written into `servers` when given.
|
|
516
|
+
|
|
517
|
+
### Problem documents
|
|
518
|
+
|
|
519
|
+
Source: `packages/server/src/problem.ts`
|
|
520
|
+
|
|
521
|
+
Every error the server answers is an [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem document
|
|
522
|
+
(`application/problem+json`): `type`, `title`, `status`, `detail`, and `error`, a copy of `detail` for clients
|
|
523
|
+
written before the standard was adopted. Handlers answer however is natural (`{ error }`); one place,
|
|
524
|
+
{@link asProblem}, makes every error response a problem document, so none can differ.
|
|
525
|
+
|
|
526
|
+
#### `problemResponse`
|
|
527
|
+
|
|
528
|
+
```ts
|
|
529
|
+
export function problemResponse(status: number, detail: string, headers: Record<string, string> = {}): Response
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
A response for a problem, built directly (used where no handler is involved, such as authentication).
|
|
533
|
+
|
|
534
|
+
#### `asProblem`
|
|
535
|
+
|
|
536
|
+
```ts
|
|
537
|
+
export async function asProblem(response: Response): Promise<Response>
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
The response made into a problem document when it is an error (status 400 or more) with a JSON body naming an
|
|
541
|
+
`error`. Headers (`WWW-Authenticate`, `Retry-After`, `Allow`) and any other body fields are kept. Anything else,
|
|
542
|
+
including every success, is returned as it is.
|
|
543
|
+
|
|
544
|
+
### Finding the viewer
|
|
545
|
+
|
|
546
|
+
Source: `packages/server/src/site.ts`
|
|
547
|
+
|
|
548
|
+
Locates the built viewer a server serves: the folder named by `--site`, `./atlas-site`, or one built once into the user's
|
|
549
|
+
cache from the viewer source shipped in the package (`atlas-visualizer build --no-data`). The build is the same for every
|
|
550
|
+
project because the server writes its own address book into the page, so it is built at most once per installed version.
|
|
551
|
+
|
|
552
|
+
#### `visualizerRoot`
|
|
553
|
+
|
|
554
|
+
```ts
|
|
555
|
+
export function visualizerRoot(): string | null
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Where the viewer's source is, in this repository and in an installed package.
|
|
559
|
+
|
|
560
|
+
#### `buildSite`
|
|
561
|
+
|
|
562
|
+
```ts
|
|
563
|
+
export async function buildSite(out: string, log: (text: string) => void): Promise<boolean>
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Build the viewer once into a folder, for a server that was not given a prebuilt one.
|
|
567
|
+
|
|
568
|
+
#### `findSite`
|
|
569
|
+
|
|
570
|
+
```ts
|
|
571
|
+
export async function findSite(named: string | undefined, cwd: string, log: (text: string) => void): Promise<string | null>
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
The viewer to serve: the one named, a build beside the project, or one built into the user's cache.
|
|
575
|
+
|
|
576
|
+
### Store protocol routes
|
|
577
|
+
|
|
578
|
+
Source: `packages/server/src/store-api.ts`
|
|
579
|
+
|
|
580
|
+
The `ObjectStore` interface over HTTP at `/api/store`: list keys under `layers/`, read and probe an object, upload one
|
|
581
|
+
(checked by `validateUpload`, immutable once stored) and remove a scratch object. This is what `httpStore` talks to. An
|
|
582
|
+
upload is told to the report only after it is stored, and a layer's manifest, parsed while it was checked, is handed on so
|
|
583
|
+
it is not read again. Everything read is served as untrusted bytes (never sniffed, never run).
|
|
584
|
+
|
|
585
|
+
See docs/server.md#the-store-protocol
|
|
586
|
+
|
|
587
|
+
#### `StoreApiOptions`
|
|
588
|
+
|
|
589
|
+
```ts
|
|
590
|
+
export type StoreApiOptions = {
|
|
591
|
+
readonly store: ObjectStore;
|
|
592
|
+
readonly auth: Auth;
|
|
593
|
+
readonly maxObjectBytes: number;
|
|
594
|
+
/** Told after something was uploaded: its key, and what kind of thing it is. */
|
|
595
|
+
readonly onStored: (key: string, kind: string, layer?: ReportLayer) => void | Promise<void>;
|
|
596
|
+
};
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
What the store routes need: the `store` they read and write, the `auth` that decides who may, the largest object accepted, and `onStored`, told after each upload with its key, its kind and (for a layer catalog entry) the layer already parsed.
|
|
600
|
+
|
|
601
|
+
#### `readLimited`
|
|
602
|
+
|
|
603
|
+
```ts
|
|
604
|
+
export async function readLimited(request: Request, limit: number): Promise<Uint8Array>
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Read a request body, refusing as soon as it is over the limit rather than after holding it all.
|
|
608
|
+
|
|
609
|
+
#### `storeApi`
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
export function storeApi(options: StoreApiOptions)
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
The Hono app of the store protocol, to be mounted at `/api/store`. Reads need role `read`; writes need `publish` through a Bearer token.
|
|
616
|
+
|
|
617
|
+
### Upload validation
|
|
618
|
+
|
|
619
|
+
Source: `packages/server/src/validate.ts`
|
|
620
|
+
|
|
621
|
+
What the server checks before it stores an object, so one bad upload cannot corrupt the report for everyone: the key is
|
|
622
|
+
one Atlas writes (`classify`), a layer's content hashes to its id, blobs and spec files are what their names say, a
|
|
623
|
+
document's files and a catalog entry's document are already there (so nothing half-uploaded is visible), and a run
|
|
624
|
+
passed its privacy scan. Refusals are `Refusal`s carrying the HTTP status to answer. Layers are immutable: the same
|
|
625
|
+
bytes again are fine, other bytes under the same key are not.
|
|
626
|
+
|
|
627
|
+
See docs/server.md#what-the-server-refuses
|
|
628
|
+
|
|
629
|
+
#### `Refusal`
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
export class Refusal extends Error
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Why an upload was not accepted. The status is what to answer.
|
|
636
|
+
|
|
637
|
+
#### `UploadKind`
|
|
638
|
+
|
|
639
|
+
```ts
|
|
640
|
+
export type UploadKind = (typeof KINDS)[number]['kind'];
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
What a key names: `layer`, `layer-catalog`, `blob`, `spec-body`, `spec-set`, `spec-catalog`, `run-manifest`, `run-catalog`, `run-file` or `scratch` (what `doctor` writes to try the store).
|
|
644
|
+
|
|
645
|
+
#### `validKey`
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
export function validKey(key: string): boolean
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
Is this a key a client may name? No traversal, no odd characters, and under `layers/`.
|
|
652
|
+
|
|
653
|
+
#### `classify`
|
|
654
|
+
|
|
655
|
+
```ts
|
|
656
|
+
export function classify(key: string): { kind: UploadKind; id: string | null } | null
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
What kind of object a key names and the id inside it (the layer id, the digest…), or null when it is not a key Atlas writes.
|
|
660
|
+
|
|
661
|
+
#### `isCatalog`
|
|
662
|
+
|
|
663
|
+
```ts
|
|
664
|
+
export const isCatalog = …
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
Catalog entries are what makes something visible, so they are the last thing a client writes.
|
|
668
|
+
|
|
669
|
+
#### `validateUpload`
|
|
670
|
+
|
|
671
|
+
```ts
|
|
672
|
+
export async function validateUpload(key: string, bytes: Uint8Array, store: ObjectStore, parsedLayer?: (layer: ReportLayer) => void): Promise<UploadKind>
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
Check an object before it is stored. What is checked is what would otherwise corrupt the report for everyone:
|
|
676
|
+
a layer whose content is not its name, a catalog entry for something not there yet, a run that failed its
|
|
677
|
+
privacy scan. Everything that is checked is checked cheaply, from the bytes in hand.
|
|
678
|
+
|
|
679
|
+
#### `sameBytes`
|
|
680
|
+
|
|
681
|
+
```ts
|
|
682
|
+
export async function sameBytes(store: ObjectStore, key: string, bytes: Uint8Array): Promise<'absent' | 'same' | 'different'>
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
Is this the same object already? Layers are immutable: the same bytes again is fine, other bytes under the same key is not.
|