From fa7cb28234849d3776b1164c35a277bea79dc863 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Thu, 16 Apr 2026 17:31:53 +0300 Subject: [PATCH 1/2] api/resources: Add the missing query parameters on the primary examples Change-type: patch See: https://balena.fibery.io/Work/Project/1704 --- openapi.yaml | 38 +++++++++---------- ...generate-openapi-spec-from-resourcejson.js | 10 +++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index befece9469..a79cb06f58 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -900,7 +900,7 @@ paths: --- - `GET /v7/device_config_variable` + `GET /v7/device_config_variable?$filter=device eq ` post: tags: - Device config variable @@ -984,7 +984,7 @@ paths: --- - `GET /v7/device_environment_variable` + `GET /v7/device_environment_variable?$filter=device/any(d:d/uuid eq '')` ### Usage Variations @@ -1075,7 +1075,7 @@ paths: --- - `GET /v7/device_service_environment_variable` + `GET /v7/device_service_environment_variable?$filter=service_install/any(si:si/device/any(d:d/uuid eq ''))` ### Usage Variations @@ -1169,7 +1169,7 @@ paths: --- - `GET /v7/device_tag` + `GET /v7/device_tag?$filter=device/uuid eq ''` post: tags: - Device tag @@ -1284,7 +1284,7 @@ paths: - Device type summary: Get a device type by its NAME description: |- - `GET /v7/device_type` + `GET /v7/device_type?$filter=name eq ''` When querying a private device type it's necessary to include your bearer token. For public device types the auth header is optional. @@ -1310,7 +1310,7 @@ paths: --- - `GET /download` + `GET /download?deviceType=&version=&fileType=.zip'` In order to download an ESR or private balenaOS image, you need to provide your bearer token. The `deviceType` and `version` parameters are required. Add an `--output` flag to provide a path for the image to be downloaded. @@ -1353,7 +1353,7 @@ paths: --- - `GET /v7/application` + `GET /v7/application?$filter=organization/any(o:o/handle eq '')` ### Usage Variations @@ -1562,7 +1562,7 @@ paths: --- - `GET /v7/application_config_variable` + `GET /v7/application_config_variable?$filter=application eq ` post: tags: - Fleet config variable @@ -1646,7 +1646,7 @@ paths: --- - `GET /v7/application_environment_variable` + `GET /v7/application_environment_variable?$filter=application eq ` post: tags: - Fleet environment variable @@ -1747,7 +1747,7 @@ paths: --- - `GET /v7/service_environment_variable` + `GET /v7/service_environment_variable?$filter=service eq ` post: tags: - Fleet service variable @@ -1830,7 +1830,7 @@ paths: --- - `GET /v7/application_tag` + `GET /v7/application_tag?$filter=application/app_name eq ''` post: tags: - Fleet tag @@ -1909,7 +1909,7 @@ paths: --- - `GET /v7/release` + `GET /v7/release?$select=raw_version&$filter=(is_final eq true) and (is_invalidated eq false) and (status eq 'success') and (semver_major gt 0) and (belongs_to__application/any(bta:(bta/is_host eq true) and (bta/is_for__device_type/any(dt:dt/slug eq ''))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` To request a list of the supported balenaOS versions for a particular device type, the `DEVICE TYPE SLUG` parameter is required. Even though this query only selects the `raw_version` field, you can additionally specify any of the fields found in the release resource. The Authorization header is optional. @@ -1937,7 +1937,7 @@ paths: --- - `GET /v7/release` + `GET /v7/release?$select=id,raw_version&$filter=(status eq 'success') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,'balena_os%2F') and endswith(a/slug,'-supervisor')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture/any(c:c/slug eq ''))))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` To request a list of the supported supervisor releases for a particular cpu architecture, the `CPU_ARCHITECTURE_SLUG` parameter is required. Even though this query only selects the `id` and `raw_version` fields, you can additionally specify any of the fields found in the release resource. The Authorization header is optional. @@ -2056,7 +2056,7 @@ paths: --- - `GET /v7/release` + `GET /v7/release?$filter=belongs_to__application eq ` ### Usage Variations @@ -2074,7 +2074,7 @@ paths: - Release summary: Get the release raw_version field description: |- - `GET /v7/release()` + `GET /v7/release()?$select=raw_version` The raw_version field is returned only when explicitly requested with $select. parameters: @@ -2099,7 +2099,7 @@ paths: --- - `GET /v7/release_tag` + `GET /v7/release_tag?$filter=release/commit eq ''` post: tags: - Release tag @@ -2145,7 +2145,7 @@ paths: --- - `GET /v7/service` + `GET /v7/service?$filter=application/app_name eq ''` /v7/service_install: get: tags: @@ -2164,7 +2164,7 @@ paths: --- - `GET /v7/service_install` + `GET /v7/service_install?$filter=device/uuid eq ''&$expand=installs__service($select=service_name)` /v7/user__has__public_key: get: tags: @@ -2358,7 +2358,7 @@ paths: tags: - User summary: Get users associated with fleet - description: '`GET /v7/user__is_member_of__application`' + description: '`GET /v7/user__is_member_of__application?$expand=user($select=id,username,actor),application_membership_role($select=id,name,actor)&$filter=is_member_of__application eq `' post: tags: - User diff --git a/tools/generate-openapi-spec-from-resourcejson.js b/tools/generate-openapi-spec-from-resourcejson.js index 14eb206d1f..978b357f6c 100644 --- a/tools/generate-openapi-spec-from-resourcejson.js +++ b/tools/generate-openapi-spec-from-resourcejson.js @@ -125,7 +125,7 @@ function convertResourceToOpenApi(inputPath, outputPath) { pathKey = `${pathKey}#${tagName.replace(/\s+/g, '_')}`; } - if (!openapi.paths[pathKey]) openapi.paths[pathKey] = {}; + openapi.paths[pathKey] ??= {}; if (!openapi.paths[pathKey][method]) { const op = { tags: [tagName], @@ -190,12 +190,13 @@ function convertResourceToOpenApi(inputPath, outputPath) { op.summary = ex.summary; op.description = ex.description || ''; op['x-primary-endpoint'] = cleanEndpoint; + op['x-primary-filter'] = ex.filters; op['x-primary-method'] = ex.method; op['x-primary-data'] = formattedData; } else { op['x-variations'].push({ summary: ex.summary, - filter: ex.filters || 'None', + filter: ex.filters, description: ex.description, endpoint: cleanEndpoint, method: ex.method, @@ -211,7 +212,7 @@ function convertResourceToOpenApi(inputPath, outputPath) { if (op['x-fields-table']) fullDescription += op['x-fields-table']; if (op['x-primary-method']) { if (op['x-fields-table']) fullDescription += '\n'; - fullDescription += `\`${op['x-primary-method']} ${op['x-primary-endpoint']}\`\n`; + fullDescription += `\`${op['x-primary-method']} ${op['x-primary-endpoint']}${op['x-primary-filter'] ? unescapeEndpoint(op['x-primary-filter']) : ''}\`\n`; if (op['x-primary-data'] && op['x-primary-data'].trim() !== '') { fullDescription += `\n**Request Body:**\n\`\`\`json\n${op['x-primary-data']}\n\`\`\`\n`; } @@ -222,7 +223,7 @@ function convertResourceToOpenApi(inputPath, outputPath) { fullDescription += '\n\n### Usage Variations\n'; op['x-variations'].forEach((v) => { fullDescription += `\n--- \n#### ${v.summary}\n`; - fullDescription += `\`${v.method} ${v.endpoint}${v.filter !== 'None' ? unescapeEndpoint(v.filter) : ''}\`\n`; + fullDescription += `\`${v.method} ${v.endpoint}${v.filter ? unescapeEndpoint(v.filter) : ''}\`\n`; if (v.data && v.data.trim() !== '') { fullDescription += `\n**Request Body:**\n\`\`\`json\n${v.data}\n\`\`\`\n`; } @@ -232,6 +233,7 @@ function convertResourceToOpenApi(inputPath, outputPath) { op.description = fullDescription.trim(); delete op['x-variations']; delete op['x-primary-endpoint']; + delete op['x-primary-filter']; delete op['x-primary-method']; delete op['x-primary-data']; delete op['x-fields-table']; From adfa0f132e33c5f20595316144818f3ef8311022 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Thu, 16 Apr 2026 19:03:32 +0300 Subject: [PATCH 2/2] api/resouces: Include the filter in the url of Supervisor & OS Release examples Change-type: patch --- config/dictionaries/resource.json | 23 +++--- openapi.yaml | 76 +++++++++++++------ ...generate-openapi-spec-from-resourcejson.js | 16 +++- 3 files changed, 81 insertions(+), 34 deletions(-) diff --git a/config/dictionaries/resource.json b/config/dictionaries/resource.json index cfa4257b4f..8616624ff8 100644 --- a/config/dictionaries/resource.json +++ b/config/dictionaries/resource.json @@ -519,7 +519,7 @@ "summary": "Get a device type by its SLUG", "description": "When querying a private device type it's necessary to include your bearer token. For public device types the auth header is optional.", "method": "GET", - "endpoint": "/v7/device_type(slug='')", + "endpoint": "/v7/device_type(slug='')", "filters": "" }, { @@ -528,7 +528,7 @@ "description": "When querying a private device type it's necessary to include your bearer token. For public device types the auth header is optional.", "method": "GET", "endpoint": "/v7/device_type", - "filters": "?\\$filter=name%20eq%20''" + "filters": "?\\$filter=name%20eq%20''" }, { "id": "get-supported-device-types", @@ -1048,6 +1048,7 @@ { "id": "supervisor_release", "name": "List Supervisor releases", + "aliasOfResource": "release", "fields": [ "id", "raw_version" @@ -1080,17 +1081,21 @@ ] }, { - "id": "balenaos_versions", + "id": "balenaos_releases", "name": "List balenaOS releases", - "fields": [], + "aliasOfResource": "release", + "fields": [ + "id", + "raw_version" + ], "examples": [ { "id": "list-balenaos-versions-for-device-type", "summary": "List the supported balenaOS versions for a device type", - "description": "To request a list of the supported balenaOS versions for a particular device type, the `DEVICE TYPE SLUG` parameter is required. Even though this query only selects the `raw_version` field, you can additionally specify any of the fields found in the release resource. The Authorization header is optional.", + "description": "To request a list of the supported balenaOS versions for a particular device type, the `DEVICE_TYPE_SLUG` parameter is required. Even though this query only selects the `raw_version` field, you can additionally specify any of the fields found in the release resource. The Authorization header is optional.", "method": "GET", "endpoint": "/v7/release", - "filters": "?\\$select=raw_version&\\$filter=(is_final%20eq%20true)%20and%20(is_invalidated%20eq%20false)%20and%20(status%20eq%20'success')%20and%20(semver_major%20gt%200)%20and%20(belongs_to__application/any(bta:(bta/is_host%20eq%20true)%20and%20(bta/is_for__device_type/any(dt:dt/slug%20eq%20''))))&\\$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc" + "filters": "?\\$select=id,raw_version&\\$filter=(is_final%20eq%20true)%20and%20(is_invalidated%20eq%20false)%20and%20(status%20eq%20'success')%20and%20(semver_major%20gt%200)%20and%20(belongs_to__application/any(bta:(bta/is_host%20eq%20true)%20and%20(bta/is_for__device_type/any(dt:dt/slug%20eq%20''))))&\\$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc" }, { "id": "list-balenaos-versions-for-private-device-type", @@ -1098,7 +1103,7 @@ "description": "Same as above, but in order to access private device types, you must provide an authentication token.", "method": "GET", "endpoint": "/v7/release", - "filters": "?\\$select=raw_version&\\$filter=(is_final%20eq%20true)%20and%20(is_invalidated%20eq%20false)%20and%20(status%20eq%20'success')%20and%20(semver_major%20gt%200)%20and%20(belongs_to__application/any(bta:(bta/is_host%20eq%20true)%20and%20(bta/is_for__device_type/any(dt:dt/slug%20eq%20''))))&\\$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc" + "filters": "?\\$select=id,raw_version&\\$filter=(is_final%20eq%20true)%20and%20(is_invalidated%20eq%20false)%20and%20(status%20eq%20'success')%20and%20(semver_major%20gt%200)%20and%20(belongs_to__application/any(bta:(bta/is_host%20eq%20true)%20and%20(bta/is_for__device_type/any(dt:dt/slug%20eq%20''))))&\\$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc" } ] }, @@ -1114,7 +1119,7 @@ "method": "GET", "endpoint": "/download", "content-type": "application/octet-stream", - "filters": "?deviceType=&version=&fileType=.zip'" + "filters": "?deviceType=&version=&fileType=.zip'" }, { "id": "download-balenaos", @@ -1123,7 +1128,7 @@ "method": "GET", "endpoint": "/download", "content-type": "application/octet-stream", - "filters": "?deviceType=&version=&fileType=.gz'" + "filters": "?deviceType=&version=&fileType=.gz'" } ] }, diff --git a/openapi.yaml b/openapi.yaml index a79cb06f58..1e6b687280 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -293,6 +293,14 @@ components: description: Type information not available yet value: description: Type information not available yet + balenaos_releases: + type: object + title: List balenaOS releases Model + properties: + id: + description: Type information not available yet + raw_version: + description: Type information not available yet supervisor_release: type: object title: List Supervisor releases Model @@ -1265,17 +1273,17 @@ paths: - name: ID in: path required: true - /v7/device_type(slug='{DEVICE TYPE SLUG}'): + /v7/device_type(slug='{DEVICE_TYPE_SLUG}'): get: tags: - Device type summary: Get a device type by its SLUG description: |- - `GET /v7/device_type(slug='')` + `GET /v7/device_type(slug='')` When querying a private device type it's necessary to include your bearer token. For public device types the auth header is optional. parameters: - - name: DEVICE TYPE SLUG + - name: DEVICE_TYPE_SLUG in: path required: true /v7/device_type: @@ -1284,7 +1292,7 @@ paths: - Device type summary: Get a device type by its NAME description: |- - `GET /v7/device_type?$filter=name eq ''` + `GET /v7/device_type?$filter=name eq ''` When querying a private device type it's necessary to include your bearer token. For public device types the auth header is optional. @@ -1310,7 +1318,7 @@ paths: --- - `GET /download?deviceType=&version=&fileType=.zip'` + `GET /download?deviceType=&version=&fileType=.zip'` In order to download an ESR or private balenaOS image, you need to provide your bearer token. The `deviceType` and `version` parameters are required. Add an `--output` flag to provide a path for the image to be downloaded. @@ -1319,7 +1327,7 @@ paths: --- #### Download public balenaOS images - `GET /download?deviceType=&version=&fileType=.gz'` + `GET /download?deviceType=&version=&fileType=.gz'` Same as above but the auth header is optional to use. The `deviceType` and `version` parameters are required. These releases also available for download on balena.io/os and the dashboard. /v7/application: @@ -1895,7 +1903,7 @@ paths: - name: ID in: path required: true - /v7/release: + /v7/release?$select=id,raw_version&$filter=%28is_final%20eq%20true%29%20and%20%28is_invalidated%20eq%20false%29%20and%20%28status%20eq%20'success'%29%20and%20%28semver_major%20gt%200%29%20and%20%28belongs_to__application/any%28bta:%28bta/is_host%20eq%20true%29%20and%20%28bta/is_for__device_type/any%28dt:dt/slug%20eq%20'{DEVICE_TYPE_SLUG}'%29%29%29%29&$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc: get: tags: - List balenaOS releases @@ -1905,23 +1913,29 @@ paths: | Field | | :--- | + | `id` | + | `raw_version` | --- - `GET /v7/release?$select=raw_version&$filter=(is_final eq true) and (is_invalidated eq false) and (status eq 'success') and (semver_major gt 0) and (belongs_to__application/any(bta:(bta/is_host eq true) and (bta/is_for__device_type/any(dt:dt/slug eq ''))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` + `GET /v7/release?$select=id,raw_version&$filter=(is_final eq true) and (is_invalidated eq false) and (status eq 'success') and (semver_major gt 0) and (belongs_to__application/any(bta:(bta/is_host eq true) and (bta/is_for__device_type/any(dt:dt/slug eq ''))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` - To request a list of the supported balenaOS versions for a particular device type, the `DEVICE TYPE SLUG` parameter is required. Even though this query only selects the `raw_version` field, you can additionally specify any of the fields found in the release resource. The Authorization header is optional. + To request a list of the supported balenaOS versions for a particular device type, the `DEVICE_TYPE_SLUG` parameter is required. Even though this query only selects the `raw_version` field, you can additionally specify any of the fields found in the release resource. The Authorization header is optional. ### Usage Variations --- #### List the supported balenaOS versions for a private device type - `GET /v7/release?$select=raw_version&$filter=(is_final eq true) and (is_invalidated eq false) and (status eq 'success') and (semver_major gt 0) and (belongs_to__application/any(bta:(bta/is_host eq true) and (bta/is_for__device_type/any(dt:dt/slug eq ''))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` + `GET /v7/release?$select=id,raw_version&$filter=(is_final eq true) and (is_invalidated eq false) and (status eq 'success') and (semver_major gt 0) and (belongs_to__application/any(bta:(bta/is_host eq true) and (bta/is_for__device_type/any(dt:dt/slug eq ''))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` Same as above, but in order to access private device types, you must provide an authentication token. - /v7/release#List_Supervisor_releases: + parameters: + - name: DEVICE_TYPE_SLUG + in: path + required: true + /v7/release?$select=id,raw_version&$filter=%28status%20eq%20'success'%29%20and%20%28is_final%20eq%20true%29%20and%20%28is_invalidated%20eq%20false%29%20and%20%28semver_major%20gt%200%29%20and%20%28belongs_to__application/any%28a:%28startswith%28a/slug,'balena_os%2F'%29%20and%20endswith%28a/slug,'-supervisor'%29%29%20and%20%28%28a/is_public%20eq%20true%29%20and%20%28a/is_host%20eq%20false%29%20and%20%28a/is_for__device_type/any%28dt:dt/is_of__cpu_architecture/any%28c:c/slug%20eq%20'{CPU_ARCHITECTURE_SLUG}'%29%29%29%29%29%29&$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc: get: tags: - List Supervisor releases @@ -1940,17 +1954,33 @@ paths: `GET /v7/release?$select=id,raw_version&$filter=(status eq 'success') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,'balena_os%2F') and endswith(a/slug,'-supervisor')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture/any(c:c/slug eq ''))))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` To request a list of the supported supervisor releases for a particular cpu architecture, the `CPU_ARCHITECTURE_SLUG` parameter is required. Even though this query only selects the `id` and `raw_version` fields, you can additionally specify any of the fields found in the release resource. The Authorization header is optional. - - - ### Usage Variations - - --- - #### Get all supervisor releases for a specific cpu architecture by ID - `GET /v7/release?$select=id,raw_version&$filter=(status eq 'success') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,'balena_os%2F') and endswith(a/slug,'-supervisor')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture eq )))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` - - --- - #### Get a specific supervisor release version for a specific cpu architecture - `GET /v7/release?$select=id,raw_version&$filter=(status eq 'success') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,'balena_os%2F') and endswith(a/slug,'-supervisor')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture/any(c:c/slug eq '')))))) and (raw_version eq '')&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc` + parameters: + - name: CPU_ARCHITECTURE_SLUG + in: path + required: true + /v7/release?$select=id,raw_version&$filter=%28status%20eq%20'success'%29%20and%20%28is_final%20eq%20true%29%20and%20%28is_invalidated%20eq%20false%29%20and%20%28semver_major%20gt%200%29%20and%20%28belongs_to__application/any%28a:%28startswith%28a/slug,'balena_os%2F'%29%20and%20endswith%28a/slug,'-supervisor'%29%29%20and%20%28%28a/is_public%20eq%20true%29%20and%20%28a/is_host%20eq%20false%29%20and%20%28a/is_for__device_type/any%28dt:dt/is_of__cpu_architecture%20eq%20{CPU_ARCHITECTURE_ID}%29%29%29%29%29&$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc: + get: + tags: + - List Supervisor releases + summary: Get all supervisor releases for a specific cpu architecture by ID + description: '`GET /v7/release?$select=id,raw_version&$filter=(status eq ''success'') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,''balena_os%2F'') and endswith(a/slug,''-supervisor'')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture eq )))))&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc`' + parameters: + - name: CPU_ARCHITECTURE_ID + in: path + required: true + /v7/release?$select=id,raw_version&$filter=%28status%20eq%20'success'%29%20and%20%28is_final%20eq%20true%29%20and%20%28is_invalidated%20eq%20false%29%20and%20%28semver_major%20gt%200%29%20and%20%28belongs_to__application/any%28a:%28startswith%28a/slug,'balena_os%2F'%29%20and%20endswith%28a/slug,'-supervisor'%29%29%20and%20%28%28a/is_public%20eq%20true%29%20and%20%28a/is_host%20eq%20false%29%20and%20%28a/is_for__device_type/any%28dt:dt/is_of__cpu_architecture/any%28c:c/slug%20eq%20'{CPU_ARCHITECTURE_SLUG}'%29%29%29%29%29%29%20and%20%28raw_version%20eq%20'{VERSION}'%29&$orderby=semver_major%20desc,semver_minor%20desc,semver_patch%20desc,revision%20desc: + get: + tags: + - List Supervisor releases + summary: Get a specific supervisor release version for a specific cpu architecture + description: '`GET /v7/release?$select=id,raw_version&$filter=(status eq ''success'') and (is_final eq true) and (is_invalidated eq false) and (semver_major gt 0) and (belongs_to__application/any(a:(startswith(a/slug,''balena_os%2F'') and endswith(a/slug,''-supervisor'')) and ((a/is_public eq true) and (a/is_host eq false) and (a/is_for__device_type/any(dt:dt/is_of__cpu_architecture/any(c:c/slug eq '''')))))) and (raw_version eq '''')&$orderby=semver_major desc,semver_minor desc,semver_patch desc,revision desc`' + parameters: + - name: CPU_ARCHITECTURE_SLUG + in: path + required: true + - name: VERSION + in: path + required: true /v7/organization: get: tags: @@ -2018,7 +2048,7 @@ paths: --- `GET /v7/organization_membership` - /v7/release#Release: + /v7/release: get: tags: - Release diff --git a/tools/generate-openapi-spec-from-resourcejson.js b/tools/generate-openapi-spec-from-resourcejson.js index 978b357f6c..1f64d97708 100644 --- a/tools/generate-openapi-spec-from-resourcejson.js +++ b/tools/generate-openapi-spec-from-resourcejson.js @@ -28,6 +28,14 @@ const unescapeEndpoint = (str) => { .replace(/%29/g, ')'); }; +const escapeFilters = (str) => { + if (!str) return ''; + return str + .replace(/ /g, '%20') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29'); +} + const formatJsonData = (dataStr) => { if (!dataStr || dataStr.trim() === '') return ''; let fixed = dataStr.replace(/"\s*\n\s*"/g, '",\n"'); @@ -117,12 +125,16 @@ function convertResourceToOpenApi(inputPath, outputPath) { const method = ex.method.toLowerCase(); const cleanEndpoint = unescapeEndpoint(ex.endpoint); - let pathKey = cleanEndpoint.split('?')[0].replace(/<([^>]+)>/g, '{$1}'); + let pathKey = cleanEndpoint.split('?')[0]; + if (resource.aliasOfResource) { + pathKey = `${cleanEndpoint}${ex.filters ? ex.filters : ''}`; + } + pathKey = pathKey.replace(/<([^>]+)>/g, '{$1}'); // Handle duplicate paths across tags via Fragment Shadowing const existingPath = openapi.paths[pathKey]; if (existingPath && Object.values(existingPath)[0].tags[0] !== tagName) { - pathKey = `${pathKey}#${tagName.replace(/\s+/g, '_')}`; + throw new Error(`Found duplicate path "${pathKey}" while generating example "${ex.id}"`); } openapi.paths[pathKey] ??= {};