diff --git a/.github/workflows/openapi-lint.yml b/.github/workflows/openapi-lint.yml index b8d5d55be..affbe288e 100644 --- a/.github/workflows/openapi-lint.yml +++ b/.github/workflows/openapi-lint.yml @@ -10,12 +10,16 @@ on: paths: - 'api-reference/*.json' - 'scripts/lint_openapi.py' + - 'scripts/api_path_redirects.py' + - 'docs.json' - '.github/workflows/openapi-lint.yml' push: branches: [main] paths: - 'api-reference/*.json' - 'scripts/lint_openapi.py' + - 'scripts/api_path_redirects.py' + - 'docs.json' - '.github/workflows/openapi-lint.yml' jobs: @@ -26,3 +30,5 @@ jobs: - uses: actions/setup-python@v5 - name: Lint specs run: python3 scripts/lint_openapi.py + - name: Check API path redirects in docs.json + run: python3 scripts/api_path_redirects.py --check diff --git a/docs.json b/docs.json index e9f68b09d..f37d2ede6 100644 --- a/docs.json +++ b/docs.json @@ -1410,6 +1410,1414 @@ { "source": "/en/on-call/integration/alert-integration/alert-sources/overview", "destination": "/en/on-call/integration/alert-integration/alert-sources/standard-alert" + }, + { + "source": "/en/api-reference/ai-sre/artifacts/artifact-gallery-read-get", + "destination": "/en/api-reference/ai-sre/artifacts/artifact-read-get" + }, + { + "source": "/en/api-reference/ai-sre/artifacts/artifact-gallery-read-list", + "destination": "/en/api-reference/ai-sre/artifacts/artifact-read-list" + }, + { + "source": "/en/api-reference/ai-sre/artifacts/artifact-gallery-write-delete", + "destination": "/en/api-reference/ai-sre/artifacts/artifact-write-delete" + }, + { + "source": "/en/api-reference/ai-sre/artifacts/artifact-gallery-write-publish", + "destination": "/en/api-reference/ai-sre/artifacts/artifact-write-publish" + }, + { + "source": "/en/api-reference/ai-sre/artifacts/artifact-gallery-write-update", + "destination": "/en/api-reference/ai-sre/artifacts/artifact-write-update" + }, + { + "source": "/en/api-reference/on-call/integrations/datasource-write-im-war-room-enabled-list", + "destination": "/en/api-reference/on-call/integrations/im-war-room-enabled-list" + }, + { + "source": "/en/api-reference/on-call/status-pages/statuspage-read-page-list", + "destination": "/en/api-reference/on-call/status-pages/status-page-read-page-list" + }, + { + "source": "/zh/api-reference/ai-sre/artifacts/artifact-gallery-read-get", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-get" + }, + { + "source": "/zh/api-reference/ai-sre/artifacts/artifact-gallery-read-list", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-list" + }, + { + "source": "/zh/api-reference/ai-sre/artifacts/artifact-gallery-write-delete", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-delete" + }, + { + "source": "/zh/api-reference/ai-sre/artifacts/artifact-gallery-write-publish", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-publish" + }, + { + "source": "/zh/api-reference/ai-sre/artifacts/artifact-gallery-write-update", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-update" + }, + { + "source": "/zh/api-reference/on-call/integrations/datasource-write-im-war-room-enabled-list", + "destination": "/zh/api-reference/on-call/integrations/im-war-room-enabled-list" + }, + { + "source": "/zh/api-reference/on-call/status-pages/statuspage-read-page-list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-read-page-list" + }, + { + "source": "/account/info", + "destination": "/zh/api-reference/platform/account/account-read-info" + }, + { + "source": "/alert-event/list", + "destination": "/zh/api-reference/on-call/alerts/alert-event-read-list" + }, + { + "source": "/alert/event/list", + "destination": "/zh/api-reference/on-call/alerts/alert-read-event-list" + }, + { + "source": "/alert/feed", + "destination": "/zh/api-reference/on-call/alerts/alert-read-feed" + }, + { + "source": "/alert/info", + "destination": "/zh/api-reference/on-call/alerts/alert-read-info" + }, + { + "source": "/alert/list", + "destination": "/zh/api-reference/on-call/alerts/alert-read-list" + }, + { + "source": "/alert/list-by-ids", + "destination": "/zh/api-reference/on-call/alerts/alert-read-list-by-ids" + }, + { + "source": "/alert/merge", + "destination": "/zh/api-reference/on-call/alerts/alert-write-merge" + }, + { + "source": "/alert/pipeline/info", + "destination": "/zh/api-reference/on-call/alerts/alert-read-pipeline-info" + }, + { + "source": "/alert/pipeline/list", + "destination": "/zh/api-reference/on-call/alerts/alert-read-pipeline-list" + }, + { + "source": "/alert/pipeline/upsert", + "destination": "/zh/api-reference/on-call/alerts/alert-write-pipeline-upsert" + }, + { + "source": "/audit/operation/list", + "destination": "/zh/api-reference/platform/audit-logs/audit-read-operation-list" + }, + { + "source": "/audit/search", + "destination": "/zh/api-reference/platform/audit-logs/audit-read-search" + }, + { + "source": "/calendar/create", + "destination": "/zh/api-reference/on-call/calendars/calendar-create" + }, + { + "source": "/calendar/delete", + "destination": "/zh/api-reference/on-call/calendars/calendar-delete" + }, + { + "source": "/calendar/event/delete", + "destination": "/zh/api-reference/on-call/calendars/cal-event-delete" + }, + { + "source": "/calendar/event/list", + "destination": "/zh/api-reference/on-call/calendars/cal-event-list" + }, + { + "source": "/calendar/event/upsert", + "destination": "/zh/api-reference/on-call/calendars/cal-event-upsert" + }, + { + "source": "/calendar/info", + "destination": "/zh/api-reference/on-call/calendars/calendar-info" + }, + { + "source": "/calendar/list", + "destination": "/zh/api-reference/on-call/calendars/calendar-list" + }, + { + "source": "/calendar/update", + "destination": "/zh/api-reference/on-call/calendars/calendar-update" + }, + { + "source": "/change/list", + "destination": "/zh/api-reference/on-call/changes/change-read-list" + }, + { + "source": "/channel/create", + "destination": "/zh/api-reference/on-call/channels/channel-create" + }, + { + "source": "/channel/delete", + "destination": "/zh/api-reference/on-call/channels/channel-delete" + }, + { + "source": "/channel/disable", + "destination": "/zh/api-reference/on-call/channels/channel-disable" + }, + { + "source": "/channel/enable", + "destination": "/zh/api-reference/on-call/channels/channel-enable" + }, + { + "source": "/channel/escalate/rule/create", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-create" + }, + { + "source": "/channel/escalate/rule/delete", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-delete" + }, + { + "source": "/channel/escalate/rule/disable", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-disable" + }, + { + "source": "/channel/escalate/rule/enable", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-enable" + }, + { + "source": "/channel/escalate/rule/info", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-info" + }, + { + "source": "/channel/escalate/rule/list", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-list" + }, + { + "source": "/channel/escalate/rule/update", + "destination": "/zh/api-reference/on-call/channels/channel-escalate-rule-update" + }, + { + "source": "/channel/info", + "destination": "/zh/api-reference/on-call/channels/channel-info" + }, + { + "source": "/channel/infos", + "destination": "/zh/api-reference/on-call/channels/channel-infos" + }, + { + "source": "/channel/inhibit/rule/create", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-create" + }, + { + "source": "/channel/inhibit/rule/delete", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-delete" + }, + { + "source": "/channel/inhibit/rule/disable", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-disable" + }, + { + "source": "/channel/inhibit/rule/enable", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-enable" + }, + { + "source": "/channel/inhibit/rule/list", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-list" + }, + { + "source": "/channel/inhibit/rule/update", + "destination": "/zh/api-reference/on-call/channels/channel-inhibit-rule-update" + }, + { + "source": "/channel/list", + "destination": "/zh/api-reference/on-call/channels/channel-list" + }, + { + "source": "/channel/silence/rule/create", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-create" + }, + { + "source": "/channel/silence/rule/delete", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-delete" + }, + { + "source": "/channel/silence/rule/disable", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-disable" + }, + { + "source": "/channel/silence/rule/enable", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-enable" + }, + { + "source": "/channel/silence/rule/list", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-list" + }, + { + "source": "/channel/silence/rule/update", + "destination": "/zh/api-reference/on-call/channels/channel-silence-rule-update" + }, + { + "source": "/channel/unsubscribe/rule/create", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-create" + }, + { + "source": "/channel/unsubscribe/rule/delete", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-delete" + }, + { + "source": "/channel/unsubscribe/rule/disable", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-disable" + }, + { + "source": "/channel/unsubscribe/rule/enable", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-enable" + }, + { + "source": "/channel/unsubscribe/rule/list", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-list" + }, + { + "source": "/channel/unsubscribe/rule/update", + "destination": "/zh/api-reference/on-call/channels/channel-unsubscribe-rule-update" + }, + { + "source": "/channel/update", + "destination": "/zh/api-reference/on-call/channels/channel-update" + }, + { + "source": "/datasource/im/person/try-link", + "destination": "/zh/api-reference/on-call/integrations/datasource-im-person-try-link" + }, + { + "source": "/datasource/im/war-room-enabled/list", + "destination": "/zh/api-reference/on-call/integrations/im-war-room-enabled-list" + }, + { + "source": "/enrichment/info", + "destination": "/zh/api-reference/on-call/alert-enrichment/enrichment-read-info" + }, + { + "source": "/enrichment/list", + "destination": "/zh/api-reference/on-call/alert-enrichment/enrichment-read-list" + }, + { + "source": "/enrichment/mapping/api/create", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-api-write-create" + }, + { + "source": "/enrichment/mapping/api/delete", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-api-write-delete" + }, + { + "source": "/enrichment/mapping/api/info", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-api-read-info" + }, + { + "source": "/enrichment/mapping/api/list", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-api-read-list" + }, + { + "source": "/enrichment/mapping/api/update", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-api-write-update" + }, + { + "source": "/enrichment/mapping/data/delete", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-write-delete" + }, + { + "source": "/enrichment/mapping/data/download", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-read-download" + }, + { + "source": "/enrichment/mapping/data/list", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-read-list" + }, + { + "source": "/enrichment/mapping/data/truncate", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-write-truncate" + }, + { + "source": "/enrichment/mapping/data/upload", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-write-upload" + }, + { + "source": "/enrichment/mapping/data/upsert", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-data-write-upsert" + }, + { + "source": "/enrichment/mapping/schema/create", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-schema-write-create" + }, + { + "source": "/enrichment/mapping/schema/delete", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-schema-write-delete" + }, + { + "source": "/enrichment/mapping/schema/info", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-schema-read-info" + }, + { + "source": "/enrichment/mapping/schema/list", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-schema-read-list" + }, + { + "source": "/enrichment/mapping/schema/update", + "destination": "/zh/api-reference/on-call/alert-enrichment/mapping-schema-write-update" + }, + { + "source": "/enrichment/upsert", + "destination": "/zh/api-reference/on-call/alert-enrichment/enrichment-write-upsert" + }, + { + "source": "/field/create", + "destination": "/zh/api-reference/on-call/alert-enrichment/field-write-create" + }, + { + "source": "/field/delete", + "destination": "/zh/api-reference/on-call/alert-enrichment/field-write-delete" + }, + { + "source": "/field/info", + "destination": "/zh/api-reference/on-call/alert-enrichment/field-read-info" + }, + { + "source": "/field/list", + "destination": "/zh/api-reference/on-call/alert-enrichment/field-read-list" + }, + { + "source": "/field/update", + "destination": "/zh/api-reference/on-call/alert-enrichment/field-write-update" + }, + { + "source": "/incident/ack", + "destination": "/zh/api-reference/on-call/incidents/incident-ack" + }, + { + "source": "/incident/alert/list", + "destination": "/zh/api-reference/on-call/incidents/incident-alert-list" + }, + { + "source": "/incident/assign", + "destination": "/zh/api-reference/on-call/incidents/incident-assign" + }, + { + "source": "/incident/comment", + "destination": "/zh/api-reference/on-call/incidents/incident-comment" + }, + { + "source": "/incident/comment-type/create", + "destination": "/zh/api-reference/on-call/incidents/incident-comment-type-create" + }, + { + "source": "/incident/comment-type/delete", + "destination": "/zh/api-reference/on-call/incidents/incident-comment-type-delete" + }, + { + "source": "/incident/comment-type/list", + "destination": "/zh/api-reference/on-call/incidents/incident-comment-type-list" + }, + { + "source": "/incident/comment-type/reorder", + "destination": "/zh/api-reference/on-call/incidents/incident-comment-type-reorder" + }, + { + "source": "/incident/comment-type/update", + "destination": "/zh/api-reference/on-call/incidents/incident-comment-type-update" + }, + { + "source": "/incident/create", + "destination": "/zh/api-reference/on-call/incidents/incident-create" + }, + { + "source": "/incident/custom-action/do", + "destination": "/zh/api-reference/on-call/incidents/incident-custom-action-do" + }, + { + "source": "/incident/disable-merge", + "destination": "/zh/api-reference/on-call/incidents/incident-disable-merge" + }, + { + "source": "/incident/feed", + "destination": "/zh/api-reference/on-call/incidents/incident-feed" + }, + { + "source": "/incident/field/reset", + "destination": "/zh/api-reference/on-call/incidents/incident-field-reset" + }, + { + "source": "/incident/info", + "destination": "/zh/api-reference/on-call/incidents/incident-info" + }, + { + "source": "/incident/list", + "destination": "/zh/api-reference/on-call/incidents/incident-list" + }, + { + "source": "/incident/list-by-ids", + "destination": "/zh/api-reference/on-call/incidents/incident-list-by-ids" + }, + { + "source": "/incident/merge", + "destination": "/zh/api-reference/on-call/incidents/incident-merge" + }, + { + "source": "/incident/past/list", + "destination": "/zh/api-reference/on-call/incidents/incident-past-list" + }, + { + "source": "/incident/post-mortem/basics/reset", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-reset-basics" + }, + { + "source": "/incident/post-mortem/content/reset", + "destination": "/zh/api-reference/on-call/incidents/incident-post-mortem-write-reset-content" + }, + { + "source": "/incident/post-mortem/delete", + "destination": "/zh/api-reference/on-call/incidents/incident-post-mortem-delete" + }, + { + "source": "/incident/post-mortem/follow-ups/reset", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-reset-follow-ups" + }, + { + "source": "/incident/post-mortem/info", + "destination": "/zh/api-reference/on-call/incidents/incident-post-mortem-info" + }, + { + "source": "/incident/post-mortem/init", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-init" + }, + { + "source": "/incident/post-mortem/list", + "destination": "/zh/api-reference/on-call/incidents/incident-post-mortem-list" + }, + { + "source": "/incident/post-mortem/status/reset", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-reset-status" + }, + { + "source": "/incident/post-mortem/template/delete", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-delete-template" + }, + { + "source": "/incident/post-mortem/template/info", + "destination": "/zh/api-reference/on-call/incidents/postmortem-read-template-info" + }, + { + "source": "/incident/post-mortem/template/list", + "destination": "/zh/api-reference/on-call/incidents/postmortem-read-list-templates" + }, + { + "source": "/incident/post-mortem/template/upsert", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-upsert-template" + }, + { + "source": "/incident/post-mortem/title/reset", + "destination": "/zh/api-reference/on-call/incidents/postmortem-write-reset-title" + }, + { + "source": "/incident/remove", + "destination": "/zh/api-reference/on-call/incidents/incident-remove" + }, + { + "source": "/incident/reopen", + "destination": "/zh/api-reference/on-call/incidents/incident-reopen" + }, + { + "source": "/incident/reset", + "destination": "/zh/api-reference/on-call/incidents/incident-reset" + }, + { + "source": "/incident/resolve", + "destination": "/zh/api-reference/on-call/incidents/incident-resolve" + }, + { + "source": "/incident/responder/add", + "destination": "/zh/api-reference/on-call/incidents/incident-responder-add" + }, + { + "source": "/incident/sdp/request/list", + "destination": "/zh/api-reference/on-call/incidents/incident-service-desk-plus-request-read-list" + }, + { + "source": "/incident/snooze", + "destination": "/zh/api-reference/on-call/incidents/incident-snooze" + }, + { + "source": "/incident/unack", + "destination": "/zh/api-reference/on-call/incidents/incident-unack" + }, + { + "source": "/incident/wake", + "destination": "/zh/api-reference/on-call/incidents/incident-wake" + }, + { + "source": "/incident/war-room/add-member", + "destination": "/zh/api-reference/on-call/incidents/incident-write-add-war-room-member" + }, + { + "source": "/incident/war-room/create", + "destination": "/zh/api-reference/on-call/incidents/incident-war-room-create" + }, + { + "source": "/incident/war-room/default-observers", + "destination": "/zh/api-reference/on-call/incidents/incident-read-get-war-room-default-observers" + }, + { + "source": "/incident/war-room/delete", + "destination": "/zh/api-reference/on-call/incidents/incident-war-room-delete" + }, + { + "source": "/incident/war-room/detail", + "destination": "/zh/api-reference/on-call/incidents/incident-war-room-detail" + }, + { + "source": "/incident/war-room/list", + "destination": "/zh/api-reference/on-call/incidents/incident-war-room-list" + }, + { + "source": "/incident/work-item/assignees/reset", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-reset-assignees" + }, + { + "source": "/incident/work-item/complete", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-complete" + }, + { + "source": "/incident/work-item/convert", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-convert" + }, + { + "source": "/incident/work-item/create", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-create" + }, + { + "source": "/incident/work-item/delete", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-delete" + }, + { + "source": "/incident/work-item/list", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-list" + }, + { + "source": "/incident/work-item/post-mortem/bind", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-bind-post-mortem" + }, + { + "source": "/incident/work-item/update", + "destination": "/zh/api-reference/on-call/incidents/incident-work-item-update" + }, + { + "source": "/insight/account", + "destination": "/zh/api-reference/on-call/analytics/insight-by-account" + }, + { + "source": "/insight/alert/topk-by-label", + "destination": "/zh/api-reference/on-call/analytics/insight-topk-alerts-by-label" + }, + { + "source": "/insight/channel", + "destination": "/zh/api-reference/on-call/analytics/insight-by-channel" + }, + { + "source": "/insight/channel/export", + "destination": "/zh/api-reference/on-call/analytics/insight-channel-export" + }, + { + "source": "/insight/incident/export", + "destination": "/zh/api-reference/on-call/analytics/insight-incident-export" + }, + { + "source": "/insight/incident/list", + "destination": "/zh/api-reference/on-call/analytics/insight-incident-list" + }, + { + "source": "/insight/responder", + "destination": "/zh/api-reference/on-call/analytics/insight-by-responder" + }, + { + "source": "/insight/responder/export", + "destination": "/zh/api-reference/on-call/analytics/insight-responder-export" + }, + { + "source": "/insight/team", + "destination": "/zh/api-reference/on-call/analytics/insight-by-team" + }, + { + "source": "/insight/team/export", + "destination": "/zh/api-reference/on-call/analytics/insight-team-export" + }, + { + "source": "/member/delete", + "destination": "/zh/api-reference/platform/members/member-delete" + }, + { + "source": "/member/info", + "destination": "/zh/api-reference/platform/members/member-info" + }, + { + "source": "/member/info/reset", + "destination": "/zh/api-reference/platform/members/member-reset-info" + }, + { + "source": "/member/invite", + "destination": "/zh/api-reference/platform/members/member-invite" + }, + { + "source": "/member/list", + "destination": "/zh/api-reference/platform/members/member-list" + }, + { + "source": "/member/notify", + "destination": "/zh/api-reference/platform/members/member-notify" + }, + { + "source": "/member/role/grant", + "destination": "/zh/api-reference/platform/members/member-grant-role" + }, + { + "source": "/member/role/revoke", + "destination": "/zh/api-reference/platform/members/member-revoke-role" + }, + { + "source": "/member/role/update", + "destination": "/zh/api-reference/platform/members/member-update-role" + }, + { + "source": "/monit/datasource/create", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-write-create" + }, + { + "source": "/monit/datasource/delete", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-write-delete" + }, + { + "source": "/monit/datasource/info", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-read-info" + }, + { + "source": "/monit/datasource/list", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-read-list" + }, + { + "source": "/monit/datasource/sls/logstores", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-read-sls-logstores" + }, + { + "source": "/monit/datasource/sls/projects", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-read-sls-projects" + }, + { + "source": "/monit/datasource/tools/invoke", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-tools-invoke" + }, + { + "source": "/monit/datasource/update", + "destination": "/zh/api-reference/monitors/data-sources/monit-datasource-write-update" + }, + { + "source": "/monit/prometheus/api/v1/label/{label_name}/values", + "destination": "/zh/api-reference/monitors/data-sources/monit-prometheus-read-label-values" + }, + { + "source": "/monit/query/data", + "destination": "/zh/api-reference/monitors/diagnostics/monit-read-query-data" + }, + { + "source": "/monit/query/explore", + "destination": "/zh/api-reference/monitors/diagnostics/monit-read-query-explore" + }, + { + "source": "/monit/rule/audit/detail", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-audit-detail" + }, + { + "source": "/monit/rule/audits", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-audits" + }, + { + "source": "/monit/rule/counter/channel", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-counter-channel" + }, + { + "source": "/monit/rule/counter/total", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-counter-total" + }, + { + "source": "/monit/rule/delete", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-delete" + }, + { + "source": "/monit/rule/delete/batch", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-delete-batch" + }, + { + "source": "/monit/rule/list/basic", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-list" + }, + { + "source": "/monit/rule/move", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-move" + }, + { + "source": "/monit/rule/update/fields", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-fields-update" + }, + { + "source": "/monit/rule/v2/create", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-create-v2" + }, + { + "source": "/monit/rule/v2/info", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-read-info-v2" + }, + { + "source": "/monit/rule/v2/update", + "destination": "/zh/api-reference/monitors/alert-rules/monit-rule-write-update-v2" + }, + { + "source": "/oncall/license/list", + "destination": "/zh/api-reference/on-call/licenses/oncall-license-read-license-list" + }, + { + "source": "/person/infos", + "destination": "/zh/api-reference/platform/members/person-infos" + }, + { + "source": "/role/delete", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-delete" + }, + { + "source": "/role/disable", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-disable" + }, + { + "source": "/role/enable", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-enable" + }, + { + "source": "/role/info", + "destination": "/zh/api-reference/platform/roles-permissions/role-read-info" + }, + { + "source": "/role/list", + "destination": "/zh/api-reference/platform/roles-permissions/role-read-list" + }, + { + "source": "/role/member/grant", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-grant-role" + }, + { + "source": "/role/member/revoke", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-revoke-role" + }, + { + "source": "/role/permission/factor/list", + "destination": "/zh/api-reference/platform/roles-permissions/role-read-list-permission-factor" + }, + { + "source": "/role/permission/list", + "destination": "/zh/api-reference/platform/roles-permissions/role-read-list-permission" + }, + { + "source": "/role/upsert", + "destination": "/zh/api-reference/platform/roles-permissions/role-write-upsert" + }, + { + "source": "/route/info", + "destination": "/zh/api-reference/on-call/channels/route-info" + }, + { + "source": "/route/list", + "destination": "/zh/api-reference/on-call/channels/route-list" + }, + { + "source": "/route/upsert", + "destination": "/zh/api-reference/on-call/channels/route-upsert" + }, + { + "source": "/rum/application/create", + "destination": "/zh/api-reference/rum/applications/rum-application-write-create" + }, + { + "source": "/rum/application/delete", + "destination": "/zh/api-reference/rum/applications/rum-application-write-delete" + }, + { + "source": "/rum/application/info", + "destination": "/zh/api-reference/rum/applications/rum-application-read-info" + }, + { + "source": "/rum/application/infos", + "destination": "/zh/api-reference/rum/applications/rum-application-read-infos" + }, + { + "source": "/rum/application/list", + "destination": "/zh/api-reference/rum/applications/rum-application-read-list" + }, + { + "source": "/rum/application/remote-config/get", + "destination": "/zh/api-reference/rum/applications/rum-application-remote-config-read-get" + }, + { + "source": "/rum/application/remote-config/history/list", + "destination": "/zh/api-reference/rum/applications/rum-application-remote-config-read-history-list" + }, + { + "source": "/rum/application/remote-config/history/revert", + "destination": "/zh/api-reference/rum/applications/rum-application-remote-config-write-history-revert" + }, + { + "source": "/rum/application/remote-config/preview", + "destination": "/zh/api-reference/rum/applications/rum-application-remote-config-read-preview" + }, + { + "source": "/rum/application/remote-config/update", + "destination": "/zh/api-reference/rum/applications/rum-application-remote-config-write-update" + }, + { + "source": "/rum/application/update", + "destination": "/zh/api-reference/rum/applications/rum-application-write-update" + }, + { + "source": "/rum/application/webhook/test", + "destination": "/zh/api-reference/rum/applications/rum-application-webhook-test" + }, + { + "source": "/rum/data/query", + "destination": "/zh/api-reference/rum/data-query/rum-read-data-query" + }, + { + "source": "/rum/error-ingestion/rules/create", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-create" + }, + { + "source": "/rum/error-ingestion/rules/delete", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-delete" + }, + { + "source": "/rum/error-ingestion/rules/disable", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-disable" + }, + { + "source": "/rum/error-ingestion/rules/enable", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-enable" + }, + { + "source": "/rum/error-ingestion/rules/history/list", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-history-list" + }, + { + "source": "/rum/error-ingestion/rules/history/revert", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-history-revert" + }, + { + "source": "/rum/error-ingestion/rules/list", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-list" + }, + { + "source": "/rum/error-ingestion/rules/update", + "destination": "/zh/api-reference/rum/error-ingestion-rules/rum-error-ingestion-rules-update" + }, + { + "source": "/rum/facet/count", + "destination": "/zh/api-reference/rum/facets/rum-read-facet-count" + }, + { + "source": "/rum/field/list", + "destination": "/zh/api-reference/rum/facets/rum-read-field-list" + }, + { + "source": "/rum/issue/export", + "destination": "/zh/api-reference/rum/issues/rum-issue-read-export" + }, + { + "source": "/rum/issue/info", + "destination": "/zh/api-reference/rum/issues/rum-issue-read-info" + }, + { + "source": "/rum/issue/list", + "destination": "/zh/api-reference/rum/issues/rum-issue-read-list" + }, + { + "source": "/rum/issue/preset-severity/rules/create", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-create" + }, + { + "source": "/rum/issue/preset-severity/rules/delete", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-delete" + }, + { + "source": "/rum/issue/preset-severity/rules/disable", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-disable" + }, + { + "source": "/rum/issue/preset-severity/rules/enable", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-enable" + }, + { + "source": "/rum/issue/preset-severity/rules/history/list", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-history-list" + }, + { + "source": "/rum/issue/preset-severity/rules/history/revert", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-history-revert" + }, + { + "source": "/rum/issue/preset-severity/rules/list", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-list" + }, + { + "source": "/rum/issue/preset-severity/rules/reorder", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-reorder" + }, + { + "source": "/rum/issue/preset-severity/rules/update", + "destination": "/zh/api-reference/rum/issue-preset-severity-rules/rum-issue-preset-severity-rules-update" + }, + { + "source": "/rum/issue/update", + "destination": "/zh/api-reference/rum/issues/rum-issue-write-update" + }, + { + "source": "/rum/resource/info", + "destination": "/zh/api-reference/rum/resources/rum-resource-read-info" + }, + { + "source": "/rum/session-replay/metadata", + "destination": "/zh/api-reference/rum/session-replay/rum-session-replay-read-metadata" + }, + { + "source": "/rum/session-replay/segments", + "destination": "/zh/api-reference/rum/session-replay/rum-session-replay-read-segments" + }, + { + "source": "/safari/a2a-agent/create", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-write-create" + }, + { + "source": "/safari/a2a-agent/delete", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-write-delete" + }, + { + "source": "/safari/a2a-agent/disable", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-write-disable" + }, + { + "source": "/safari/a2a-agent/enable", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-write-enable" + }, + { + "source": "/safari/a2a-agent/get", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-read-get" + }, + { + "source": "/safari/a2a-agent/list", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-read-list" + }, + { + "source": "/safari/a2a-agent/update", + "destination": "/zh/api-reference/ai-sre/a2a-agents/remote-agent-write-update" + }, + { + "source": "/safari/artifact/gallery/delete", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-delete" + }, + { + "source": "/safari/artifact/gallery/file-state", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-get-file-state" + }, + { + "source": "/safari/artifact/gallery/get", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-get" + }, + { + "source": "/safari/artifact/gallery/list", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-list" + }, + { + "source": "/safari/artifact/gallery/publish-from-file", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-publish" + }, + { + "source": "/safari/artifact/gallery/share/enable", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-share-enable" + }, + { + "source": "/safari/artifact/gallery/share/revoke", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-share-revoke" + }, + { + "source": "/safari/artifact/gallery/share/sync", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-share-sync" + }, + { + "source": "/safari/artifact/gallery/update", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-write-update" + }, + { + "source": "/safari/artifact/sign", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-sign" + }, + { + "source": "/safari/artifact/stream", + "destination": "/zh/api-reference/ai-sre/artifacts/artifact-read-stream" + }, + { + "source": "/safari/automation/rule/create", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-write-create" + }, + { + "source": "/safari/automation/rule/delete", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-write-delete" + }, + { + "source": "/safari/automation/rule/get", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-read-get" + }, + { + "source": "/safari/automation/rule/list", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-read-list" + }, + { + "source": "/safari/automation/rule/run", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-write-run" + }, + { + "source": "/safari/automation/rule/update", + "destination": "/zh/api-reference/ai-sre/automations/automation-rule-write-update" + }, + { + "source": "/safari/automation/run/list", + "destination": "/zh/api-reference/ai-sre/automations/automation-run-read-list" + }, + { + "source": "/safari/automation/template/list", + "destination": "/zh/api-reference/ai-sre/automations/automation-template-read-list" + }, + { + "source": "/safari/knowledge/file/delete", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-file-write-delete" + }, + { + "source": "/safari/knowledge/file/get", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-file-read-get" + }, + { + "source": "/safari/knowledge/file/list", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-file-read-list" + }, + { + "source": "/safari/knowledge/file/put", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-file-write-put" + }, + { + "source": "/safari/knowledge/get", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-pack-read-get" + }, + { + "source": "/safari/knowledge/pack/delete", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-pack-write-delete" + }, + { + "source": "/safari/knowledge/pack/ensure", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-pack-write-ensure" + }, + { + "source": "/safari/knowledge/pack/list", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-pack-read-list" + }, + { + "source": "/safari/knowledge/pack/update", + "destination": "/zh/api-reference/ai-sre/knowledge/knowledge-pack-write-update" + }, + { + "source": "/safari/mcp/server/create", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-write-server-create" + }, + { + "source": "/safari/mcp/server/delete", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-write-server-delete" + }, + { + "source": "/safari/mcp/server/disable", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-write-server-disable" + }, + { + "source": "/safari/mcp/server/enable", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-write-server-enable" + }, + { + "source": "/safari/mcp/server/get", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-read-server-get" + }, + { + "source": "/safari/mcp/server/list", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-read-server-list" + }, + { + "source": "/safari/mcp/server/update", + "destination": "/zh/api-reference/ai-sre/mcp-servers/mcp-write-server-update" + }, + { + "source": "/safari/session/delete", + "destination": "/zh/api-reference/ai-sre/sessions/session-write-delete" + }, + { + "source": "/safari/session/export", + "destination": "/zh/api-reference/ai-sre/sessions/session-read-export" + }, + { + "source": "/safari/session/get", + "destination": "/zh/api-reference/ai-sre/sessions/session-read-info" + }, + { + "source": "/safari/session/list", + "destination": "/zh/api-reference/ai-sre/sessions/session-read-list" + }, + { + "source": "/safari/skill/delete", + "destination": "/zh/api-reference/ai-sre/skills/skill-write-delete" + }, + { + "source": "/safari/skill/disable", + "destination": "/zh/api-reference/ai-sre/skills/skill-write-disable" + }, + { + "source": "/safari/skill/enable", + "destination": "/zh/api-reference/ai-sre/skills/skill-read-enable" + }, + { + "source": "/safari/skill/get", + "destination": "/zh/api-reference/ai-sre/skills/skill-read-get" + }, + { + "source": "/safari/skill/list", + "destination": "/zh/api-reference/ai-sre/skills/skill-read-list" + }, + { + "source": "/safari/skill/update", + "destination": "/zh/api-reference/ai-sre/skills/skill-write-update" + }, + { + "source": "/safari/skill/upload", + "destination": "/zh/api-reference/ai-sre/skills/skill-write-upload" + }, + { + "source": "/schedule/by-person", + "destination": "/zh/api-reference/on-call/schedules/schedule-by-person" + }, + { + "source": "/schedule/create", + "destination": "/zh/api-reference/on-call/schedules/schedule-create" + }, + { + "source": "/schedule/delete", + "destination": "/zh/api-reference/on-call/schedules/schedule-delete" + }, + { + "source": "/schedule/info", + "destination": "/zh/api-reference/on-call/schedules/schedule-info" + }, + { + "source": "/schedule/infos", + "destination": "/zh/api-reference/on-call/schedules/schedule-infos" + }, + { + "source": "/schedule/list", + "destination": "/zh/api-reference/on-call/schedules/schedule-list" + }, + { + "source": "/schedule/preview", + "destination": "/zh/api-reference/on-call/schedules/schedule-preview" + }, + { + "source": "/schedule/self", + "destination": "/zh/api-reference/on-call/schedules/schedule-self" + }, + { + "source": "/schedule/update", + "destination": "/zh/api-reference/on-call/schedules/schedule-update" + }, + { + "source": "/sourcemap/list", + "destination": "/zh/api-reference/rum/sourcemaps/sourcemap-read-list" + }, + { + "source": "/sourcemap/stack/enrich", + "destination": "/zh/api-reference/rum/sourcemaps/sourcemap-read-stack-enrich" + }, + { + "source": "/status-page/change/active/list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-active-list" + }, + { + "source": "/status-page/change/create", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-create" + }, + { + "source": "/status-page/change/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-delete" + }, + { + "source": "/status-page/change/info", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-info" + }, + { + "source": "/status-page/change/list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-list" + }, + { + "source": "/status-page/change/timeline/create", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-timeline-create" + }, + { + "source": "/status-page/change/timeline/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-timeline-delete" + }, + { + "source": "/status-page/change/timeline/update", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-timeline-update" + }, + { + "source": "/status-page/change/update", + "destination": "/zh/api-reference/on-call/status-pages/status-page-change-update" + }, + { + "source": "/status-page/component/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-component-delete" + }, + { + "source": "/status-page/component/upsert", + "destination": "/zh/api-reference/on-call/status-pages/status-page-component-upsert" + }, + { + "source": "/status-page/create", + "destination": "/zh/api-reference/on-call/status-pages/status-page-create" + }, + { + "source": "/status-page/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-delete" + }, + { + "source": "/status-page/draft/create", + "destination": "/zh/api-reference/on-call/status-pages/status-page-draft-create" + }, + { + "source": "/status-page/info", + "destination": "/zh/api-reference/on-call/status-pages/status-page-info" + }, + { + "source": "/status-page/list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-read-page-list" + }, + { + "source": "/status-page/migrate-email-subscribers", + "destination": "/zh/api-reference/on-call/status-pages/status-page-migrate-email-subscribers" + }, + { + "source": "/status-page/migrate-structure", + "destination": "/zh/api-reference/on-call/status-pages/status-page-migrate-structure" + }, + { + "source": "/status-page/migration/cancel", + "destination": "/zh/api-reference/on-call/status-pages/status-page-migration-cancel" + }, + { + "source": "/status-page/migration/status", + "destination": "/zh/api-reference/on-call/status-pages/status-page-migration-status" + }, + { + "source": "/status-page/section/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-section-delete" + }, + { + "source": "/status-page/section/upsert", + "destination": "/zh/api-reference/on-call/status-pages/status-page-section-upsert" + }, + { + "source": "/status-page/subscriber/export", + "destination": "/zh/api-reference/on-call/status-pages/status-page-subscriber-export" + }, + { + "source": "/status-page/subscriber/import", + "destination": "/zh/api-reference/on-call/status-pages/status-page-subscriber-import" + }, + { + "source": "/status-page/subscriber/list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-subscriber-list" + }, + { + "source": "/status-page/template/delete", + "destination": "/zh/api-reference/on-call/status-pages/status-page-template-delete" + }, + { + "source": "/status-page/template/list", + "destination": "/zh/api-reference/on-call/status-pages/status-page-template-list" + }, + { + "source": "/status-page/template/upsert", + "destination": "/zh/api-reference/on-call/status-pages/status-page-template-upsert" + }, + { + "source": "/status-page/update", + "destination": "/zh/api-reference/on-call/status-pages/status-page-update" + }, + { + "source": "/team/delete", + "destination": "/zh/api-reference/platform/teams/team-write-delete" + }, + { + "source": "/team/info", + "destination": "/zh/api-reference/platform/teams/team-read-info" + }, + { + "source": "/team/infos", + "destination": "/zh/api-reference/platform/teams/team-read-infos" + }, + { + "source": "/team/list", + "destination": "/zh/api-reference/platform/teams/team-read-list" + }, + { + "source": "/team/upsert", + "destination": "/zh/api-reference/platform/teams/team-write-upsert" + }, + { + "source": "/template/create", + "destination": "/zh/api-reference/on-call/notification-templates/template-write-create" + }, + { + "source": "/template/delete", + "destination": "/zh/api-reference/on-call/notification-templates/template-write-delete" + }, + { + "source": "/template/info", + "destination": "/zh/api-reference/on-call/notification-templates/template-read-info" + }, + { + "source": "/template/list", + "destination": "/zh/api-reference/on-call/notification-templates/template-read-list" + }, + { + "source": "/template/preview", + "destination": "/zh/api-reference/on-call/notification-templates/template-read-preview" + }, + { + "source": "/template/update", + "destination": "/zh/api-reference/on-call/notification-templates/template-write-update" + }, + { + "source": "/webhook/history/detail", + "destination": "/zh/api-reference/on-call/integrations/webhook-history-detail" + }, + { + "source": "/webhook/history/list", + "destination": "/zh/api-reference/on-call/integrations/webhook-history-list" } ], "navigation": { diff --git a/scripts/api_path_redirects.py b/scripts/api_path_redirects.py new file mode 100644 index 000000000..0311678ab --- /dev/null +++ b/scripts/api_path_redirects.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +"""Keep docs.json redirects from bare API paths to their reference pages. + +Every API reference page embeds its operation path (for example +`/safari/mcp/server/update`) as a root-relative string in the rendered page +data. Crawlers resolve that string against docs.flashduty.com and request it, +which 404s because every page lives under `/zh/` or `/en/`. This script +redirects each such bare path to the Chinese (default locale) reference page +of that operation, as listed in the docs.json `zh` navigation. + +Managed entries are the redirects whose source has no locale prefix and whose +destination is a `/zh/api-reference/` page; all other redirects are left as is. + +Usage: + python3 scripts/api_path_redirects.py # rewrite docs.json + python3 scripts/api_path_redirects.py --check # exit 1 if docs.json is stale +""" +import json +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +DOCS_JSON = ROOT / "docs.json" +LOCALE = "zh" +DEST_PREFIX = f"/{LOCALE}/api-reference/" +PAGE_RE = re.compile(r"^(GET|POST|PUT|PATCH|DELETE) (/\S*)$") + + +def nav_operations(node, spec=None): + """Yield (spec_file, method, path) for every OpenAPI page in a nav subtree.""" + if isinstance(node, dict): + spec = node.get("openapi", spec) + for key in ("tabs", "groups", "pages"): + for child in node.get(key, []): + yield from nav_operations(child, spec) + elif isinstance(node, str): + m = PAGE_RE.match(node) + if m: + yield spec, m.group(1).lower(), m.group(2) + + +def is_managed(redirect) -> bool: + return not redirect["source"].startswith(("/zh/", "/en/")) and redirect[ + "destination" + ].startswith(DEST_PREFIX) + + +def build_redirects(docs) -> list: + lang = next(l for l in docs["navigation"]["languages"] if l["language"] == LOCALE) + specs = {} + by_source = {} + for spec, method, path in nav_operations(lang): + if spec not in specs: + specs[spec] = json.loads((ROOT / spec).read_text(encoding="utf-8")) + href = specs[spec]["paths"][path][method]["x-mint"]["href"] + # a path served by several methods redirects to its first listed page + by_source.setdefault(path, href) + return [{"source": s, "destination": d} for s, d in sorted(by_source.items())] + + +def main() -> int: + text = DOCS_JSON.read_text(encoding="utf-8") + docs = json.loads(text) + kept = [r for r in docs["redirects"] if not is_managed(r)] + docs["redirects"] = kept + build_redirects(docs) + out = json.dumps(docs, ensure_ascii=False, indent=2) + "\n" + if "--check" in sys.argv[1:]: + if out != text: + print("docs.json API path redirects are stale; run: python3 scripts/api_path_redirects.py") + return 1 + return 0 + DOCS_JSON.write_text(out, encoding="utf-8") + return 0 + + +if __name__ == "__main__": + sys.exit(main())