[8.16] [OAS] Beautify generated operation ids (#198132) (#198556)

# Backport

This will backport the following commits from `main` to `8.16`:
 - [OAS] Beautify generated operation ids (#198132) (e53d68c2)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Jean-Louis
Leysens","email":"jeanlouis.leysens@elastic.co"},"sourceCommit":{"committedDate":"2024-10-30T19:11:24Z","message":"[OAS]
Beautify generated operation ids
(#198132)","sha":"e53d68c26d6c1f5330ee196938c650a786919a70"},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: lcawl <lcawley@elastic.co>
This commit is contained in:
Jean-Louis Leysens 2024-11-01 00:59:41 +01:00 committed by GitHub
parent 16eedd240b
commit 556baac78d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 286 additions and 223 deletions

View file

@ -347,7 +347,7 @@
"/api/actions": {
"get": {
"deprecated": true,
"operationId": "%2Fapi%2Factions#0",
"operationId": "get-actions",
"parameters": [
{
"description": "The version of the API to use",
@ -372,7 +372,7 @@
"/api/actions/action": {
"post": {
"deprecated": true,
"operationId": "%2Fapi%2Factions%2Faction#0",
"operationId": "post-actions-action",
"parameters": [
{
"description": "The version of the API to use",
@ -496,7 +496,7 @@
"delete": {
"deprecated": true,
"description": "WARNING: When you delete a connector, it cannot be recovered.",
"operationId": "%2Fapi%2Factions%2Faction%2F%7Bid%7D#0",
"operationId": "delete-actions-action-id",
"parameters": [
{
"description": "The version of the API to use",
@ -542,7 +542,7 @@
},
"get": {
"deprecated": true,
"operationId": "%2Fapi%2Factions%2Faction%2F%7Bid%7D#1",
"operationId": "get-actions-action-id",
"parameters": [
{
"description": "The version of the API to use",
@ -628,7 +628,7 @@
},
"put": {
"deprecated": true,
"operationId": "%2Fapi%2Factions%2Faction%2F%7Bid%7D#2",
"operationId": "put-actions-action-id",
"parameters": [
{
"description": "The version of the API to use",
@ -754,7 +754,7 @@
"/api/actions/action/{id}/_execute": {
"post": {
"deprecated": true,
"operationId": "%2Fapi%2Factions%2Faction%2F%7Bid%7D%2F_execute#0",
"operationId": "post-actions-action-id-execute",
"parameters": [
{
"description": "The version of the API to use",
@ -871,7 +871,7 @@
"/api/actions/connector/{id}": {
"delete": {
"description": "WARNING: When you delete a connector, it cannot be recovered.",
"operationId": "%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#0",
"operationId": "delete-actions-connector-id",
"parameters": [
{
"description": "The version of the API to use",
@ -916,7 +916,7 @@
]
},
"get": {
"operationId": "%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#1",
"operationId": "get-actions-connector-id",
"parameters": [
{
"description": "The version of the API to use",
@ -1001,7 +1001,7 @@
]
},
"post": {
"operationId": "%2Fapi%2Factions%2Fconnector%2F%7Bid%3F%7D#0",
"operationId": "post-actions-connector-id",
"parameters": [
{
"description": "The version of the API to use",
@ -1130,7 +1130,7 @@
]
},
"put": {
"operationId": "%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#2",
"operationId": "put-actions-connector-id",
"parameters": [
{
"description": "The version of the API to use",
@ -1257,7 +1257,7 @@
"/api/actions/connector/{id}/_execute": {
"post": {
"description": "You can use this API to test an action that involves interaction with Kibana services or integrations with third-party systems.",
"operationId": "%2Fapi%2Factions%2Fconnector%2F%7Bid%7D%2F_execute#0",
"operationId": "post-actions-connector-id-execute",
"parameters": [
{
"description": "The version of the API to use",
@ -1374,7 +1374,7 @@
"/api/actions/connector_types": {
"get": {
"description": "You do not need any Kibana feature privileges to run this API.",
"operationId": "%2Fapi%2Factions%2Fconnector_types#0",
"operationId": "get-actions-connector-types",
"parameters": [
{
"description": "The version of the API to use",
@ -1407,7 +1407,7 @@
},
"/api/actions/connectors": {
"get": {
"operationId": "%2Fapi%2Factions%2Fconnectors#0",
"operationId": "get-actions-connectors",
"parameters": [
{
"description": "The version of the API to use",
@ -1432,7 +1432,7 @@
"/api/actions/list_action_types": {
"get": {
"deprecated": true,
"operationId": "%2Fapi%2Factions%2Flist_action_types#0",
"operationId": "get-actions-list-action-types",
"parameters": [
{
"description": "The version of the API to use",
@ -1456,7 +1456,7 @@
},
"/api/alerting/rule/{id}": {
"delete": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D#2",
"operationId": "delete-alerting-rule-id",
"parameters": [
{
"description": "The version of the API to use",
@ -1510,7 +1510,7 @@
]
},
"get": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D#0",
"operationId": "get-alerting-rule-id",
"parameters": [
{
"description": "The version of the API to use",
@ -2446,7 +2446,7 @@
]
},
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%3F%7D#0",
"operationId": "post-alerting-rule-id",
"parameters": [
{
"description": "The version of the API to use",
@ -3684,7 +3684,7 @@
]
},
"put": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D#1",
"operationId": "put-alerting-rule-id",
"parameters": [
{
"description": "The version of the API to use",
@ -4910,7 +4910,7 @@
},
"/api/alerting/rule/{id}/_disable": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_disable#0",
"operationId": "post-alerting-rule-id-disable",
"parameters": [
{
"description": "The version of the API to use",
@ -4984,7 +4984,7 @@
},
"/api/alerting/rule/{id}/_enable": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_enable#0",
"operationId": "post-alerting-rule-id-enable",
"parameters": [
{
"description": "The version of the API to use",
@ -5040,7 +5040,7 @@
},
"/api/alerting/rule/{id}/_mute_all": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_mute_all#0",
"operationId": "post-alerting-rule-id-mute-all",
"parameters": [
{
"description": "The version of the API to use",
@ -5096,7 +5096,7 @@
},
"/api/alerting/rule/{id}/_unmute_all": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_unmute_all#0",
"operationId": "post-alerting-rule-id-unmute-all",
"parameters": [
{
"description": "The version of the API to use",
@ -5152,7 +5152,7 @@
},
"/api/alerting/rule/{id}/_update_api_key": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_update_api_key#0",
"operationId": "post-alerting-rule-id-update-api-key",
"parameters": [
{
"description": "The version of the API to use",
@ -5211,7 +5211,7 @@
},
"/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_mute#0",
"operationId": "post-alerting-rule-rule-id-alert-alert-id-mute",
"parameters": [
{
"description": "The version of the API to use",
@ -5276,7 +5276,7 @@
},
"/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute": {
"post": {
"operationId": "%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_unmute#0",
"operationId": "post-alerting-rule-rule-id-alert-alert-id-unmute",
"parameters": [
{
"description": "The version of the API to use",
@ -5341,7 +5341,7 @@
},
"/api/alerting/rules/_find": {
"get": {
"operationId": "%2Fapi%2Falerting%2Frules%2F_find#0",
"operationId": "get-alerting-rules-find",
"parameters": [
{
"description": "The version of the API to use",
@ -6409,7 +6409,7 @@
},
"/api/security/role": {
"get": {
"operationId": "%2Fapi%2Fsecurity%2Frole#0",
"operationId": "get-security-role",
"parameters": [
{
"description": "The version of the API to use",
@ -6446,7 +6446,7 @@
},
"/api/security/role/{name}": {
"delete": {
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1",
"operationId": "delete-security-role-name",
"parameters": [
{
"description": "The version of the API to use",
@ -6491,7 +6491,7 @@
]
},
"get": {
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0",
"operationId": "get-security-role-name",
"parameters": [
{
"description": "The version of the API to use",
@ -6537,7 +6537,7 @@
},
"put": {
"description": "Create a new Kibana role or update the attributes of an existing role. Kibana roles are stored in the Elasticsearch native realm.",
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2",
"operationId": "put-security-role-name",
"parameters": [
{
"description": "The version of the API to use",
@ -6856,7 +6856,7 @@
},
"/api/security/roles": {
"post": {
"operationId": "%2Fapi%2Fsecurity%2Froles#0",
"operationId": "post-security-roles",
"parameters": [
{
"description": "The version of the API to use",
@ -7167,7 +7167,7 @@
"/api/spaces/_copy_saved_objects": {
"post": {
"description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.",
"operationId": "%2Fapi%2Fspaces%2F_copy_saved_objects#0",
"operationId": "post-spaces-copy-saved-objects",
"parameters": [
{
"description": "The version of the API to use",
@ -7265,7 +7265,7 @@
},
"/api/spaces/_disable_legacy_url_aliases": {
"post": {
"operationId": "%2Fapi%2Fspaces%2F_disable_legacy_url_aliases#0",
"operationId": "post-spaces-disable-legacy-url-aliases",
"parameters": [
{
"description": "The version of the API to use",
@ -7341,7 +7341,7 @@
"/api/spaces/_get_shareable_references": {
"post": {
"description": "Collect references and space contexts for saved objects.",
"operationId": "%2Fapi%2Fspaces%2F_get_shareable_references#0",
"operationId": "post-spaces-get-shareable-references",
"parameters": [
{
"description": "The version of the API to use",
@ -7410,7 +7410,7 @@
"/api/spaces/_resolve_copy_saved_objects_errors": {
"post": {
"description": "Overwrite saved objects that are returned as errors from the copy saved objects to space API.",
"operationId": "%2Fapi%2Fspaces%2F_resolve_copy_saved_objects_errors#0",
"operationId": "post-spaces-resolve-copy-saved-objects-errors",
"parameters": [
{
"description": "The version of the API to use",
@ -7531,7 +7531,7 @@
"/api/spaces/_update_objects_spaces": {
"post": {
"description": "Update one or more saved objects to add or remove them from some spaces.",
"operationId": "%2Fapi%2Fspaces%2F_update_objects_spaces#0",
"operationId": "post-spaces-update-objects-spaces",
"parameters": [
{
"description": "The version of the API to use",
@ -7617,7 +7617,7 @@
},
"/api/spaces/space": {
"get": {
"operationId": "%2Fapi%2Fspaces%2Fspace#0",
"operationId": "get-spaces-space",
"parameters": [
{
"description": "The version of the API to use",
@ -7697,7 +7697,7 @@
]
},
"post": {
"operationId": "%2Fapi%2Fspaces%2Fspace#1",
"operationId": "post-spaces-space",
"parameters": [
{
"description": "The version of the API to use",
@ -7798,7 +7798,7 @@
"/api/spaces/space/{id}": {
"delete": {
"description": "When you delete a space, all saved objects that belong to the space are automatically deleted, which is permanent and cannot be undone.",
"operationId": "%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#2",
"operationId": "delete-spaces-space-id",
"parameters": [
{
"description": "The version of the API to use",
@ -7846,7 +7846,7 @@
]
},
"get": {
"operationId": "%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#0",
"operationId": "get-spaces-space-id",
"parameters": [
{
"description": "The version of the API to use",
@ -7881,7 +7881,7 @@
]
},
"put": {
"operationId": "%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#1",
"operationId": "put-spaces-space-id",
"parameters": [
{
"description": "The version of the API to use",
@ -7990,7 +7990,7 @@
},
"/api/status": {
"get": {
"operationId": "%2Fapi%2Fstatus#0",
"operationId": "get-status",
"parameters": [
{
"description": "The version of the API to use",

View file

@ -78,7 +78,7 @@ paths:
/api/actions:
get:
deprecated: true
operationId: '%2Fapi%2Factions#0'
operationId: get-actions
parameters:
- description: The version of the API to use
in: header
@ -95,7 +95,7 @@ paths:
/api/actions/action:
post:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction#0'
operationId: post-actions-action
parameters:
- description: The version of the API to use
in: header
@ -188,7 +188,7 @@ paths:
delete:
deprecated: true
description: 'WARNING: When you delete a connector, it cannot be recovered.'
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#0'
operationId: delete-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -219,7 +219,7 @@ paths:
- connectors
get:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#1'
operationId: get-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -285,7 +285,7 @@ paths:
- connectors
put:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#2'
operationId: put-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -378,7 +378,7 @@ paths:
'/api/actions/action/{id}/_execute':
post:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D%2F_execute#0'
operationId: post-actions-action-id-execute
parameters:
- description: The version of the API to use
in: header
@ -464,7 +464,7 @@ paths:
/api/actions/connector_types:
get:
description: You do not need any Kibana feature privileges to run this API.
operationId: '%2Fapi%2Factions%2Fconnector_types#0'
operationId: get-actions-connector-types
parameters:
- description: The version of the API to use
in: header
@ -489,7 +489,7 @@ paths:
'/api/actions/connector/{id}':
delete:
description: 'WARNING: When you delete a connector, it cannot be recovered.'
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#0'
operationId: delete-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -519,7 +519,7 @@ paths:
tags:
- connectors
get:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#1'
operationId: get-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -584,7 +584,7 @@ paths:
tags:
- connectors
post:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%3F%7D#0'
operationId: post-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -680,7 +680,7 @@ paths:
tags:
- connectors
put:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#2'
operationId: put-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -776,7 +776,7 @@ paths:
description: >-
You can use this API to test an action that involves interaction with
Kibana services or integrations with third-party systems.
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D%2F_execute#0'
operationId: post-actions-connector-id-execute
parameters:
- description: The version of the API to use
in: header
@ -861,7 +861,7 @@ paths:
- connectors
/api/actions/connectors:
get:
operationId: '%2Fapi%2Factions%2Fconnectors#0'
operationId: get-actions-connectors
parameters:
- description: The version of the API to use
in: header
@ -878,7 +878,7 @@ paths:
/api/actions/list_action_types:
get:
deprecated: true
operationId: '%2Fapi%2Factions%2Flist_action_types#0'
operationId: get-actions-list-action-types
parameters:
- description: The version of the API to use
in: header
@ -1282,7 +1282,7 @@ paths:
- alerting
'/api/alerting/rule/{id}':
delete:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#2'
operationId: delete-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -1318,7 +1318,7 @@ paths:
tags:
- alerting
get:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#0'
operationId: get-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -2166,7 +2166,7 @@ paths:
tags:
- alerting
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%3F%7D#0'
operationId: post-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -3339,7 +3339,7 @@ paths:
tags:
- alerting
put:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#1'
operationId: put-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -4486,7 +4486,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_disable':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_disable#0'
operationId: post-alerting-rule-id-disable
parameters:
- description: The version of the API to use
in: header
@ -4535,7 +4535,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_enable':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_enable#0'
operationId: post-alerting-rule-id-enable
parameters:
- description: The version of the API to use
in: header
@ -4572,7 +4572,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_mute_all':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_mute_all#0'
operationId: post-alerting-rule-id-mute-all
parameters:
- description: The version of the API to use
in: header
@ -4609,7 +4609,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_unmute_all':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_unmute_all#0'
operationId: post-alerting-rule-id-unmute-all
parameters:
- description: The version of the API to use
in: header
@ -4646,7 +4646,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_update_api_key':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_update_api_key#0'
operationId: post-alerting-rule-id-update-api-key
parameters:
- description: The version of the API to use
in: header
@ -4685,8 +4685,7 @@ paths:
- alerting
'/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute':
post:
operationId: >-
%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_mute#0
operationId: post-alerting-rule-rule-id-alert-alert-id-mute
parameters:
- description: The version of the API to use
in: header
@ -4729,8 +4728,7 @@ paths:
- alerting
'/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute':
post:
operationId: >-
%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_unmute#0
operationId: post-alerting-rule-rule-id-alert-alert-id-unmute
parameters:
- description: The version of the API to use
in: header
@ -4773,7 +4771,7 @@ paths:
- alerting
/api/alerting/rules/_find:
get:
operationId: '%2Fapi%2Falerting%2Frules%2F_find#0'
operationId: get-alerting-rules-find
parameters:
- description: The version of the API to use
in: header
@ -20391,7 +20389,7 @@ paths:
- Prompts API
/api/security/role:
get:
operationId: '%2Fapi%2Fsecurity%2Frole#0'
operationId: get-security-role
parameters:
- description: The version of the API to use
in: header
@ -20418,7 +20416,7 @@ paths:
- roles
'/api/security/role/{name}':
delete:
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1'
operationId: delete-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20448,7 +20446,7 @@ paths:
tags:
- roles
get:
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0'
operationId: get-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20484,7 +20482,7 @@ paths:
description: >-
Create a new Kibana role or update the attributes of an existing role.
Kibana roles are stored in the Elasticsearch native realm.
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2'
operationId: put-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20767,7 +20765,7 @@ paths:
- roles
/api/security/roles:
post:
operationId: '%2Fapi%2Fsecurity%2Froles#0'
operationId: post-security-roles
parameters:
- description: The version of the API to use
in: header
@ -21058,7 +21056,7 @@ paths:
request to overwrite any objects that already exist in the target space
if they share an identifier or you can use the resolve copy saved
objects conflicts API to do this on a per-object basis.
operationId: '%2Fapi%2Fspaces%2F_copy_saved_objects#0'
operationId: post-spaces-copy-saved-objects
parameters:
- description: The version of the API to use
in: header
@ -21145,7 +21143,7 @@ paths:
- spaces
/api/spaces/_disable_legacy_url_aliases:
post:
operationId: '%2Fapi%2Fspaces%2F_disable_legacy_url_aliases#0'
operationId: post-spaces-disable-legacy-url-aliases
parameters:
- description: The version of the API to use
in: header
@ -21199,7 +21197,7 @@ paths:
/api/spaces/_get_shareable_references:
post:
description: Collect references and space contexts for saved objects.
operationId: '%2Fapi%2Fspaces%2F_get_shareable_references#0'
operationId: post-spaces-get-shareable-references
parameters:
- description: The version of the API to use
in: header
@ -21247,7 +21245,7 @@ paths:
description: >-
Overwrite saved objects that are returned as errors from the copy saved
objects to space API.
operationId: '%2Fapi%2Fspaces%2F_resolve_copy_saved_objects_errors#0'
operationId: post-spaces-resolve-copy-saved-objects-errors
parameters:
- description: The version of the API to use
in: header
@ -21342,7 +21340,7 @@ paths:
/api/spaces/_update_objects_spaces:
post:
description: Update one or more saved objects to add or remove them from some spaces.
operationId: '%2Fapi%2Fspaces%2F_update_objects_spaces#0'
operationId: post-spaces-update-objects-spaces
parameters:
- description: The version of the API to use
in: header
@ -21405,7 +21403,7 @@ paths:
- spaces
/api/spaces/space:
get:
operationId: '%2Fapi%2Fspaces%2Fspace#0'
operationId: get-spaces-space
parameters:
- description: The version of the API to use
in: header
@ -21461,7 +21459,7 @@ paths:
tags:
- spaces
post:
operationId: '%2Fapi%2Fspaces%2Fspace#1'
operationId: post-spaces-space
parameters:
- description: The version of the API to use
in: header
@ -21550,7 +21548,7 @@ paths:
description: >-
When you delete a space, all saved objects that belong to the space are
automatically deleted, which is permanent and cannot be undone.
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#2'
operationId: delete-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21582,7 +21580,7 @@ paths:
tags:
- spaces
get:
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#0'
operationId: get-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21605,7 +21603,7 @@ paths:
tags:
- spaces
put:
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#1'
operationId: put-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21699,7 +21697,7 @@ paths:
- spaces
/api/status:
get:
operationId: '%2Fapi%2Fstatus#0'
operationId: get-status
parameters:
- description: The version of the API to use
in: header

View file

@ -78,7 +78,7 @@ paths:
/api/actions:
get:
deprecated: true
operationId: '%2Fapi%2Factions#0'
operationId: get-actions
parameters:
- description: The version of the API to use
in: header
@ -95,7 +95,7 @@ paths:
/api/actions/action:
post:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction#0'
operationId: post-actions-action
parameters:
- description: The version of the API to use
in: header
@ -188,7 +188,7 @@ paths:
delete:
deprecated: true
description: 'WARNING: When you delete a connector, it cannot be recovered.'
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#0'
operationId: delete-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -219,7 +219,7 @@ paths:
- connectors
get:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#1'
operationId: get-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -285,7 +285,7 @@ paths:
- connectors
put:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D#2'
operationId: put-actions-action-id
parameters:
- description: The version of the API to use
in: header
@ -378,7 +378,7 @@ paths:
'/api/actions/action/{id}/_execute':
post:
deprecated: true
operationId: '%2Fapi%2Factions%2Faction%2F%7Bid%7D%2F_execute#0'
operationId: post-actions-action-id-execute
parameters:
- description: The version of the API to use
in: header
@ -464,7 +464,7 @@ paths:
/api/actions/connector_types:
get:
description: You do not need any Kibana feature privileges to run this API.
operationId: '%2Fapi%2Factions%2Fconnector_types#0'
operationId: get-actions-connector-types
parameters:
- description: The version of the API to use
in: header
@ -489,7 +489,7 @@ paths:
'/api/actions/connector/{id}':
delete:
description: 'WARNING: When you delete a connector, it cannot be recovered.'
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#0'
operationId: delete-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -519,7 +519,7 @@ paths:
tags:
- connectors
get:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#1'
operationId: get-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -584,7 +584,7 @@ paths:
tags:
- connectors
post:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%3F%7D#0'
operationId: post-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -680,7 +680,7 @@ paths:
tags:
- connectors
put:
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D#2'
operationId: put-actions-connector-id
parameters:
- description: The version of the API to use
in: header
@ -776,7 +776,7 @@ paths:
description: >-
You can use this API to test an action that involves interaction with
Kibana services or integrations with third-party systems.
operationId: '%2Fapi%2Factions%2Fconnector%2F%7Bid%7D%2F_execute#0'
operationId: post-actions-connector-id-execute
parameters:
- description: The version of the API to use
in: header
@ -861,7 +861,7 @@ paths:
- connectors
/api/actions/connectors:
get:
operationId: '%2Fapi%2Factions%2Fconnectors#0'
operationId: get-actions-connectors
parameters:
- description: The version of the API to use
in: header
@ -878,7 +878,7 @@ paths:
/api/actions/list_action_types:
get:
deprecated: true
operationId: '%2Fapi%2Factions%2Flist_action_types#0'
operationId: get-actions-list-action-types
parameters:
- description: The version of the API to use
in: header
@ -1282,7 +1282,7 @@ paths:
- alerting
'/api/alerting/rule/{id}':
delete:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#2'
operationId: delete-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -1318,7 +1318,7 @@ paths:
tags:
- alerting
get:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#0'
operationId: get-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -2166,7 +2166,7 @@ paths:
tags:
- alerting
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%3F%7D#0'
operationId: post-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -3339,7 +3339,7 @@ paths:
tags:
- alerting
put:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D#1'
operationId: put-alerting-rule-id
parameters:
- description: The version of the API to use
in: header
@ -4486,7 +4486,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_disable':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_disable#0'
operationId: post-alerting-rule-id-disable
parameters:
- description: The version of the API to use
in: header
@ -4535,7 +4535,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_enable':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_enable#0'
operationId: post-alerting-rule-id-enable
parameters:
- description: The version of the API to use
in: header
@ -4572,7 +4572,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_mute_all':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_mute_all#0'
operationId: post-alerting-rule-id-mute-all
parameters:
- description: The version of the API to use
in: header
@ -4609,7 +4609,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_unmute_all':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_unmute_all#0'
operationId: post-alerting-rule-id-unmute-all
parameters:
- description: The version of the API to use
in: header
@ -4646,7 +4646,7 @@ paths:
- alerting
'/api/alerting/rule/{id}/_update_api_key':
post:
operationId: '%2Fapi%2Falerting%2Frule%2F%7Bid%7D%2F_update_api_key#0'
operationId: post-alerting-rule-id-update-api-key
parameters:
- description: The version of the API to use
in: header
@ -4685,8 +4685,7 @@ paths:
- alerting
'/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute':
post:
operationId: >-
%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_mute#0
operationId: post-alerting-rule-rule-id-alert-alert-id-mute
parameters:
- description: The version of the API to use
in: header
@ -4729,8 +4728,7 @@ paths:
- alerting
'/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute':
post:
operationId: >-
%2Fapi%2Falerting%2Frule%2F%7Brule_id%7D%2Falert%2F%7Balert_id%7D%2F_unmute#0
operationId: post-alerting-rule-rule-id-alert-alert-id-unmute
parameters:
- description: The version of the API to use
in: header
@ -4773,7 +4771,7 @@ paths:
- alerting
/api/alerting/rules/_find:
get:
operationId: '%2Fapi%2Falerting%2Frules%2F_find#0'
operationId: get-alerting-rules-find
parameters:
- description: The version of the API to use
in: header
@ -20391,7 +20389,7 @@ paths:
- Prompts API
/api/security/role:
get:
operationId: '%2Fapi%2Fsecurity%2Frole#0'
operationId: get-security-role
parameters:
- description: The version of the API to use
in: header
@ -20418,7 +20416,7 @@ paths:
- roles
'/api/security/role/{name}':
delete:
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1'
operationId: delete-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20448,7 +20446,7 @@ paths:
tags:
- roles
get:
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0'
operationId: get-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20484,7 +20482,7 @@ paths:
description: >-
Create a new Kibana role or update the attributes of an existing role.
Kibana roles are stored in the Elasticsearch native realm.
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2'
operationId: put-security-role-name
parameters:
- description: The version of the API to use
in: header
@ -20767,7 +20765,7 @@ paths:
- roles
/api/security/roles:
post:
operationId: '%2Fapi%2Fsecurity%2Froles#0'
operationId: post-security-roles
parameters:
- description: The version of the API to use
in: header
@ -21058,7 +21056,7 @@ paths:
request to overwrite any objects that already exist in the target space
if they share an identifier or you can use the resolve copy saved
objects conflicts API to do this on a per-object basis.
operationId: '%2Fapi%2Fspaces%2F_copy_saved_objects#0'
operationId: post-spaces-copy-saved-objects
parameters:
- description: The version of the API to use
in: header
@ -21145,7 +21143,7 @@ paths:
- spaces
/api/spaces/_disable_legacy_url_aliases:
post:
operationId: '%2Fapi%2Fspaces%2F_disable_legacy_url_aliases#0'
operationId: post-spaces-disable-legacy-url-aliases
parameters:
- description: The version of the API to use
in: header
@ -21199,7 +21197,7 @@ paths:
/api/spaces/_get_shareable_references:
post:
description: Collect references and space contexts for saved objects.
operationId: '%2Fapi%2Fspaces%2F_get_shareable_references#0'
operationId: post-spaces-get-shareable-references
parameters:
- description: The version of the API to use
in: header
@ -21247,7 +21245,7 @@ paths:
description: >-
Overwrite saved objects that are returned as errors from the copy saved
objects to space API.
operationId: '%2Fapi%2Fspaces%2F_resolve_copy_saved_objects_errors#0'
operationId: post-spaces-resolve-copy-saved-objects-errors
parameters:
- description: The version of the API to use
in: header
@ -21342,7 +21340,7 @@ paths:
/api/spaces/_update_objects_spaces:
post:
description: Update one or more saved objects to add or remove them from some spaces.
operationId: '%2Fapi%2Fspaces%2F_update_objects_spaces#0'
operationId: post-spaces-update-objects-spaces
parameters:
- description: The version of the API to use
in: header
@ -21405,7 +21403,7 @@ paths:
- spaces
/api/spaces/space:
get:
operationId: '%2Fapi%2Fspaces%2Fspace#0'
operationId: get-spaces-space
parameters:
- description: The version of the API to use
in: header
@ -21461,7 +21459,7 @@ paths:
tags:
- spaces
post:
operationId: '%2Fapi%2Fspaces%2Fspace#1'
operationId: post-spaces-space
parameters:
- description: The version of the API to use
in: header
@ -21550,7 +21548,7 @@ paths:
description: >-
When you delete a space, all saved objects that belong to the space are
automatically deleted, which is permanent and cannot be undone.
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#2'
operationId: delete-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21582,7 +21580,7 @@ paths:
tags:
- spaces
get:
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#0'
operationId: get-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21605,7 +21603,7 @@ paths:
tags:
- spaces
put:
operationId: '%2Fapi%2Fspaces%2Fspace%2F%7Bid%7D#1'
operationId: put-spaces-space-id
parameters:
- description: The version of the API to use
in: header
@ -21699,7 +21697,7 @@ paths:
- spaces
/api/status:
get:
operationId: '%2Fapi%2Fstatus#0'
operationId: get-status
parameters:
- description: The version of the API to use
in: header

View file

@ -44,7 +44,7 @@ Object {
"paths": Object {
"/foo/{id}": Object {
"get": Object {
"operationId": "%2Ffoo%2F%7Bid%7D#0",
"operationId": "get-foo-id",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -138,7 +138,7 @@ Object {
"/bar": Object {
"get": Object {
"deprecated": true,
"operationId": "%2Fbar#0",
"operationId": "get-bar",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -231,7 +231,7 @@ OK response oas-test-version-2",
"/foo/{id}/{path*}": Object {
"delete": Object {
"description": "route description",
"operationId": "%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#2",
"operationId": "delete-foo-id-path",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -269,7 +269,7 @@ OK response oas-test-version-2",
},
"get": Object {
"description": "route description",
"operationId": "%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#0",
"operationId": "get-foo-id-path",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -415,7 +415,7 @@ OK response oas-test-version-2",
},
"post": Object {
"description": "route description",
"operationId": "%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#1",
"operationId": "post-foo-id-path",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -572,7 +572,7 @@ OK response oas-test-version-2",
},
"/no-xsrf/{id}/{path*}": Object {
"post": Object {
"operationId": "%2Fno-xsrf%2F%7Bid%7D%2F%7Bpath*%7D#1",
"operationId": "post-no-xsrf-id-path-2",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -724,7 +724,7 @@ Object {
"paths": Object {
"/recursive": Object {
"get": Object {
"operationId": "%2Frecursive#0",
"operationId": "get-recursive",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -807,7 +807,7 @@ Object {
"paths": Object {
"/foo/{id}": Object {
"get": Object {
"operationId": "%2Ffoo%2F%7Bid%7D#0",
"operationId": "get-foo-id",
"parameters": Array [
Object {
"description": "The version of the API to use",
@ -845,7 +845,7 @@ Object {
},
"/test": Object {
"get": Object {
"operationId": "%2Ftest#0",
"operationId": "get-test",
"parameters": Array [
Object {
"description": "The version of the API to use",

View file

@ -35,7 +35,7 @@ export const sharedOas = {
get: {
deprecated: true,
'x-discontinued': 'route discontinued version or date',
operationId: '%2Fbar#0',
operationId: 'get-bar',
parameters: [
{
description: 'The version of the API to use',
@ -154,7 +154,7 @@ export const sharedOas = {
'/foo/{id}/{path*}': {
get: {
description: 'route description',
operationId: '%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#0',
operationId: 'get-foo-id-path',
parameters: [
{
description: 'The version of the API to use',
@ -278,7 +278,7 @@ export const sharedOas = {
},
post: {
description: 'route description',
operationId: '%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#1',
operationId: 'post-foo-id-path',
parameters: [
{
description: 'The version of the API to use',

View file

@ -10,10 +10,9 @@
import type { CoreVersionedRouter, Router } from '@kbn/core-http-router-server-internal';
import type { OpenAPIV3 } from 'openapi-types';
import { OasConverter } from './oas_converter';
import { createOperationIdCounter } from './operation_id_counter';
import { processRouter } from './process_router';
import { processVersionedRouter } from './process_versioned_router';
import { buildGlobalTags } from './util';
import { buildGlobalTags, createOpIdGenerator } from './util';
export const openApiVersion = '3.0.0';
@ -40,8 +39,8 @@ export const generateOpenApiDocument = (
): OpenAPIV3.Document => {
const { filters } = opts;
const converter = new OasConverter();
const getOpId = createOperationIdCounter();
const paths: OpenAPIV3.PathsObject = {};
const getOpId = createOpIdGenerator();
for (const router of appRouters.routers) {
const result = processRouter(router, converter, getOpId, filters);
Object.assign(paths, result.paths);

View file

@ -1,32 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { createOperationIdCounter } from './operation_id_counter';
test('empty case', () => {
const opIdCounter = createOperationIdCounter();
expect(opIdCounter('')).toBe('#0');
});
test('other cases', () => {
const opIdCounter = createOperationIdCounter();
const tests = [
['/', '%2F#0'],
['/api/cool', '%2Fapi%2Fcool#0'],
['/api/cool', '%2Fapi%2Fcool#1'],
['/api/cool', '%2Fapi%2Fcool#2'],
['/api/cool/{variable}', '%2Fapi%2Fcool%2F%7Bvariable%7D#0'],
['/api/cool/{optionalVariable?}', '%2Fapi%2Fcool%2F%7BoptionalVariable%3F%7D#0'],
['/api/cool/{optionalVariable?}', '%2Fapi%2Fcool%2F%7BoptionalVariable%3F%7D#1'],
];
tests.forEach(([input, expected]) => {
expect(opIdCounter(input)).toBe(expected);
});
});

View file

@ -1,24 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
export type OperationIdCounter = (name: string) => string;
export const createOperationIdCounter = () => {
const operationIdCounters = new Map<string, number>();
return (name: string): string => {
name = encodeURIComponent(name);
// Aliases an operationId to ensure it is unique across
// multiple method+path combinations sharing a name.
// "search" -> "search#0", "search#1", etc.
const operationIdCount = operationIdCounters.get(name) ?? 0;
const aliasedName = name + '#' + operationIdCount.toString();
operationIdCounters.set(name, operationIdCount + 1);
return aliasedName;
};
};

View file

@ -10,9 +10,9 @@
import { schema } from '@kbn/config-schema';
import { Router } from '@kbn/core-http-router-server-internal';
import { OasConverter } from './oas_converter';
import { createOperationIdCounter } from './operation_id_counter';
import { extractResponses, processRouter } from './process_router';
import { type InternalRouterRoute } from './type';
import { createOpIdGenerator } from './util';
describe('extractResponses', () => {
let oasConverter: OasConverter;
@ -86,18 +86,21 @@ describe('processRouter', () => {
const testRouter = {
getRoutes: () => [
{
method: 'get',
path: '/foo',
options: { access: 'internal', deprecated: true, discontinued: 'discontinued router' },
handler: jest.fn(),
validationSchemas: { request: { body: schema.object({}) } },
},
{
method: 'get',
path: '/bar',
options: {},
handler: jest.fn(),
validationSchemas: { request: { body: schema.object({}) } },
},
{
method: 'get',
path: '/baz',
options: {},
handler: jest.fn(),
@ -125,20 +128,20 @@ describe('processRouter', () => {
} as unknown as Router;
it('only provides routes for version 2023-10-31', () => {
const result1 = processRouter(testRouter, new OasConverter(), createOperationIdCounter(), {
const result1 = processRouter(testRouter, new OasConverter(), createOpIdGenerator(), {
version: '2023-10-31',
});
expect(Object.keys(result1.paths!)).toHaveLength(4);
const result2 = processRouter(testRouter, new OasConverter(), createOperationIdCounter(), {
const result2 = processRouter(testRouter, new OasConverter(), createOpIdGenerator(), {
version: '2024-10-31',
});
expect(Object.keys(result2.paths!)).toHaveLength(0);
});
it('updates description with privileges required', () => {
const result = processRouter(testRouter, new OasConverter(), createOperationIdCounter(), {
const result = processRouter(testRouter, new OasConverter(), createOpIdGenerator(), {
version: '2023-10-31',
});

View file

@ -24,8 +24,8 @@ import {
mergeResponseContent,
prepareRoutes,
setXState,
GetOpId,
} from './util';
import type { OperationIdCounter } from './operation_id_counter';
import type { GenerateOpenApiDocumentOptionsFilters } from './generate_oas';
import type { CustomOperationObject, InternalRouterRoute } from './type';
import { extractAuthzDescription } from './extract_authz_description';
@ -33,7 +33,7 @@ import { extractAuthzDescription } from './extract_authz_description';
export const processRouter = (
appRouter: Router,
converter: OasConverter,
getOpId: OperationIdCounter,
getOpId: GetOpId,
filters?: GenerateOpenApiDocumentOptionsFilters
) => {
const paths: OpenAPIV3.PathsObject = {};
@ -89,7 +89,7 @@ export const processRouter = (
: undefined,
responses: extractResponses(route, converter),
parameters,
operationId: getOpId(route.path),
operationId: getOpId({ path: route.path, method: route.method }),
};
setXState(route.options.availability, operation);

View file

@ -8,18 +8,15 @@
*/
import { schema } from '@kbn/config-schema';
import type {
CoreVersionedRouter,
VersionedRouterRoute,
} from '@kbn/core-http-router-server-internal';
import type { CoreVersionedRouter } from '@kbn/core-http-router-server-internal';
import { get } from 'lodash';
import { OasConverter } from './oas_converter';
import { createOperationIdCounter } from './operation_id_counter';
import {
processVersionedRouter,
extractVersionedResponses,
extractVersionedRequestBodies,
} from './process_versioned_router';
import { createOpIdGenerator } from './util';
let oasConverter: OasConverter;
beforeEach(() => {
@ -127,7 +124,7 @@ describe('processVersionedRouter', () => {
const baseCase = processVersionedRouter(
{ getRoutes: () => [createTestRoute()] } as unknown as CoreVersionedRouter,
new OasConverter(),
createOperationIdCounter(),
createOpIdGenerator(),
{}
);
@ -139,7 +136,7 @@ describe('processVersionedRouter', () => {
const filteredCase = processVersionedRouter(
{ getRoutes: () => [createTestRoute()] } as unknown as CoreVersionedRouter,
new OasConverter(),
createOperationIdCounter(),
createOpIdGenerator(),
{ version: '2023-10-31' }
);
expect(Object.keys(get(filteredCase, 'paths["/foo"].get.responses.200.content')!)).toEqual([
@ -151,7 +148,7 @@ describe('processVersionedRouter', () => {
const results = processVersionedRouter(
{ getRoutes: () => [createTestRoute()] } as unknown as CoreVersionedRouter,
new OasConverter(),
createOperationIdCounter(),
createOpIdGenerator(),
{}
);
expect(results.paths['/foo']).toBeDefined();
@ -164,9 +161,10 @@ describe('processVersionedRouter', () => {
});
});
const createTestRoute: () => VersionedRouterRoute = () => ({
const createTestRoute: () => any = () => ({
path: '/foo',
method: 'get',
isVersioned: true,
options: {
access: 'public',
deprecated: true,

View file

@ -19,7 +19,6 @@ import { extractAuthzDescription } from './extract_authz_description';
import type { GenerateOpenApiDocumentOptionsFilters } from './generate_oas';
import type { OasConverter } from './oas_converter';
import { isReferenceObject } from './oas_converter/common';
import type { OperationIdCounter } from './operation_id_counter';
import {
prepareRoutes,
getPathParameters,
@ -31,12 +30,13 @@ import {
mergeResponseContent,
getXsrfHeaderForMethod,
setXState,
GetOpId,
} from './util';
export const processVersionedRouter = (
appRouter: CoreVersionedRouter,
converter: OasConverter,
getOpId: OperationIdCounter,
getOpId: GetOpId,
filters?: GenerateOpenApiDocumentOptionsFilters
) => {
const routes = prepareRoutes(appRouter.getRoutes(), filters);
@ -120,7 +120,7 @@ export const processVersionedRouter = (
? extractVersionedResponse(handler, converter, contentType)
: extractVersionedResponses(route, converter, contentType),
parameters,
operationId: getOpId(route.path),
operationId: getOpId({ path: route.path, method: route.method }),
};
setXState(route.options.options?.availability, operation);

View file

@ -15,6 +15,8 @@ import {
mergeResponseContent,
prepareRoutes,
getPathParameters,
createOpIdGenerator,
GetOpId,
} from './util';
import { assignToPaths, extractTags } from './util';
@ -260,3 +262,83 @@ describe('getPathParameters', () => {
expect(getPathParameters(input)).toEqual(output);
});
});
describe('createOpIdGenerator', () => {
let getOpId: GetOpId;
beforeEach(() => {
getOpId = createOpIdGenerator();
});
test('empty', () => {
expect(() => getOpId({ method: '', path: '/asd' })).toThrow(/Must provide method and path/);
expect(() => getOpId({ method: 'get', path: '' })).toThrow(/Must provide method and path/);
expect(() => getOpId({ method: '', path: '' })).toThrow(/Must provide method and path/);
});
test('disambiguate', () => {
expect(getOpId({ method: 'get', path: '/test' })).toBe('get-test');
expect(getOpId({ method: 'get', path: '/test' })).toBe('get-test-2');
expect(getOpId({ method: 'get', path: '/test' })).toBe('get-test-3');
expect(getOpId({ method: 'get', path: '/test' })).toBe('get-test-4');
});
test.each([
{ input: { method: 'GET', path: '/api/file' }, output: 'get-file' },
{ input: { method: 'GET', path: '///api/file///' }, output: 'get-file' },
{ input: { method: 'POST', path: '/internal/api/file' }, output: 'post-file' },
{ input: { method: 'PUT', path: '/internal/file' }, output: 'put-file' },
{ input: { method: 'Put', path: 'fOO/fILe' }, output: 'put-foo-file' },
{
input: { method: 'delete', path: '/api/my/really/cool/domain/resource' },
output: 'delete-my-really-cool-domain-resource',
},
{
input: {
method: 'delete',
path: '/api/my/really/cool/domain/resource',
},
output: 'delete-my-really-cool-domain-resource',
},
{
input: {
method: 'get',
path: '/api/my/resource/{id}',
},
output: 'get-my-resource-id',
},
{
input: {
method: 'get',
path: '/api/my/resource/{id}/{type?}',
},
output: 'get-my-resource-id-type',
},
{
input: {
method: 'get',
path: '/api/my/resource/{id?}',
},
output: 'get-my-resource-id',
},
{
input: {
method: 'get',
path: '/api/my/resource/{path*}',
},
output: 'get-my-resource-path',
},
{
input: {
method: 'get',
path: '/api/my/underscore_resource',
},
output: 'get-my-underscore-resource',
},
{
input: {
method: 'get',
path: '/api/my/_underscore_resource',
},
output: 'get-my-underscore-resource',
},
])('$input.method $input.path -> $output', ({ input, output }) => {
expect(getOpId(input)).toBe(output);
});
});

View file

@ -166,10 +166,10 @@ export const getXsrfHeaderForMethod = (
];
};
export function setXState(
export const setXState = (
availability: RouteConfigOptions<RouteMethod>['availability'],
operation: CustomOperationObject
): void {
): void => {
if (availability) {
if (availability.stability === 'experimental') {
operation['x-state'] = 'Technical Preview';
@ -178,4 +178,45 @@ export function setXState(
operation['x-state'] = 'Beta';
}
}
}
};
export type GetOpId = (input: { path: string; method: string }) => string;
/**
* Best effort to generate operation IDs from route values
*/
export const createOpIdGenerator = (): GetOpId => {
const idMap = new Map<string, number>();
return function getOpId({ path, method }) {
if (!method || !path) {
throw new Error(
`Must provide method and path, received: method: "${method}", path: "${path}"`
);
}
path = path
.trim()
.replace(/^[\/]+/, '')
.replace(/[\/]+$/, '')
.toLowerCase();
const removePrefixes = ['internal/api/', 'internal/', 'api/']; // longest to shortest
for (const prefix of removePrefixes) {
if (path.startsWith(prefix)) {
path = path.substring(prefix.length);
break;
}
}
path = path
.replace(/[\{\}\?\*]/g, '') // remove special chars
.replace(/[\/_]/g, '-') // everything else to dashes
.replace(/[-]+/g, '-'); // single dashes
const opId = `${method.toLowerCase()}-${path}`;
const cachedCount = idMap.get(opId) ?? 0;
idMap.set(opId, cachedCount + 1);
return cachedCount > 0 ? `${opId}-${cachedCount + 1}` : opId;
};
};