diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 5215c3cf0a68f..a0469257cacd2 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -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", diff --git a/oas_docs/output/kibana.staging.yaml b/oas_docs/output/kibana.staging.yaml index 1b38c3ecc8984..b672704e2b053 100644 --- a/oas_docs/output/kibana.staging.yaml +++ b/oas_docs/output/kibana.staging.yaml @@ -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 diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 1b38c3ecc8984..b672704e2b053 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -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 diff --git a/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap b/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap index 818c0502ad774..c147a38445247 100644 --- a/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap +++ b/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap @@ -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", diff --git a/packages/kbn-router-to-openapispec/src/generate_oas.test.fixture.ts b/packages/kbn-router-to-openapispec/src/generate_oas.test.fixture.ts index b3f20da38915b..f4ba66f992134 100644 --- a/packages/kbn-router-to-openapispec/src/generate_oas.test.fixture.ts +++ b/packages/kbn-router-to-openapispec/src/generate_oas.test.fixture.ts @@ -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', diff --git a/packages/kbn-router-to-openapispec/src/generate_oas.ts b/packages/kbn-router-to-openapispec/src/generate_oas.ts index 8bc3333193624..9c7423147721b 100644 --- a/packages/kbn-router-to-openapispec/src/generate_oas.ts +++ b/packages/kbn-router-to-openapispec/src/generate_oas.ts @@ -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); diff --git a/packages/kbn-router-to-openapispec/src/operation_id_counter.test.ts b/packages/kbn-router-to-openapispec/src/operation_id_counter.test.ts deleted file mode 100644 index dbc4bf5956d69..0000000000000 --- a/packages/kbn-router-to-openapispec/src/operation_id_counter.test.ts +++ /dev/null @@ -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); - }); -}); diff --git a/packages/kbn-router-to-openapispec/src/operation_id_counter.ts b/packages/kbn-router-to-openapispec/src/operation_id_counter.ts deleted file mode 100644 index 2d576b1ca67c3..0000000000000 --- a/packages/kbn-router-to-openapispec/src/operation_id_counter.ts +++ /dev/null @@ -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(); - 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; - }; -}; diff --git a/packages/kbn-router-to-openapispec/src/process_router.test.ts b/packages/kbn-router-to-openapispec/src/process_router.test.ts index 96a10b25d648a..17191e7ab1b1c 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.test.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.test.ts @@ -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', }); diff --git a/packages/kbn-router-to-openapispec/src/process_router.ts b/packages/kbn-router-to-openapispec/src/process_router.ts index c66e3ee0f7bbf..f096d2bb1ca32 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.ts @@ -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); diff --git a/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts b/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts index 3166b7f906985..c2eb872f1e225 100644 --- a/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts +++ b/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts @@ -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, diff --git a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts index c92b3a5736003..f0c45b82d1d81 100644 --- a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts @@ -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); diff --git a/packages/kbn-router-to-openapispec/src/util.test.ts b/packages/kbn-router-to-openapispec/src/util.test.ts index abbb605df79e5..f9692e57e1f50 100644 --- a/packages/kbn-router-to-openapispec/src/util.test.ts +++ b/packages/kbn-router-to-openapispec/src/util.test.ts @@ -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); + }); +}); diff --git a/packages/kbn-router-to-openapispec/src/util.ts b/packages/kbn-router-to-openapispec/src/util.ts index beefbebc0aec7..a5718fa92120f 100644 --- a/packages/kbn-router-to-openapispec/src/util.ts +++ b/packages/kbn-router-to-openapispec/src/util.ts @@ -166,10 +166,10 @@ export const getXsrfHeaderForMethod = ( ]; }; -export function setXState( +export const setXState = ( availability: RouteConfigOptions['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(); + 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; + }; +};