Skip to content

Commit

Permalink
updating sauce connect api (#260)
Browse files Browse the repository at this point in the history
* apis: updating sauce connect api

* docs: generating api docs

* tests: updating versions.json mock
  • Loading branch information
waggledans authored Aug 19, 2024
1 parent 69a114c commit c231cd5
Show file tree
Hide file tree
Showing 8 changed files with 576 additions and 93 deletions.
166 changes: 166 additions & 0 deletions apis/sauce.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,84 @@
},
"type": "object"
},
"SauceConnectDownloadInfo": {
"type": "object",
"properties": {
"download_url": {
"type": "string"
},
"sha1": {
"type": "string",
"nullable": true
},
"sha256": {
"type": "string",
"nullable": true
},
"version": {
"type": "string",
"nullable": true
}
}
},
"SauceConnectByPlatform": {
"type": "object",
"properties": {
"linux": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"linux-arm64": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"win32": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"osx": {
"$ref": "#/definitions/SauceConnectDownloadInfo"
}
}
},
"SauceConnectVersions": {
"type": "object",
"properties": {
"latest_version": {
"type": "string"
},
"client_version": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["LATEST", "UPGRADE", "PRERELEASE", "UNKNOWN", "EOL"]
},
"info_url": {
"type": "string"
},
"download_url": {
"type": "string"
},
"sha1": {
"type": "string",
"nullable": true
},
"sha256": {
"type": "string",
"nullable": true
}
},
"downloads": {
"$ref": "#/definitions/SauceConnectByPlatform"
},
"all_downloads": {
"type": "array",
"items": {
"$ref": "#/definitions/SauceConnectByPlatform"
}
}
},
"SauceStatus": {
"properties": {
"service_operational": {
Expand Down Expand Up @@ -742,6 +820,20 @@
"required": true,
"type": "string"
},
"clientHost": {
"description": "SC client host OS and CPU arch",
"in": "query",
"name": "client_host",
"required": false,
"type": "string"
},
"clientVersion": {
"description": "SC client version",
"in": "query",
"name": "client_version",
"required": false,
"type": "string"
},
"filepath": {
"description": "file path to store the asset at",
"in": "path",
Expand All @@ -756,6 +848,14 @@
"required": true,
"type": "string"
},
"filter": {
"description": "Filter expression to apply before returning query results",
"in": "query",
"name": "filter",
"enum": ["v2alpha", "one_per_pool"],
"required": false,
"type": "string"
},
"full": {
"description": "Should the response result contain everything or just the basics",
"in": "query",
Expand Down Expand Up @@ -811,6 +911,21 @@
"type": "object"
}
},
"protocol": {
"description": "Sauce Connect Protocol",
"in": "query",
"name": "protocol",
"required": false,
"enum": ["kgp", "h2c"],
"type": "string"
},
"reason": {
"description": "Reason for stopping a tunnel",
"in": "query",
"name": "reason",
"required": true,
"type": "string"
},
"subaccounts": {
"default": false,
"description": "Include subaccounts in list of jobs",
Expand All @@ -825,6 +940,13 @@
"required": true,
"type": "string"
},
"wait_for_jobs": {
"default": true,
"description": "Wait for jobs to finish",
"in": "query",
"name": "wait_for_jobs",
"type": "boolean"
},
"jobIds": {
"description": "list of jobIds",
"in": "query",
Expand Down Expand Up @@ -1539,6 +1661,12 @@
},
{
"$ref": "#/parameters/full"
},
{
"$ref": "#/parameters/filter"
},
{
"$ref": "#/parameters/protocol"
}
],
"responses": {
Expand Down Expand Up @@ -1577,6 +1705,12 @@
},
{
"$ref": "#/parameters/id"
},
{
"$ref": "#/parameters/reason"
},
{
"$ref": "#/parameters/wait_for_jobs"
}
],
"responses": {
Expand Down Expand Up @@ -1633,6 +1767,38 @@
"tags": ["Tunnel"]
}
},
"/v1/public/tunnels/info/versions": {
"get": {
"operationId": "sc_versions",
"parameters": [
{
"$ref": "#/parameters/clientVersion"
},
{
"$ref": "#/parameters/clientHost"
},
{
"$ref": "#/parameters/all"
}
],
"responses": {
"200": {
"description": "Tunnels",
"schema": {
"$ref": "#/definitions/SauceConnectVersions"
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
},
"summary": "Get tunnels for the user or all the users in the team",
"tags": ["Tunnel"]
}
},
"/v1/jobs/{id}/{assetName}": {
"get": {
"operationId": "download_job_asset",
Expand Down
83 changes: 14 additions & 69 deletions docs/interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,46 +61,6 @@ The following commands are available via package or cli tool:
<code>api.getStatus()</code>
</td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/manual</code><br>
complete manual task
<h3>Example:</h3>
<code>api.deleteManualJob(ids)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/manual</code><br>
Creates a manual job
<h3>Example:</h3>
<code>api.createManualJob(capabilities)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/manual/options/</code><br>
returns a list of supported platforms in the Sauce cloud
<h3>Example:</h3>
<code>api.listManualPlatforms()</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/manual/{taskId}</code><br>
get manual task
<h3>Example:</h3>
<code>api.getManualJob(taskId)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/manual/{taskId}/screenshot</code><br>
Take screenshot in manual session
<h3>Example:</h3>
<code>api.createManualJobScreenshot(taskId)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/me</code><br>
Expand All @@ -109,22 +69,6 @@ The following commands are available via package or cli tool:
<code>api.getCurrentUser()</code>
</td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/tasks</code><br>
complete manual task
<h3>Example:</h3>
<code>api.deleteManualJobLegacy(ids)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/tasks</code><br>
Creates a manual job
<h3>Example:</h3>
<code>api.createManualJobLegacy(capabilities)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/users/{username}</code><br>
Expand Down Expand Up @@ -220,15 +164,16 @@ The following commands are available via package or cli tool:
<h3>Example:</h3>
<code>api.listTunnels(username, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>all</b>: Should the response contain the same team user data</li> <li><b>full</b>: Should the response result contain everything or just the basics</li> </ul> </td>
<ul> <li><b>all</b>: Should the response contain the same team user data</li> <li><b>full</b>: Should the response result contain everything or just the basics</li> <li><b>filter</b>: Filter expression to apply before returning query results</li> <li><b>protocol</b>: Sauce Connect Protocol</li> </ul> </td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/{username}/tunnels/{id}</code><br>
Delete a Tunnel
<h3>Example:</h3>
<code>api.deleteTunnel(username, id)</code>
</td>
<code>api.deleteTunnel(username, id, reason, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>wait_for_jobs</b>: Wait for jobs to finish</li> </ul> </td>
</tr>
<tr>
<td>
Expand All @@ -238,6 +183,15 @@ The following commands are available via package or cli tool:
<code>api.getTunnel(username, id)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/public/tunnels/info/versions</code><br>
Get tunnels for the user or all the users in the team
<h3>Example:</h3>
<code>api.scVersions({ ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>client_version</b>: SC client version</li> <li><b>client_host</b>: SC client host OS and CPU arch</li> <li><b>all</b>: Should the response contain the same team user data</li> </ul> </td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/jobs/{id}/{assetName}</code><br>
Expand All @@ -256,15 +210,6 @@ The following commands are available via package or cli tool:
<br><h4>Options</h4>
<ul> <li><b>full</b>: Should the response result contain everything or just the basics</li> </ul> </td>
</tr>
<tr>
<td>
<b>POST</b> <code>/storage/upload</code><br>
Returns new application id after the upload.
<h3>Example:</h3>
<code>api.uploadApp({ ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>App-Type</b>: Application type</li> <li><b>App-Identifier</b>: Your custom unique identifier for your app</li> <li><b>App-DisplayName</b>: Your custom display name</li> <li><b>App-Active</b>: If true makes uploaded application active one</li> <li><b>body</b>: No description available.</li> </ul> </td>
</tr>
<tr>
<td>
<b>GET</b> <code>/metrics/</code><br>
Expand Down Expand Up @@ -584,7 +529,7 @@ The following commands are available via package or cli tool:
<h3>Example:</h3>
<code>api.getBuildsV2(build_source, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>user_id</b>: user_id</li> <li><b>org_id</b>: org_id</li> <li><b>group_id</b>: group_id</li> <li><b>team_id</b>: team_id</li> <li><b>status</b>: status</li> <li><b>name</b>: start</li> <li><b>end</b>: end</li> <li><b>limit</b>: Number of results to return</li> <li><b>offset</b>: Starting number</li> <li><b>sort</b>: sort</li> </ul> </td>
<ul> <li><b>user_id</b>: user_id</li> <li><b>org_id</b>: org_id</li> <li><b>group_id</b>: group_id</li> <li><b>team_id</b>: team_id</li> <li><b>status</b>: status</li> <li><b>start_time</b>: start_time</li> <li><b>end_time</b>: end_time</li> <li><b>limit</b>: Number of results to return</li> <li><b>offset</b>: Starting number</li> <li><b>sort</b>: sort</li> </ul> </td>
</tr>
<tr>
<td>
Expand Down
14 changes: 9 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,20 +529,24 @@ export default class SauceLabs {
const options = args.slice(pathParams.length)[0] || {};
for (const optionParam of params.filter((p) => p.in === 'query')) {
const expectedType = optionParam.type.replace('integer', 'number');
// I'm not sure why query param name is camel-cased here, underscore params do exist in Sauce Labs.
const optionName = camelCase(optionParam.name);
const option = options[optionName];
const optionValue = options[optionName] || options[optionParam.name];
const isRequired =
Boolean(optionParam.required) ||
(typeof optionParam.required === 'undefined' &&
typeof optionParam.default === 'undefined');
if ((isRequired || option) && !isValidType(option, expectedType)) {
if (
(isRequired || optionValue) &&
!isValidType(optionValue, expectedType)
) {
throw new Error(
`Expected parameter for option '${optionName}' from type '${expectedType}', found '${typeof option}'`
`Expected parameter for option '${optionName}' from type '${expectedType}', found '${typeof optionValue}'`
);
}

if (typeof option !== 'undefined') {
bodyMap.set(optionParam.name, option);
if (typeof optionValue !== 'undefined') {
bodyMap.set(optionParam.name, optionValue);
}
}

Expand Down
Loading

0 comments on commit c231cd5

Please sign in to comment.