From 5b863f760b4c8f22dd7d4476b513e3f5e9c54894 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Wed, 22 Jan 2025 20:03:43 -0500 Subject: [PATCH] feat(api): add openapi specification --- api/components/responses/400.yml | 17 +++ api/components/responses/401.yml | 17 +++ api/components/responses/403.yml | 7 + api/components/responses/404.yml | 15 ++ api/components/schemas/app.yml | 48 +++++++ api/components/schemas/cmd.yml | 3 + api/components/schemas/prep-cmd.yml | 16 +++ api/openapi.yml | 44 ++++++ api/paths/confighttp/apps/apps-by-index.yml | 37 +++++ api/paths/confighttp/apps/apps.yml | 151 ++++++++++++++++++++ api/paths/confighttp/logs/logs.yml | 20 +++ 11 files changed, 375 insertions(+) create mode 100644 api/components/responses/400.yml create mode 100644 api/components/responses/401.yml create mode 100644 api/components/responses/403.yml create mode 100644 api/components/responses/404.yml create mode 100644 api/components/schemas/app.yml create mode 100644 api/components/schemas/cmd.yml create mode 100644 api/components/schemas/prep-cmd.yml create mode 100644 api/openapi.yml create mode 100644 api/paths/confighttp/apps/apps-by-index.yml create mode 100644 api/paths/confighttp/apps/apps.yml create mode 100644 api/paths/confighttp/logs/logs.yml diff --git a/api/components/responses/400.yml b/api/components/responses/400.yml new file mode 100644 index 00000000..3736c409 --- /dev/null +++ b/api/components/responses/400.yml @@ -0,0 +1,17 @@ +--- +description: Bad Request - A parameter was not specified, or was specified incorrectly. +content: + application/json: + schema: + type: object + properties: + status_code: + type: string + status: + type: string + error: + type: string + example: + status_code: 400 + status: false + error: "Bad Request" diff --git a/api/components/responses/401.yml b/api/components/responses/401.yml new file mode 100644 index 00000000..5699431e --- /dev/null +++ b/api/components/responses/401.yml @@ -0,0 +1,17 @@ +--- +description: Unauthorized - The request requires user authentication. +content: + application/json: + schema: + type: object + properties: + status_code: + type: string + status: + type: string + error: + type: string + example: + status_code: 401 + status: false + error: "Unauthorized" diff --git a/api/components/responses/403.yml b/api/components/responses/403.yml new file mode 100644 index 00000000..9d2fd072 --- /dev/null +++ b/api/components/responses/403.yml @@ -0,0 +1,7 @@ +--- +description: Forbidden - The server understood the request, but is refusing to fulfill it. +content: + # TODO: return JSON response. + text/plain: + schema: + type: string diff --git a/api/components/responses/404.yml b/api/components/responses/404.yml new file mode 100644 index 00000000..1de9b3f6 --- /dev/null +++ b/api/components/responses/404.yml @@ -0,0 +1,15 @@ +--- +description: Not Found - The requested resource could not be found. +content: + application/json: + schema: + type: object + properties: + status_code: + type: integer + format: int32 + error: + type: string + example: + status_code: 404 + error: "Not Found" diff --git a/api/components/schemas/app.yml b/api/components/schemas/app.yml new file mode 100644 index 00000000..0a5a22db --- /dev/null +++ b/api/components/schemas/app.yml @@ -0,0 +1,48 @@ +--- +type: object +required: + - name +properties: + name: + type: string + description: Application Name, as shown on Moonlight + output: + type: string + description: The file where the output of the command is stored, if it is not specified, the output is ignored + cmd: + $ref: "./cmd.yml" + description: The main application to start. If blank, no application will be started. + exclude-global-prep-cmd: + type: boolean + description: Enable/Disable the execution of Global Prep Commands for this application. + elevated: + type: boolean + description: Run the application as an elevated process. + auto-detach: + type: boolean + description: Continue streaming if the application exits quickly + wait-all: + type: boolean + description: Continue streaming until all app processes exit + exit-timeout: + type: integer + description: Number of seconds to wait for all app processes to gracefully exit when requested to quit. + image-path: + type: string + description: | + Application icon/picture/image path that will be sent to client. Image must be a PNG file. + If not set, Sunshine will send default box image. + working-dir: + type: string + description: | + The working directory that should be passed to the process. + For example, some applications use the working directory to search for configuration files. + If not set, Sunshine will default to the parent directory of the command + prep-cmd: + type: array + items: + $ref: "./prep-cmd.yml" + detached: + type: array + items: + $ref: "./cmd.yml" diff --git a/api/components/schemas/cmd.yml b/api/components/schemas/cmd.yml new file mode 100644 index 00000000..4306ba9d --- /dev/null +++ b/api/components/schemas/cmd.yml @@ -0,0 +1,3 @@ +--- +type: string +description: Command to execute diff --git a/api/components/schemas/prep-cmd.yml b/api/components/schemas/prep-cmd.yml new file mode 100644 index 00000000..943ec543 --- /dev/null +++ b/api/components/schemas/prep-cmd.yml @@ -0,0 +1,16 @@ +--- +type: object +required: + - do + - undo + - elevated +properties: + do: + $ref: "./cmd.yml" + description: Command to run before the application starts. + undo: + $ref: "./cmd.yml" + description: Command to run after the application exits. + elevated: + type: boolean + description: Run the command as an elevated process. diff --git a/api/openapi.yml b/api/openapi.yml new file mode 100644 index 00000000..02ad95c2 --- /dev/null +++ b/api/openapi.yml @@ -0,0 +1,44 @@ +--- +# https://openapi.tools + +openapi: 3.1.0 + +info: + title: Sunshine + summary: Self-hosted game stream host for Moonlight. + version: 0.0.0 + contact: + name: LizardByte + url: https://app.lizardbyte.dev/support + license: + name: GNU General Public License v3.0 only + url: https://github.com/LizardByte/Sunshine/blob/master/LICENSE + +servers: + - url: "https://{host}:{ui-port}" + description: Sunshine server + variables: + host: + default: "localhost" + ui-port: + default: 47990 + +security: + - basicAuth: [] + +components: + securitySchemes: + # TODO: update when JWT is implemented (https://github.com/LizardByte/Sunshine/pull/2995) + # https://swagger.io/specification/#security-scheme-object-examples + basicAuth: + description: HTTP Basic authentication + type: http + scheme: basic + +paths: + /api/apps: + $ref: "./paths/confighttp/apps/apps.yml" + /api/apps/{index}: + $ref: "./paths/confighttp/apps/apps-by-index.yml" + /api/logs: + $ref: "./paths/confighttp/logs/logs.yml" diff --git a/api/paths/confighttp/apps/apps-by-index.yml b/api/paths/confighttp/apps/apps-by-index.yml new file mode 100644 index 00000000..2f389755 --- /dev/null +++ b/api/paths/confighttp/apps/apps-by-index.yml @@ -0,0 +1,37 @@ +--- +delete: + summary: Delete an application. + description: | + Delete an application. + operationId: deleteApps + tags: + - Apps + parameters: + - name: index + in: path + description: The index of the application to delete. + required: true + schema: + type: integer + format: int32 + responses: + '200': + description: The application was deleted successfully. + content: + application/json: + schema: + type: object + properties: + status: + type: string + result: + type: string + example: + status: true + result: "application 9999 deleted" + '400': + $ref: "../../../components/responses/400.yml" + '401': + $ref: "../../../components/responses/401.yml" + '403': + $ref: "../../../components/responses/403.yml" diff --git a/api/paths/confighttp/apps/apps.yml b/api/paths/confighttp/apps/apps.yml new file mode 100644 index 00000000..9047b672 --- /dev/null +++ b/api/paths/confighttp/apps/apps.yml @@ -0,0 +1,151 @@ +--- +get: + summary: Get the list of available applications. + description: | + Get the list of available applications. + operationId: getApps + tags: + - Apps + responses: + '200': + description: A list of available applications. + content: + application/json: + schema: + type: array + items: + $ref: "../../../components/schemas/app.yml" + example: + - name: "Example App" + output: "/path/to/output.log" + cmd: "example-command" + exclude-global-prep-cmd: false + elevated: false + auto-detach: true + wait-all: false + exit-timeout: 30 + image-path: "/path/to/image.png" + working-dir: "/path/to/working-dir" + prep-cmd: + - do: "prep-command-1" + undo: "undo-command-1" + elevated: false + detached: + - "detached-command-1" + '401': + $ref: "../../../components/responses/401.yml" + '403': + $ref: "../../../components/responses/403.yml" + +post: + summary: Save an application. + description: | + Save an application. + To save a new application the index must be `-1`. + To update an existing application, you must provide the current index of the application. + operationId: postApps + tags: + - Apps + parameters: + - name: index + in: query + description: The index of the application to update. If the index is -1, a new application will be created. + required: true + schema: + type: integer + format: int32 + - name: name + in: query + description: Application Name + required: false + schema: + type: string + - name: output + in: query + description: Log Output Path + required: false + schema: + type: string + - name: cmd + in: query + description: Command to run the application + required: false + schema: + $ref: "../../../components/schemas/cmd.yml" + - name: exclude-global-prep-cmd + in: query + description: Enable/Disable the execution of Global Prep Commands for this application. + required: false + schema: + type: boolean + - name: elevated + in: query + description: Run the application as an elevated process. + required: false + schema: + type: boolean + - name: auto-detach + in: query + description: Continue streaming if the application exits quickly + required: false + schema: + type: boolean + - name: wait-all + in: query + description: Continue streaming until all app processes exit + required: false + schema: + type: boolean + - name: exit-timeout + in: query + description: Number of seconds to wait for all app processes to gracefully exit when requested to quit. + required: false + schema: + type: integer + format: int32 + - name: prep-cmd + in: query + description: Commands to run before the main application + required: false + schema: + type: array + items: + $ref: "../../../components/schemas/prep-cmd.yml" + - name: detached + in: query + description: Commands to run in detached processes + required: false + schema: + type: array + items: + $ref: "../../../components/schemas/cmd.yml" + - name: image-path + in: query + description: Full path to the application image. Must be a png file. + required: false + schema: + type: string + - name: working-dir + in: query + description: The working directory that should be passed to the process. + required: false + schema: + type: string + responses: + '200': + description: The application was saved successfully. + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: + status: true + '400': + $ref: "../../../components/responses/400.yml" + '401': + $ref: "../../../components/responses/401.yml" + '403': + $ref: "../../../components/responses/403.yml" diff --git a/api/paths/confighttp/logs/logs.yml b/api/paths/confighttp/logs/logs.yml new file mode 100644 index 00000000..b64b44fe --- /dev/null +++ b/api/paths/confighttp/logs/logs.yml @@ -0,0 +1,20 @@ +--- +get: + summary: Get the logs from the log file. + description: | + Get the logs from the log file. + operationId: getLogs + tags: + - Logs + responses: + '200': + description: The contents of the log file. + content: + text/plain: + schema: + type: string + example: '[2025-01-15 17:07:58.131]: Info: Sunshine version: v...' + '401': + $ref: "../../../components/responses/401.yml" + '403': + $ref: "../../../components/responses/403.yml"