From c3f3384bfc842a35fb295ea14cbdb03451aa7ddf Mon Sep 17 00:00:00 2001 From: andig Date: Mon, 3 Aug 2026 13:06:37 +0200 Subject: [PATCH] API: generate /api/state documentation from UI types (#32431) Co-authored-by: Michael Geers --- .github/workflows/default.yml | 3 + .github/workflows/documentation.yml | 2 +- .github/workflows/openapi-validate.yml | 3 +- .gitignore | 1 + Dockerfile | 1 - Makefile | 5 +- .../components/ChargingPlans/ChargingPlan.vue | 4 +- .../ChargingPlans/ChargingPlanModal.vue | 8 +- .../components/ChargingPlans/PlanStrategy.vue | 2 +- .../ChargingPlans/PlansRepeatingSettings.vue | 2 +- .../ChargingPlans/PlansSettings.vue | 16 +- .../js/components/ChargingPlans/Warnings.vue | 3 +- assets/js/components/ChargingPlans/types.d.ts | 39 - assets/js/components/Forecast/Chart.vue | 3 +- assets/js/components/Forecast/GridDetails.vue | 3 +- assets/js/components/Forecast/PriceChart.vue | 3 +- assets/js/components/Forecast/SolarChart.vue | 2 +- .../js/components/Forecast/SolarDetails.vue | 2 +- assets/js/components/Forecast/ValueChart.vue | 2 +- .../js/components/Forecast/ValueDetails.vue | 2 +- assets/js/components/Forecast/echarts.ts | 2 +- assets/js/components/Forecast/types.ts | 27 - assets/js/components/Loadpoints/Loadpoint.vue | 2 +- .../js/components/Tariff/SmartCostLimit.vue | 3 +- assets/js/components/Vehicles/Title.vue | 2 +- assets/js/components/Vehicles/Vehicle.vue | 2 +- assets/js/types/evcc.ts | 645 +- assets/js/utils/forecast.ts | 2 +- cmd/openapi/openapi.go | 28 - go.mod | 1 - package-lock.json | 392 +- package.json | 6 + scripts/state-schema/index.ts | 33 + scripts/state-schema/openapi.ts | 38 + scripts/state-schema/schemas.ts | 221 + scripts/state-schema/validate.ts | 114 + server/mcp/openapi.json | 8462 +++++++++++------ server/mcp/openapi.md | 44 +- server/openapi.go | 3 +- server/openapi.state.yaml | 1829 ++++ server/openapi.yaml | 111 +- server/openapi_test.go | 1 + tests/state-api.spec.ts | 28 + tsconfig.json | 2 +- 44 files changed, 8757 insertions(+), 3347 deletions(-) delete mode 100644 assets/js/components/ChargingPlans/types.d.ts delete mode 100644 assets/js/components/Forecast/types.ts delete mode 100644 cmd/openapi/openapi.go create mode 100644 scripts/state-schema/index.ts create mode 100644 scripts/state-schema/openapi.ts create mode 100644 scripts/state-schema/schemas.ts create mode 100644 scripts/state-schema/validate.ts create mode 100644 server/openapi.state.yaml create mode 100644 tests/state-api.spec.ts diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index 7bd731a3c..895bbe2df 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -176,6 +176,9 @@ jobs: - name: Install run: make install-ui + - name: OpenAPI + run: make openapi + - name: Lint run: make lint-ui diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index f9ada3d4a..387a43baa 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -58,7 +58,7 @@ jobs: - name: Prepare OpenAPI spec run: | mkdir -p ./openapi-deploy - cp ./server/openapi.yaml ./openapi-deploy/openapi.yaml + npx --yes @redocly/cli@2 bundle ./server/openapi.yaml -o ./openapi-deploy/openapi.yaml - name: Deploy OpenAPI spec to docs repo uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4 diff --git a/.github/workflows/openapi-validate.yml b/.github/workflows/openapi-validate.yml index 1067bacf7..aa3281018 100644 --- a/.github/workflows/openapi-validate.yml +++ b/.github/workflows/openapi-validate.yml @@ -8,6 +8,7 @@ on: pull_request: paths: - "server/openapi.yaml" + - "server/openapi.state.yaml" - ".github/workflows/openapi-validate.yml" jobs: @@ -22,4 +23,4 @@ jobs: with: go-version: stable - name: Validate OpenAPI spec - run: go run github.com/getkin/kin-openapi/cmd/validate@v0.133.0 -- server/openapi.yaml + run: go run github.com/getkin/kin-openapi/cmd/validate@v0.133.0 -ext -- server/openapi.yaml diff --git a/.gitignore b/.gitignore index 48573ca2a..dd0405372 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ testdata/**/* !assets/js/**/*.yaml !package*.json !evcc.dist.yaml +!server/openapi.state.yaml !.coderabbit.yaml !tests/**/*.evcc.yaml !tests/**/*.tpl.yaml diff --git a/Dockerfile b/Dockerfile index 02a63044e..e224d4f30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,7 +48,6 @@ RUN --mount=type=cache,target=${GOMODCACHE} go mod download # install tools COPY Makefile . COPY cmd/implement/ cmd/implement/ -COPY cmd/openapi/ cmd/openapi/ COPY api/ api/ RUN --mount=type=cache,target=${GOMODCACHE} make install diff --git a/Makefile b/Makefile index 736483078..7f2e3838e 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ CURRDIR := $(shell pwd) default:: ui build -all:: clean install install-ui ui assets lint test-ui lint-ui test build +all:: clean install install-ui ui assets openapi lint test-ui lint-ui test build clean:: rm -rf dist/ @@ -48,6 +48,9 @@ ui:: assets:: go generate ./... +openapi:: + vp run openapi + docs:: go generate github.com/evcc-io/evcc/util/templates/... diff --git a/assets/js/components/ChargingPlans/ChargingPlan.vue b/assets/js/components/ChargingPlans/ChargingPlan.vue index ab3edd481..96eeda0bc 100644 --- a/assets/js/components/ChargingPlans/ChargingPlan.vue +++ b/assets/js/components/ChargingPlans/ChargingPlan.vue @@ -38,9 +38,7 @@ import formatter from "@/mixins/formatter"; import minuteTicker from "@/mixins/minuteTicker"; import { optionStep, fmtEnergy } from "@/utils/energyOptions.ts"; import { defineComponent, type PropType } from "vue"; -import type { CURRENCY, Vehicle } from "@/types/evcc"; -import type { PlanStrategy } from "./types"; -import type { Forecast } from "@/types/evcc.ts"; +import type { CURRENCY, Forecast, PlanStrategy, Vehicle } from "@/types/evcc"; export default defineComponent({ name: "ChargingPlan", diff --git a/assets/js/components/ChargingPlans/ChargingPlanModal.vue b/assets/js/components/ChargingPlans/ChargingPlanModal.vue index bc019dd27..9a4784ebe 100644 --- a/assets/js/components/ChargingPlans/ChargingPlanModal.vue +++ b/assets/js/components/ChargingPlans/ChargingPlanModal.vue @@ -47,13 +47,17 @@ import GenericModal from "../Helper/GenericModal.vue"; import PlansSettings from "./PlansSettings.vue"; import api from "@/api"; import type { + CURRENCY, + Forecast, PlanStrategy, RepeatingPlan, + SMART_COST_TYPE, StaticEnergyPlan, StaticPlan, StaticSocPlan, -} from "./types"; -import type { CURRENCY, Forecast, SMART_COST_TYPE, UiLoadpoint, Vehicle } from "@/types/evcc"; + UiLoadpoint, + Vehicle, +} from "@/types/evcc"; export default defineComponent({ name: "ChargingPlanModal", diff --git a/assets/js/components/ChargingPlans/PlanStrategy.vue b/assets/js/components/ChargingPlans/PlanStrategy.vue index a8014a76b..0e63f3f83 100644 --- a/assets/js/components/ChargingPlans/PlanStrategy.vue +++ b/assets/js/components/ChargingPlans/PlanStrategy.vue @@ -64,7 +64,7 @@